Work more on waterbox and convert GPGX64 to use the new PERunner. Doesn't work yet.
This commit is contained in:
parent
6053cd6e35
commit
a325969963
|
@ -42,7 +42,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
|
|||
|
||||
try
|
||||
{
|
||||
Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
|
||||
Elf = new PeRunner(comm.CoreFileProvider.DllPath(), "gpgx.exe", 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
|
||||
|
||||
if (Elf.ShouldMonitor)
|
||||
Core = BizInvoker.GetInvoker<LibGPGX>(Elf, Elf);
|
||||
else
|
||||
|
@ -152,7 +153,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
|
|||
}
|
||||
|
||||
LibGPGX Core;
|
||||
ElfRunner Elf;
|
||||
PeRunner Elf;
|
||||
|
||||
DiscSystem.Disc CD;
|
||||
DiscSystem.DiscSectorReader DiscSectorReader;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Common.BizInvoke;
|
||||
using BizHawk.Emulation.Common;
|
||||
using PeNet;
|
||||
using System;
|
||||
|
@ -12,7 +13,10 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
public class PeRunner : Swappable, IImportResolver, IBinaryStateable
|
||||
{
|
||||
public class PeWrapper : IImportResolver, IBinaryStateable, IDisposable
|
||||
/// <summary>
|
||||
/// manages one PE file within the the set of loaded PE files
|
||||
/// </summary>
|
||||
private class PeWrapper : IImportResolver, IBinaryStateable, IDisposable
|
||||
{
|
||||
public Dictionary<int, IntPtr> ExportsByOrdinal { get; } = new Dictionary<int, IntPtr>();
|
||||
/// <summary>
|
||||
|
@ -37,6 +41,22 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
|
||||
public IntPtr EntryPoint { get; private set; }
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
private delegate bool DllEntry(IntPtr instance, int reason, IntPtr reserved);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
private delegate void ExeEntry();
|
||||
|
||||
public bool RunDllEntry()
|
||||
{
|
||||
var entryThunk = (DllEntry)Marshal.GetDelegateForFunctionPointer(EntryPoint, typeof(DllEntry));
|
||||
return entryThunk(Z.US(Start), 1, IntPtr.Zero); // DLL_PROCESS_ATTACH
|
||||
}
|
||||
public void RunExeEntry()
|
||||
{
|
||||
var entryThunk = (ExeEntry)Marshal.GetDelegateForFunctionPointer(EntryPoint, typeof(ExeEntry));
|
||||
entryThunk();
|
||||
}
|
||||
|
||||
public PeWrapper(string moduleName, byte[] fileData)
|
||||
{
|
||||
ModuleName = moduleName;
|
||||
|
@ -89,22 +109,20 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
LoadOffset = (long)Start - (long)_pe.ImageNtHeaders.OptionalHeader.ImageBase;
|
||||
Memory = new MemoryBlock(Start, Size);
|
||||
Memory.Activate();
|
||||
Memory.Protect(Start, Size, MemoryBlock.Protection.RW);
|
||||
|
||||
// copy headers
|
||||
{
|
||||
ulong length = _pe.ImageNtHeaders.OptionalHeader.SizeOfHeaders;
|
||||
Memory.Protect(Start, length, MemoryBlock.Protection.RW);
|
||||
Marshal.Copy(_fileData, 0, Z.US(Start), (int)length);
|
||||
}
|
||||
Marshal.Copy(_fileData, 0, Z.US(Start), (int)_pe.ImageNtHeaders.OptionalHeader.SizeOfHeaders);
|
||||
|
||||
// copy sections
|
||||
foreach (var s in _pe.ImageSectionHeaders)
|
||||
{
|
||||
ulong start = Start + s.VirtualAddress;
|
||||
ulong length = s.VirtualSize;
|
||||
ulong datalength = Math.Min(s.VirtualSize, s.SizeOfRawData);
|
||||
|
||||
Marshal.Copy(_fileData, (int)s.PointerToRawData, Z.US(start), (int)s.SizeOfRawData);
|
||||
WaterboxUtils.ZeroMemory(Z.US(start + s.SizeOfRawData), (long)(length - s.SizeOfRawData));
|
||||
Marshal.Copy(_fileData, (int)s.PointerToRawData, Z.US(start), (int)datalength);
|
||||
WaterboxUtils.ZeroMemory(Z.US(start + datalength), (long)(length - datalength));
|
||||
}
|
||||
|
||||
// apply relocations
|
||||
|
@ -161,7 +179,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
module = new Dictionary<string, IntPtr>();
|
||||
ImportsByModule.Add(import.DLL, module);
|
||||
}
|
||||
module.Add(import.Name, Z.US(import.Thunk));
|
||||
module.Add(import.Name, Z.US(Start + import.Thunk));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,6 +267,186 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// serves as a standin for libpsxscl.so
|
||||
/// </summary>
|
||||
private class Psx
|
||||
{
|
||||
private readonly PeRunner _parent;
|
||||
private readonly List<Delegate> _traps = new List<Delegate>();
|
||||
|
||||
public Psx(PeRunner parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PsxContext
|
||||
{
|
||||
public int Size;
|
||||
public int Options;
|
||||
public IntPtr SyscallVtable;
|
||||
public IntPtr LdsoVtable;
|
||||
public IntPtr PsxVtable;
|
||||
public uint SysIdx;
|
||||
public uint LibcIdx;
|
||||
public IntPtr PthreadSurrogate;
|
||||
public IntPtr PthreadCreate;
|
||||
public IntPtr DoGlobalCtors;
|
||||
public IntPtr DoGlobalDtors;
|
||||
}
|
||||
|
||||
private IntPtr CreateVtable(string moduleName, ICollection<string> entries)
|
||||
{
|
||||
var imports = _parent._exports[moduleName];
|
||||
var ret = Z.US(_parent._sealedheap.Allocate((ulong)(entries.Count * IntPtr.Size), 16));
|
||||
var pointers = entries.Select(e =>
|
||||
{
|
||||
var ptr = imports.Resolve(e);
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
var s = string.Format("Trapped on unimplemented function {0}:{1}", moduleName, e);
|
||||
Action del = () => { throw new InvalidOperationException(e); };
|
||||
_traps.Add(del);
|
||||
ptr = Marshal.GetFunctionPointerForDelegate(del);
|
||||
}
|
||||
return ptr;
|
||||
}).ToArray();
|
||||
Marshal.Copy(pointers, 0, ret, pointers.Length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "__psx_init")]
|
||||
public int PsxInit(ref int argc, ref IntPtr argv, ref IntPtr envp, [In, Out]ref PsxContext context)
|
||||
{
|
||||
{
|
||||
// argc = 1, argv = ["foobar, NULL], envp = [NULL]
|
||||
argc = 1;
|
||||
var argArea = _parent._sealedheap.Allocate(32, 16);
|
||||
argv = Z.US(argArea);
|
||||
envp = Z.US(argArea + (uint)IntPtr.Size * 2);
|
||||
Marshal.WriteIntPtr(Z.US(argArea), Z.US(argArea + 24));
|
||||
Marshal.WriteInt64(Z.US(argArea + 24), 0x7261626f6f66);
|
||||
}
|
||||
|
||||
context.SyscallVtable = CreateVtable("__syscalls", Enumerable.Range(0, 340).Select(i => "n" + i).ToList());
|
||||
context.LdsoVtable = CreateVtable("__syscalls", new[] // ldso
|
||||
{
|
||||
"dladdr", "dlinfo", "dlsym", "dlopen", "dlclose", "dlerror", "reset_tls"
|
||||
});
|
||||
context.PsxVtable = CreateVtable("__syscalls", new[] // psx
|
||||
{
|
||||
"start_main", "convert_thread", "unmapself", "log_output"
|
||||
});
|
||||
var extraTable = CreateVtable("__syscalls", new[]
|
||||
{
|
||||
"pthread_surrogate", "pthread_create", "do_global_ctors", "do_global_dtors"
|
||||
});
|
||||
{
|
||||
var tmp = new IntPtr[4];
|
||||
Marshal.Copy(extraTable, tmp, 0, 4);
|
||||
context.PthreadSurrogate = tmp[0];
|
||||
context.PthreadCreate = tmp[1];
|
||||
context.DoGlobalCtors = tmp[2];
|
||||
context.DoGlobalDtors = tmp[3];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// special emulator-functions
|
||||
/// </summary>
|
||||
private class Emu
|
||||
{
|
||||
private readonly PeRunner _parent;
|
||||
public Emu(PeRunner parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
public class EndOfMainException: Exception
|
||||
{
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_sealed")]
|
||||
public IntPtr AllocSealed(UIntPtr size)
|
||||
{
|
||||
return Z.US(_parent._sealedheap.Allocate((ulong)size, 16));
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_invisible")]
|
||||
public IntPtr AllocInvisible(UIntPtr size)
|
||||
{
|
||||
return Z.US(_parent._invisibleheap.Allocate((ulong)size, 16));
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "_debug_puts")]
|
||||
public void DebugPuts(IntPtr s)
|
||||
{
|
||||
Console.WriteLine("_debug_puts:" + Marshal.PtrToStringAnsi(s));
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "_leave_main")]
|
||||
public void LeaveMain()
|
||||
{
|
||||
throw new EndOfMainException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// syscall emulation layer, as well as a bit of other stuff
|
||||
/// </summary>
|
||||
private class Syscalls
|
||||
{
|
||||
private readonly PeRunner _parent;
|
||||
public Syscalls(PeRunner parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "log_output")]
|
||||
public void DebugPuts(IntPtr s)
|
||||
{
|
||||
Console.WriteLine("_psx_log_output:" + Marshal.PtrToStringAnsi(s));
|
||||
}
|
||||
|
||||
[BizExport(CallingConvention.Cdecl, EntryPoint = "n12")]
|
||||
public UIntPtr Brk(UIntPtr _p)
|
||||
{
|
||||
// does MUSL use this?
|
||||
var heap = _parent._heap;
|
||||
|
||||
var start = heap.Memory.Start;
|
||||
var end = start + heap.Used;
|
||||
var max = heap.Memory.End;
|
||||
|
||||
var p = (ulong)_p;
|
||||
|
||||
if (p < start || p > max)
|
||||
{
|
||||
// failure: return current break
|
||||
return Z.UU(end);
|
||||
}
|
||||
else if (p > end)
|
||||
{
|
||||
// increase size of heap
|
||||
heap.Allocate(p - end, 1);
|
||||
return Z.UU(p);
|
||||
}
|
||||
else if (p < end)
|
||||
{
|
||||
throw new InvalidOperationException("We don't support shrinking heaps");
|
||||
}
|
||||
else
|
||||
{
|
||||
// no change
|
||||
return Z.UU(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// usual starting address for the executable
|
||||
private static readonly ulong CanonicalStart = 0x0000036f00000000;
|
||||
|
||||
|
@ -282,26 +480,52 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
/// </summary>
|
||||
private Heap _invisibleheap;
|
||||
|
||||
/// <summary>
|
||||
/// all loaded PE files
|
||||
/// </summary>
|
||||
private readonly List<PeWrapper> _modules = new List<PeWrapper>();
|
||||
|
||||
/// <summary>
|
||||
/// anything at all that needs to be disposed on finish
|
||||
/// </summary>
|
||||
private readonly List<IDisposable> _disposeList = new List<IDisposable>();
|
||||
|
||||
/// <summary>
|
||||
/// anything at all that needs its state saved and loaded
|
||||
/// </summary>
|
||||
private readonly List<IBinaryStateable> _savestateComponents = new List<IBinaryStateable>();
|
||||
|
||||
/// <summary>
|
||||
/// all of the exports, including real PeWrapper ones and fake ones
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, IImportResolver> _exports = new Dictionary<string, IImportResolver>();
|
||||
|
||||
private Psx _psx;
|
||||
private Emu _emu;
|
||||
private Syscalls _syscalls;
|
||||
|
||||
public PeRunner(string directory, string filename, ulong heapsize, ulong sealedheapsize, ulong invisibleheapsize)
|
||||
{
|
||||
Initialize(_nextStart);
|
||||
Enter();
|
||||
try
|
||||
{
|
||||
// load any predefined exports
|
||||
_psx = new Psx(this);
|
||||
_exports.Add("libpsxscl.so", BizExvoker.GetExvoker(_psx));
|
||||
_emu = new Emu(this);
|
||||
_exports.Add("libemuhost.so", BizExvoker.GetExvoker(_emu));
|
||||
_syscalls = new Syscalls(this);
|
||||
_exports.Add("__syscalls", BizExvoker.GetExvoker(_syscalls));
|
||||
|
||||
// load and connect all modules, starting with the executable
|
||||
var todoModules = new Queue<string>();
|
||||
todoModules.Enqueue(filename);
|
||||
var loadedModules = new Dictionary<string, IImportResolver>();
|
||||
|
||||
while (todoModules.Count > 0)
|
||||
{
|
||||
var moduleName = todoModules.Dequeue();
|
||||
if (!loadedModules.ContainsKey(moduleName))
|
||||
if (!_exports.ContainsKey(moduleName))
|
||||
{
|
||||
var module = new PeWrapper(moduleName, File.ReadAllBytes(Path.Combine(directory, moduleName)));
|
||||
module.Mount(_nextStart);
|
||||
|
@ -310,7 +534,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
_savestateComponents.Add(module);
|
||||
_disposeList.Add(module);
|
||||
|
||||
loadedModules.Add(moduleName, module);
|
||||
_exports.Add(moduleName, module);
|
||||
_modules.Add(module);
|
||||
foreach (var name in module.ImportsByModule.Keys)
|
||||
{
|
||||
|
@ -323,7 +547,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
foreach (var name in module.ImportsByModule.Keys)
|
||||
{
|
||||
module.ConnectImports(name, loadedModules[name]);
|
||||
module.ConnectImports(name, _exports[name]);
|
||||
}
|
||||
}
|
||||
foreach (var module in _modules)
|
||||
|
@ -352,6 +576,19 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
AddMemoryBlock(_invisibleheap.Memory);
|
||||
_savestateComponents.Add(_invisibleheap);
|
||||
_disposeList.Add(_invisibleheap);
|
||||
|
||||
try
|
||||
{
|
||||
_modules[0].RunExeEntry();
|
||||
throw new InvalidOperationException("main() returned!");
|
||||
}
|
||||
catch (Emu.EndOfMainException)
|
||||
{ }
|
||||
foreach (var m in _modules.Skip(1))
|
||||
{
|
||||
if (!m.RunDllEntry())
|
||||
throw new InvalidOperationException("DllMain() returned false");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -370,6 +607,14 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
return _modules[0].Resolve(entryPoint);
|
||||
}
|
||||
|
||||
public void Seal()
|
||||
{
|
||||
using (this.EnterExit())
|
||||
{
|
||||
_sealedheap.Seal();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
using (this.EnterExit())
|
||||
|
@ -406,6 +651,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
_disposeList.Clear();
|
||||
PurgeMemoryBlocks();
|
||||
_modules.Clear();
|
||||
_exports.Clear();
|
||||
_heap = null;
|
||||
_sealedheap = null;
|
||||
_invisibleheap = null;
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
CC = x86_64-nt64-midipix-gcc
|
||||
|
||||
CCFLAGS:= -Wall -O2# -mcmodel=large
|
||||
|
||||
TARGET = libemuhost.so
|
||||
|
||||
LDFLAGS = -shared
|
||||
|
||||
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c')
|
||||
OBJ_DIR:=$(ROOT_DIR)/obj
|
||||
|
||||
_OBJS:=$(SRCS:.c=.o)
|
||||
OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS))
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) -c -o $@ $< $(CCFLAGS)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
$(TARGET) : $(OBJS)
|
||||
@$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR)
|
||||
rm -f $(TARGET)
|
||||
|
||||
#install:
|
||||
# $(CP) $(TARGET) $(DEST_$(ARCH))
|
|
@ -0,0 +1,7 @@
|
|||
#include "emulibc.h"
|
||||
|
||||
// this is just used to build a dummy .so file that isn't used
|
||||
void *alloc_sealed(size_t size) { return NULL; }
|
||||
void *alloc_invisible(size_t size) { return NULL; }
|
||||
void _debug_puts(const char *s) { }
|
||||
void _leave_main(void) { }
|
|
@ -4,9 +4,9 @@
|
|||
#include <stddef.h>
|
||||
|
||||
// mark an entry point or callback pointer
|
||||
#define ECL_ENTRY __attribute__((ms_abi))
|
||||
#define ECL_ENTRY
|
||||
// mark a visible symbol
|
||||
#define ECL_EXPORT __attribute__((visibility("default")))
|
||||
#define ECL_EXPORT
|
||||
|
||||
// allocate memory from the "sealed" pool. this memory can never be freed,
|
||||
// and can only be allocated or written to during the init phase. after that, the host
|
||||
|
@ -22,4 +22,8 @@ void *alloc_invisible(size_t size);
|
|||
// send a debug string somewhere, bypassing stdio
|
||||
void _debug_puts(const char *);
|
||||
|
||||
// this might be used for something
|
||||
void _leave_main(void);
|
||||
|
||||
|
||||
#endif
|
|
@ -1,32 +1,16 @@
|
|||
CC = gcc
|
||||
|
||||
ARCH = 64
|
||||
#MACHINE = $(shell $(CC) -dumpmachine)
|
||||
#ifneq (,$(findstring i686,$(MACHINE)))
|
||||
# ARCH = 32
|
||||
#else ifneq (,$(findstring x86_64,$(MACHINE)))
|
||||
# ARCH = 64
|
||||
#else
|
||||
# $(error Unknown arch)
|
||||
#endif
|
||||
CC = x86_64-nt64-midipix-gcc
|
||||
|
||||
CCFLAGS:=-Icore -Iutil -Icore/m68k -Icore/z80 -Icore/input_hw \
|
||||
-Icore/cart_hw -Icore/cart_hw/svp -Icore/sound -Icore/ntsc -Icore/cd_hw \
|
||||
-I../emulibc \
|
||||
-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \
|
||||
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
|
||||
-DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \
|
||||
-ffreestanding -nostdinc -nostdlib \
|
||||
-I../libc/includes -I../libc/internals \
|
||||
-mcmodel=large -O2
|
||||
-O2#-mcmodel=large
|
||||
|
||||
TARGET = gpgx.elf
|
||||
TARGET = gpgx.exe
|
||||
|
||||
LDFLAGS_32 =
|
||||
LDFLAGS_64 = -static
|
||||
LDFLAGS = $(LDFLAGS_$(ARCH)) $(CCFLAGS)
|
||||
|
||||
#DEST_32 = ../../../../../output/dll
|
||||
#DEST_64 = ../../../../../output64/dll
|
||||
LDFLAGS = -Wl,--dynamicbase,--export-all-symbols
|
||||
|
||||
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c')
|
||||
|
@ -43,8 +27,8 @@ all: $(TARGET)
|
|||
|
||||
.PHONY: clean all
|
||||
|
||||
$(TARGET) : $(OBJS) lscript
|
||||
@$(CC) -o $@ $(LDFLAGS) -T lscript $(CCFLAGS) $(OBJS) ../libc/emulibc.a
|
||||
$(TARGET) : $(OBJS)
|
||||
@$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) ../emulibc/libemuhost.so
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR)
|
||||
|
|
|
@ -713,3 +713,8 @@ GPGX_EX int gpgx_getregs(gpregister_t *regs)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
_leave_main();
|
||||
}
|
||||
|
|
|
@ -1,228 +0,0 @@
|
|||
/* dumped with -Wl,-verbose; base address moved
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
|
||||
"elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x0000036f00000000)); . = SEGMENT_START("text-segment", 0x0000036f00000000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
|
||||
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
|
||||
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
}
|
||||
.plt : { *(.plt) *(.iplt) }
|
||||
.plt.bnd : { *(.plt.bnd) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* 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 (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* 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))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section 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 *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
.data :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.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.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
.lbss :
|
||||
{
|
||||
*(.dynlbss)
|
||||
*(.lbss .lbss.* .gnu.linkonce.lb.*)
|
||||
*(LARGE_COMMON)
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
|
||||
}
|
||||
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.ldata .ldata.* .gnu.linkonce.l.*)
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
_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_line.* .debug_line_end ) }
|
||||
.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) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
|
@ -1,41 +0,0 @@
|
|||
CC:=gcc
|
||||
TARGET:=emulibc.a
|
||||
|
||||
CFLAGS:=-Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow \
|
||||
-Wpointer-arith -Wwrite-strings -Wmissing-declarations \
|
||||
-Wno-long-long -Wuninitialized -Wno-deprecated-declarations \
|
||||
-Wredundant-decls -Winline -Wcast-align -Wno-format \
|
||||
-Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Wno-unused-but-set-variable -Wno-parentheses \
|
||||
-Iinternals -Iincludes -Icompileincludes \
|
||||
-ffreestanding -std=c11 -D_PDCLIB_BUILD -nostdinc -nostdlib \
|
||||
-mcmodel=large -O2
|
||||
|
||||
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c' -o -name '*.s')
|
||||
OBJ_DIR:=$(ROOT_DIR)/obj
|
||||
|
||||
_OBJS:=$(SRCS:.c=.o)
|
||||
_OBJS:=$(_OBJS:.s=.o)
|
||||
OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS))
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
$(OBJ_DIR)/%.o: %.s
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
@ar rcs $@ $^
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR)
|
||||
rm -f $(TARGET)
|
||||
|
||||
print-% : ; @echo $* = $($*)
|
|
@ -1,110 +0,0 @@
|
|||
Credits
|
||||
=======
|
||||
|
||||
The vast majority of PDCLib is original work by me. I felt it was the only way
|
||||
to ensure that the code was indeed free of third-party rights, and thus free to
|
||||
be released into the Public Domain.
|
||||
|
||||
Another issue was that of coding style, quality and stability of the code, and
|
||||
the urge to really understand every miniscule part of the code as to be able to
|
||||
maintain it well once v1.0 has been released.
|
||||
|
||||
That is not to say there are no credits to be given. To the contrary:
|
||||
|
||||
Paul Edwards (author of the PDPCLIB), for inspirational code fragments, thanks.
|
||||
|
||||
P.J. Plauger (author of "The Standard C Library"), for a book without which I
|
||||
would not have been able to create PDCLib at this quality, thanks.
|
||||
|
||||
Paul Bourke (author of mathlib), for allowing me access to a complete math
|
||||
library under public domain terms so I could use it as a reference, thanks.
|
||||
|
||||
Peter ("Candy") Bindels (netizen of osdev.org), who located a copy of Cody
|
||||
& Waite's "Software Manual for the Elementary Functions" for me and saved me
|
||||
serious cash in the process, thanks.
|
||||
|
||||
Michael Moody, who contributed the generic implementation for <stdarg.h> to
|
||||
the Public Domain which can now be found in <_PDCLIB_config.h>, thanks.
|
||||
|
||||
Rod Pemberton, for pointing out several flaws in early versions of PDCLib and
|
||||
giving other valuable hints, thanks.
|
||||
|
||||
Brian Damgaard, for a very friendly exchange over the fine details of the
|
||||
Quicksort algorithm and its implementation in PDCLib, thanks.
|
||||
|
||||
Rink Springer, for very precise bug reports including patches, and a heads-up
|
||||
on the capabilities of PDCLib when I most needed it, thanks.
|
||||
|
||||
Everyone involved in the first, "public" attempt at PDCLib, for bearing with me
|
||||
when I restarted from scratch, thanks.
|
||||
|
||||
Everyone bearing with me during the "stdio block", a period of many years in
|
||||
which PDCLib received not a single update because I was stuck and could not
|
||||
find the time and energy to work it out.
|
||||
|
||||
Lennart Frid<69>n and Sammy Nordstr<74>m, who have been great pals even after I sunk
|
||||
some other project that had eaten countless hours of work between the three of
|
||||
us, thanks.
|
||||
|
||||
My wife, daughter, and son for sharing husband and daddy with this strange
|
||||
machine, thanks.
|
||||
|
||||
|
||||
Style
|
||||
=====
|
||||
|
||||
I followed a set of guidelines in creating PDCLib. If you find some piece that
|
||||
does not adhere to them, that's a bug worth reporting. I mean it. I am a bit
|
||||
obsessive when it comes to coding style. ;-)
|
||||
|
||||
- All the stuff that is not part of the standard specification is "hidden" in
|
||||
the _PDCLIB_* namespace - functions, variables, macros, files, directories.
|
||||
This is to make it easier to distinguish between what the standard dictates
|
||||
and what I added to make PDCLib work.
|
||||
|
||||
- Any internal includes (i.e. those not specified by the standard) have their
|
||||
header guards defined in the *including* file, for a tiny bit of compile-time
|
||||
performance.
|
||||
|
||||
- I always try to minimize the use of local variables. Wherever possible I used
|
||||
parameters passed by-value directly, and deferred declaration of locals to the
|
||||
innermost block of statements, in hopes that it might reduce memory footprint
|
||||
when the library is compiled with a compiler that is not that great at
|
||||
optimization.
|
||||
|
||||
- Every function, every static data item that could possibly be shared, got its
|
||||
own implementation file. This means the library itself is probably larger than
|
||||
strictly necessary, and might take a couple of clock cycles longer to link,
|
||||
but it reduces size of object files and executables.
|
||||
|
||||
- Where possible, I tried to share functionality between similar functions (as
|
||||
can be seen in the atoi() and strtol() function families). This means one or
|
||||
two additional function calls, but again reduces memory footprint and eases
|
||||
maintenance of the library.
|
||||
|
||||
- Function arguments are named exactly as in the standard document.
|
||||
|
||||
- The standard is taken quite literally in places. For example, the default
|
||||
implementations of memcpy() really copies char-wise. This runs contrary to
|
||||
earlier claims of performance, but is consistent with the *letter* of the
|
||||
standard, and you will probably use your compiler builtins (through a platform
|
||||
overlay) anyhow.
|
||||
|
||||
- Every file has an Id tag, so that it is on file for *every* code file.
|
||||
|
||||
- PDCLib code has no bias towards POSIX; indeed the absence of POSIX tidbits is
|
||||
one of its hallmarks. However, PDCLib also has no bias *against* POSIX, and
|
||||
when one platform abstraction is as good as another, I chose the POSIX one for
|
||||
sheer familiarity. (This is mainly referring to naming and parameter lists of
|
||||
OS "glue" functions.)
|
||||
|
||||
- Identifiers are tersely named, but not cryptically abbreviated, and should be
|
||||
intuitive enough to allow easy understanding of PDCLib inner workings.
|
||||
|
||||
- I disagree with the notion that good code needs no comments. Code tells you
|
||||
*how*, but not the *why*, and you have to figure out the *what* yourself. So
|
||||
I added comments to every nontrivial piece of code explaining my motives and
|
||||
hopefully keeping overly ambitious editors from repeating my mistakes. The
|
||||
header files especially should be self-documenting to the point of being a
|
||||
suitable replacement for any library reference book you might be using.
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
Unicode Data Files include all data files under the directories
|
||||
http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
|
||||
http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF online
|
||||
code charts under the directory http://www.unicode.org/Public/. Software
|
||||
includes any source code published in the Unicode Standard or under the
|
||||
directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
|
||||
http://www.unicode.org/cldr/data/.
|
||||
|
||||
NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
|
||||
INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"),
|
||||
AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND
|
||||
BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO
|
||||
NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWAR.
|
||||
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright © 1991-2013 Unicode, Inc. All rights reserved. Distributed under the
|
||||
Terms of Use in http://www.unicode.org/copyright.html.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
the Unicode data files and any associated documentation (the "Data Files") or
|
||||
Unicode software and any associated documentation (the "Software") to deal in
|
||||
the Data Files or Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, and/or sell copies of
|
||||
the Data Files or Software, and to permit persons to whom the Data Files or
|
||||
Software are furnished to do so, provided that (a) the above copyright notice(s)
|
||||
and this permission notice appear with all copies of the Data Files or Software,
|
||||
(b) both the above copyright notice(s) and this permission notice appear in
|
||||
associated documentation, and (c) there is clear notice in each modified Data
|
||||
File or in the Software as well as in the documentation associated with the Data
|
||||
File(s) or Software that the data or software has been modified.
|
||||
|
||||
THE DATA FILES AND SOFTWARE ARE 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 OF THIRD
|
||||
PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings in
|
||||
these Data Files or Software without prior written authorization of the
|
||||
copyright holder.
|
|
@ -1,188 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef _LIBM_H
|
||||
#define _LIBM_H
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
#include <endian.h>
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
union ldshape {
|
||||
long double f;
|
||||
struct {
|
||||
uint64_t m;
|
||||
uint16_t se;
|
||||
} i;
|
||||
};
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
union ldshape {
|
||||
long double f;
|
||||
struct {
|
||||
uint64_t lo;
|
||||
uint32_t mid;
|
||||
uint16_t top;
|
||||
uint16_t se;
|
||||
} i;
|
||||
struct {
|
||||
uint64_t lo;
|
||||
uint64_t hi;
|
||||
} i2;
|
||||
};
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
|
||||
union ldshape {
|
||||
long double f;
|
||||
struct {
|
||||
uint16_t se;
|
||||
uint16_t top;
|
||||
uint32_t mid;
|
||||
uint64_t lo;
|
||||
} i;
|
||||
struct {
|
||||
uint64_t hi;
|
||||
uint64_t lo;
|
||||
} i2;
|
||||
};
|
||||
#else
|
||||
#error Unsupported long double representation
|
||||
#endif
|
||||
|
||||
#define FORCE_EVAL(x) do { \
|
||||
if (sizeof(x) == sizeof(float)) { \
|
||||
volatile float __x; \
|
||||
__x = (x); \
|
||||
} else if (sizeof(x) == sizeof(double)) { \
|
||||
volatile double __x; \
|
||||
__x = (x); \
|
||||
} else { \
|
||||
volatile long double __x; \
|
||||
__x = (x); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Get two 32 bit ints from a double. */
|
||||
#define EXTRACT_WORDS(hi,lo,d) \
|
||||
do { \
|
||||
union {double f; uint64_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
(hi) = __u.i >> 32; \
|
||||
(lo) = (uint32_t)__u.i; \
|
||||
} while (0)
|
||||
|
||||
/* Get the more significant 32 bit int from a double. */
|
||||
#define GET_HIGH_WORD(hi,d) \
|
||||
do { \
|
||||
union {double f; uint64_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
(hi) = __u.i >> 32; \
|
||||
} while (0)
|
||||
|
||||
/* Get the less significant 32 bit int from a double. */
|
||||
#define GET_LOW_WORD(lo,d) \
|
||||
do { \
|
||||
union {double f; uint64_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
(lo) = (uint32_t)__u.i; \
|
||||
} while (0)
|
||||
|
||||
/* Set a double from two 32 bit ints. */
|
||||
#define INSERT_WORDS(d,hi,lo) \
|
||||
do { \
|
||||
union {double f; uint64_t i;} __u; \
|
||||
__u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \
|
||||
(d) = __u.f; \
|
||||
} while (0)
|
||||
|
||||
/* Set the more significant 32 bits of a double from an int. */
|
||||
#define SET_HIGH_WORD(d,hi) \
|
||||
do { \
|
||||
union {double f; uint64_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
__u.i &= 0xffffffff; \
|
||||
__u.i |= (uint64_t)(hi) << 32; \
|
||||
(d) = __u.f; \
|
||||
} while (0)
|
||||
|
||||
/* Set the less significant 32 bits of a double from an int. */
|
||||
#define SET_LOW_WORD(d,lo) \
|
||||
do { \
|
||||
union {double f; uint64_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
__u.i &= 0xffffffff00000000ull; \
|
||||
__u.i |= (uint32_t)(lo); \
|
||||
(d) = __u.f; \
|
||||
} while (0)
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
#define GET_FLOAT_WORD(w,d) \
|
||||
do { \
|
||||
union {float f; uint32_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
(w) = __u.i; \
|
||||
} while (0)
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
#define SET_FLOAT_WORD(d,w) \
|
||||
do { \
|
||||
union {float f; uint32_t i;} __u; \
|
||||
__u.i = (w); \
|
||||
(d) = __u.f; \
|
||||
} while (0)
|
||||
|
||||
#undef __CMPLX
|
||||
#undef CMPLX
|
||||
#undef CMPLXF
|
||||
#undef CMPLXL
|
||||
|
||||
#define __CMPLX(x, y, t) \
|
||||
((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
|
||||
|
||||
#define CMPLX(x, y) __CMPLX(x, y, double)
|
||||
#define CMPLXF(x, y) __CMPLX(x, y, float)
|
||||
#define CMPLXL(x, y) __CMPLX(x, y, long double)
|
||||
|
||||
/* fdlibm kernel functions */
|
||||
|
||||
int __rem_pio2_large(double*,double*,int,int,int);
|
||||
|
||||
int __rem_pio2(double,double*);
|
||||
double __sin(double,double,int);
|
||||
double __cos(double,double);
|
||||
double __tan(double,double,int);
|
||||
double __expo2(double);
|
||||
double complex __ldexp_cexp(double complex,int);
|
||||
|
||||
int __rem_pio2f(float,double*);
|
||||
float __sindf(double);
|
||||
float __cosdf(double);
|
||||
float __tandf(double,int);
|
||||
float __expo2f(float);
|
||||
float complex __ldexp_cexpf(float complex,int);
|
||||
|
||||
int __rem_pio2l(long double, long double *);
|
||||
long double __sinl(long double, long double, int);
|
||||
long double __cosl(long double, long double);
|
||||
long double __tanl(long double, long double, int);
|
||||
|
||||
/* polynomial evaluation */
|
||||
long double __polevll(long double, const long double *, int);
|
||||
long double __p1evll(long double, const long double *, int);
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
includes for compiling the library only
|
|
@ -1,11 +0,0 @@
|
|||
This directory holds various "internals" of PDCLib:
|
||||
|
||||
- definitions of helper functions not specified by the standard (hidden in the
|
||||
_PDCLIB_* namespace);
|
||||
|
||||
- definitions of data objects, both internal (like digits.c) and specified by
|
||||
the standard (errno.c);
|
||||
|
||||
- test drivers for functionality that does not have its own implementation
|
||||
file to put the test driver in.
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
/* ASCII codec
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#ifndef REGTEST
|
||||
#include <uchar.h>
|
||||
#include "_PDCLIB_encoding.h"
|
||||
|
||||
static bool ascii_mbsinit( const mbstate_t *ps )
|
||||
{ return 1; }
|
||||
|
||||
static bool asciitoc32(
|
||||
char32_t *restrict *restrict p_outbuf,
|
||||
size_t *restrict p_outsz,
|
||||
const char *restrict *restrict p_inbuf,
|
||||
size_t *restrict p_insz,
|
||||
mbstate_t *restrict p_ps
|
||||
)
|
||||
{
|
||||
while(*p_outsz && *p_insz) {
|
||||
unsigned char c = **p_inbuf;
|
||||
if(c > 127)
|
||||
return false;
|
||||
|
||||
if(p_outbuf) {
|
||||
**p_outbuf = c;
|
||||
(*p_outbuf)++;
|
||||
}
|
||||
|
||||
(*p_inbuf)++;
|
||||
(*p_insz)--;
|
||||
(*p_outsz)--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool c32toascii(
|
||||
char *restrict *restrict p_outbuf,
|
||||
size_t *restrict p_outsz,
|
||||
const char32_t *restrict *restrict p_inbuf,
|
||||
size_t *restrict p_insz,
|
||||
mbstate_t *restrict p_ps
|
||||
)
|
||||
{
|
||||
while(*p_outsz && *p_insz) {
|
||||
char32_t c = **p_inbuf;
|
||||
if(c > 127)
|
||||
return false;
|
||||
|
||||
if(p_outbuf) {
|
||||
**p_outbuf = c;
|
||||
(*p_outbuf)++;
|
||||
}
|
||||
|
||||
(*p_inbuf)++;
|
||||
(*p_insz)--;
|
||||
(*p_outsz)--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct _PDCLIB_charcodec_t _PDCLIB_ascii_codec = {
|
||||
.__mbsinit = ascii_mbsinit,
|
||||
.__mbstoc32s = asciitoc32,
|
||||
.__c32stombs = c32toascii,
|
||||
.__mb_max = 1,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
// Valid conversion & back
|
||||
|
||||
char32_t c32out[5];
|
||||
|
||||
char32_t *c32ptr = &c32out[0];
|
||||
size_t c32rem = 5;
|
||||
char *chrptr = (char*) &abcde[0];
|
||||
size_t chrrem = 5;
|
||||
mbstate_t mbs = { 0 };
|
||||
|
||||
TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
|
||||
TESTCASE(c32rem == 0);
|
||||
TESTCASE(chrrem == 0);
|
||||
TESTCASE(c32ptr == &c32out[5]);
|
||||
TESTCASE(chrptr == &abcde[5]);
|
||||
TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
|
||||
c32out[3] == 'd' && c32out[4] == 'e');
|
||||
|
||||
char chrout[5];
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 5;
|
||||
chrptr = &chrout[0];
|
||||
chrrem = 5;
|
||||
|
||||
|
||||
TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
|
||||
TESTCASE(c32rem == 0);
|
||||
TESTCASE(chrrem == 0);
|
||||
TESTCASE(c32ptr == &c32out[5]);
|
||||
TESTCASE(chrptr == &chrout[5]);
|
||||
TESTCASE(memcmp(chrout, abcde, 5) == 0);
|
||||
|
||||
// Invalid conversions
|
||||
char badascii = '\xC0';
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 5;
|
||||
chrptr = &badascii;
|
||||
chrrem = 1;
|
||||
TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
|
||||
TESTCASE(c32ptr == &c32out[0]);
|
||||
TESTCASE(c32rem == 5);
|
||||
TESTCASE(chrptr == &badascii);
|
||||
TESTCASE(chrrem == 1);
|
||||
|
||||
char32_t baduni = 0xC0;
|
||||
c32ptr = &baduni;
|
||||
c32rem = 1;
|
||||
chrptr = &chrout[0];
|
||||
chrrem = 5;
|
||||
TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
|
||||
TESTCASE(c32ptr == &baduni);
|
||||
TESTCASE(c32rem == 1);
|
||||
TESTCASE(chrptr == &chrout[0]);
|
||||
TESTCASE(chrrem == 5);
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* _PDCLIB_atomax( const char * )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_int.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
_PDCLIB_intmax_t _PDCLIB_atomax( const char * s )
|
||||
{
|
||||
_PDCLIB_intmax_t rc = 0;
|
||||
char sign = '+';
|
||||
const char * x;
|
||||
/* TODO: In other than "C" locale, additional patterns may be defined */
|
||||
while ( isspace( *s ) ) ++s;
|
||||
if ( *s == '+' ) ++s;
|
||||
else if ( *s == '-' ) sign = *(s++);
|
||||
/* TODO: Earlier version was missing tolower() but was not caught by tests */
|
||||
while ( ( x = memchr( _PDCLIB_digits, tolower(*(s++)), 10 ) ) != NULL )
|
||||
{
|
||||
rc = rc * 10 + ( x - _PDCLIB_digits );
|
||||
}
|
||||
return ( sign == '+' ) ? rc : -rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
/* basic functionality */
|
||||
TESTCASE( _PDCLIB_atomax( "123" ) == 123 );
|
||||
/* testing skipping of leading whitespace and trailing garbage */
|
||||
TESTCASE( _PDCLIB_atomax( " \n\v\t\f123xyz" ) == 123 );
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||
/* _PDCLIB_closeall( void )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_io.h"
|
||||
extern _PDCLIB_file_t * _PDCLIB_filelist;
|
||||
|
||||
void _PDCLIB_closeall( void )
|
||||
{
|
||||
_PDCLIB_file_t * stream = _PDCLIB_filelist;
|
||||
_PDCLIB_file_t * next;
|
||||
while ( stream != NULL )
|
||||
{
|
||||
next = stream->next;
|
||||
fclose( stream );
|
||||
stream = next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
/* No testdriver */
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/* _PDCLIB_digits
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_int.h"
|
||||
#endif
|
||||
|
||||
char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
/* For _PDCLIB/print.c only; obsolete with ctype.h */
|
||||
char _PDCLIB_Xdigits[] = "0123456789ABCDEF";
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
TESTCASE( strcmp( _PDCLIB_digits, "0123456789abcdefghijklmnopqrstuvwxyz" ) == 0 );
|
||||
TESTCASE( strcmp( _PDCLIB_Xdigits, "0123456789ABCDEF" ) == 0 );
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
/* _PDCLIB_fileops
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#ifndef REGTEST
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "_PDCLIB_glue.h"
|
||||
#include <errno.h>
|
||||
|
||||
static bool readf( _PDCLIB_fd_t self, void * buf, size_t length,
|
||||
size_t * numBytesRead )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length,
|
||||
size_t * numBytesWritten )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return false;
|
||||
}
|
||||
static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,
|
||||
int_fast64_t* newPos )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void closef( _PDCLIB_fd_t self )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
}
|
||||
|
||||
const _PDCLIB_fileops_t _PDCLIB_fileops = {
|
||||
.read = readf,
|
||||
.write = writef,
|
||||
.seek = seekf,
|
||||
.close = closef,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
// Tested by stdio test cases
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
/* _PDCLIB_initclocale( locale_t )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_clocale.h"
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
void _PDCLIB_initclocale( locale_t l )
|
||||
{
|
||||
// TODO: There will be more added here...
|
||||
|
||||
l->_WCType = _PDCLIB_wcinfo;
|
||||
l->_WCTypeSize = _PDCLIB_wcinfo_size;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,126 +0,0 @@
|
|||
/* Latin-1 codec
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#ifndef REGTEST
|
||||
#include <uchar.h>
|
||||
#include "_PDCLIB_encoding.h"
|
||||
|
||||
static bool latin1_mbsinit( const mbstate_t *ps )
|
||||
{ return 1; }
|
||||
|
||||
static bool latin1toc32(
|
||||
char32_t *restrict *restrict p_outbuf,
|
||||
size_t *restrict p_outsz,
|
||||
const char *restrict *restrict p_inbuf,
|
||||
size_t *restrict p_insz,
|
||||
mbstate_t *restrict p_ps
|
||||
)
|
||||
{
|
||||
while(*p_outsz && *p_insz) {
|
||||
unsigned char c = **p_inbuf;
|
||||
|
||||
if(p_outbuf) {
|
||||
**p_outbuf = c;
|
||||
(*p_outbuf)++;
|
||||
}
|
||||
|
||||
(*p_inbuf)++;
|
||||
(*p_insz)--;
|
||||
(*p_outsz)--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool c32tolatin1(
|
||||
char *restrict *restrict p_outbuf,
|
||||
size_t *restrict p_outsz,
|
||||
const char32_t *restrict *restrict p_inbuf,
|
||||
size_t *restrict p_insz,
|
||||
mbstate_t *restrict p_ps
|
||||
)
|
||||
{
|
||||
while(*p_outsz && *p_insz) {
|
||||
char32_t c = **p_inbuf;
|
||||
if(c > 255)
|
||||
return false;
|
||||
|
||||
if(p_outbuf) {
|
||||
**p_outbuf = c;
|
||||
(*p_outbuf)++;
|
||||
}
|
||||
|
||||
(*p_inbuf)++;
|
||||
(*p_insz)--;
|
||||
(*p_outsz)--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct _PDCLIB_charcodec_t _PDCLIB_latin1_codec = {
|
||||
.__mbsinit = latin1_mbsinit,
|
||||
.__mbstoc32s = latin1toc32,
|
||||
.__c32stombs = c32tolatin1,
|
||||
.__mb_max = 1,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
// Valid conversion & back
|
||||
|
||||
char32_t c32out[5];
|
||||
|
||||
char32_t *c32ptr = &c32out[0];
|
||||
size_t c32rem = 5;
|
||||
char *chrptr = (char*) &abcde[0];
|
||||
size_t chrrem = 5;
|
||||
mbstate_t mbs = { 0 };
|
||||
|
||||
TESTCASE(latin1toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
|
||||
TESTCASE(c32rem == 0);
|
||||
TESTCASE(chrrem == 0);
|
||||
TESTCASE(c32ptr == &c32out[5]);
|
||||
TESTCASE(chrptr == &abcde[5]);
|
||||
TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
|
||||
c32out[3] == 'd' && c32out[4] == 'e');
|
||||
|
||||
char chrout[5];
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 5;
|
||||
chrptr = &chrout[0];
|
||||
chrrem = 5;
|
||||
|
||||
|
||||
TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
|
||||
TESTCASE(c32rem == 0);
|
||||
TESTCASE(chrrem == 0);
|
||||
TESTCASE(c32ptr == &c32out[5]);
|
||||
TESTCASE(chrptr == &chrout[5]);
|
||||
TESTCASE(memcmp(chrout, abcde, 5) == 0);
|
||||
|
||||
// Invalid conversions
|
||||
char32_t baduni = 0xFFFE;
|
||||
c32ptr = &baduni;
|
||||
c32rem = 1;
|
||||
chrptr = &chrout[0];
|
||||
chrrem = 5;
|
||||
TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
|
||||
TESTCASE(c32ptr == &baduni);
|
||||
TESTCASE(c32rem == 1);
|
||||
TESTCASE(chrptr == &chrout[0]);
|
||||
TESTCASE(chrrem == 5);
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/* _PDCLIB_open( char const * const, int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
/* This is a stub implementation of open.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_glue.h"
|
||||
|
||||
bool _PDCLIB_open( _PDCLIB_fd_t * pFd, const _PDCLIB_fileops_t ** pOps,
|
||||
char const * const filename, unsigned int mode )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/* _PDCLIB_seed
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
unsigned long int _PDCLIB_seed = 1;
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
/* no tests for raw data */
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||
/* _PDCLIB_strtox_main( const char * *, int, _PDCLIB_uintmax_t, _PDCLIB_uintmax_t, int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_int.h"
|
||||
_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limval, int limdigit, char * sign )
|
||||
{
|
||||
_PDCLIB_uintmax_t rc = 0;
|
||||
int digit = -1;
|
||||
const char * x;
|
||||
while ( ( x = memchr( _PDCLIB_digits, tolower(**p), base ) ) != NULL )
|
||||
{
|
||||
digit = x - _PDCLIB_digits;
|
||||
if ( ( rc < limval ) || ( ( rc == limval ) && ( digit <= limdigit ) ) )
|
||||
{
|
||||
rc = rc * base + (unsigned)digit;
|
||||
++(*p);
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = ERANGE;
|
||||
/* TODO: Only if endptr != NULL - but do we really want *another* parameter? */
|
||||
/* TODO: Earlier version was missing tolower() here but was not caught by tests */
|
||||
while ( memchr( _PDCLIB_digits, tolower(**p), base ) != NULL ) ++(*p);
|
||||
/* TODO: This is ugly, but keeps caller from negating the error value */
|
||||
*sign = '+';
|
||||
return error;
|
||||
}
|
||||
}
|
||||
if ( digit == -1 )
|
||||
{
|
||||
*p = NULL;
|
||||
return 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
#include <errno.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
const char * p;
|
||||
char test[] = "123_";
|
||||
char fail[] = "xxx";
|
||||
char sign = '-';
|
||||
/* basic functionality */
|
||||
p = test;
|
||||
errno = 0;
|
||||
TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)12, 3, &sign ) == 123 );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( p == &test[3] );
|
||||
/* proper functioning to smaller base */
|
||||
p = test;
|
||||
TESTCASE( _PDCLIB_strtox_main( &p, 8u, (uintmax_t)999, (uintmax_t)12, 3, &sign ) == 0123 );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( p == &test[3] );
|
||||
/* overflowing subject sequence must still return proper endptr */
|
||||
p = test;
|
||||
TESTCASE( _PDCLIB_strtox_main( &p, 4u, (uintmax_t)999, (uintmax_t)1, 2, &sign ) == 999 );
|
||||
TESTCASE( errno == ERANGE );
|
||||
TESTCASE( p == &test[3] );
|
||||
TESTCASE( sign == '+' );
|
||||
/* testing conversion failure */
|
||||
errno = 0;
|
||||
p = fail;
|
||||
sign = '-';
|
||||
TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)99, 8, &sign ) == 0 );
|
||||
TESTCASE( p == NULL );
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,90 +0,0 @@
|
|||
/* _PDCLIB_strtox_prelim( const char *, char *, int * )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#ifndef REGTEST
|
||||
const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base )
|
||||
{
|
||||
/* skipping leading whitespace */
|
||||
while ( isspace( *p ) ) ++p;
|
||||
/* determining / skipping sign */
|
||||
if ( *p != '+' && *p != '-' ) *sign = '+';
|
||||
else *sign = *(p++);
|
||||
/* determining base */
|
||||
if ( *p == '0' )
|
||||
{
|
||||
++p;
|
||||
if ( ( *base == 0 || *base == 16 ) && ( *p == 'x' || *p == 'X' ) )
|
||||
{
|
||||
*base = 16;
|
||||
++p;
|
||||
/* catching a border case here: "0x" followed by a non-digit should
|
||||
be parsed as the unprefixed zero.
|
||||
We have to "rewind" the parsing; having the base set to 16 if it
|
||||
was zero previously does not hurt, as the result is zero anyway.
|
||||
*/
|
||||
if ( memchr( _PDCLIB_digits, tolower(*p), *base ) == NULL )
|
||||
{
|
||||
p -= 2;
|
||||
}
|
||||
}
|
||||
else if ( *base == 0 )
|
||||
{
|
||||
*base = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
--p;
|
||||
}
|
||||
}
|
||||
else if ( ! *base )
|
||||
{
|
||||
*base = 10;
|
||||
}
|
||||
return ( ( *base >= 2 ) && ( *base <= 36 ) ) ? p : NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
int base = 0;
|
||||
char sign = '\0';
|
||||
char test1[] = " 123";
|
||||
char test2[] = "\t+0123";
|
||||
char test3[] = "\v-0x123";
|
||||
TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] );
|
||||
TESTCASE( sign == '+' );
|
||||
TESTCASE( base == 10 );
|
||||
base = 0;
|
||||
sign = '\0';
|
||||
TESTCASE( _PDCLIB_strtox_prelim( test2, &sign, &base ) == &test2[3] );
|
||||
TESTCASE( sign == '+' );
|
||||
TESTCASE( base == 8 );
|
||||
base = 0;
|
||||
sign = '\0';
|
||||
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[4] );
|
||||
TESTCASE( sign == '-' );
|
||||
TESTCASE( base == 16 );
|
||||
base = 10;
|
||||
sign = '\0';
|
||||
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] );
|
||||
TESTCASE( sign == '-' );
|
||||
TESTCASE( base == 10 );
|
||||
base = 1;
|
||||
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
|
||||
base = 37;
|
||||
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,338 +0,0 @@
|
|||
/* UTF-8 codec
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#ifndef REGTEST
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <uchar.h>
|
||||
#include <assert.h>
|
||||
#include "_PDCLIB_encoding.h"
|
||||
|
||||
/* Use of the mbstate:
|
||||
*
|
||||
* _StUC[0] is the current decoding state
|
||||
* _St32[1] is the character accumulated so far
|
||||
*/
|
||||
|
||||
static bool utf8_mbsinit( const mbstate_t *p_s )
|
||||
{ return p_s->_StUC[0] == 0; }
|
||||
|
||||
enum {
|
||||
DecStart = 0,
|
||||
|
||||
Dec2B2,
|
||||
|
||||
Dec3B2,
|
||||
Dec3B3,
|
||||
|
||||
Dec4B2,
|
||||
Dec4B3,
|
||||
Dec4B4
|
||||
};
|
||||
|
||||
#define state (p_s->_StUC[0])
|
||||
#define accum (p_s->_St32[1])
|
||||
|
||||
#define START_CONVERSION \
|
||||
bool result = true; \
|
||||
|
||||
#define END_CONVERSION \
|
||||
end_conversion: \
|
||||
return result
|
||||
|
||||
#define FINISH(_r) do { \
|
||||
result = (_r); \
|
||||
goto end_conversion; \
|
||||
} while(0)
|
||||
|
||||
#define OUT32(_c) do { \
|
||||
if(p_outbuf) \
|
||||
(*((*p_outbuf)++)) = (_c); \
|
||||
(*p_outsz)--; \
|
||||
_PDCLIB_UNDEFINED(accum); \
|
||||
state = DecStart; \
|
||||
} while(0)
|
||||
|
||||
#define CHECK_CONTINUATION \
|
||||
do { if((c & 0xC0) != 0x80) return false; } while(0)
|
||||
|
||||
static bool utf8toc32(
|
||||
char32_t *restrict *restrict p_outbuf,
|
||||
size_t *restrict p_outsz,
|
||||
const char *restrict *restrict p_inbuf,
|
||||
size_t *restrict p_insz,
|
||||
mbstate_t *restrict p_s
|
||||
)
|
||||
{
|
||||
START_CONVERSION
|
||||
while(*p_outsz && *p_insz) {
|
||||
unsigned char c = **p_inbuf;
|
||||
char32_t c32;
|
||||
switch(state) {
|
||||
case DecStart:
|
||||
// 1 byte
|
||||
if(c <= 0x7F) {
|
||||
OUT32(c);
|
||||
} else if(c <= 0xDF) {
|
||||
accum = (c & 0x1F) << 6;
|
||||
state = Dec2B2;
|
||||
} else if(c <= 0xEF) {
|
||||
accum = (c & 0x0F) << 12;
|
||||
state = Dec3B2;
|
||||
} else if(c <= 0xF4) {
|
||||
accum = (c & 0x07) << 18;
|
||||
state = Dec4B2;
|
||||
} else {
|
||||
// 5+byte sequence illegal
|
||||
FINISH(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case Dec2B2:
|
||||
CHECK_CONTINUATION;
|
||||
|
||||
c32 = accum | (c & 0x3F);
|
||||
|
||||
// Overlong sequence (e.g. NUL injection)
|
||||
if(c32 <= 0x7F)
|
||||
FINISH(false);
|
||||
|
||||
OUT32(c32);
|
||||
break;
|
||||
|
||||
case Dec3B2:
|
||||
CHECK_CONTINUATION;
|
||||
accum |= (c & 0x3F) << 6;
|
||||
state = Dec3B3;
|
||||
break;
|
||||
|
||||
case Dec3B3:
|
||||
CHECK_CONTINUATION;
|
||||
|
||||
c32 = accum | (c & 0x3F);
|
||||
|
||||
// Overlong
|
||||
if(c32 <= 0x07FF)
|
||||
FINISH(false);
|
||||
|
||||
// Surrogate
|
||||
if(c32 >= 0xD800 && c32 <= 0xDFFF)
|
||||
FINISH(false);
|
||||
|
||||
OUT32(c32);
|
||||
break;
|
||||
|
||||
case Dec4B2:
|
||||
CHECK_CONTINUATION;
|
||||
accum |= (c & 0x3F) << 12;
|
||||
state = Dec4B3;
|
||||
break;
|
||||
|
||||
case Dec4B3:
|
||||
CHECK_CONTINUATION;
|
||||
accum |= (c & 0x3F) << 6;
|
||||
state = Dec4B4;
|
||||
break;
|
||||
|
||||
case Dec4B4:
|
||||
CHECK_CONTINUATION;
|
||||
|
||||
c32 = accum | (c & 0x3F);
|
||||
|
||||
// Overlong
|
||||
if(c32 <= 0xFFFF) FINISH(false);
|
||||
|
||||
// Not in Unicode
|
||||
if(c32 > 0x10FFFF) FINISH(false);
|
||||
|
||||
OUT32(c32);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(!"Invalid state");
|
||||
}
|
||||
|
||||
(*p_inbuf)++;
|
||||
(*p_insz)--;
|
||||
}
|
||||
END_CONVERSION;
|
||||
}
|
||||
|
||||
enum {
|
||||
EncStart = 0,
|
||||
Enc1R,
|
||||
Enc2R,
|
||||
Enc3R,
|
||||
};
|
||||
|
||||
static bool c32toutf8(
|
||||
char *restrict *restrict p_outbuf,
|
||||
size_t *restrict p_outsz,
|
||||
const char32_t *restrict *restrict p_inbuf,
|
||||
size_t *restrict p_insz,
|
||||
mbstate_t *restrict p_s
|
||||
)
|
||||
{
|
||||
START_CONVERSION
|
||||
while(*p_outsz) {
|
||||
unsigned char outc = 0;
|
||||
switch(state) {
|
||||
case Enc3R:
|
||||
outc = 0x80 | ((accum >> 12) & 0x3F);
|
||||
state = Enc2R;
|
||||
break;
|
||||
|
||||
case Enc2R:
|
||||
outc = 0x80 | ((accum >> 6) & 0x3F);
|
||||
state = Enc1R;
|
||||
break;
|
||||
|
||||
case Enc1R:
|
||||
outc = 0x80 | (accum & 0x3F);
|
||||
state = EncStart;
|
||||
_PDCLIB_UNDEFINED(accum);
|
||||
break;
|
||||
|
||||
case EncStart:
|
||||
if(*p_insz == 0)
|
||||
FINISH(true);
|
||||
|
||||
accum = **p_inbuf;
|
||||
(*p_inbuf)++;
|
||||
(*p_insz)--;
|
||||
|
||||
if(accum <= 0x7F) {
|
||||
outc = accum;
|
||||
state = EncStart;
|
||||
_PDCLIB_UNDEFINED(accum);
|
||||
} else if(accum <= 0x7FF) {
|
||||
outc = 0xC0 | (accum >> 6);
|
||||
state = Enc1R;
|
||||
} else if(accum <= 0xFFFF) {
|
||||
outc = 0xE0 | (accum >> 12);
|
||||
state = Enc2R;
|
||||
} else if(accum <= 0x10FFFF) {
|
||||
outc = 0xF0 | (accum >> 18);
|
||||
state = Enc3R;
|
||||
} else {
|
||||
FINISH(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(p_outbuf) {
|
||||
**p_outbuf = outc;
|
||||
(*p_outbuf)++;
|
||||
}
|
||||
(*p_outsz)--;
|
||||
}
|
||||
END_CONVERSION;
|
||||
}
|
||||
|
||||
const struct _PDCLIB_charcodec_t _PDCLIB_utf8_codec = {
|
||||
.__mbsinit = utf8_mbsinit,
|
||||
.__mbstoc32s = utf8toc32,
|
||||
.__c32stombs = c32toutf8,
|
||||
.__mb_max = 4,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
#ifndef REGTEST
|
||||
// Valid conversion & back
|
||||
|
||||
static const char* input = "abcde" "\xDF\xBF" "\xEF\xBF\xBF"
|
||||
"\xF4\x8F\xBF\xBF";
|
||||
|
||||
char32_t c32out[8];
|
||||
|
||||
char32_t *c32ptr = &c32out[0];
|
||||
size_t c32rem = 8;
|
||||
const char *chrptr = (char*) &input[0];
|
||||
size_t chrrem = strlen(input);
|
||||
mbstate_t mbs = { 0 };
|
||||
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs));
|
||||
TESTCASE(c32rem == 0);
|
||||
TESTCASE(chrrem == 0);
|
||||
TESTCASE(c32ptr == &c32out[8]);
|
||||
TESTCASE(chrptr == &input[strlen(input)]);
|
||||
TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' &&
|
||||
c32out[3] == 'd' && c32out[4] == 'e' && c32out[5] == 0x7FF &&
|
||||
c32out[6] == 0xFFFF && c32out[7] == 0x10FFFF);
|
||||
|
||||
char chrout[strlen(input)];
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 8;
|
||||
chrptr = &chrout[0];
|
||||
chrrem = strlen(input);
|
||||
TESTCASE(c32toutf8(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs));
|
||||
TESTCASE(c32rem == 0);
|
||||
TESTCASE(chrrem == 0);
|
||||
TESTCASE(c32ptr == &c32out[8]);
|
||||
TESTCASE(chrptr == &chrout[strlen(input)]);
|
||||
TESTCASE(memcmp(chrout, input, strlen(input)) == 0);
|
||||
|
||||
// Multi-part conversion
|
||||
static const char* mpinput = "\xDF\xBF";
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 8;
|
||||
chrptr = &mpinput[0];
|
||||
chrrem = 1;
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs));
|
||||
TESTCASE(c32ptr == &c32out[0]);
|
||||
TESTCASE(c32rem == 8);
|
||||
TESTCASE(chrptr == &mpinput[1]);
|
||||
TESTCASE(chrrem == 0);
|
||||
chrrem = 1;
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs));
|
||||
TESTCASE(c32ptr == &c32out[1]);
|
||||
TESTCASE(c32rem == 7);
|
||||
TESTCASE(chrptr == &mpinput[2]);
|
||||
TESTCASE(chrrem == 0);
|
||||
|
||||
// Invalid conversions
|
||||
|
||||
// Overlong nuls
|
||||
const char* nul2 = "\xC0\x80";
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 8;
|
||||
chrptr = &nul2[0];
|
||||
chrrem = 2;
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
|
||||
memset(&mbs, 0, sizeof mbs);
|
||||
const char* nul3 = "\xE0\x80\x80";
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 8;
|
||||
chrptr = &nul3[0];
|
||||
chrrem = 3;
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
|
||||
memset(&mbs, 0, sizeof mbs);
|
||||
const char* nul4 = "\xF0\x80\x80\x80";
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 8;
|
||||
chrptr = &nul4[0];
|
||||
chrrem = 4;
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
|
||||
|
||||
// Starting on a continuation
|
||||
const char* cont = "\x80";
|
||||
c32ptr = &c32out[0];
|
||||
c32rem = 8;
|
||||
chrptr = &cont[0];
|
||||
chrrem = 1;
|
||||
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/* _PDCLIB_assert( char const * )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
|
||||
#include "_PDCLIB_aux.h"
|
||||
|
||||
void _PDCLIB_assert99( char const * const message1, char const * const function, char const * const message2 )
|
||||
{
|
||||
fputs( message1, stderr );
|
||||
fputs( function, stderr );
|
||||
fputs( message2, stderr );
|
||||
abort();
|
||||
}
|
||||
|
||||
void _PDCLIB_assert89( char const * const message )
|
||||
{
|
||||
fputs( message, stderr );
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
#include <signal.h>
|
||||
|
||||
static int EXPECTED_ABORT = 0;
|
||||
static int UNEXPECTED_ABORT = 1;
|
||||
|
||||
static void aborthandler( int sig )
|
||||
{
|
||||
TESTCASE( ! EXPECTED_ABORT );
|
||||
exit( (signed int)TEST_RESULTS );
|
||||
}
|
||||
|
||||
#define NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
static int disabled_test( void )
|
||||
{
|
||||
int i = 0;
|
||||
assert( i == 0 ); /* NDEBUG set, condition met */
|
||||
assert( i == 1 ); /* NDEBUG set, condition fails */
|
||||
return i;
|
||||
}
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR );
|
||||
TESTCASE( disabled_test() == 0 );
|
||||
assert( UNEXPECTED_ABORT ); /* NDEBUG not set, condition met */
|
||||
assert( EXPECTED_ABORT ); /* NDEBUG not set, condition fails - should abort */
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,39 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "_PDCLIB_glue.h"
|
||||
#include <errno.h>
|
||||
#include <emulibc.h>
|
||||
|
||||
ECL_EXPORT ECL_ENTRY __attribute__((noreturn)) void (*_ecl_trap)(void); // something very unexpected happened. should not return
|
||||
ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk)(size_t n); // sbrk. won't return if the request can't be satisfied
|
||||
ECL_EXPORT ECL_ENTRY void (*_ecl_debug_puts)(const char *); // low level debug write, doesn't involve STDIO
|
||||
|
||||
ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_sealed)(size_t n); // allocate memory; see emulibc.h
|
||||
ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_invisible)(size_t n); // allocate memory; see emulibc.h
|
||||
|
||||
void *alloc_sealed(size_t size)
|
||||
{
|
||||
return _ecl_sbrk_sealed(size);
|
||||
}
|
||||
|
||||
void *alloc_invisible(size_t size)
|
||||
{
|
||||
return _ecl_sbrk_invisible(size);
|
||||
}
|
||||
|
||||
void _debug_puts(const char *s)
|
||||
{
|
||||
_ecl_debug_puts(s);
|
||||
}
|
||||
|
||||
void *_PDCLIB_sbrk(size_t n)
|
||||
{
|
||||
void *ret = _ecl_sbrk(n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _PDCLIB_Exit( int status )
|
||||
{
|
||||
_ecl_trap();
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/* _PDCLIB_rename( const char *, const char * )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_glue.h"
|
||||
#include <errno.h>
|
||||
|
||||
int _PDCLIB_rename( const char * old, const char * new )
|
||||
{
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,113 +0,0 @@
|
|||
/* stdarg
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#ifdef TEST
|
||||
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
typedef int (*intfunc_t)( void );
|
||||
|
||||
enum tag_t
|
||||
{
|
||||
TAG_END,
|
||||
TAG_INT,
|
||||
TAG_LONG,
|
||||
TAG_LLONG,
|
||||
TAG_DBL,
|
||||
TAG_LDBL,
|
||||
TAG_INTPTR,
|
||||
TAG_LDBLPTR,
|
||||
TAG_FUNCPTR
|
||||
};
|
||||
|
||||
static int dummy( void )
|
||||
{
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
static int test( enum tag_t s, ... )
|
||||
{
|
||||
enum tag_t tag = s;
|
||||
va_list ap;
|
||||
va_start( ap, s );
|
||||
for (;;)
|
||||
{
|
||||
switch ( tag )
|
||||
{
|
||||
case TAG_INT:
|
||||
{
|
||||
TESTCASE( va_arg( ap, int ) == INT_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_LONG:
|
||||
{
|
||||
TESTCASE( va_arg( ap, long ) == LONG_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_LLONG:
|
||||
{
|
||||
TESTCASE( va_arg( ap, long long ) == LLONG_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_DBL:
|
||||
{
|
||||
TESTCASE( va_arg( ap, double ) == DBL_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_LDBL:
|
||||
{
|
||||
TESTCASE( va_arg( ap, long double ) == LDBL_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_INTPTR:
|
||||
{
|
||||
TESTCASE( *( va_arg( ap, int * ) ) == INT_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_LDBLPTR:
|
||||
{
|
||||
TESTCASE( *( va_arg( ap, long double * ) ) == LDBL_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_FUNCPTR:
|
||||
{
|
||||
intfunc_t function;
|
||||
TESTCASE( ( function = va_arg( ap, intfunc_t ) ) == dummy );
|
||||
TESTCASE( function() == INT_MAX );
|
||||
tag = va_arg( ap, enum tag_t );
|
||||
break;
|
||||
}
|
||||
case TAG_END:
|
||||
{
|
||||
va_end( ap );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main( void )
|
||||
{
|
||||
int x = INT_MAX;
|
||||
long double d = LDBL_MAX;
|
||||
test( TAG_END );
|
||||
test( TAG_INT, INT_MAX, TAG_END );
|
||||
test( TAG_LONG, LONG_MAX, TAG_LLONG, LLONG_MAX, TAG_END );
|
||||
test( TAG_DBL, DBL_MAX, TAG_LDBL, LDBL_MAX, TAG_END );
|
||||
test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,522 +0,0 @@
|
|||
/* _PDCLIB_stdinit
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
/* This is an example initialization of stdin, stdout and stderr to the integer
|
||||
file descriptors 0, 1, and 2, respectively. This applies for a great variety
|
||||
of operating systems, including POSIX compliant ones.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_io.h"
|
||||
#include "_PDCLIB_locale.h"
|
||||
#include "_PDCLIB_encoding.h"
|
||||
|
||||
extern const _PDCLIB_fileops_t _PDCLIB_fileops;
|
||||
|
||||
/* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file
|
||||
descriptors 0, 1, and 2 respectively.
|
||||
*/
|
||||
/* TODO: This is proof-of-concept, requires finetuning. */
|
||||
static char _PDCLIB_sin_buffer[BUFSIZ];
|
||||
static char _PDCLIB_sout_buffer[BUFSIZ];
|
||||
static char _PDCLIB_serr_buffer[BUFSIZ];
|
||||
|
||||
static unsigned char _PDCLIB_sin_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
|
||||
static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
|
||||
static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
|
||||
|
||||
|
||||
static FILE _PDCLIB_serr = {
|
||||
.ops = &_PDCLIB_fileops,
|
||||
.buffer = _PDCLIB_serr_buffer,
|
||||
.bufsize = BUFSIZ,
|
||||
.bufidx = 0,
|
||||
.bufend = 0,
|
||||
.ungetidx = 0,
|
||||
.ungetbuf = _PDCLIB_serr_ungetbuf,
|
||||
.status = _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC,
|
||||
.filename = NULL,
|
||||
.next = NULL,
|
||||
};
|
||||
static FILE _PDCLIB_sout = {
|
||||
.ops = &_PDCLIB_fileops,
|
||||
.buffer = _PDCLIB_sout_buffer,
|
||||
.bufsize = BUFSIZ,
|
||||
.bufidx = 0,
|
||||
.bufend = 0,
|
||||
.ungetidx = 0,
|
||||
.ungetbuf = _PDCLIB_sout_ungetbuf,
|
||||
.status = _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC,
|
||||
.filename = NULL,
|
||||
.next = &_PDCLIB_serr
|
||||
};
|
||||
static FILE _PDCLIB_sin = {
|
||||
.ops = &_PDCLIB_fileops,
|
||||
.buffer = _PDCLIB_sin_buffer,
|
||||
.bufsize = BUFSIZ,
|
||||
.bufidx = 0,
|
||||
.bufend = 0,
|
||||
.ungetidx = 0,
|
||||
.ungetbuf = _PDCLIB_sin_ungetbuf,
|
||||
.status = _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC,
|
||||
.filename = NULL,
|
||||
.next = &_PDCLIB_sout
|
||||
};
|
||||
|
||||
FILE *stdin = &_PDCLIB_sin;
|
||||
FILE *stdout = &_PDCLIB_sout;
|
||||
FILE *stderr = &_PDCLIB_serr;
|
||||
|
||||
FILE *_PDCLIB_filelist = &_PDCLIB_sin;
|
||||
|
||||
/* "C" locale - defaulting to ASCII-7.
|
||||
1 kByte (+ 4 byte) of <ctype.h> data.
|
||||
Each line: flags, lowercase, uppercase, collation.
|
||||
*/
|
||||
static const _PDCLIB_ctype_t global_ctype[] = {
|
||||
{ /* EOF */ 0, 0, 0, 0 },
|
||||
{ /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00, 0x00 },
|
||||
{ /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01, 0x01 },
|
||||
{ /* STX */ _PDCLIB_CTYPE_CNTRL, 0x02, 0x02, 0x02 },
|
||||
{ /* ETX */ _PDCLIB_CTYPE_CNTRL, 0x03, 0x03, 0x03 },
|
||||
{ /* EOT */ _PDCLIB_CTYPE_CNTRL, 0x04, 0x04, 0x04 },
|
||||
{ /* ENQ */ _PDCLIB_CTYPE_CNTRL, 0x05, 0x05, 0x05 },
|
||||
{ /* ACK */ _PDCLIB_CTYPE_CNTRL, 0x06, 0x06, 0x06 },
|
||||
{ /* BEL */ _PDCLIB_CTYPE_CNTRL, 0x07, 0x07, 0x07 },
|
||||
{ /* BS */ _PDCLIB_CTYPE_CNTRL, 0x08, 0x08, 0x08 },
|
||||
{ /* HT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x09, 0x09, 0x09 },
|
||||
{ /* LF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0A, 0x0A, 0x0A },
|
||||
{ /* VT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0B, 0x0B, 0x0B },
|
||||
{ /* FF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0C, 0x0C, 0x0C },
|
||||
{ /* CR */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0D, 0x0D, 0x0D },
|
||||
{ /* SO */ _PDCLIB_CTYPE_CNTRL, 0x0E, 0x0E, 0x0E },
|
||||
{ /* SI */ _PDCLIB_CTYPE_CNTRL, 0x0F, 0x0F, 0x0F },
|
||||
{ /* DLE */ _PDCLIB_CTYPE_CNTRL, 0x10, 0x10, 0x10 },
|
||||
{ /* DC1 */ _PDCLIB_CTYPE_CNTRL, 0x11, 0x11, 0x11 },
|
||||
{ /* DC2 */ _PDCLIB_CTYPE_CNTRL, 0x12, 0x12, 0x12 },
|
||||
{ /* DC3 */ _PDCLIB_CTYPE_CNTRL, 0x13, 0x13, 0x13 },
|
||||
{ /* DC4 */ _PDCLIB_CTYPE_CNTRL, 0x14, 0x14, 0x14 },
|
||||
{ /* NAK */ _PDCLIB_CTYPE_CNTRL, 0x15, 0x15, 0x15 },
|
||||
{ /* SYN */ _PDCLIB_CTYPE_CNTRL, 0x16, 0x16, 0x16 },
|
||||
{ /* ETB */ _PDCLIB_CTYPE_CNTRL, 0x17, 0x17, 0x17 },
|
||||
{ /* CAN */ _PDCLIB_CTYPE_CNTRL, 0x18, 0x18, 0x18 },
|
||||
{ /* EM */ _PDCLIB_CTYPE_CNTRL, 0x19, 0x19, 0x19 },
|
||||
{ /* SUB */ _PDCLIB_CTYPE_CNTRL, 0x1A, 0x1A, 0x1A },
|
||||
{ /* ESC */ _PDCLIB_CTYPE_CNTRL, 0x1B, 0x1B, 0x1B },
|
||||
{ /* FS */ _PDCLIB_CTYPE_CNTRL, 0x1C, 0x1C, 0x1C },
|
||||
{ /* GS */ _PDCLIB_CTYPE_CNTRL, 0x1D, 0x1D, 0x1D },
|
||||
{ /* RS */ _PDCLIB_CTYPE_CNTRL, 0x1E, 0x1E, 0x1E },
|
||||
{ /* US */ _PDCLIB_CTYPE_CNTRL, 0x1F, 0x1F, 0x1F },
|
||||
{ /* SP */ _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x20, 0x20, 0x20 },
|
||||
{ /* '!' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x21, 0x21, 0x21 },
|
||||
{ /* '"' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x22, 0x22, 0x22 },
|
||||
{ /* '#' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x23, 0x23, 0x23 },
|
||||
{ /* '$' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x24, 0x24, 0x24 },
|
||||
{ /* '%' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x25, 0x25, 0x25 },
|
||||
{ /* '&' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x26, 0x26, 0x26 },
|
||||
{ /* ''' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x27, 0x27, 0x27 },
|
||||
{ /* '(' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x28, 0x28, 0x28 },
|
||||
{ /* ')' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x29, 0x29, 0x29 },
|
||||
{ /* '*' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2A, 0x2A, 0x2A },
|
||||
{ /* '+' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2B, 0x2B, 0x2B },
|
||||
{ /* ',' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2C, 0x2C, 0x2C },
|
||||
{ /* '-' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2D, 0x2D, 0x2D },
|
||||
{ /* '.' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2E, 0x2E, 0x2E },
|
||||
{ /* '/' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2F, 0x2F, 0x2F },
|
||||
{ /* '0' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x30, 0x30, 0x30 },
|
||||
{ /* '1' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x31, 0x31, 0x31 },
|
||||
{ /* '2' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x32, 0x32, 0x32 },
|
||||
{ /* '3' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x33, 0x33, 0x33 },
|
||||
{ /* '4' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x34, 0x34, 0x34 },
|
||||
{ /* '5' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x35, 0x35, 0x35 },
|
||||
{ /* '6' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x36, 0x36, 0x36 },
|
||||
{ /* '7' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x37, 0x37, 0x37 },
|
||||
{ /* '8' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x38, 0x38, 0x38 },
|
||||
{ /* '9' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x39, 0x39, 0x39 },
|
||||
{ /* ':' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3A, 0x3A, 0x3A },
|
||||
{ /* ';' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3B, 0x3B, 0x3B },
|
||||
{ /* '<' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3C, 0x3C, 0x3C },
|
||||
{ /* '=' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3D, 0x3D, 0x3D },
|
||||
{ /* '>' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3E, 0x3E, 0x3E },
|
||||
{ /* '?' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3F, 0x3F, 0x3F },
|
||||
{ /* '@' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x40, 0x40, 0x40 },
|
||||
{ /* 'A' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x41 },
|
||||
{ /* 'B' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x42 },
|
||||
{ /* 'C' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x43 },
|
||||
{ /* 'D' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x44 },
|
||||
{ /* 'E' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x45 },
|
||||
{ /* 'F' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x46 },
|
||||
{ /* 'G' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x47, 0x67, 0x47 },
|
||||
{ /* 'H' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x48, 0x68, 0x48 },
|
||||
{ /* 'I' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x49, 0x69, 0x49 },
|
||||
{ /* 'J' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4A, 0x6A, 0x4A },
|
||||
{ /* 'K' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4B, 0x6B, 0x4B },
|
||||
{ /* 'L' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4C, 0x6C, 0x4C },
|
||||
{ /* 'M' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4D, 0x6D, 0x4D },
|
||||
{ /* 'N' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4E, 0x6E, 0x4E },
|
||||
{ /* 'O' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4F, 0x6F, 0x4F },
|
||||
{ /* 'P' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x50, 0x70, 0x50 },
|
||||
{ /* 'Q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x51, 0x71, 0x51 },
|
||||
{ /* 'R' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x52, 0x72, 0x52 },
|
||||
{ /* 'S' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x53, 0x73, 0x53 },
|
||||
{ /* 'T' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x54, 0x74, 0x54 },
|
||||
{ /* 'U' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x55, 0x75, 0x55 },
|
||||
{ /* 'V' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x56, 0x76, 0x56 },
|
||||
{ /* 'W' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x57, 0x77, 0x57 },
|
||||
{ /* 'X' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x58, 0x78, 0x58 },
|
||||
{ /* 'Y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x59, 0x79, 0x59 },
|
||||
{ /* 'Z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x5A, 0x7A, 0x5A },
|
||||
{ /* '[' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5B, 0x5B, 0x5B },
|
||||
{ /* '\' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5C, 0x5C, 0x5C },
|
||||
{ /* ']' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5D, 0x5D, 0x5D },
|
||||
{ /* '^' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5E, 0x5E, 0x5E },
|
||||
{ /* '_' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5F, 0x5F, 0x5F },
|
||||
{ /* '`' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x60, 0x60, 0x60 },
|
||||
{ /* 'a' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x61 },
|
||||
{ /* 'b' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x62 },
|
||||
{ /* 'c' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x63 },
|
||||
{ /* 'd' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x64 },
|
||||
{ /* 'e' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x65 },
|
||||
{ /* 'f' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x66 },
|
||||
{ /* 'g' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x47, 0x67, 0x67 },
|
||||
{ /* 'h' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x48, 0x68, 0x68 },
|
||||
{ /* 'i' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x49, 0x69, 0x69 },
|
||||
{ /* 'j' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4A, 0x6A, 0x6A },
|
||||
{ /* 'k' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4B, 0x6B, 0x6B },
|
||||
{ /* 'l' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4C, 0x6C, 0x6C },
|
||||
{ /* 'm' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4D, 0x6D, 0x6D },
|
||||
{ /* 'n' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4E, 0x6E, 0x6E },
|
||||
{ /* 'o' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4F, 0x6F, 0x6F },
|
||||
{ /* 'p' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x50, 0x70, 0x70 },
|
||||
{ /* 'q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x51, 0x71, 0x71 },
|
||||
{ /* 'r' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x52, 0x72, 0x72 },
|
||||
{ /* 's' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x53, 0x73, 0x73 },
|
||||
{ /* 't' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x54, 0x74, 0x74 },
|
||||
{ /* 'u' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x55, 0x75, 0x75 },
|
||||
{ /* 'v' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x56, 0x76, 0x76 },
|
||||
{ /* 'w' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x57, 0x77, 0x77 },
|
||||
{ /* 'x' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x58, 0x78, 0x78 },
|
||||
{ /* 'y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x59, 0x79, 0x79 },
|
||||
{ /* 'z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x5A, 0x7A, 0x7A },
|
||||
{ /* '{' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7B, 0x7B, 0x7B },
|
||||
{ /* '|' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7C, 0x7C, 0x7C },
|
||||
{ /* '}' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7D, 0x7D, 0x7D },
|
||||
{ /* '~' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7E, 0x7E, 0x7E },
|
||||
{ /* DEL */ _PDCLIB_CTYPE_CNTRL, 0x7F, 0x7F, 0x7F },
|
||||
{ 0x00, 0x80, 0x80, 0x80 },
|
||||
{ 0x00, 0x81, 0x81, 0x81 },
|
||||
{ 0x00, 0x82, 0x82, 0x82 },
|
||||
{ 0x00, 0x83, 0x83, 0x83 },
|
||||
{ 0x00, 0x84, 0x84, 0x84 },
|
||||
{ 0x00, 0x85, 0x85, 0x85 },
|
||||
{ 0x00, 0x86, 0x86, 0x86 },
|
||||
{ 0x00, 0x87, 0x87, 0x87 },
|
||||
{ 0x00, 0x88, 0x88, 0x88 },
|
||||
{ 0x00, 0x89, 0x89, 0x89 },
|
||||
{ 0x00, 0x8A, 0x8A, 0x8A },
|
||||
{ 0x00, 0x8B, 0x8B, 0x8B },
|
||||
{ 0x00, 0x8C, 0x8C, 0x8C },
|
||||
{ 0x00, 0x8D, 0x8D, 0x8D },
|
||||
{ 0x00, 0x8E, 0x8E, 0x8E },
|
||||
{ 0x00, 0x8F, 0x8F, 0x8F },
|
||||
{ 0x00, 0x90, 0x90, 0x90 },
|
||||
{ 0x00, 0x91, 0x91, 0x91 },
|
||||
{ 0x00, 0x92, 0x92, 0x92 },
|
||||
{ 0x00, 0x93, 0x93, 0x93 },
|
||||
{ 0x00, 0x94, 0x94, 0x94 },
|
||||
{ 0x00, 0x95, 0x95, 0x95 },
|
||||
{ 0x00, 0x96, 0x96, 0x96 },
|
||||
{ 0x00, 0x97, 0x97, 0x97 },
|
||||
{ 0x00, 0x98, 0x98, 0x98 },
|
||||
{ 0x00, 0x99, 0x99, 0x99 },
|
||||
{ 0x00, 0x9A, 0x9A, 0x9A },
|
||||
{ 0x00, 0x9B, 0x9B, 0x9B },
|
||||
{ 0x00, 0x9C, 0x9C, 0x9C },
|
||||
{ 0x00, 0x9D, 0x9D, 0x9D },
|
||||
{ 0x00, 0x9E, 0x9E, 0x9E },
|
||||
{ 0x00, 0x9F, 0x9F, 0x9F },
|
||||
{ 0x00, 0xA0, 0xA0, 0xA0 },
|
||||
{ 0x00, 0xA1, 0xA1, 0xA1 },
|
||||
{ 0x00, 0xA2, 0xA2, 0xA2 },
|
||||
{ 0x00, 0xA3, 0xA3, 0xA3 },
|
||||
{ 0x00, 0xA4, 0xA4, 0xA4 },
|
||||
{ 0x00, 0xA5, 0xA5, 0xA5 },
|
||||
{ 0x00, 0xA6, 0xA6, 0xA6 },
|
||||
{ 0x00, 0xA7, 0xA7, 0xA7 },
|
||||
{ 0x00, 0xA8, 0xA8, 0xA8 },
|
||||
{ 0x00, 0xA9, 0xA9, 0xA9 },
|
||||
{ 0x00, 0xAA, 0xAA, 0xAA },
|
||||
{ 0x00, 0xAB, 0xAB, 0xAB },
|
||||
{ 0x00, 0xAC, 0xAC, 0xAC },
|
||||
{ 0x00, 0xAD, 0xAD, 0xAD },
|
||||
{ 0x00, 0xAE, 0xAE, 0xAE },
|
||||
{ 0x00, 0xAF, 0xAF, 0xAF },
|
||||
{ 0x00, 0xB0, 0xB0, 0xB0 },
|
||||
{ 0x00, 0xB1, 0xB1, 0xB1 },
|
||||
{ 0x00, 0xB2, 0xB2, 0xB2 },
|
||||
{ 0x00, 0xB3, 0xB3, 0xB3 },
|
||||
{ 0x00, 0xB4, 0xB4, 0xB4 },
|
||||
{ 0x00, 0xB5, 0xB5, 0xB5 },
|
||||
{ 0x00, 0xB6, 0xB6, 0xB6 },
|
||||
{ 0x00, 0xB7, 0xB7, 0xB7 },
|
||||
{ 0x00, 0xB8, 0xB8, 0xB8 },
|
||||
{ 0x00, 0xB9, 0xB9, 0xB9 },
|
||||
{ 0x00, 0xBA, 0xBA, 0xBA },
|
||||
{ 0x00, 0xBB, 0xBB, 0xBB },
|
||||
{ 0x00, 0xBC, 0xBC, 0xBC },
|
||||
{ 0x00, 0xBD, 0xBD, 0xBD },
|
||||
{ 0x00, 0xBE, 0xBE, 0xBE },
|
||||
{ 0x00, 0xBF, 0xBF, 0xBF },
|
||||
{ 0x00, 0xC0, 0xC0, 0xC0 },
|
||||
{ 0x00, 0xC1, 0xC1, 0xC1 },
|
||||
{ 0x00, 0xC2, 0xC2, 0xC2 },
|
||||
{ 0x00, 0xC3, 0xC3, 0xC3 },
|
||||
{ 0x00, 0xC4, 0xC4, 0xC4 },
|
||||
{ 0x00, 0xC5, 0xC5, 0xC5 },
|
||||
{ 0x00, 0xC6, 0xC6, 0xC6 },
|
||||
{ 0x00, 0xC7, 0xC7, 0xC7 },
|
||||
{ 0x00, 0xC8, 0xC8, 0xC8 },
|
||||
{ 0x00, 0xC9, 0xC9, 0xC9 },
|
||||
{ 0x00, 0xCA, 0xCA, 0xCA },
|
||||
{ 0x00, 0xCB, 0xCB, 0xCB },
|
||||
{ 0x00, 0xCC, 0xCC, 0xCC },
|
||||
{ 0x00, 0xCD, 0xCD, 0xCD },
|
||||
{ 0x00, 0xCE, 0xCE, 0xCE },
|
||||
{ 0x00, 0xCF, 0xCF, 0xCF },
|
||||
{ 0x00, 0xD0, 0xD0, 0xD0 },
|
||||
{ 0x00, 0xD1, 0xD1, 0xD1 },
|
||||
{ 0x00, 0xD2, 0xD2, 0xD2 },
|
||||
{ 0x00, 0xD3, 0xD3, 0xD3 },
|
||||
{ 0x00, 0xD4, 0xD4, 0xD4 },
|
||||
{ 0x00, 0xD5, 0xD5, 0xD5 },
|
||||
{ 0x00, 0xD6, 0xD6, 0xD6 },
|
||||
{ 0x00, 0xD7, 0xD7, 0xD7 },
|
||||
{ 0x00, 0xD8, 0xD8, 0xD8 },
|
||||
{ 0x00, 0xD9, 0xD9, 0xD9 },
|
||||
{ 0x00, 0xDA, 0xDA, 0xDA },
|
||||
{ 0x00, 0xDB, 0xDB, 0xDB },
|
||||
{ 0x00, 0xDC, 0xDC, 0xDC },
|
||||
{ 0x00, 0xDD, 0xDD, 0xDD },
|
||||
{ 0x00, 0xDE, 0xDE, 0xDE },
|
||||
{ 0x00, 0xDF, 0xDF, 0xDF },
|
||||
{ 0x00, 0xE0, 0xE0, 0xE0 },
|
||||
{ 0x00, 0xE1, 0xE1, 0xE1 },
|
||||
{ 0x00, 0xE2, 0xE2, 0xE2 },
|
||||
{ 0x00, 0xE3, 0xE3, 0xE3 },
|
||||
{ 0x00, 0xE4, 0xE4, 0xE4 },
|
||||
{ 0x00, 0xE5, 0xE5, 0xE5 },
|
||||
{ 0x00, 0xE6, 0xE6, 0xE6 },
|
||||
{ 0x00, 0xE7, 0xE7, 0xE7 },
|
||||
{ 0x00, 0xE8, 0xE8, 0xE8 },
|
||||
{ 0x00, 0xE9, 0xE9, 0xE9 },
|
||||
{ 0x00, 0xEA, 0xEA, 0xEA },
|
||||
{ 0x00, 0xEB, 0xEB, 0xEB },
|
||||
{ 0x00, 0xEC, 0xEC, 0xEC },
|
||||
{ 0x00, 0xED, 0xED, 0xED },
|
||||
{ 0x00, 0xEE, 0xEE, 0xEE },
|
||||
{ 0x00, 0xEF, 0xEF, 0xEF },
|
||||
{ 0x00, 0xF0, 0xF0, 0xF0 },
|
||||
{ 0x00, 0xF1, 0xF1, 0xF1 },
|
||||
{ 0x00, 0xF2, 0xF2, 0xF2 },
|
||||
{ 0x00, 0xF3, 0xF3, 0xF3 },
|
||||
{ 0x00, 0xF4, 0xF4, 0xF4 },
|
||||
{ 0x00, 0xF5, 0xF5, 0xF5 },
|
||||
{ 0x00, 0xF6, 0xF6, 0xF6 },
|
||||
{ 0x00, 0xF7, 0xF7, 0xF7 },
|
||||
{ 0x00, 0xF8, 0xF8, 0xF8 },
|
||||
{ 0x00, 0xF9, 0xF9, 0xF9 },
|
||||
{ 0x00, 0xFA, 0xFA, 0xFA },
|
||||
{ 0x00, 0xFB, 0xFB, 0xFB },
|
||||
{ 0x00, 0xFC, 0xFC, 0xFC },
|
||||
{ 0x00, 0xFD, 0xFD, 0xFD },
|
||||
{ 0x00, 0xFE, 0xFE, 0xFE },
|
||||
{ 0x00, 0xFF, 0xFF, 0xFF }
|
||||
};
|
||||
|
||||
extern const struct _PDCLIB_charcodec_t _PDCLIB_ascii_codec;
|
||||
struct _PDCLIB_locale _PDCLIB_global_locale = {
|
||||
._Codec = &_PDCLIB_ascii_codec,
|
||||
._Conv = {
|
||||
/* decimal_point */ (char *)".",
|
||||
/* thousands_sep */ (char *)"",
|
||||
/* grouping */ (char *)"",
|
||||
/* mon_decimal_point */ (char *)"",
|
||||
/* mon_thousands_sep */ (char *)"",
|
||||
/* mon_grouping */ (char *)"",
|
||||
/* positive_sign */ (char *)"",
|
||||
/* negative_sign */ (char *)"",
|
||||
/* currency_symbol */ (char *)"",
|
||||
/* int_curr_symbol */ (char *)"",
|
||||
/* frac_digits */ CHAR_MAX,
|
||||
/* p_cs_precedes */ CHAR_MAX,
|
||||
/* n_cs_precedes */ CHAR_MAX,
|
||||
/* p_sep_by_space */ CHAR_MAX,
|
||||
/* n_sep_by_space */ CHAR_MAX,
|
||||
/* p_sign_posn */ CHAR_MAX,
|
||||
/* n_sign_posn */ CHAR_MAX,
|
||||
/* int_frac_digits */ CHAR_MAX,
|
||||
/* int_p_cs_precedes */ CHAR_MAX,
|
||||
/* int_n_cs_precedes */ CHAR_MAX,
|
||||
/* int_p_sep_by_space */ CHAR_MAX,
|
||||
/* int_n_sep_by_space */ CHAR_MAX,
|
||||
/* int_p_sign_posn */ CHAR_MAX,
|
||||
/* int_n_sign_posn */ CHAR_MAX,
|
||||
},
|
||||
._CType = &global_ctype[1],
|
||||
._ErrnoStr = {
|
||||
"Success",
|
||||
"EPERM (operation not permitted)",
|
||||
"ENOENT (no such file or directory)",
|
||||
"ESRCH (no such process)",
|
||||
"EINTR (interrupted)",
|
||||
"EIO (io error)",
|
||||
"ENXIO (no such device or address)",
|
||||
"E2BIG (argument list too long)",
|
||||
"ENOEXEC (executable format error)",
|
||||
"EBADF (bad file descriptor)",
|
||||
"ECHILD (no child process)",
|
||||
"EAGAIN (resource unavailable try again)",
|
||||
"ENOMEM (not enough memory)",
|
||||
"EACCES (permission denied)",
|
||||
"EFAULT (bad address)",
|
||||
"Unknown error",
|
||||
"EBUSY (device or resource busy)",
|
||||
"EEXIST (file exists)",
|
||||
"EXDEV (cross device link)",
|
||||
"ENODEV (no such device)",
|
||||
"ENOTDIR (not a directory)",
|
||||
"EISDIR (is a directory)",
|
||||
"EINVAL (invalid argument)",
|
||||
"ENFILE (too many files open in system)",
|
||||
"EMFILE (too many files open)",
|
||||
"ENOTTY (inappropriate io control operation)",
|
||||
"ETXTBSY (text file busy)",
|
||||
"EFBIG (file too large)",
|
||||
"ENOSPC (no space on device)",
|
||||
"ESPIPE (invalid seek)",
|
||||
"EROFS (read only file system)",
|
||||
"EMLINK (too many links)",
|
||||
"EPIPE (broken pipe)",
|
||||
"EDOM (argument out of domain)",
|
||||
"ERANGE (result out of range)",
|
||||
"EDEADLK (resource deadlock would occur)",
|
||||
"ENAMETOOLONG (filename too long)",
|
||||
"ENOLCK (no lock available)",
|
||||
"ENOSYS (function not supported)",
|
||||
"ENOTEMPTY (directory not empty)",
|
||||
"ELOOP (too many symbolic link levels)",
|
||||
"Unknown error",
|
||||
"ENOMSG (no message)",
|
||||
"EIDRM (identifier removed)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"ENOSTR (not a stream)",
|
||||
"ENODATA (no message available)",
|
||||
"ETIME (stream timeout)",
|
||||
"ENOSR (no stream resources)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"ENOLINK (no link)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"EPROTO (protocol error)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"EBADMSG (bad message)",
|
||||
"EOVERFLOW (value too large)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"EILSEQ (illegal byte sequence)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"ENOTSOCK (not a socket)",
|
||||
"EDESTADDRREQ (destination address required)",
|
||||
"EMSGSIZE (message size)",
|
||||
"EPROTOTYPE (wrong protocol type)",
|
||||
"ENOPROTOOPT (no protocol option)",
|
||||
"EPROTONOSUPPORT (protocol not supported)",
|
||||
"Unknown error",
|
||||
"ENOTSUP (not supported)",
|
||||
"Unknown error",
|
||||
"EAFNOSUPPORT (address family not supported)",
|
||||
"EADDRINUSE (address in use)",
|
||||
"EADDRNOTAVAIL (address not available)",
|
||||
"ENETDOWN (network down)",
|
||||
"ENETUNREACH (network unreachable)",
|
||||
"ENETRESET (network reset)",
|
||||
"ECONNABORTED (connection aborted)",
|
||||
"ECONNRESET (connection reset)",
|
||||
"ENOBUFS (no buffer space)",
|
||||
"EISCONN (already connected)",
|
||||
"ENOTCONN (not connected)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"ETIMEDOUT (timed out)",
|
||||
"ECONNREFUSED (connection refused)",
|
||||
"Unknown error",
|
||||
"EHOSTUNREACH (host unreachable)",
|
||||
"EALREADY (connection already in progress)",
|
||||
"EINPROGRESS (operation in progress)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"ECANCELED (operation canceled)",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"Unknown error",
|
||||
"EOWNERDEAD (owner dead)",
|
||||
"ENOTRECOVERABLE (state not recoverable)",
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
/* Testing covered by several other testdrivers using stdin / stdout /
|
||||
stderr.
|
||||
*/
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,50 +0,0 @@
|
|||
#include "_PDCLIB_glue.h"
|
||||
#include <threads.h>
|
||||
|
||||
|
||||
#undef WIN32
|
||||
#undef _WIN32
|
||||
#define DLMALLOC_EXPORT _PDCLIB_API
|
||||
#define MALLOC_ALIGNMENT _PDCLIB_MALLOC_ALIGN
|
||||
#define MSPACES 0
|
||||
#define USE_LOCKS 0
|
||||
#define USE_SPIN_LOCKS 0
|
||||
#define USE_RECURSIVE_LOCKS 0
|
||||
#undef NEED_GLOBAL_LOCK_INIT
|
||||
#define FOOTERS 0
|
||||
#undef USE_DL_PREFIX
|
||||
#define MALLOC_INSPECT_ALL 0
|
||||
#define ABORT abort()
|
||||
#define PROCEED_ON_ERROR 0
|
||||
#define DEBUG 0
|
||||
#define ABORT_ON_ASSERT_FAILURE 1
|
||||
#define MALLOC_FAILURE_ACTION errno = ENOMEM
|
||||
#define HAVE_MORECORE 1
|
||||
#define MORECORE _PDCLIB_sbrk
|
||||
#define MORECORE_CONTIGUOUS 1
|
||||
#define MORECORE_CANNOT_TRIM 1
|
||||
#define NO_SEGMENT_TRAVERSAL 0
|
||||
#define HAVE_MMAP 0
|
||||
#define HAVE_MREMAP 0
|
||||
#define USE_BUILTIN_FFS 0
|
||||
#define malloc_getpagesize _PDCLIB_MALLOC_PAGESIZE
|
||||
#define USE_DEV_RANDOM 0
|
||||
#define NO_MALLINFO 1
|
||||
#define MALLINFO_FIELD_TYPE size_t
|
||||
#define NO_MALLOC_STATS 1
|
||||
#define DEFAULT_GRANULARITY _PDCLIB_MALLOC_GRANULARITY
|
||||
#define DEFAULT_TRIM_THRESHOLD _PDCLIB_MALLOC_TRIM_THRESHOLD
|
||||
#define DEFAULT_MMAP_THREHOLD _PDCLIB_MALLOC_MMAP_THRESHOLD
|
||||
#define MAX_RELEASE_CHECK_RATE _PDCLIB_MALLOC_RELEASE_CHECK_RATE
|
||||
|
||||
/* C standard says this is so */
|
||||
#define REALLOC_ZERO_BYTES_FREES 1
|
||||
#define LACKS_UNISTD_H
|
||||
#define LACKS_FCNTL_H
|
||||
#define LACKS_SYS_PARAM_H
|
||||
#define LACKS_SYS_MMAN_H
|
||||
#define LACKS_STRINGS_H
|
||||
#define LACKS_SYS_TYPES_H
|
||||
#define LACKS_SCHED_H
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
|
@ -1,36 +0,0 @@
|
|||
/* isalnum( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isalnum( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & ( _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isalnum( 'a' ) );
|
||||
TESTCASE( isalnum( 'z' ) );
|
||||
TESTCASE( isalnum( 'A' ) );
|
||||
TESTCASE( isalnum( 'Z' ) );
|
||||
TESTCASE( isalnum( '0' ) );
|
||||
TESTCASE( isalnum( '9' ) );
|
||||
TESTCASE( ! isalnum( ' ' ) );
|
||||
TESTCASE( ! isalnum( '\n' ) );
|
||||
TESTCASE( ! isalnum( '@' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||
/* isalpha( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isalpha( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_ALPHA );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isalpha( 'a' ) );
|
||||
TESTCASE( isalpha( 'z' ) );
|
||||
TESTCASE( ! isalpha( ' ' ) );
|
||||
TESTCASE( ! isalpha( '1' ) );
|
||||
TESTCASE( ! isalpha( '@' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,6 +0,0 @@
|
|||
#include <ctype.h>
|
||||
|
||||
int isascii(int c)
|
||||
{
|
||||
return (unsigned)c < 128;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* isblank( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isblank( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_BLANK );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isblank( ' ' ) );
|
||||
TESTCASE( isblank( '\t' ) );
|
||||
TESTCASE( ! isblank( '\v' ) );
|
||||
TESTCASE( ! isblank( '\r' ) );
|
||||
TESTCASE( ! isblank( 'x' ) );
|
||||
TESTCASE( ! isblank( '@' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
/* iscntrl( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int iscntrl( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_CNTRL );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( iscntrl( '\a' ) );
|
||||
TESTCASE( iscntrl( '\b' ) );
|
||||
TESTCASE( iscntrl( '\n' ) );
|
||||
TESTCASE( ! iscntrl( ' ' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||
/* isdigit( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isdigit( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_DIGIT );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isdigit( '0' ) );
|
||||
TESTCASE( isdigit( '9' ) );
|
||||
TESTCASE( ! isdigit( ' ' ) );
|
||||
TESTCASE( ! isdigit( 'a' ) );
|
||||
TESTCASE( ! isdigit( '@' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
/* isgraph( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isgraph( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_GRAPH );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isgraph( 'a' ) );
|
||||
TESTCASE( isgraph( 'z' ) );
|
||||
TESTCASE( isgraph( 'A' ) );
|
||||
TESTCASE( isgraph( 'Z' ) );
|
||||
TESTCASE( isgraph( '@' ) );
|
||||
TESTCASE( ! isgraph( '\t' ) );
|
||||
TESTCASE( ! isgraph( '\0' ) );
|
||||
TESTCASE( ! isgraph( ' ' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||
/* islower( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int islower( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_LOWER );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( islower( 'a' ) );
|
||||
TESTCASE( islower( 'z' ) );
|
||||
TESTCASE( ! islower( 'A' ) );
|
||||
TESTCASE( ! islower( 'Z' ) );
|
||||
TESTCASE( ! islower( ' ' ) );
|
||||
TESTCASE( ! islower( '@' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
/* isprint( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isprint( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isprint( 'a' ) );
|
||||
TESTCASE( isprint( 'z' ) );
|
||||
TESTCASE( isprint( 'A' ) );
|
||||
TESTCASE( isprint( 'Z' ) );
|
||||
TESTCASE( isprint( '@' ) );
|
||||
TESTCASE( ! isprint( '\t' ) );
|
||||
TESTCASE( ! isprint( '\0' ) );
|
||||
TESTCASE( isprint( ' ' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||
/* ispunct( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int ispunct( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_PUNCT );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( ! ispunct( 'a' ) );
|
||||
TESTCASE( ! ispunct( 'z' ) );
|
||||
TESTCASE( ! ispunct( 'A' ) );
|
||||
TESTCASE( ! ispunct( 'Z' ) );
|
||||
TESTCASE( ispunct( '@' ) );
|
||||
TESTCASE( ispunct( '.' ) );
|
||||
TESTCASE( ! ispunct( '\t' ) );
|
||||
TESTCASE( ! ispunct( '\0' ) );
|
||||
TESTCASE( ! ispunct( ' ' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/* isspace( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isspace( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_SPACE );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isspace( ' ' ) );
|
||||
TESTCASE( isspace( '\f' ) );
|
||||
TESTCASE( isspace( '\n' ) );
|
||||
TESTCASE( isspace( '\r' ) );
|
||||
TESTCASE( isspace( '\t' ) );
|
||||
TESTCASE( isspace( '\v' ) );
|
||||
TESTCASE( ! isspace( 'a' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||
/* isupper( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isupper( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_UPPER );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isupper( 'A' ) );
|
||||
TESTCASE( isupper( 'Z' ) );
|
||||
TESTCASE( ! isupper( 'a' ) );
|
||||
TESTCASE( ! isupper( 'z' ) );
|
||||
TESTCASE( ! isupper( ' ' ) );
|
||||
TESTCASE( ! isupper( '@' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/* isxdigit( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int isxdigit( int c )
|
||||
{
|
||||
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_XDIGT );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( isxdigit( '0' ) );
|
||||
TESTCASE( isxdigit( '9' ) );
|
||||
TESTCASE( isxdigit( 'a' ) );
|
||||
TESTCASE( isxdigit( 'f' ) );
|
||||
TESTCASE( ! isxdigit( 'g' ) );
|
||||
TESTCASE( isxdigit( 'A' ) );
|
||||
TESTCASE( isxdigit( 'F' ) );
|
||||
TESTCASE( ! isxdigit( 'G' ) );
|
||||
TESTCASE( ! isxdigit( '@' ) );
|
||||
TESTCASE( ! isxdigit( ' ' ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||
/* tolower( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int tolower( int c )
|
||||
{
|
||||
return _PDCLIB_threadlocale()->_CType[c].lower;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( tolower( 'A' ) == 'a' );
|
||||
TESTCASE( tolower( 'Z' ) == 'z' );
|
||||
TESTCASE( tolower( 'a' ) == 'a' );
|
||||
TESTCASE( tolower( 'z' ) == 'z' );
|
||||
TESTCASE( tolower( '@' ) == '@' );
|
||||
TESTCASE( tolower( '[' ) == '[' );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||
/* toupper( int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
int toupper( int c )
|
||||
{
|
||||
return _PDCLIB_threadlocale()->_CType[c].upper;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( toupper( 'a' ) == 'A' );
|
||||
TESTCASE( toupper( 'z' ) == 'Z' );
|
||||
TESTCASE( toupper( 'A' ) == 'A' );
|
||||
TESTCASE( toupper( 'Z' ) == 'Z' );
|
||||
TESTCASE( toupper( '@' ) == '@' );
|
||||
TESTCASE( toupper( '[' ) == '[' );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/* _PDCLIB_errno
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef REGTEST
|
||||
#include <threads.h>
|
||||
|
||||
/* Temporary */
|
||||
|
||||
static int _PDCLIB_errno = 0;
|
||||
|
||||
int * _PDCLIB_errno_func()
|
||||
{
|
||||
return &_PDCLIB_errno;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
errno = 0;
|
||||
TESTCASE( errno == 0 );
|
||||
errno = EDOM;
|
||||
TESTCASE( errno == EDOM );
|
||||
errno = ERANGE;
|
||||
TESTCASE( errno == ERANGE );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/* imaxabs( intmax_t )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
|
||||
intmax_t imaxabs( intmax_t j )
|
||||
{
|
||||
return ( j >= 0 ) ? j : -j;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
#include <limits.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( imaxabs( (intmax_t)0 ) == 0 );
|
||||
TESTCASE( imaxabs( INTMAX_MAX ) == INTMAX_MAX );
|
||||
TESTCASE( imaxabs( INTMAX_MIN + 1 ) == -( INTMAX_MIN + 1 ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
/* lldiv( long long int, long long int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
|
||||
imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom )
|
||||
{
|
||||
imaxdiv_t rc;
|
||||
rc.quot = numer / denom;
|
||||
rc.rem = numer % denom;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
imaxdiv_t result;
|
||||
result = imaxdiv( (intmax_t)5, (intmax_t)2 );
|
||||
TESTCASE( result.quot == 2 && result.rem == 1 );
|
||||
result = imaxdiv( (intmax_t)-5, (intmax_t)2 );
|
||||
TESTCASE( result.quot == -2 && result.rem == -1 );
|
||||
result = imaxdiv( (intmax_t)5, (intmax_t)-2 );
|
||||
TESTCASE( result.quot == -2 && result.rem == 1 );
|
||||
TESTCASE( sizeof( result.quot ) == sizeof( intmax_t ) );
|
||||
TESTCASE( sizeof( result.rem ) == sizeof( intmax_t ) );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,146 +0,0 @@
|
|||
/* strtoimax( const char *, char * *, int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base )
|
||||
{
|
||||
intmax_t rc;
|
||||
char sign = '+';
|
||||
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
|
||||
if ( base < 2 || base > 36 ) return 0;
|
||||
if ( sign == '+' )
|
||||
{
|
||||
rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MAX, (uintmax_t)( INTMAX_MAX / base ), (int)( INTMAX_MAX % base ), &sign );
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MIN, (uintmax_t)( INTMAX_MIN / -base ), (int)( -( INTMAX_MIN % base ) ), &sign );
|
||||
}
|
||||
if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr;
|
||||
return ( sign == '+' ) ? rc : -rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
char * endptr;
|
||||
/* this, to base 36, overflows even a 256 bit integer */
|
||||
char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_";
|
||||
/* tricky border case */
|
||||
char tricky[] = "+0xz";
|
||||
errno = 0;
|
||||
/* basic functionality */
|
||||
TESTCASE( strtoimax( "123", NULL, 10 ) == 123 );
|
||||
/* proper detecting of default base 10 */
|
||||
TESTCASE( strtoimax( "456", NULL, 0 ) == 456 );
|
||||
/* proper functioning to smaller base */
|
||||
TESTCASE( strtoimax( "14", NULL, 8 ) == 12 );
|
||||
/* proper autodetecting of octal */
|
||||
TESTCASE( strtoimax( "016", NULL, 0 ) == 14 );
|
||||
/* proper autodetecting of hexadecimal, lowercase 'x' */
|
||||
TESTCASE( strtoimax( "0xFF", NULL, 0 ) == 255 );
|
||||
/* proper autodetecting of hexadecimal, uppercase 'X' */
|
||||
TESTCASE( strtoimax( "0Xa1", NULL, 0 ) == 161 );
|
||||
/* proper handling of border case: 0x followed by non-hexdigit */
|
||||
TESTCASE( strtoimax( tricky, &endptr, 0 ) == 0 );
|
||||
TESTCASE( endptr == tricky + 2 );
|
||||
/* proper handling of border case: 0 followed by non-octdigit */
|
||||
TESTCASE( strtoimax( tricky, &endptr, 8 ) == 0 );
|
||||
TESTCASE( endptr == tricky + 2 );
|
||||
/* errno should still be 0 */
|
||||
TESTCASE( errno == 0 );
|
||||
/* overflowing subject sequence must still return proper endptr */
|
||||
TESTCASE( strtoimax( overflow, &endptr, 36 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == ERANGE );
|
||||
TESTCASE( ( endptr - overflow ) == 53 );
|
||||
/* same for positive */
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( overflow + 1, &endptr, 36 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
TESTCASE( ( endptr - overflow ) == 53 );
|
||||
/* testing skipping of leading whitespace */
|
||||
TESTCASE( strtoimax( " \n\v\t\f789", NULL, 0 ) == 789 );
|
||||
/* testing conversion failure */
|
||||
TESTCASE( strtoimax( overflow, &endptr, 10 ) == 0 );
|
||||
TESTCASE( endptr == overflow );
|
||||
endptr = NULL;
|
||||
TESTCASE( strtoimax( overflow, &endptr, 0 ) == 0 );
|
||||
TESTCASE( endptr == overflow );
|
||||
/* These tests assume two-complement, but conversion should work for */
|
||||
/* one-complement and signed magnitude just as well. Anyone having a */
|
||||
/* platform to test this on? */
|
||||
errno = 0;
|
||||
#if INTMAX_MAX >> 62 == 1
|
||||
/* testing "odd" overflow, i.e. base is not a power of two */
|
||||
TESTCASE( strtoimax( "9223372036854775807", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "9223372036854775808", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( "-9223372036854775807", NULL, 0 ) == (INTMAX_MIN + 1) );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-9223372036854775808", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-9223372036854775809", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == ERANGE );
|
||||
/* testing "even" overflow, i.e. base is power of two */
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( "0x7fffffffffffffff", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "0x8000000000000000", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( "-0x7fffffffffffffff", NULL, 0 ) == (INTMAX_MIN + 1) );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-0x8000000000000000", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-0x8000000000000001", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == ERANGE );
|
||||
#elif LLONG_MAX >> 126 == 1
|
||||
/* testing "odd" overflow, i.e. base is not a power of two */
|
||||
TESTCASE( strtoimax( "170141183460469231731687303715884105728", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( "-170141183460469231731687303715884105728", NULL, 0 ) == (INTMAX_MIN + 1) );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-170141183460469231731687303715884105730", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == ERANGE );
|
||||
/* testing "even" overflow, i.e. base is power of two */
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( "0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
errno = 0;
|
||||
TESTCASE( strtoimax( "-0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == (INTMAX_MIN + 1) );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoimax( "-0x80000000000000000000000000000001", NULL, 0 ) == INTMAX_MIN );
|
||||
TESTCASE( errno == ERANGE );
|
||||
#else
|
||||
#error Unsupported width of 'intmax_t' (neither 64 nor 128 bit).
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,109 +0,0 @@
|
|||
/* strtoumax( const char *, char * *, int )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef REGTEST
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base )
|
||||
{
|
||||
uintmax_t rc;
|
||||
char sign = '+';
|
||||
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
|
||||
if ( base < 2 || base > 36 ) return 0;
|
||||
rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)UINTMAX_MAX, (uintmax_t)( UINTMAX_MAX / base ), (int)( UINTMAX_MAX % base ), &sign );
|
||||
if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr;
|
||||
return ( sign == '+' ) ? rc : -rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
#include <errno.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
char * endptr;
|
||||
/* this, to base 36, overflows even a 256 bit integer */
|
||||
char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_";
|
||||
/* tricky border case */
|
||||
char tricky[] = "+0xz";
|
||||
errno = 0;
|
||||
/* basic functionality */
|
||||
TESTCASE( strtoumax( "123", NULL, 10 ) == 123 );
|
||||
/* proper detecting of default base 10 */
|
||||
TESTCASE( strtoumax( "456", NULL, 0 ) == 456 );
|
||||
/* proper functioning to smaller base */
|
||||
TESTCASE( strtoumax( "14", NULL, 8 ) == 12 );
|
||||
/* proper autodetecting of octal */
|
||||
TESTCASE( strtoumax( "016", NULL, 0 ) == 14 );
|
||||
/* proper autodetecting of hexadecimal, lowercase 'x' */
|
||||
TESTCASE( strtoumax( "0xFF", NULL, 0 ) == 255 );
|
||||
/* proper autodetecting of hexadecimal, uppercase 'X' */
|
||||
TESTCASE( strtoumax( "0Xa1", NULL, 0 ) == 161 );
|
||||
/* proper handling of border case: 0x followed by non-hexdigit */
|
||||
TESTCASE( strtoumax( tricky, &endptr, 0 ) == 0 );
|
||||
TESTCASE( endptr == tricky + 2 );
|
||||
/* proper handling of border case: 0 followed by non-octdigit */
|
||||
TESTCASE( strtoumax( tricky, &endptr, 8 ) == 0 );
|
||||
TESTCASE( endptr == tricky + 2 );
|
||||
/* errno should still be 0 */
|
||||
TESTCASE( errno == 0 );
|
||||
/* overflowing subject sequence must still return proper endptr */
|
||||
TESTCASE( strtoumax( overflow, &endptr, 36 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
TESTCASE( ( endptr - overflow ) == 53 );
|
||||
/* same for positive */
|
||||
errno = 0;
|
||||
TESTCASE( strtoumax( overflow + 1, &endptr, 36 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
TESTCASE( ( endptr - overflow ) == 53 );
|
||||
/* testing skipping of leading whitespace */
|
||||
TESTCASE( strtoumax( " \n\v\t\f789", NULL, 0 ) == 789 );
|
||||
/* testing conversion failure */
|
||||
TESTCASE( strtoumax( overflow, &endptr, 10 ) == 0 );
|
||||
TESTCASE( endptr == overflow );
|
||||
endptr = NULL;
|
||||
TESTCASE( strtoumax( overflow, &endptr, 0 ) == 0 );
|
||||
TESTCASE( endptr == overflow );
|
||||
errno = 0;
|
||||
/* uintmax_t -> long long -> 64 bit */
|
||||
#if UINTMAX_MAX >> 63 == 1
|
||||
/* testing "odd" overflow, i.e. base is not power of two */
|
||||
TESTCASE( strtoumax( "18446744073709551615", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoumax( "18446744073709551616", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
/* testing "even" overflow, i.e. base is power of two */
|
||||
errno = 0;
|
||||
TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoumax( "0x10000000000000000", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
/* uintmax_t -> long long -> 128 bit */
|
||||
#elif UINTMAX_MAX >> 127 == 1
|
||||
/* testing "odd" overflow, i.e. base is not power of two */
|
||||
TESTCASE( strtoumax( "340282366920938463463374607431768211455", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoumax( "340282366920938463463374607431768211456", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
/* testing "even" everflow, i.e. base is power of two */
|
||||
errno = 0;
|
||||
TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == 0 );
|
||||
TESTCASE( strtoumax( "0x100000000000000000000000000000000", NULL, 0 ) == UINTMAX_MAX );
|
||||
TESTCASE( errno == ERANGE );
|
||||
#else
|
||||
#error Unsupported width of 'uintmax_t' (neither 64 nor 128 bit).
|
||||
#endif
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,194 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: ascii -*-
|
||||
# Unicode Data Converter
|
||||
#
|
||||
# This file is part of the Public Domain C Library (PDCLib).
|
||||
# Permission is granted to use, modify, and / or redistribute at will.
|
||||
"""
|
||||
Converts the character information provdied by Unicode in the UnicodeData.txt
|
||||
file from the Unicode character database into a table for use by PDCLib.
|
||||
|
||||
Usage: Download the UnicodeData.txt file to the same directory as this script
|
||||
and then run it. Both Python 2 and 3 are supported.
|
||||
|
||||
Download the data from
|
||||
ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
|
||||
|
||||
We do some simple "run" compression, because characters in the Unicode Data file
|
||||
tend to come in groups with the same properties.
|
||||
"""
|
||||
import os
|
||||
|
||||
# MUST BE KEPT SYNCHRONIZED WITH _PDCLIB_locale.h
|
||||
BIT_ALPHA = 1
|
||||
BIT_BLANK = 2
|
||||
BIT_CNTRL = 4
|
||||
BIT_GRAPH = 8
|
||||
BIT_PUNCT = 16
|
||||
BIT_SPACE = 32
|
||||
BIT_LOWER = 64
|
||||
BIT_UPPER = 128
|
||||
BIT_DIGIT = 256
|
||||
BIT_XDIGT = 512
|
||||
|
||||
# Category to bitfield mapping
|
||||
categories = {
|
||||
'Lu': BIT_ALPHA | BIT_GRAPH | BIT_UPPER, # Uppercase
|
||||
'Ll': BIT_ALPHA | BIT_GRAPH | BIT_LOWER, # Lowercase
|
||||
'Lt': BIT_ALPHA | BIT_GRAPH | BIT_UPPER, # Title case. Upper?
|
||||
'Lm': BIT_ALPHA | BIT_GRAPH, # Modifier. Case?
|
||||
'Lo': BIT_ALPHA | BIT_GRAPH, # "Other" letter (e.g. Ideograph)
|
||||
'Nd': BIT_DIGIT | BIT_GRAPH, # Decimal digit
|
||||
'Nl': BIT_GRAPH, # Letter-like numeric character
|
||||
'No': BIT_GRAPH, # Other numeric
|
||||
'Pc': BIT_PUNCT | BIT_GRAPH, # Connecting punctuation
|
||||
'Pd': BIT_PUNCT | BIT_GRAPH, # Dash punctuation
|
||||
'Ps': BIT_PUNCT | BIT_GRAPH, # Opening punctuation
|
||||
'Pe': BIT_PUNCT | BIT_GRAPH, # Closing punctuation
|
||||
'Pi': BIT_PUNCT | BIT_GRAPH, # Opening quote
|
||||
'Pf': BIT_PUNCT | BIT_GRAPH, # Closing quote
|
||||
'Po': BIT_PUNCT | BIT_GRAPH, # Other punctuation
|
||||
'Sm': BIT_GRAPH, # Mathematical symbol
|
||||
'Sc': BIT_GRAPH, # Currency symbol
|
||||
'Sk': BIT_GRAPH, # Non-letterlike modifier symbol
|
||||
'So': BIT_GRAPH, # Other symbol
|
||||
'Zs': BIT_SPACE, # Non-zero-width space character
|
||||
'Zl': BIT_SPACE, # Line separator
|
||||
'Zp': BIT_SPACE, # Paragraph separator
|
||||
'Cc': BIT_CNTRL, # C0/C1 control codes
|
||||
}
|
||||
|
||||
# Characters with special properties
|
||||
special = {
|
||||
# Blank characters
|
||||
0x0020: BIT_SPACE | BIT_BLANK, # space
|
||||
0x0009: BIT_SPACE | BIT_BLANK, # tab
|
||||
|
||||
# Digits
|
||||
0x0030: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0031: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0032: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0033: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0034: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0035: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0036: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0037: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0038: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
0x0039: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
|
||||
|
||||
# A-F (hex uppercase)
|
||||
0x0041: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
|
||||
0x0042: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
|
||||
0x0043: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
|
||||
0x0044: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
|
||||
0x0045: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
|
||||
0x0046: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
|
||||
|
||||
|
||||
# a-f (hex lowercase)
|
||||
0x0061: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
|
||||
0x0062: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
|
||||
0x0063: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
|
||||
0x0064: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
|
||||
0x0065: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
|
||||
0x0066: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
|
||||
}
|
||||
|
||||
class Group:
|
||||
def __init__(self, start, flags, upper_delta, lower_delta):
|
||||
self.start = start
|
||||
self.flags = flags
|
||||
self.upper_delta = upper_delta
|
||||
self.lower_delta = lower_delta
|
||||
self.chars = []
|
||||
|
||||
def add_char(self, num, label):
|
||||
self.chars.append((num, label))
|
||||
|
||||
def write_to_file(self, f):
|
||||
for char in self.chars:
|
||||
f.write("// %x %s\n" % char)
|
||||
f.write(" { 0x%X, \t0x%X, \t0x%X, \t%d, \t%d },\n" %
|
||||
(self.start, len(self.chars), self.flags, self.lower_delta, self.upper_delta))
|
||||
|
||||
def next(self):
|
||||
return self.start + len(self.chars)
|
||||
|
||||
groups = []
|
||||
|
||||
def add_char(num, upper, lower, bits, label):
|
||||
upper_delta = upper - num
|
||||
lower_delta = lower - num
|
||||
|
||||
if len(groups) != 0:
|
||||
cur = groups[-1]
|
||||
if num == cur.next() and cur.flags == bits and \
|
||||
cur.upper_delta == upper_delta and \
|
||||
cur.lower_delta == lower_delta:
|
||||
cur.add_char(num, label)
|
||||
return
|
||||
|
||||
g = Group(num, bits, upper_delta, lower_delta)
|
||||
g.add_char(num, label)
|
||||
groups.append(g)
|
||||
|
||||
in_file = open('UnicodeData.txt', 'r')
|
||||
out_file = open('_PDCLIB_unicodedata.c', 'w')
|
||||
try:
|
||||
for line in in_file:
|
||||
(num_hex, name, category, combining_class, bidi_class, decomposition,
|
||||
numeric_type, numeric_digit, numeric_value, mirrored, u1name, iso_com,
|
||||
upper_case_hex, lower_case_hex, title_case_hex) = line.split(";")
|
||||
|
||||
num = int(num_hex, 16)
|
||||
upper_case = int(upper_case_hex, 16) if len(upper_case_hex) else num
|
||||
lower_case = int(lower_case_hex, 16) if len(lower_case_hex) else num
|
||||
bits = special.get(num, categories.get(category, 0))
|
||||
|
||||
if upper_case == 0 and lower_case == 0 and bits == 0:
|
||||
continue
|
||||
|
||||
add_char(num, upper_case, lower_case, bits, name)
|
||||
|
||||
out_file.write("""
|
||||
/* Unicode Character Information ** AUTOMATICALLY GENERATED FILE **
|
||||
*
|
||||
* This file is part of the PDCLib public domain C Library, but is automatically
|
||||
* generated from the Unicode character data information file found at
|
||||
* ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
|
||||
*
|
||||
* As a result, the licensing that applies to that file also applies to this
|
||||
* file. The licensing which applies to the Unicode character data can be found
|
||||
* in Exhibit 1 of the Unicode Terms of Use, found at
|
||||
* http://www.unicode.org/copyright.html#Exhibit1
|
||||
*/
|
||||
#ifndef REGTEST
|
||||
#include <_PDCLIB_locale.h>
|
||||
|
||||
const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[] = {
|
||||
// { value, \tlength, \tflags,\tlower,\tupper\t}, // name
|
||||
""")
|
||||
for g in groups:
|
||||
g.write_to_file(out_file)
|
||||
out_file.write('};\n\n')
|
||||
out_file.write("""
|
||||
const size_t _PDCLIB_wcinfo_size = sizeof(_PDCLIB_wcinfo) / sizeof(_PDCLIB_wcinfo[0]);
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
int main( void )
|
||||
{
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
||||
|
||||
""")
|
||||
except:
|
||||
in_file.close()
|
||||
out_file.close()
|
||||
os.remove('_PDCLIB_unicodedata.c')
|
||||
raise
|
||||
else:
|
||||
in_file.close()
|
||||
out_file.close()
|
|
@ -1,27 +0,0 @@
|
|||
/* _PDCLIB_mb_cur_max( void )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
#include "_PDCLIB_encoding.h"
|
||||
|
||||
size_t _PDCLIB_mb_cur_max( void )
|
||||
{
|
||||
return _PDCLIB_threadlocale()->_Codec->__mb_max;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( NO_TESTDRIVER );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +0,0 @@
|
|||
#include <_PDCLIB_locale.h>
|
||||
|
||||
locale_t _PDCLIB_locale_fake;
|
|
@ -1,29 +0,0 @@
|
|||
/* freelocale( locale_t )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
#include <assert.h>
|
||||
|
||||
void freelocale( locale_t newloc )
|
||||
{
|
||||
if( newloc != NULL ) {
|
||||
assert( ! "Not implemented" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( NO_TESTDRIVER );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||
/* localeconv( void )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
struct lconv * localeconv( void )
|
||||
{
|
||||
return &_PDCLIB_threadlocale()->_Conv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( NO_TESTDRIVER );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||
/* setlocale( int, const char * )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
char * setlocale( int category, const char * locale )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( NO_TESTDRIVER );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||
/* uselocale( locale_t )
|
||||
|
||||
This file is part of the Public Domain C Library (PDCLib).
|
||||
Permission is granted to use, modify, and / or redistribute at will.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#ifndef REGTEST
|
||||
#include "_PDCLIB_locale.h"
|
||||
|
||||
#ifdef _PDCLIB_LOCALE_METHOD
|
||||
locale_t uselocale( locale_t newloc )
|
||||
{
|
||||
locale_t oldloc = _PDCLIB_threadlocale();
|
||||
|
||||
if(newloc == LC_GLOBAL_LOCALE) {
|
||||
_PDCLIB_setthreadlocale(NULL);
|
||||
} else if(newloc != NULL) {
|
||||
_PDCLIB_setthreadlocale(newloc);
|
||||
}
|
||||
|
||||
return oldloc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include "_PDCLIB_test.h"
|
||||
|
||||
int main( void )
|
||||
{
|
||||
TESTCASE( NO_TESTDRIVER );
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/*
|
||||
* __cos( x, y )
|
||||
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
|
||||
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||
* Input y is the tail of x.
|
||||
*
|
||||
* Algorithm
|
||||
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
|
||||
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
|
||||
* 3. cos(x) is approximated by a polynomial of degree 14 on
|
||||
* [0,pi/4]
|
||||
* 4 14
|
||||
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
|
||||
* where the remez error is
|
||||
*
|
||||
* | 2 4 6 8 10 12 14 | -58
|
||||
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
|
||||
* | |
|
||||
*
|
||||
* 4 6 8 10 12 14
|
||||
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
|
||||
* cos(x) ~ 1 - x*x/2 + r
|
||||
* since cos(x+y) ~ cos(x) - sin(x)*y
|
||||
* ~ cos(x) - x*y,
|
||||
* a correction term is necessary in cos(x) and hence
|
||||
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
|
||||
* For better accuracy, rearrange to
|
||||
* cos(x+y) ~ w + (tmp + (r-x*y))
|
||||
* where w = 1 - x*x/2 and tmp is a tiny correction term
|
||||
* (1 - x*x/2 == w + tmp exactly in infinite precision).
|
||||
* The exactness of w + tmp in infinite precision depends on w
|
||||
* and tmp having the same precision as x. If they have extra
|
||||
* precision due to compiler bugs, then the extra precision is
|
||||
* only good provided it is retained in all terms of the final
|
||||
* expression for cos(). Retention happens in all cases tested
|
||||
* under FreeBSD, so don't pessimize things by forcibly clipping
|
||||
* any extra precision in w.
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const double
|
||||
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
|
||||
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
|
||||
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
|
||||
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
|
||||
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
|
||||
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
|
||||
|
||||
double __cos(double x, double y)
|
||||
{
|
||||
double_t hz,z,r,w;
|
||||
|
||||
z = x*x;
|
||||
w = z*z;
|
||||
r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
|
||||
hz = 0.5*z;
|
||||
w = 1.0-hz;
|
||||
return w + (((1.0-w)-hz) + (z*r-x*y));
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
* Debugged and optimized by Bruce D. Evans.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
|
||||
static const double
|
||||
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
|
||||
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
|
||||
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
|
||||
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
|
||||
|
||||
float __cosdf(double x)
|
||||
{
|
||||
double_t r, w, z;
|
||||
|
||||
/* Try to optimize for parallel evaluation as in __tandf.c. */
|
||||
z = x*x;
|
||||
w = z*z;
|
||||
r = C2+z*C3;
|
||||
return ((1.0+z*C0) + w*C1) + (w*z)*r;
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
|
||||
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
#if LDBL_MANT_DIG == 64
|
||||
/*
|
||||
* ld80 version of __cos.c. See __cos.c for most comments.
|
||||
*/
|
||||
/*
|
||||
* Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
|
||||
* |cos(x) - c(x)| < 2**-75.1
|
||||
*
|
||||
* The coefficients of c(x) were generated by a pari-gp script using
|
||||
* a Remez algorithm that searches for the best higher coefficients
|
||||
* after rounding leading coefficients to a specified precision.
|
||||
*
|
||||
* Simpler methods like Chebyshev or basic Remez barely suffice for
|
||||
* cos() in 64-bit precision, because we want the coefficient of x^2
|
||||
* to be precisely -0.5 so that multiplying by it is exact, and plain
|
||||
* rounding of the coefficients of a good polynomial approximation only
|
||||
* gives this up to about 64-bit precision. Plain rounding also gives
|
||||
* a mediocre approximation for the coefficient of x^4, but a rounding
|
||||
* error of 0.5 ulps for this coefficient would only contribute ~0.01
|
||||
* ulps to the final error, so this is unimportant. Rounding errors in
|
||||
* higher coefficients are even less important.
|
||||
*
|
||||
* In fact, coefficients above the x^4 one only need to have 53-bit
|
||||
* precision, and this is more efficient. We get this optimization
|
||||
* almost for free from the complications needed to search for the best
|
||||
* higher coefficients.
|
||||
*/
|
||||
static const long double
|
||||
C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
|
||||
static const double
|
||||
C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
|
||||
C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
|
||||
C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
|
||||
C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
|
||||
C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
|
||||
C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */
|
||||
#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
/*
|
||||
* ld128 version of __cos.c. See __cos.c for most comments.
|
||||
*/
|
||||
/*
|
||||
* Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
|
||||
* |cos(x) - c(x))| < 2**-122.0
|
||||
*
|
||||
* 113-bit precision requires more care than 64-bit precision, since
|
||||
* simple methods give a minimax polynomial with coefficient for x^2
|
||||
* that is 1 ulp below 0.5, but we want it to be precisely 0.5. See
|
||||
* above for more details.
|
||||
*/
|
||||
static const long double
|
||||
C1 = 0.04166666666666666666666666666666658424671L,
|
||||
C2 = -0.001388888888888888888888888888863490893732L,
|
||||
C3 = 0.00002480158730158730158730158600795304914210L,
|
||||
C4 = -0.2755731922398589065255474947078934284324e-6L,
|
||||
C5 = 0.2087675698786809897659225313136400793948e-8L,
|
||||
C6 = -0.1147074559772972315817149986812031204775e-10L,
|
||||
C7 = 0.4779477332386808976875457937252120293400e-13L;
|
||||
static const double
|
||||
C8 = -0.1561920696721507929516718307820958119868e-15,
|
||||
C9 = 0.4110317413744594971475941557607804508039e-18,
|
||||
C10 = -0.8896592467191938803288521958313920156409e-21,
|
||||
C11 = 0.1601061435794535138244346256065192782581e-23;
|
||||
#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
|
||||
z*(C8+z*(C9+z*(C10+z*C11)))))))))))
|
||||
#endif
|
||||
|
||||
long double __cosl(long double x, long double y)
|
||||
{
|
||||
long double hz,z,r,w;
|
||||
|
||||
z = x*x;
|
||||
r = POLY(z);
|
||||
hz = 0.5*z;
|
||||
w = 1.0-hz;
|
||||
return w + (((1.0-w)-hz) + (z*r-x*y));
|
||||
}
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
|
||||
static const int k = 2043;
|
||||
static const double kln2 = 0x1.62066151add8bp+10;
|
||||
|
||||
/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
|
||||
double __expo2(double x)
|
||||
{
|
||||
double scale;
|
||||
|
||||
/* note that k is odd and scale*scale overflows */
|
||||
INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);
|
||||
/* exp(x - k ln2) * 2**(k-1) */
|
||||
return exp(x - kln2) * scale * scale;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
|
||||
static const int k = 235;
|
||||
static const float kln2 = 0x1.45c778p+7f;
|
||||
|
||||
/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
|
||||
float __expo2f(float x)
|
||||
{
|
||||
float scale;
|
||||
|
||||
/* note that k is odd and scale*scale overflows */
|
||||
SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
|
||||
/* exp(x - k ln2) * 2**(k-1) */
|
||||
return expf(x - kln2) * scale * scale;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int __fpclassify(double x)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
int e = u.i>>52 & 0x7ff;
|
||||
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int __fpclassifyf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
int e = u.i>>23 & 0xff;
|
||||
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
int __fpclassifyl(long double x)
|
||||
{
|
||||
return __fpclassify(x);
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
|
||||
int __fpclassifyl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
int e = u.i.se & 0x7fff;
|
||||
int msb = u.i.m>>63;
|
||||
if (!e && !msb)
|
||||
return u.i.m ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (!msb)
|
||||
return FP_NAN;
|
||||
if (e == 0x7fff)
|
||||
return u.i.m << 1 ? FP_NAN : FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
int __fpclassifyl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
int e = u.i.se & 0x7fff;
|
||||
u.i.se = 0;
|
||||
if (!e)
|
||||
return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;
|
||||
if (e == 0x7fff)
|
||||
return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;
|
||||
return FP_NORMAL;
|
||||
}
|
||||
#endif
|
|
@ -1,63 +0,0 @@
|
|||
#include <float.h>
|
||||
#include "__invtrigl.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
|
||||
static const long double
|
||||
pS0 = 1.66666666666666666631e-01L,
|
||||
pS1 = -4.16313987993683104320e-01L,
|
||||
pS2 = 3.69068046323246813704e-01L,
|
||||
pS3 = -1.36213932016738603108e-01L,
|
||||
pS4 = 1.78324189708471965733e-02L,
|
||||
pS5 = -2.19216428382605211588e-04L,
|
||||
pS6 = -7.10526623669075243183e-06L,
|
||||
qS1 = -2.94788392796209867269e+00L,
|
||||
qS2 = 3.27309890266528636716e+00L,
|
||||
qS3 = -1.68285799854822427013e+00L,
|
||||
qS4 = 3.90699412641738801874e-01L,
|
||||
qS5 = -3.14365703596053263322e-02L;
|
||||
|
||||
const long double pio2_hi = 1.57079632679489661926L;
|
||||
const long double pio2_lo = -2.50827880633416601173e-20L;
|
||||
|
||||
/* used in asinl() and acosl() */
|
||||
/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */
|
||||
long double __invtrigl_R(long double z)
|
||||
{
|
||||
long double p, q;
|
||||
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6))))));
|
||||
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5))));
|
||||
return p/q;
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
static const long double
|
||||
pS0 = 1.66666666666666666666666666666700314e-01L,
|
||||
pS1 = -7.32816946414566252574527475428622708e-01L,
|
||||
pS2 = 1.34215708714992334609030036562143589e+00L,
|
||||
pS3 = -1.32483151677116409805070261790752040e+00L,
|
||||
pS4 = 7.61206183613632558824485341162121989e-01L,
|
||||
pS5 = -2.56165783329023486777386833928147375e-01L,
|
||||
pS6 = 4.80718586374448793411019434585413855e-02L,
|
||||
pS7 = -4.42523267167024279410230886239774718e-03L,
|
||||
pS8 = 1.44551535183911458253205638280410064e-04L,
|
||||
pS9 = -2.10558957916600254061591040482706179e-07L,
|
||||
qS1 = -4.84690167848739751544716485245697428e+00L,
|
||||
qS2 = 9.96619113536172610135016921140206980e+00L,
|
||||
qS3 = -1.13177895428973036660836798461641458e+01L,
|
||||
qS4 = 7.74004374389488266169304117714658761e+00L,
|
||||
qS5 = -3.25871986053534084709023539900339905e+00L,
|
||||
qS6 = 8.27830318881232209752469022352928864e-01L,
|
||||
qS7 = -1.18768052702942805423330715206348004e-01L,
|
||||
qS8 = 8.32600764660522313269101537926539470e-03L,
|
||||
qS9 = -1.99407384882605586705979504567947007e-04L;
|
||||
|
||||
const long double pio2_hi = 1.57079632679489661923132169163975140L;
|
||||
const long double pio2_lo = 4.33590506506189051239852201302167613e-35L;
|
||||
|
||||
long double __invtrigl_R(long double z)
|
||||
{
|
||||
long double p, q;
|
||||
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))));
|
||||
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(pS6+z*(pS7+z*(pS8+z*pS9))))))));
|
||||
return p/q;
|
||||
}
|
||||
#endif
|
|
@ -1,6 +0,0 @@
|
|||
/* shared by acosl, asinl and atan2l */
|
||||
#define pio2_hi __pio2_hi
|
||||
#define pio2_lo __pio2_lo
|
||||
extern const long double pio2_hi, pio2_lo;
|
||||
|
||||
long double __invtrigl_R(long double z);
|
|
@ -1,93 +0,0 @@
|
|||
/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */
|
||||
/*
|
||||
* Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* Evaluate polynomial
|
||||
*
|
||||
*
|
||||
* SYNOPSIS:
|
||||
*
|
||||
* int N;
|
||||
* long double x, y, coef[N+1], polevl[];
|
||||
*
|
||||
* y = polevll( x, coef, N );
|
||||
*
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Evaluates polynomial of degree N:
|
||||
*
|
||||
* 2 N
|
||||
* y = C + C x + C x +...+ C x
|
||||
* 0 1 2 N
|
||||
*
|
||||
* Coefficients are stored in reverse order:
|
||||
*
|
||||
* coef[0] = C , ..., coef[N] = C .
|
||||
* N 0
|
||||
*
|
||||
* The function p1evll() assumes that coef[N] = 1.0 and is
|
||||
* omitted from the array. Its calling arguments are
|
||||
* otherwise the same as polevll().
|
||||
*
|
||||
*
|
||||
* SPEED:
|
||||
*
|
||||
* In the interest of speed, there are no checks for out
|
||||
* of bounds arithmetic. This routine is used by most of
|
||||
* the functions in the library. Depending on available
|
||||
* equipment features, the user may wish to rewrite the
|
||||
* program in microcode or assembly language.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
#else
|
||||
/*
|
||||
* Polynomial evaluator:
|
||||
* P[0] x^n + P[1] x^(n-1) + ... + P[n]
|
||||
*/
|
||||
long double __polevll(long double x, const long double *P, int n)
|
||||
{
|
||||
long double y;
|
||||
|
||||
y = *P++;
|
||||
do {
|
||||
y = y * x + *P++;
|
||||
} while (--n);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Polynomial evaluator:
|
||||
* x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
|
||||
*/
|
||||
long double __p1evll(long double x, const long double *P, int n)
|
||||
{
|
||||
long double y;
|
||||
|
||||
n -= 1;
|
||||
y = x + *P++;
|
||||
do {
|
||||
y = y * x + *P++;
|
||||
} while (--n);
|
||||
|
||||
return y;
|
||||
}
|
||||
#endif
|
|
@ -1,177 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
* Optimized by Bruce D. Evans.
|
||||
*/
|
||||
/* __rem_pio2(x,y)
|
||||
*
|
||||
* return the remainder of x rem pi/2 in y[0]+y[1]
|
||||
* use __rem_pio2_large() for large x
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
|
||||
#define EPS DBL_EPSILON
|
||||
#elif FLT_EVAL_METHOD==2
|
||||
#define EPS LDBL_EPSILON
|
||||
#endif
|
||||
|
||||
/*
|
||||
* invpio2: 53 bits of 2/pi
|
||||
* pio2_1: first 33 bit of pi/2
|
||||
* pio2_1t: pi/2 - pio2_1
|
||||
* pio2_2: second 33 bit of pi/2
|
||||
* pio2_2t: pi/2 - (pio2_1+pio2_2)
|
||||
* pio2_3: third 33 bit of pi/2
|
||||
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
|
||||
*/
|
||||
static const double
|
||||
toint = 1.5/EPS,
|
||||
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
|
||||
pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
|
||||
pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
|
||||
pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
|
||||
pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
|
||||
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
|
||||
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
|
||||
|
||||
/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
|
||||
int __rem_pio2(double x, double *y)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {x};
|
||||
double_t z,w,t,r,fn;
|
||||
double tx[3],ty[2];
|
||||
uint32_t ix;
|
||||
int sign, n, ex, ey, i;
|
||||
|
||||
sign = u.i>>63;
|
||||
ix = u.i>>32 & 0x7fffffff;
|
||||
if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */
|
||||
if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
|
||||
goto medium; /* cancellation -- use medium case */
|
||||
if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */
|
||||
if (!sign) {
|
||||
z = x - pio2_1; /* one round good to 85 bits */
|
||||
y[0] = z - pio2_1t;
|
||||
y[1] = (z-y[0]) - pio2_1t;
|
||||
return 1;
|
||||
} else {
|
||||
z = x + pio2_1;
|
||||
y[0] = z + pio2_1t;
|
||||
y[1] = (z-y[0]) + pio2_1t;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!sign) {
|
||||
z = x - 2*pio2_1;
|
||||
y[0] = z - 2*pio2_1t;
|
||||
y[1] = (z-y[0]) - 2*pio2_1t;
|
||||
return 2;
|
||||
} else {
|
||||
z = x + 2*pio2_1;
|
||||
y[0] = z + 2*pio2_1t;
|
||||
y[1] = (z-y[0]) + 2*pio2_1t;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */
|
||||
if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */
|
||||
if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */
|
||||
goto medium;
|
||||
if (!sign) {
|
||||
z = x - 3*pio2_1;
|
||||
y[0] = z - 3*pio2_1t;
|
||||
y[1] = (z-y[0]) - 3*pio2_1t;
|
||||
return 3;
|
||||
} else {
|
||||
z = x + 3*pio2_1;
|
||||
y[0] = z + 3*pio2_1t;
|
||||
y[1] = (z-y[0]) + 3*pio2_1t;
|
||||
return -3;
|
||||
}
|
||||
} else {
|
||||
if (ix == 0x401921fb) /* |x| ~= 4pi/2 */
|
||||
goto medium;
|
||||
if (!sign) {
|
||||
z = x - 4*pio2_1;
|
||||
y[0] = z - 4*pio2_1t;
|
||||
y[1] = (z-y[0]) - 4*pio2_1t;
|
||||
return 4;
|
||||
} else {
|
||||
z = x + 4*pio2_1;
|
||||
y[0] = z + 4*pio2_1t;
|
||||
y[1] = (z-y[0]) + 4*pio2_1t;
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
|
||||
medium:
|
||||
/* rint(x/(pi/2)), Assume round-to-nearest. */
|
||||
fn = (double_t)x*invpio2 + toint - toint;
|
||||
n = (int32_t)fn;
|
||||
r = x - fn*pio2_1;
|
||||
w = fn*pio2_1t; /* 1st round, good to 85 bits */
|
||||
y[0] = r - w;
|
||||
u.f = y[0];
|
||||
ey = u.i>>52 & 0x7ff;
|
||||
ex = ix>>20;
|
||||
if (ex - ey > 16) { /* 2nd round, good to 118 bits */
|
||||
t = r;
|
||||
w = fn*pio2_2;
|
||||
r = t - w;
|
||||
w = fn*pio2_2t - ((t-r)-w);
|
||||
y[0] = r - w;
|
||||
u.f = y[0];
|
||||
ey = u.i>>52 & 0x7ff;
|
||||
if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */
|
||||
t = r;
|
||||
w = fn*pio2_3;
|
||||
r = t - w;
|
||||
w = fn*pio2_3t - ((t-r)-w);
|
||||
y[0] = r - w;
|
||||
}
|
||||
}
|
||||
y[1] = (r - y[0]) - w;
|
||||
return n;
|
||||
}
|
||||
/*
|
||||
* all other (large) arguments
|
||||
*/
|
||||
if (ix >= 0x7ff00000) { /* x is inf or NaN */
|
||||
y[0] = y[1] = x - x;
|
||||
return 0;
|
||||
}
|
||||
/* set z = scalbn(|x|,-ilogb(x)+23) */
|
||||
u.f = x;
|
||||
u.i &= (uint64_t)-1>>12;
|
||||
u.i |= (uint64_t)(0x3ff + 23)<<52;
|
||||
z = u.f;
|
||||
for (i=0; i < 2; i++) {
|
||||
tx[i] = (double)(int32_t)z;
|
||||
z = (z-tx[i])*0x1p24;
|
||||
}
|
||||
tx[i] = z;
|
||||
/* skip zero terms, first term is non-zero */
|
||||
while (tx[i] == 0.0)
|
||||
i--;
|
||||
n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
|
||||
if (sign) {
|
||||
y[0] = -ty[0];
|
||||
y[1] = -ty[1];
|
||||
return -n;
|
||||
}
|
||||
y[0] = ty[0];
|
||||
y[1] = ty[1];
|
||||
return n;
|
||||
}
|
|
@ -1,442 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/*
|
||||
* __rem_pio2_large(x,y,e0,nx,prec)
|
||||
* double x[],y[]; int e0,nx,prec;
|
||||
*
|
||||
* __rem_pio2_large return the last three digits of N with
|
||||
* y = x - N*pi/2
|
||||
* so that |y| < pi/2.
|
||||
*
|
||||
* The method is to compute the integer (mod 8) and fraction parts of
|
||||
* (2/pi)*x without doing the full multiplication. In general we
|
||||
* skip the part of the product that are known to be a huge integer (
|
||||
* more accurately, = 0 mod 8 ). Thus the number of operations are
|
||||
* independent of the exponent of the input.
|
||||
*
|
||||
* (2/pi) is represented by an array of 24-bit integers in ipio2[].
|
||||
*
|
||||
* Input parameters:
|
||||
* x[] The input value (must be positive) is broken into nx
|
||||
* pieces of 24-bit integers in double precision format.
|
||||
* x[i] will be the i-th 24 bit of x. The scaled exponent
|
||||
* of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
|
||||
* match x's up to 24 bits.
|
||||
*
|
||||
* Example of breaking a double positive z into x[0]+x[1]+x[2]:
|
||||
* e0 = ilogb(z)-23
|
||||
* z = scalbn(z,-e0)
|
||||
* for i = 0,1,2
|
||||
* x[i] = floor(z)
|
||||
* z = (z-x[i])*2**24
|
||||
*
|
||||
*
|
||||
* y[] ouput result in an array of double precision numbers.
|
||||
* The dimension of y[] is:
|
||||
* 24-bit precision 1
|
||||
* 53-bit precision 2
|
||||
* 64-bit precision 2
|
||||
* 113-bit precision 3
|
||||
* The actual value is the sum of them. Thus for 113-bit
|
||||
* precison, one may have to do something like:
|
||||
*
|
||||
* long double t,w,r_head, r_tail;
|
||||
* t = (long double)y[2] + (long double)y[1];
|
||||
* w = (long double)y[0];
|
||||
* r_head = t+w;
|
||||
* r_tail = w - (r_head - t);
|
||||
*
|
||||
* e0 The exponent of x[0]. Must be <= 16360 or you need to
|
||||
* expand the ipio2 table.
|
||||
*
|
||||
* nx dimension of x[]
|
||||
*
|
||||
* prec an integer indicating the precision:
|
||||
* 0 24 bits (single)
|
||||
* 1 53 bits (double)
|
||||
* 2 64 bits (extended)
|
||||
* 3 113 bits (quad)
|
||||
*
|
||||
* External function:
|
||||
* double scalbn(), floor();
|
||||
*
|
||||
*
|
||||
* Here is the description of some local variables:
|
||||
*
|
||||
* jk jk+1 is the initial number of terms of ipio2[] needed
|
||||
* in the computation. The minimum and recommended value
|
||||
* for jk is 3,4,4,6 for single, double, extended, and quad.
|
||||
* jk+1 must be 2 larger than you might expect so that our
|
||||
* recomputation test works. (Up to 24 bits in the integer
|
||||
* part (the 24 bits of it that we compute) and 23 bits in
|
||||
* the fraction part may be lost to cancelation before we
|
||||
* recompute.)
|
||||
*
|
||||
* jz local integer variable indicating the number of
|
||||
* terms of ipio2[] used.
|
||||
*
|
||||
* jx nx - 1
|
||||
*
|
||||
* jv index for pointing to the suitable ipio2[] for the
|
||||
* computation. In general, we want
|
||||
* ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
|
||||
* is an integer. Thus
|
||||
* e0-3-24*jv >= 0 or (e0-3)/24 >= jv
|
||||
* Hence jv = max(0,(e0-3)/24).
|
||||
*
|
||||
* jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
|
||||
*
|
||||
* q[] double array with integral value, representing the
|
||||
* 24-bits chunk of the product of x and 2/pi.
|
||||
*
|
||||
* q0 the corresponding exponent of q[0]. Note that the
|
||||
* exponent for q[i] would be q0-24*i.
|
||||
*
|
||||
* PIo2[] double precision array, obtained by cutting pi/2
|
||||
* into 24 bits chunks.
|
||||
*
|
||||
* f[] ipio2[] in floating point
|
||||
*
|
||||
* iq[] integer array by breaking up q[] in 24-bits chunk.
|
||||
*
|
||||
* fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
|
||||
*
|
||||
* ih integer. If >0 it indicates q[] is >= 0.5, hence
|
||||
* it also indicates the *sign* of the result.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Constants:
|
||||
* The hexadecimal values are the intended ones for the following
|
||||
* constants. The decimal values may be used, provided that the
|
||||
* compiler will convert from decimal to binary accurately enough
|
||||
* to produce the hexadecimal values shown.
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const int init_jk[] = {3,4,4,6}; /* initial value for jk */
|
||||
|
||||
/*
|
||||
* Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
|
||||
*
|
||||
* integer array, contains the (24*i)-th to (24*i+23)-th
|
||||
* bit of 2/pi after binary point. The corresponding
|
||||
* floating value is
|
||||
*
|
||||
* ipio2[i] * 2^(-24(i+1)).
|
||||
*
|
||||
* NB: This table must have at least (e0-3)/24 + jk terms.
|
||||
* For quad precision (e0 <= 16360, jk = 6), this is 686.
|
||||
*/
|
||||
static const int32_t ipio2[] = {
|
||||
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
|
||||
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
|
||||
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
|
||||
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
|
||||
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
|
||||
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
|
||||
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
|
||||
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
|
||||
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
|
||||
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
|
||||
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
|
||||
|
||||
#if LDBL_MAX_EXP > 1024
|
||||
0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6,
|
||||
0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2,
|
||||
0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35,
|
||||
0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30,
|
||||
0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C,
|
||||
0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4,
|
||||
0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770,
|
||||
0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7,
|
||||
0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19,
|
||||
0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522,
|
||||
0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16,
|
||||
0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6,
|
||||
0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E,
|
||||
0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48,
|
||||
0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3,
|
||||
0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF,
|
||||
0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55,
|
||||
0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612,
|
||||
0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929,
|
||||
0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC,
|
||||
0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B,
|
||||
0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C,
|
||||
0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4,
|
||||
0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB,
|
||||
0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC,
|
||||
0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C,
|
||||
0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F,
|
||||
0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5,
|
||||
0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437,
|
||||
0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B,
|
||||
0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA,
|
||||
0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD,
|
||||
0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3,
|
||||
0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3,
|
||||
0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717,
|
||||
0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F,
|
||||
0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61,
|
||||
0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB,
|
||||
0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51,
|
||||
0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0,
|
||||
0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C,
|
||||
0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6,
|
||||
0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC,
|
||||
0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED,
|
||||
0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328,
|
||||
0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D,
|
||||
0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0,
|
||||
0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B,
|
||||
0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4,
|
||||
0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3,
|
||||
0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F,
|
||||
0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD,
|
||||
0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B,
|
||||
0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4,
|
||||
0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761,
|
||||
0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31,
|
||||
0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30,
|
||||
0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262,
|
||||
0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E,
|
||||
0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1,
|
||||
0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C,
|
||||
0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4,
|
||||
0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08,
|
||||
0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196,
|
||||
0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9,
|
||||
0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4,
|
||||
0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC,
|
||||
0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C,
|
||||
0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0,
|
||||
0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C,
|
||||
0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0,
|
||||
0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC,
|
||||
0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22,
|
||||
0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893,
|
||||
0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7,
|
||||
0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5,
|
||||
0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F,
|
||||
0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4,
|
||||
0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF,
|
||||
0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B,
|
||||
0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2,
|
||||
0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138,
|
||||
0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E,
|
||||
0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569,
|
||||
0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34,
|
||||
0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9,
|
||||
0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D,
|
||||
0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F,
|
||||
0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855,
|
||||
0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569,
|
||||
0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B,
|
||||
0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE,
|
||||
0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41,
|
||||
0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49,
|
||||
0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F,
|
||||
0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110,
|
||||
0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8,
|
||||
0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365,
|
||||
0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A,
|
||||
0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270,
|
||||
0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5,
|
||||
0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616,
|
||||
0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B,
|
||||
0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const double PIo2[] = {
|
||||
1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
|
||||
7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
|
||||
5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
|
||||
3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
|
||||
1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
|
||||
1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
|
||||
2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
|
||||
2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
|
||||
};
|
||||
|
||||
int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
|
||||
{
|
||||
int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
|
||||
double z,fw,f[20],fq[20],q[20];
|
||||
|
||||
/* initialize jk*/
|
||||
jk = init_jk[prec];
|
||||
jp = jk;
|
||||
|
||||
/* determine jx,jv,q0, note that 3>q0 */
|
||||
jx = nx-1;
|
||||
jv = (e0-3)/24; if(jv<0) jv=0;
|
||||
q0 = e0-24*(jv+1);
|
||||
|
||||
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
|
||||
j = jv-jx; m = jx+jk;
|
||||
for (i=0; i<=m; i++,j++)
|
||||
f[i] = j<0 ? 0.0 : (double)ipio2[j];
|
||||
|
||||
/* compute q[0],q[1],...q[jk] */
|
||||
for (i=0; i<=jk; i++) {
|
||||
for (j=0,fw=0.0; j<=jx; j++)
|
||||
fw += x[j]*f[jx+i-j];
|
||||
q[i] = fw;
|
||||
}
|
||||
|
||||
jz = jk;
|
||||
recompute:
|
||||
/* distill q[] into iq[] reversingly */
|
||||
for (i=0,j=jz,z=q[jz]; j>0; i++,j--) {
|
||||
fw = (double)(int32_t)(0x1p-24*z);
|
||||
iq[i] = (int32_t)(z - 0x1p24*fw);
|
||||
z = q[j-1]+fw;
|
||||
}
|
||||
|
||||
/* compute n */
|
||||
z = scalbn(z,q0); /* actual value of z */
|
||||
z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
|
||||
n = (int32_t)z;
|
||||
z -= (double)n;
|
||||
ih = 0;
|
||||
if (q0 > 0) { /* need iq[jz-1] to determine n */
|
||||
i = iq[jz-1]>>(24-q0); n += i;
|
||||
iq[jz-1] -= i<<(24-q0);
|
||||
ih = iq[jz-1]>>(23-q0);
|
||||
}
|
||||
else if (q0 == 0) ih = iq[jz-1]>>23;
|
||||
else if (z >= 0.5) ih = 2;
|
||||
|
||||
if (ih > 0) { /* q > 0.5 */
|
||||
n += 1; carry = 0;
|
||||
for (i=0; i<jz; i++) { /* compute 1-q */
|
||||
j = iq[i];
|
||||
if (carry == 0) {
|
||||
if (j != 0) {
|
||||
carry = 1;
|
||||
iq[i] = 0x1000000 - j;
|
||||
}
|
||||
} else
|
||||
iq[i] = 0xffffff - j;
|
||||
}
|
||||
if (q0 > 0) { /* rare case: chance is 1 in 12 */
|
||||
switch(q0) {
|
||||
case 1:
|
||||
iq[jz-1] &= 0x7fffff; break;
|
||||
case 2:
|
||||
iq[jz-1] &= 0x3fffff; break;
|
||||
}
|
||||
}
|
||||
if (ih == 2) {
|
||||
z = 1.0 - z;
|
||||
if (carry != 0)
|
||||
z -= scalbn(1.0,q0);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if recomputation is needed */
|
||||
if (z == 0.0) {
|
||||
j = 0;
|
||||
for (i=jz-1; i>=jk; i--) j |= iq[i];
|
||||
if (j == 0) { /* need recomputation */
|
||||
for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
|
||||
|
||||
for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
|
||||
f[jx+i] = (double)ipio2[jv+i];
|
||||
for (j=0,fw=0.0; j<=jx; j++)
|
||||
fw += x[j]*f[jx+i-j];
|
||||
q[i] = fw;
|
||||
}
|
||||
jz += k;
|
||||
goto recompute;
|
||||
}
|
||||
}
|
||||
|
||||
/* chop off zero terms */
|
||||
if (z == 0.0) {
|
||||
jz -= 1;
|
||||
q0 -= 24;
|
||||
while (iq[jz] == 0) {
|
||||
jz--;
|
||||
q0 -= 24;
|
||||
}
|
||||
} else { /* break z into 24-bit if necessary */
|
||||
z = scalbn(z,-q0);
|
||||
if (z >= 0x1p24) {
|
||||
fw = (double)(int32_t)(0x1p-24*z);
|
||||
iq[jz] = (int32_t)(z - 0x1p24*fw);
|
||||
jz += 1;
|
||||
q0 += 24;
|
||||
iq[jz] = (int32_t)fw;
|
||||
} else
|
||||
iq[jz] = (int32_t)z;
|
||||
}
|
||||
|
||||
/* convert integer "bit" chunk to floating-point value */
|
||||
fw = scalbn(1.0,q0);
|
||||
for (i=jz; i>=0; i--) {
|
||||
q[i] = fw*(double)iq[i];
|
||||
fw *= 0x1p-24;
|
||||
}
|
||||
|
||||
/* compute PIo2[0,...,jp]*q[jz,...,0] */
|
||||
for(i=jz; i>=0; i--) {
|
||||
for (fw=0.0,k=0; k<=jp && k<=jz-i; k++)
|
||||
fw += PIo2[k]*q[i+k];
|
||||
fq[jz-i] = fw;
|
||||
}
|
||||
|
||||
/* compress fq[] into y[] */
|
||||
switch(prec) {
|
||||
case 0:
|
||||
fw = 0.0;
|
||||
for (i=jz; i>=0; i--)
|
||||
fw += fq[i];
|
||||
y[0] = ih==0 ? fw : -fw;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
fw = 0.0;
|
||||
for (i=jz; i>=0; i--)
|
||||
fw += fq[i];
|
||||
// TODO: drop excess precision here once double_t is used
|
||||
fw = (double)fw;
|
||||
y[0] = ih==0 ? fw : -fw;
|
||||
fw = fq[0]-fw;
|
||||
for (i=1; i<=jz; i++)
|
||||
fw += fq[i];
|
||||
y[1] = ih==0 ? fw : -fw;
|
||||
break;
|
||||
case 3: /* painful */
|
||||
for (i=jz; i>0; i--) {
|
||||
fw = fq[i-1]+fq[i];
|
||||
fq[i] += fq[i-1]-fw;
|
||||
fq[i-1] = fw;
|
||||
}
|
||||
for (i=jz; i>1; i--) {
|
||||
fw = fq[i-1]+fq[i];
|
||||
fq[i] += fq[i-1]-fw;
|
||||
fq[i-1] = fw;
|
||||
}
|
||||
for (fw=0.0,i=jz; i>=2; i--)
|
||||
fw += fq[i];
|
||||
if (ih==0) {
|
||||
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
|
||||
} else {
|
||||
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
|
||||
}
|
||||
}
|
||||
return n&7;
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
* Debugged and optimized by Bruce D. Evans.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/* __rem_pio2f(x,y)
|
||||
*
|
||||
* return the remainder of x rem pi/2 in *y
|
||||
* use double precision for everything except passing x
|
||||
* use __rem_pio2_large() for large x
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
|
||||
#define EPS DBL_EPSILON
|
||||
#elif FLT_EVAL_METHOD==2
|
||||
#define EPS LDBL_EPSILON
|
||||
#endif
|
||||
|
||||
/*
|
||||
* invpio2: 53 bits of 2/pi
|
||||
* pio2_1: first 25 bits of pi/2
|
||||
* pio2_1t: pi/2 - pio2_1
|
||||
*/
|
||||
static const double
|
||||
toint = 1.5/EPS,
|
||||
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
|
||||
pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
|
||||
pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
|
||||
|
||||
int __rem_pio2f(float x, double *y)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
double tx[1],ty[1];
|
||||
double_t fn;
|
||||
uint32_t ix;
|
||||
int n, sign, e0;
|
||||
|
||||
ix = u.i & 0x7fffffff;
|
||||
/* 25+53 bit pi is good enough for medium size */
|
||||
if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */
|
||||
/* Use a specialized rint() to get fn. Assume round-to-nearest. */
|
||||
fn = (double_t)x*invpio2 + toint - toint;
|
||||
n = (int32_t)fn;
|
||||
*y = x - fn*pio2_1 - fn*pio2_1t;
|
||||
return n;
|
||||
}
|
||||
if(ix>=0x7f800000) { /* x is inf or NaN */
|
||||
*y = x-x;
|
||||
return 0;
|
||||
}
|
||||
/* scale x into [2^23, 2^24-1] */
|
||||
sign = u.i>>31;
|
||||
e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */
|
||||
u.i = ix - (e0<<23);
|
||||
tx[0] = u.f;
|
||||
n = __rem_pio2_large(tx,ty,e0,1,0);
|
||||
if (sign) {
|
||||
*y = -ty[0];
|
||||
return -n;
|
||||
}
|
||||
*y = ty[0];
|
||||
return n;
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
* Optimized by Bruce D. Evans.
|
||||
*/
|
||||
#include "libm.h"
|
||||
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
/* ld80 and ld128 version of __rem_pio2(x,y)
|
||||
*
|
||||
* return the remainder of x rem pi/2 in y[0]+y[1]
|
||||
* use __rem_pio2_large() for large x
|
||||
*/
|
||||
|
||||
static const long double toint = 1.5/LDBL_EPSILON;
|
||||
|
||||
#if LDBL_MANT_DIG == 64
|
||||
/* u ~< 0x1p25*pi/2 */
|
||||
#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))
|
||||
#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)
|
||||
#define ROUND1 22
|
||||
#define ROUND2 61
|
||||
#define NX 3
|
||||
#define NY 2
|
||||
/*
|
||||
* invpio2: 64 bits of 2/pi
|
||||
* pio2_1: first 39 bits of pi/2
|
||||
* pio2_1t: pi/2 - pio2_1
|
||||
* pio2_2: second 39 bits of pi/2
|
||||
* pio2_2t: pi/2 - (pio2_1+pio2_2)
|
||||
* pio2_3: third 39 bits of pi/2
|
||||
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
|
||||
*/
|
||||
static const double
|
||||
pio2_1 = 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */
|
||||
pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */
|
||||
pio2_3 = 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-133 */
|
||||
static const long double
|
||||
invpio2 = 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p-64 */
|
||||
pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */
|
||||
pio2_2t = 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p-144 */
|
||||
pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
/* u ~< 0x1p45*pi/2 */
|
||||
#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))
|
||||
#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)
|
||||
#define ROUND1 51
|
||||
#define ROUND2 119
|
||||
#define NX 5
|
||||
#define NY 3
|
||||
static const long double
|
||||
invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */
|
||||
pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */
|
||||
pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */
|
||||
pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */
|
||||
pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */
|
||||
pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */
|
||||
pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */
|
||||
#endif
|
||||
|
||||
int __rem_pio2l(long double x, long double *y)
|
||||
{
|
||||
union ldshape u,uz;
|
||||
long double z,w,t,r,fn;
|
||||
double tx[NX],ty[NY];
|
||||
int ex,ey,n,i;
|
||||
|
||||
u.f = x;
|
||||
ex = u.i.se & 0x7fff;
|
||||
if (SMALL(u)) {
|
||||
/* rint(x/(pi/2)), Assume round-to-nearest. */
|
||||
fn = x*invpio2 + toint - toint;
|
||||
n = QUOBITS(fn);
|
||||
r = x-fn*pio2_1;
|
||||
w = fn*pio2_1t; /* 1st round good to 102/180 bits (ld80/ld128) */
|
||||
y[0] = r-w;
|
||||
u.f = y[0];
|
||||
ey = u.i.se & 0x7fff;
|
||||
if (ex - ey > ROUND1) { /* 2nd iteration needed, good to 141/248 (ld80/ld128) */
|
||||
t = r;
|
||||
w = fn*pio2_2;
|
||||
r = t-w;
|
||||
w = fn*pio2_2t-((t-r)-w);
|
||||
y[0] = r-w;
|
||||
u.f = y[0];
|
||||
ey = u.i.se & 0x7fff;
|
||||
if (ex - ey > ROUND2) { /* 3rd iteration, good to 180/316 bits */
|
||||
t = r; /* will cover all possible cases (not verified for ld128) */
|
||||
w = fn*pio2_3;
|
||||
r = t-w;
|
||||
w = fn*pio2_3t-((t-r)-w);
|
||||
y[0] = r-w;
|
||||
}
|
||||
}
|
||||
y[1] = (r - y[0]) - w;
|
||||
return n;
|
||||
}
|
||||
/*
|
||||
* all other (large) arguments
|
||||
*/
|
||||
if (ex == 0x7fff) { /* x is inf or NaN */
|
||||
y[0] = y[1] = x - x;
|
||||
return 0;
|
||||
}
|
||||
/* set z = scalbn(|x|,-ilogb(x)+23) */
|
||||
uz.f = x;
|
||||
uz.i.se = 0x3fff + 23;
|
||||
z = uz.f;
|
||||
for (i=0; i < NX - 1; i++) {
|
||||
tx[i] = (double)(int32_t)z;
|
||||
z = (z-tx[i])*0x1p24;
|
||||
}
|
||||
tx[i] = z;
|
||||
while (tx[i] == 0)
|
||||
i--;
|
||||
n = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY);
|
||||
w = ty[1];
|
||||
if (NY == 3)
|
||||
w += ty[2];
|
||||
r = ty[0] + w;
|
||||
/* TODO: for ld128 this does not follow the recommendation of the
|
||||
comments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */
|
||||
w -= r - ty[0];
|
||||
if (u.i.se >> 15) {
|
||||
y[0] = -r;
|
||||
y[1] = -w;
|
||||
return -n;
|
||||
}
|
||||
y[0] = r;
|
||||
y[1] = w;
|
||||
return n;
|
||||
}
|
||||
#endif
|
|
@ -1,13 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
// FIXME: macro in math.h
|
||||
int __signbit(double x)
|
||||
{
|
||||
union {
|
||||
double d;
|
||||
uint64_t i;
|
||||
} y = { x };
|
||||
return y.i>>63;
|
||||
}
|
||||
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
// FIXME: macro in math.h
|
||||
int __signbitf(float x)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
} y = { x };
|
||||
return y.i>>31;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
int __signbitl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
return u.i.se >> 15;
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
int __signbitl(long double x)
|
||||
{
|
||||
return __signbit(x);
|
||||
}
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/* __sin( x, y, iy)
|
||||
* kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
|
||||
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||
* Input y is the tail of x.
|
||||
* Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
|
||||
*
|
||||
* Algorithm
|
||||
* 1. Since sin(-x) = -sin(x), we need only to consider positive x.
|
||||
* 2. Callers must return sin(-0) = -0 without calling here since our
|
||||
* odd polynomial is not evaluated in a way that preserves -0.
|
||||
* Callers may do the optimization sin(x) ~ x for tiny x.
|
||||
* 3. sin(x) is approximated by a polynomial of degree 13 on
|
||||
* [0,pi/4]
|
||||
* 3 13
|
||||
* sin(x) ~ x + S1*x + ... + S6*x
|
||||
* where
|
||||
*
|
||||
* |sin(x) 2 4 6 8 10 12 | -58
|
||||
* |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
|
||||
* | x |
|
||||
*
|
||||
* 4. sin(x+y) = sin(x) + sin'(x')*y
|
||||
* ~ sin(x) + (1-x*x/2)*y
|
||||
* For better accuracy, let
|
||||
* 3 2 2 2 2
|
||||
* r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
|
||||
* then 3 2
|
||||
* sin(x) = x + (S1*x + (x *(r-y/2)+y))
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const double
|
||||
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
|
||||
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
|
||||
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
|
||||
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
|
||||
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
|
||||
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
|
||||
|
||||
double __sin(double x, double y, int iy)
|
||||
{
|
||||
double_t z,r,v,w;
|
||||
|
||||
z = x*x;
|
||||
w = z*z;
|
||||
r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
|
||||
v = z*x;
|
||||
if (iy == 0)
|
||||
return x + v*(S1 + z*r);
|
||||
else
|
||||
return x - ((z*(0.5*y - v*r) - y) - v*S1);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
* Optimized by Bruce D. Evans.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
|
||||
static const double
|
||||
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
|
||||
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
|
||||
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
|
||||
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
|
||||
|
||||
float __sindf(double x)
|
||||
{
|
||||
double_t r, s, w, z;
|
||||
|
||||
/* Try to optimize for parallel evaluation as in __tandf.c. */
|
||||
z = x*x;
|
||||
w = z*z;
|
||||
r = S3 + z*S4;
|
||||
s = z*x;
|
||||
return (x + s*(S1 + z*S2)) + s*w*r;
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */
|
||||
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
#if LDBL_MANT_DIG == 64
|
||||
/*
|
||||
* ld80 version of __sin.c. See __sin.c for most comments.
|
||||
*/
|
||||
/*
|
||||
* Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]
|
||||
* |sin(x)/x - s(x)| < 2**-72.1
|
||||
*
|
||||
* See __cosl.c for more details about the polynomial.
|
||||
*/
|
||||
static const long double
|
||||
S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */
|
||||
static const double
|
||||
S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */
|
||||
S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */
|
||||
S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */
|
||||
S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
|
||||
S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */
|
||||
S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */
|
||||
S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */
|
||||
#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
/*
|
||||
* ld128 version of __sin.c. See __sin.c for most comments.
|
||||
*/
|
||||
/*
|
||||
* Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]
|
||||
* |sin(x)/x - s(x)| < 2**-122.1
|
||||
*
|
||||
* See __cosl.c for more details about the polynomial.
|
||||
*/
|
||||
static const long double
|
||||
S1 = -0.16666666666666666666666666666666666606732416116558L,
|
||||
S2 = 0.0083333333333333333333333333333331135404851288270047L,
|
||||
S3 = -0.00019841269841269841269841269839935785325638310428717L,
|
||||
S4 = 0.27557319223985890652557316053039946268333231205686e-5L,
|
||||
S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
|
||||
S6 = 0.16059043836821614596571832194524392581082444805729e-9L,
|
||||
S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
|
||||
S8 = 0.28114572543451292625024967174638477283187397621303e-14L;
|
||||
static const double
|
||||
S9 = -0.82206352458348947812512122163446202498005154296863e-17,
|
||||
S10 = 0.19572940011906109418080609928334380560135358385256e-19,
|
||||
S11 = -0.38680813379701966970673724299207480965452616911420e-22,
|
||||
S12 = 0.64038150078671872796678569586315881020659912139412e-25;
|
||||
#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \
|
||||
z*(S9+z*(S10+z*(S11+z*S12))))))))))
|
||||
#endif
|
||||
|
||||
long double __sinl(long double x, long double y, int iy)
|
||||
{
|
||||
long double z,r,v;
|
||||
|
||||
z = x*x;
|
||||
v = z*x;
|
||||
r = POLY(z);
|
||||
if (iy == 0)
|
||||
return x+v*(S1+z*r);
|
||||
return x-((z*(0.5*y-v*r)-y)-v*S1);
|
||||
}
|
||||
#endif
|
|
@ -1,110 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/* __tan( x, y, k )
|
||||
* kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
|
||||
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||
* Input y is the tail of x.
|
||||
* Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.
|
||||
*
|
||||
* Algorithm
|
||||
* 1. Since tan(-x) = -tan(x), we need only to consider positive x.
|
||||
* 2. Callers must return tan(-0) = -0 without calling here since our
|
||||
* odd polynomial is not evaluated in a way that preserves -0.
|
||||
* Callers may do the optimization tan(x) ~ x for tiny x.
|
||||
* 3. tan(x) is approximated by a odd polynomial of degree 27 on
|
||||
* [0,0.67434]
|
||||
* 3 27
|
||||
* tan(x) ~ x + T1*x + ... + T13*x
|
||||
* where
|
||||
*
|
||||
* |tan(x) 2 4 26 | -59.2
|
||||
* |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
|
||||
* | x |
|
||||
*
|
||||
* Note: tan(x+y) = tan(x) + tan'(x)*y
|
||||
* ~ tan(x) + (1+x*x)*y
|
||||
* Therefore, for better accuracy in computing tan(x+y), let
|
||||
* 3 2 2 2 2
|
||||
* r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
|
||||
* then
|
||||
* 3 2
|
||||
* tan(x+y) = x + (T1*x + (x *(r+y)+y))
|
||||
*
|
||||
* 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
|
||||
* tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
|
||||
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const double T[] = {
|
||||
3.33333333333334091986e-01, /* 3FD55555, 55555563 */
|
||||
1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
|
||||
5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
|
||||
2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
|
||||
8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
|
||||
3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
|
||||
1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
|
||||
5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
|
||||
2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
|
||||
7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
|
||||
7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
|
||||
-1.85586374855275456654e-05, /* BEF375CB, DB605373 */
|
||||
2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
|
||||
},
|
||||
pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
|
||||
pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
|
||||
|
||||
double __tan(double x, double y, int odd)
|
||||
{
|
||||
double_t z, r, v, w, s, a;
|
||||
double w0, a0;
|
||||
uint32_t hx;
|
||||
int big, sign;
|
||||
|
||||
GET_HIGH_WORD(hx,x);
|
||||
big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */
|
||||
if (big) {
|
||||
sign = hx>>31;
|
||||
if (sign) {
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
x = (pio4 - x) + (pio4lo - y);
|
||||
y = 0.0;
|
||||
}
|
||||
z = x * x;
|
||||
w = z * z;
|
||||
/*
|
||||
* Break x^5*(T[1]+x^2*T[2]+...) into
|
||||
* x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
|
||||
* x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
|
||||
*/
|
||||
r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));
|
||||
v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));
|
||||
s = z * x;
|
||||
r = y + z*(s*(r + v) + y) + s*T[0];
|
||||
w = x + r;
|
||||
if (big) {
|
||||
s = 1 - 2*odd;
|
||||
v = s - 2.0 * (x + (r - w*w/(w + s)));
|
||||
return sign ? -v : v;
|
||||
}
|
||||
if (!odd)
|
||||
return w;
|
||||
/* -1.0/(x+r) has up to 2ulp error, so compute it accurately */
|
||||
w0 = w;
|
||||
SET_LOW_WORD(w0, 0);
|
||||
v = r - (w0 - x); /* w0+v = r+x */
|
||||
a0 = a = -1.0 / w;
|
||||
SET_LOW_WORD(a0, 0);
|
||||
return a0 + a*(1.0 + a0*w0 + a0*v);
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
* Optimized by Bruce D. Evans.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
|
||||
static const double T[] = {
|
||||
0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
|
||||
0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
|
||||
0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */
|
||||
0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */
|
||||
0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */
|
||||
0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
|
||||
};
|
||||
|
||||
float __tandf(double x, int odd)
|
||||
{
|
||||
double_t z,r,w,s,t,u;
|
||||
|
||||
z = x*x;
|
||||
/*
|
||||
* Split up the polynomial into small independent terms to give
|
||||
* opportunities for parallel evaluation. The chosen splitting is
|
||||
* micro-optimized for Athlons (XP, X64). It costs 2 multiplications
|
||||
* relative to Horner's method on sequential machines.
|
||||
*
|
||||
* We add the small terms from lowest degree up for efficiency on
|
||||
* non-sequential machines (the lowest degree terms tend to be ready
|
||||
* earlier). Apart from this, we don't care about order of
|
||||
* operations, and don't need to to care since we have precision to
|
||||
* spare. However, the chosen splitting is good for accuracy too,
|
||||
* and would give results as accurate as Horner's method if the
|
||||
* small terms were added from highest degree down.
|
||||
*/
|
||||
r = T[4] + z*T[5];
|
||||
t = T[2] + z*T[3];
|
||||
w = z*z;
|
||||
s = z*x;
|
||||
u = T[0] + z*T[1];
|
||||
r = (x + s*u) + (s*w)*(t + w*r);
|
||||
return odd ? -1.0/r : r;
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */
|
||||
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
#if LDBL_MANT_DIG == 64
|
||||
/*
|
||||
* ld80 version of __tan.c. See __tan.c for most comments.
|
||||
*/
|
||||
/*
|
||||
* Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]
|
||||
* |tan(x)/x - t(x)| < 2**-71.9
|
||||
*
|
||||
* See __cosl.c for more details about the polynomial.
|
||||
*/
|
||||
static const long double
|
||||
T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */
|
||||
T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */
|
||||
T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */
|
||||
pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */
|
||||
pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */
|
||||
static const double
|
||||
T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */
|
||||
T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */
|
||||
T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */
|
||||
T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */
|
||||
T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */
|
||||
T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */
|
||||
T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */
|
||||
T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */
|
||||
T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */
|
||||
T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */
|
||||
T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */
|
||||
T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */
|
||||
T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */
|
||||
#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
|
||||
w * (T25 + w * (T29 + w * T33)))))))
|
||||
#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
|
||||
w * (T27 + w * T31))))))
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
/*
|
||||
* ld128 version of __tan.c. See __tan.c for most comments.
|
||||
*/
|
||||
/*
|
||||
* Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]
|
||||
* |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)
|
||||
*
|
||||
* See __cosl.c for more details about the polynomial.
|
||||
*/
|
||||
static const long double
|
||||
T3 = 0x1.5555555555555555555555555553p-2L,
|
||||
T5 = 0x1.1111111111111111111111111eb5p-3L,
|
||||
T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,
|
||||
T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,
|
||||
T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,
|
||||
T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,
|
||||
T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,
|
||||
T17 = 0x1.355824803674477dfcf726649efep-11L,
|
||||
T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,
|
||||
T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,
|
||||
T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,
|
||||
T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,
|
||||
T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,
|
||||
T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,
|
||||
T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,
|
||||
T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,
|
||||
T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,
|
||||
T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,
|
||||
pio4 = 0x1.921fb54442d18469898cc51701b8p-1L,
|
||||
pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;
|
||||
static const double
|
||||
T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */
|
||||
T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */
|
||||
T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */
|
||||
T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */
|
||||
T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */
|
||||
T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */
|
||||
T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */
|
||||
T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */
|
||||
T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */
|
||||
T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */
|
||||
#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
|
||||
w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \
|
||||
w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))
|
||||
#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
|
||||
w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \
|
||||
w * (T47 + w * (T51 + w * T55))))))))))))
|
||||
#endif
|
||||
|
||||
long double __tanl(long double x, long double y, int odd) {
|
||||
long double z, r, v, w, s, a, t;
|
||||
int big, sign;
|
||||
|
||||
big = fabsl(x) >= 0.67434;
|
||||
if (big) {
|
||||
sign = 0;
|
||||
if (x < 0) {
|
||||
sign = 1;
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
x = (pio4 - x) + (pio4lo - y);
|
||||
y = 0.0;
|
||||
}
|
||||
z = x * x;
|
||||
w = z * z;
|
||||
r = RPOLY(w);
|
||||
v = z * VPOLY(w);
|
||||
s = z * x;
|
||||
r = y + z * (s * (r + v) + y) + T3 * s;
|
||||
w = x + r;
|
||||
if (big) {
|
||||
s = 1 - 2*odd;
|
||||
v = s - 2.0 * (x + (r - w * w / (w + s)));
|
||||
return sign ? -v : v;
|
||||
}
|
||||
if (!odd)
|
||||
return w;
|
||||
/*
|
||||
* if allow error up to 2 ulp, simply return
|
||||
* -1.0 / (x+r) here
|
||||
*/
|
||||
/* compute -1.0 / (x+r) accurately */
|
||||
z = w;
|
||||
z = z + 0x1p32 - 0x1p32;
|
||||
v = r - (z - x); /* z+v = r+x */
|
||||
t = a = -1.0 / w; /* a = -1.0/w */
|
||||
t = t + 0x1p32 - 0x1p32;
|
||||
s = 1.0 + t * z;
|
||||
return t + a * (s + t * v);
|
||||
}
|
||||
#endif
|
|
@ -1,101 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/* acos(x)
|
||||
* Method :
|
||||
* acos(x) = pi/2 - asin(x)
|
||||
* acos(-x) = pi/2 + asin(x)
|
||||
* For |x|<=0.5
|
||||
* acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
|
||||
* For x>0.5
|
||||
* acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
|
||||
* = 2asin(sqrt((1-x)/2))
|
||||
* = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
|
||||
* = 2f + (2c + 2s*z*R(z))
|
||||
* where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
|
||||
* for f so that f+c ~ sqrt(z).
|
||||
* For x<-0.5
|
||||
* acos(x) = pi - 2asin(sqrt((1-|x|)/2))
|
||||
* = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
|
||||
*
|
||||
* Special cases:
|
||||
* if x is NaN, return x itself;
|
||||
* if |x|>1, return NaN with invalid signal.
|
||||
*
|
||||
* Function needed: sqrt
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const double
|
||||
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
|
||||
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
|
||||
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
|
||||
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
|
||||
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
|
||||
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
|
||||
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
|
||||
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
|
||||
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
|
||||
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
|
||||
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
|
||||
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
|
||||
|
||||
static double R(double z)
|
||||
{
|
||||
double_t p, q;
|
||||
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
|
||||
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
|
||||
return p/q;
|
||||
}
|
||||
|
||||
double acos(double x)
|
||||
{
|
||||
double z,w,s,c,df;
|
||||
uint32_t hx,ix;
|
||||
|
||||
GET_HIGH_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
/* |x| >= 1 or nan */
|
||||
if (ix >= 0x3ff00000) {
|
||||
uint32_t lx;
|
||||
|
||||
GET_LOW_WORD(lx,x);
|
||||
if ((ix-0x3ff00000 | lx) == 0) {
|
||||
/* acos(1)=0, acos(-1)=pi */
|
||||
if (hx >> 31)
|
||||
return 2*pio2_hi + 0x1p-120f;
|
||||
return 0;
|
||||
}
|
||||
return 0/(x-x);
|
||||
}
|
||||
/* |x| < 0.5 */
|
||||
if (ix < 0x3fe00000) {
|
||||
if (ix <= 0x3c600000) /* |x| < 2**-57 */
|
||||
return pio2_hi + 0x1p-120f;
|
||||
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
|
||||
}
|
||||
/* x < -0.5 */
|
||||
if (hx >> 31) {
|
||||
z = (1.0+x)*0.5;
|
||||
s = sqrt(z);
|
||||
w = R(z)*s-pio2_lo;
|
||||
return 2*(pio2_hi - (s+w));
|
||||
}
|
||||
/* x > 0.5 */
|
||||
z = (1.0-x)*0.5;
|
||||
s = sqrt(z);
|
||||
df = s;
|
||||
SET_LOW_WORD(df,0);
|
||||
c = (z-df*df)/(s+df);
|
||||
w = R(z)*s+c;
|
||||
return 2*(df+w);
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const float
|
||||
pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
|
||||
pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
|
||||
pS0 = 1.6666586697e-01,
|
||||
pS1 = -4.2743422091e-02,
|
||||
pS2 = -8.6563630030e-03,
|
||||
qS1 = -7.0662963390e-01;
|
||||
|
||||
static float R(float z)
|
||||
{
|
||||
float_t p, q;
|
||||
p = z*(pS0+z*(pS1+z*pS2));
|
||||
q = 1.0f+z*qS1;
|
||||
return p/q;
|
||||
}
|
||||
|
||||
float acosf(float x)
|
||||
{
|
||||
float z,w,s,c,df;
|
||||
uint32_t hx,ix;
|
||||
|
||||
GET_FLOAT_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
/* |x| >= 1 or nan */
|
||||
if (ix >= 0x3f800000) {
|
||||
if (ix == 0x3f800000) {
|
||||
if (hx >> 31)
|
||||
return 2*pio2_hi + 0x1p-120f;
|
||||
return 0;
|
||||
}
|
||||
return 0/(x-x);
|
||||
}
|
||||
/* |x| < 0.5 */
|
||||
if (ix < 0x3f000000) {
|
||||
if (ix <= 0x32800000) /* |x| < 2**-26 */
|
||||
return pio2_hi + 0x1p-120f;
|
||||
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
|
||||
}
|
||||
/* x < -0.5 */
|
||||
if (hx >> 31) {
|
||||
z = (1+x)*0.5f;
|
||||
s = sqrtf(z);
|
||||
w = R(z)*s-pio2_lo;
|
||||
return 2*(pio2_hi - (s+w));
|
||||
}
|
||||
/* x > 0.5 */
|
||||
z = (1-x)*0.5f;
|
||||
s = sqrtf(z);
|
||||
GET_FLOAT_WORD(hx,s);
|
||||
SET_FLOAT_WORD(df,hx&0xfffff000);
|
||||
c = (z-df*df)/(s+df);
|
||||
w = R(z)*s+c;
|
||||
return 2*(df+w);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
#if FLT_EVAL_METHOD==2
|
||||
#undef sqrt
|
||||
#define sqrt sqrtl
|
||||
#endif
|
||||
|
||||
/* acosh(x) = log(x + sqrt(x*x-1)) */
|
||||
double acosh(double x)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {.f = x};
|
||||
unsigned e = u.i >> 52 & 0x7ff;
|
||||
|
||||
/* x < 1 domain error is handled in the called functions */
|
||||
|
||||
if (e < 0x3ff + 1)
|
||||
/* |x| < 2, up to 2ulp error in [1,1.125] */
|
||||
return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));
|
||||
if (e < 0x3ff + 26)
|
||||
/* |x| < 0x1p26 */
|
||||
return log(2*x - 1/(x+sqrt(x*x-1)));
|
||||
/* |x| >= 0x1p26 or nan */
|
||||
return log(x) + 0.693147180559945309417232121458176568;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
#if FLT_EVAL_METHOD==2
|
||||
#undef sqrtf
|
||||
#define sqrtf sqrtl
|
||||
#elif FLT_EVAL_METHOD==1
|
||||
#undef sqrtf
|
||||
#define sqrtf sqrt
|
||||
#endif
|
||||
|
||||
/* acosh(x) = log(x + sqrt(x*x-1)) */
|
||||
float acoshf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
uint32_t a = u.i & 0x7fffffff;
|
||||
|
||||
if (a < 0x3f800000+(1<<23))
|
||||
/* |x| < 2, invalid if x < 1 or nan */
|
||||
/* up to 2ulp error in [1,1.125] */
|
||||
return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));
|
||||
if (a < 0x3f800000+(12<<23))
|
||||
/* |x| < 0x1p12 */
|
||||
return logf(2*x - 1/(x+sqrtf(x*x-1)));
|
||||
/* x >= 0x1p12 */
|
||||
return logf(x) + 0.693147180559945309417232121458176568f;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
long double acoshl(long double x)
|
||||
{
|
||||
return acosh(x);
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
|
||||
/* acosh(x) = log(x + sqrt(x*x-1)) */
|
||||
long double acoshl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
int e = u.i.se & 0x7fff;
|
||||
|
||||
if (e < 0x3fff + 1)
|
||||
/* |x| < 2, invalid if x < 1 or nan */
|
||||
return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));
|
||||
if (e < 0x3fff + 32)
|
||||
/* |x| < 0x1p32 */
|
||||
return logl(2*x - 1/(x+sqrtl(x*x-1)));
|
||||
return logl(x) + 0.693147180559945309417232121458176568L;
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
// TODO: broken implementation to make things compile
|
||||
long double acoshl(long double x)
|
||||
{
|
||||
return acosh(x);
|
||||
}
|
||||
#endif
|
|
@ -1,67 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/*
|
||||
* See comments in acos.c.
|
||||
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
long double acosl(long double x)
|
||||
{
|
||||
return acos(x);
|
||||
}
|
||||
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
#include "__invtrigl.h"
|
||||
#if LDBL_MANT_DIG == 64
|
||||
#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
#define CLEARBOTTOM(u) (u.i.lo = 0)
|
||||
#endif
|
||||
|
||||
long double acosl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
long double z, s, c, f;
|
||||
uint16_t e = u.i.se & 0x7fff;
|
||||
|
||||
/* |x| >= 1 or nan */
|
||||
if (e >= 0x3fff) {
|
||||
if (x == 1)
|
||||
return 0;
|
||||
if (x == -1)
|
||||
return 2*pio2_hi + 0x1p-120f;
|
||||
return 0/(x-x);
|
||||
}
|
||||
/* |x| < 0.5 */
|
||||
if (e < 0x3fff - 1) {
|
||||
if (e < 0x3fff - LDBL_MANT_DIG - 1)
|
||||
return pio2_hi + 0x1p-120f;
|
||||
return pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x);
|
||||
}
|
||||
/* x < -0.5 */
|
||||
if (u.i.se >> 15) {
|
||||
z = (1 + x)*0.5;
|
||||
s = sqrtl(z);
|
||||
return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));
|
||||
}
|
||||
/* x > 0.5 */
|
||||
z = (1 - x)*0.5;
|
||||
s = sqrtl(z);
|
||||
u.f = s;
|
||||
CLEARBOTTOM(u);
|
||||
f = u.f;
|
||||
c = (z - f*f)/(s + f);
|
||||
return 2*(__invtrigl_R(z)*s + c + f);
|
||||
}
|
||||
#endif
|
|
@ -1,107 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/* asin(x)
|
||||
* Method :
|
||||
* Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
|
||||
* we approximate asin(x) on [0,0.5] by
|
||||
* asin(x) = x + x*x^2*R(x^2)
|
||||
* where
|
||||
* R(x^2) is a rational approximation of (asin(x)-x)/x^3
|
||||
* and its remez error is bounded by
|
||||
* |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
|
||||
*
|
||||
* For x in [0.5,1]
|
||||
* asin(x) = pi/2-2*asin(sqrt((1-x)/2))
|
||||
* Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
|
||||
* then for x>0.98
|
||||
* asin(x) = pi/2 - 2*(s+s*z*R(z))
|
||||
* = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
|
||||
* For x<=0.98, let pio4_hi = pio2_hi/2, then
|
||||
* f = hi part of s;
|
||||
* c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
|
||||
* and
|
||||
* asin(x) = pi/2 - 2*(s+s*z*R(z))
|
||||
* = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
|
||||
* = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
|
||||
*
|
||||
* Special cases:
|
||||
* if x is NaN, return x itself;
|
||||
* if |x|>1, return NaN with invalid signal.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const double
|
||||
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
|
||||
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
|
||||
/* coefficients for R(x^2) */
|
||||
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
|
||||
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
|
||||
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
|
||||
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
|
||||
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
|
||||
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
|
||||
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
|
||||
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
|
||||
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
|
||||
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
|
||||
|
||||
static double R(double z)
|
||||
{
|
||||
double_t p, q;
|
||||
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
|
||||
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
|
||||
return p/q;
|
||||
}
|
||||
|
||||
double asin(double x)
|
||||
{
|
||||
double z,r,s;
|
||||
uint32_t hx,ix;
|
||||
|
||||
GET_HIGH_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
/* |x| >= 1 or nan */
|
||||
if (ix >= 0x3ff00000) {
|
||||
uint32_t lx;
|
||||
GET_LOW_WORD(lx, x);
|
||||
if ((ix-0x3ff00000 | lx) == 0)
|
||||
/* asin(1) = +-pi/2 with inexact */
|
||||
return x*pio2_hi + 0x1p-120f;
|
||||
return 0/(x-x);
|
||||
}
|
||||
/* |x| < 0.5 */
|
||||
if (ix < 0x3fe00000) {
|
||||
/* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */
|
||||
if (ix < 0x3e500000 && ix >= 0x00100000)
|
||||
return x;
|
||||
return x + x*R(x*x);
|
||||
}
|
||||
/* 1 > |x| >= 0.5 */
|
||||
z = (1 - fabs(x))*0.5;
|
||||
s = sqrt(z);
|
||||
r = R(z);
|
||||
if (ix >= 0x3fef3333) { /* if |x| > 0.975 */
|
||||
x = pio2_hi-(2*(s+s*r)-pio2_lo);
|
||||
} else {
|
||||
double f,c;
|
||||
/* f+c = sqrt(z) */
|
||||
f = s;
|
||||
SET_LOW_WORD(f,0);
|
||||
c = (z-f*f)/(s+f);
|
||||
x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
|
||||
}
|
||||
if (hx >> 31)
|
||||
return -x;
|
||||
return x;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
#include "libm.h"
|
||||
|
||||
static const double
|
||||
pio2 = 1.570796326794896558e+00;
|
||||
|
||||
static const float
|
||||
/* coefficients for R(x^2) */
|
||||
pS0 = 1.6666586697e-01,
|
||||
pS1 = -4.2743422091e-02,
|
||||
pS2 = -8.6563630030e-03,
|
||||
qS1 = -7.0662963390e-01;
|
||||
|
||||
static float R(float z)
|
||||
{
|
||||
float_t p, q;
|
||||
p = z*(pS0+z*(pS1+z*pS2));
|
||||
q = 1.0f+z*qS1;
|
||||
return p/q;
|
||||
}
|
||||
|
||||
float asinf(float x)
|
||||
{
|
||||
double s;
|
||||
float z;
|
||||
uint32_t hx,ix;
|
||||
|
||||
GET_FLOAT_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
if (ix >= 0x3f800000) { /* |x| >= 1 */
|
||||
if (ix == 0x3f800000) /* |x| == 1 */
|
||||
return x*pio2 + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */
|
||||
return 0/(x-x); /* asin(|x|>1) is NaN */
|
||||
}
|
||||
if (ix < 0x3f000000) { /* |x| < 0.5 */
|
||||
/* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
|
||||
if (ix < 0x39800000 && ix >= 0x00800000)
|
||||
return x;
|
||||
return x + x*R(x*x);
|
||||
}
|
||||
/* 1 > |x| >= 0.5 */
|
||||
z = (1 - fabsf(x))*0.5f;
|
||||
s = sqrt(z);
|
||||
x = pio2 - 2*(s+s*R(z));
|
||||
if (hx >> 31)
|
||||
return -x;
|
||||
return x;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
|
||||
double asinh(double x)
|
||||
{
|
||||
union {double f; uint64_t i;} u = {.f = x};
|
||||
unsigned e = u.i >> 52 & 0x7ff;
|
||||
unsigned s = u.i >> 63;
|
||||
|
||||
/* |x| */
|
||||
u.i &= (uint64_t)-1/2;
|
||||
x = u.f;
|
||||
|
||||
if (e >= 0x3ff + 26) {
|
||||
/* |x| >= 0x1p26 or inf or nan */
|
||||
x = log(x) + 0.693147180559945309417232121458176568;
|
||||
} else if (e >= 0x3ff + 1) {
|
||||
/* |x| >= 2 */
|
||||
x = log(2*x + 1/(sqrt(x*x+1)+x));
|
||||
} else if (e >= 0x3ff - 26) {
|
||||
/* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */
|
||||
x = log1p(x + x*x/(sqrt(x*x+1)+1));
|
||||
} else {
|
||||
/* |x| < 0x1p-26, raise inexact if x != 0 */
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
}
|
||||
return s ? -x : x;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
|
||||
float asinhf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
uint32_t i = u.i & 0x7fffffff;
|
||||
unsigned s = u.i >> 31;
|
||||
|
||||
/* |x| */
|
||||
u.i = i;
|
||||
x = u.f;
|
||||
|
||||
if (i >= 0x3f800000 + (12<<23)) {
|
||||
/* |x| >= 0x1p12 or inf or nan */
|
||||
x = logf(x) + 0.693147180559945309417232121458176568f;
|
||||
} else if (i >= 0x3f800000 + (1<<23)) {
|
||||
/* |x| >= 2 */
|
||||
x = logf(2*x + 1/(sqrtf(x*x+1)+x));
|
||||
} else if (i >= 0x3f800000 - (12<<23)) {
|
||||
/* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
|
||||
x = log1pf(x + x*x/(sqrtf(x*x+1)+1));
|
||||
} else {
|
||||
/* |x| < 0x1p-12, raise inexact if x!=0 */
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
}
|
||||
return s ? -x : x;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#include "libm.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
long double asinhl(long double x)
|
||||
{
|
||||
return asinh(x);
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
|
||||
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
|
||||
long double asinhl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
unsigned e = u.i.se & 0x7fff;
|
||||
unsigned s = u.i.se >> 15;
|
||||
|
||||
/* |x| */
|
||||
u.i.se = e;
|
||||
x = u.f;
|
||||
|
||||
if (e >= 0x3fff + 32) {
|
||||
/* |x| >= 0x1p32 or inf or nan */
|
||||
x = logl(x) + 0.693147180559945309417232121458176568L;
|
||||
} else if (e >= 0x3fff + 1) {
|
||||
/* |x| >= 2 */
|
||||
x = logl(2*x + 1/(sqrtl(x*x+1)+x));
|
||||
} else if (e >= 0x3fff - 32) {
|
||||
/* |x| >= 0x1p-32 */
|
||||
x = log1pl(x + x*x/(sqrtl(x*x+1)+1));
|
||||
} else {
|
||||
/* |x| < 0x1p-32, raise inexact if x!=0 */
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
}
|
||||
return s ? -x : x;
|
||||
}
|
||||
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
|
||||
// TODO: broken implementation to make things compile
|
||||
long double asinhl(long double x)
|
||||
{
|
||||
return asinh(x);
|
||||
}
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/*
|
||||
* See comments in asin.c.
|
||||
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
|
||||
*/
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
|
||||
long double asinl(long double x)
|
||||
{
|
||||
return asin(x);
|
||||
}
|
||||
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
|
||||
#include "__invtrigl.h"
|
||||
#if LDBL_MANT_DIG == 64
|
||||
#define CLOSETO1(u) (u.i.m>>56 >= 0xf7)
|
||||
#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
#define CLOSETO1(u) (u.i.top >= 0xee00)
|
||||
#define CLEARBOTTOM(u) (u.i.lo = 0)
|
||||
#endif
|
||||
|
||||
long double asinl(long double x)
|
||||
{
|
||||
union ldshape u = {x};
|
||||
long double z, r, s;
|
||||
uint16_t e = u.i.se & 0x7fff;
|
||||
int sign = u.i.se >> 15;
|
||||
|
||||
if (e >= 0x3fff) { /* |x| >= 1 or nan */
|
||||
/* asin(+-1)=+-pi/2 with inexact */
|
||||
if (x == 1 || x == -1)
|
||||
return x*pio2_hi + 0x1p-120f;
|
||||
return 0/(x-x);
|
||||
}
|
||||
if (e < 0x3fff - 1) { /* |x| < 0.5 */
|
||||
if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {
|
||||
/* return x with inexact if x!=0 */
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
return x;
|
||||
}
|
||||
return x + x*__invtrigl_R(x*x);
|
||||
}
|
||||
/* 1 > |x| >= 0.5 */
|
||||
z = (1.0 - fabsl(x))*0.5;
|
||||
s = sqrtl(z);
|
||||
r = __invtrigl_R(z);
|
||||
if (CLOSETO1(u)) {
|
||||
x = pio2_hi - (2*(s+s*r)-pio2_lo);
|
||||
} else {
|
||||
long double f, c;
|
||||
u.f = s;
|
||||
CLEARBOTTOM(u);
|
||||
f = u.f;
|
||||
c = (z - f*f)/(s + f);
|
||||
x = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
|
||||
}
|
||||
return sign ? -x : x;
|
||||
}
|
||||
#endif
|
|
@ -1,116 +0,0 @@
|
|||
/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
/* atan(x)
|
||||
* Method
|
||||
* 1. Reduce x to positive by atan(x) = -atan(-x).
|
||||
* 2. According to the integer k=4t+0.25 chopped, t=x, the argument
|
||||
* is further reduced to one of the following intervals and the
|
||||
* arctangent of t is evaluated by the corresponding formula:
|
||||
*
|
||||
* [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
|
||||
* [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
|
||||
* [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
|
||||
* [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
|
||||
* [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
|
||||
*
|
||||
* Constants:
|
||||
* The hexadecimal values are the intended ones for the following
|
||||
* constants. The decimal values may be used, provided that the
|
||||
* compiler will convert from decimal to binary accurately enough
|
||||
* to produce the hexadecimal values shown.
|
||||
*/
|
||||
|
||||
|
||||
#include "libm.h"
|
||||
|
||||
static const double atanhi[] = {
|
||||
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
|
||||
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
|
||||
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
|
||||
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
|
||||
};
|
||||
|
||||
static const double atanlo[] = {
|
||||
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
|
||||
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
|
||||
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
|
||||
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
|
||||
};
|
||||
|
||||
static const double aT[] = {
|
||||
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
|
||||
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
|
||||
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
|
||||
-1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
|
||||
9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
|
||||
-7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
|
||||
6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
|
||||
-5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
|
||||
4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
|
||||
-3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
|
||||
1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
|
||||
};
|
||||
|
||||
double atan(double x)
|
||||
{
|
||||
double_t w,s1,s2,z;
|
||||
uint32_t ix,sign;
|
||||
int id;
|
||||
|
||||
GET_HIGH_WORD(ix, x);
|
||||
sign = ix >> 31;
|
||||
ix &= 0x7fffffff;
|
||||
if (ix >= 0x44100000) { /* if |x| >= 2^66 */
|
||||
if (isnan(x))
|
||||
return x;
|
||||
z = atanhi[3] + 0x1p-120f;
|
||||
return sign ? -z : z;
|
||||
}
|
||||
if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
|
||||
if (ix < 0x3e400000) { /* |x| < 2^-27 */
|
||||
if (ix < 0x00100000)
|
||||
/* raise underflow for subnormal x */
|
||||
FORCE_EVAL((float)x);
|
||||
return x;
|
||||
}
|
||||
id = -1;
|
||||
} else {
|
||||
x = fabs(x);
|
||||
if (ix < 0x3ff30000) { /* |x| < 1.1875 */
|
||||
if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */
|
||||
id = 0;
|
||||
x = (2.0*x-1.0)/(2.0+x);
|
||||
} else { /* 11/16 <= |x| < 19/16 */
|
||||
id = 1;
|
||||
x = (x-1.0)/(x+1.0);
|
||||
}
|
||||
} else {
|
||||
if (ix < 0x40038000) { /* |x| < 2.4375 */
|
||||
id = 2;
|
||||
x = (x-1.5)/(1.0+1.5*x);
|
||||
} else { /* 2.4375 <= |x| < 2^66 */
|
||||
id = 3;
|
||||
x = -1.0/x;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* end of argument reduction */
|
||||
z = x*x;
|
||||
w = z*z;
|
||||
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
|
||||
s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
|
||||
s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
|
||||
if (id < 0)
|
||||
return x - x*(s1+s2);
|
||||
z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
|
||||
return sign ? -z : z;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue