compiled newlib, need to hook up the system calls
This commit is contained in:
@@ -1,4 +1,327 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/globals.c.o",
|
||||||
|
"kernel/globals.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/globals.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/globals.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/kmain.c.o",
|
||||||
|
"kernel/kmain.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/kmain.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/kmain.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/pic/pic.c.o",
|
||||||
|
"kernel/drivers/pic/pic.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/vga/vga.c.o",
|
||||||
|
"kernel/drivers/vga/vga.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/vga/vga.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/vga/vga.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/ide/ide.c.o",
|
||||||
|
"kernel/drivers/ide/ide.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/ide/ide.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/ide/ide.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/ps2/ps2.c.o",
|
||||||
|
"kernel/drivers/ps2/ps2.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/ps2/ps2.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/ps2/ps2.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/iso/iso.c.o",
|
||||||
|
"kernel/drivers/iso/iso.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/iso/iso.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/iso/iso.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/gdt.c.o",
|
||||||
|
"kernel/gdt.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/gdt.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/gdt.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/memory/mm.c.o",
|
||||||
|
"kernel/memory/mm.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/memory/mm.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/memory/mm.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/interrupts.c.o",
|
||||||
|
"kernel/interrupts.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/interrupts.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/interrupts.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/syscall.c.o",
|
||||||
|
"kernel/syscall.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/syscall.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/syscall.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/lib/stream.c.o",
|
||||||
|
"kernel/lib/stream.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/lib/stream.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/lib/stream.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/lib/memory.c.o",
|
||||||
|
"kernel/lib/memory.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/lib/memory.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/lib/memory.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/lib/print.c.o",
|
||||||
|
"kernel/lib/print.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/lib/print.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/lib/print.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/lib/tasks.c.o",
|
||||||
|
"kernel/lib/tasks.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/lib/tasks.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/lib/tasks.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/scheduler.c.o",
|
||||||
|
"kernel/scheduler.c"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/scheduler.c",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/scheduler.c.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/syscall.S.o",
|
||||||
|
"kernel/syscall.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/syscall.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/syscall.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/common.S.o",
|
||||||
|
"kernel/common.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/common.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/common.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/pic/pic.S.o",
|
||||||
|
"kernel/drivers/pic/pic.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pic/pic.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pic/pic.S.o"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"arguments": [
|
"arguments": [
|
||||||
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
@@ -15,5 +338,107 @@
|
|||||||
"directory": "/home/slinky/source/RockOS",
|
"directory": "/home/slinky/source/RockOS",
|
||||||
"file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit.S",
|
"file": "/home/slinky/source/RockOS/kernel/drivers/pit/pit.S",
|
||||||
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit.S.o"
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/pit/pit.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/drivers/ps2/ps2.S.o",
|
||||||
|
"kernel/drivers/ps2/ps2.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/drivers/ps2/ps2.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/drivers/ps2/ps2.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/memory/mm_stubs.S.o",
|
||||||
|
"kernel/memory/mm_stubs.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/memory/mm_stubs.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/memory/mm_stubs.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/boot/boot.S.o",
|
||||||
|
"kernel/boot/boot.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/boot/boot.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/boot/boot.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/scheduler.S.o",
|
||||||
|
"kernel/scheduler.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/scheduler.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/scheduler.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/gdt.S.o",
|
||||||
|
"kernel/gdt.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/gdt.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/gdt.S.o"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": [
|
||||||
|
"/home/slinky/opt/cross/bin/i686-elf-gcc",
|
||||||
|
"-c",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-O2",
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Ikernel",
|
||||||
|
"-o",
|
||||||
|
"obj/kernel/interrupts.S.o",
|
||||||
|
"kernel/interrupts.S"
|
||||||
|
],
|
||||||
|
"directory": "/home/slinky/source/RockOS",
|
||||||
|
"file": "/home/slinky/source/RockOS/kernel/interrupts.S",
|
||||||
|
"output": "/home/slinky/source/RockOS/obj/kernel/interrupts.S.o"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ higher:
|
|||||||
push %eax
|
push %eax
|
||||||
call kmain
|
call kmain
|
||||||
loop:
|
loop:
|
||||||
|
hlt
|
||||||
jmp loop
|
jmp loop
|
||||||
|
|
||||||
.section .bss
|
.section .bss
|
||||||
|
|||||||
10
kernel/common.h
Normal file
10
kernel/common.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef KCOMMON_H
|
||||||
|
#define KCOMMON_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void enable_interrupts();
|
||||||
|
void disable_interrupts();
|
||||||
|
uint32_t fetch_cr3();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
.code32
|
.code32
|
||||||
.global init_pit
|
.global init_pit
|
||||||
init_pit: # tickrate: 1193182/1000 = 0x04A9 (1000hz) (1ms)
|
init_pit:
|
||||||
movb $0x36, %al
|
movb $0x36, %al
|
||||||
outb %al, $0x43
|
outb %al, $0x43
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ void init_gdt() {
|
|||||||
for (uint32_t i = 0; i < sizeof(tss_entry); i++) {
|
for (uint32_t i = 0; i < sizeof(tss_entry); i++) {
|
||||||
((char*)&tss)[i] = 0;
|
((char*)&tss)[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tss.ss0 = 0x10;
|
tss.ss0 = 0x10;
|
||||||
tss.iomap_base = sizeof(tss_entry);
|
tss.iomap_base = sizeof(tss_entry);
|
||||||
|
|
||||||
@@ -136,6 +137,7 @@ void init_gdt() {
|
|||||||
|
|
||||||
gdtr.limit = 6 * sizeof(uint64_t) - 1;
|
gdtr.limit = 6 * sizeof(uint64_t) - 1;
|
||||||
gdtr.base = (uint32_t)&gdt;
|
gdtr.base = (uint32_t)&gdt;
|
||||||
|
|
||||||
load_gdt();
|
load_gdt();
|
||||||
tss_flush();
|
tss_flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ isr\num:
|
|||||||
jmp isr_common_stub
|
jmp isr_common_stub
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.extern common_interrupt_handler
|
.extern common_interrupt_handler # interrupts.c
|
||||||
isr_common_stub:
|
isr_common_stub:
|
||||||
pushal
|
pushal
|
||||||
|
|
||||||
@@ -40,18 +40,20 @@ ISR_ERRCODE 14 # Page Fault (Has Error Code!)
|
|||||||
|
|
||||||
// This is a special case so we need to handle it for task switching
|
// This is a special case so we need to handle it for task switching
|
||||||
.global isr32
|
.global isr32
|
||||||
|
.extern switch_context # scheduler.c
|
||||||
|
.extern send_eoi_master # drivers/pic/pic.c
|
||||||
isr32:
|
isr32:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
pushal
|
pushal
|
||||||
|
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call schedule_next_task
|
call switch_context
|
||||||
movl %eax, %esp
|
movl %eax, %esp
|
||||||
|
|
||||||
call send_eoi_master
|
call send_eoi_master
|
||||||
|
|
||||||
popal
|
popal
|
||||||
|
|
||||||
sti
|
sti
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ typedef struct __attribute__((packed)) {
|
|||||||
uint32_t eip, cs, eflags, useresp, ss;
|
uint32_t eip, cs, eflags, useresp, ss;
|
||||||
} registers;
|
} registers;
|
||||||
|
|
||||||
|
// (interrupts.S)
|
||||||
extern void load_idt(void);
|
extern void load_idt(void);
|
||||||
|
|
||||||
// isr stubs
|
|
||||||
extern void isr0();
|
extern void isr0();
|
||||||
extern void isr1();
|
extern void isr1();
|
||||||
extern void isr8();
|
extern void isr8();
|
||||||
@@ -127,10 +126,6 @@ void common_interrupt_handler(registers *args) {
|
|||||||
while(1);
|
while(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 32:
|
|
||||||
// wake the PIT timer driver
|
|
||||||
send_eoi_master();
|
|
||||||
break;
|
|
||||||
case 33: {
|
case 33: {
|
||||||
uint8_t data = ps2_read_data();
|
uint8_t data = ps2_read_data();
|
||||||
send_eoi_master();
|
send_eoi_master();
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "multiboot.h"
|
#include "multiboot.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "elf.h"
|
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <lib/stream.h>
|
#include <lib/stream.h>
|
||||||
@@ -20,21 +20,22 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern void enable_interrupts();
|
|
||||||
extern void disable_interrupts();
|
|
||||||
extern uint32_t fetch_cr3();
|
|
||||||
|
|
||||||
extern char __kernel_start;
|
extern char __kernel_start;
|
||||||
extern char __kernel_end;
|
extern char __kernel_end;
|
||||||
|
|
||||||
void kernel_test_task() {
|
void first_task() {
|
||||||
while (1) {
|
kprintf("task started\n");
|
||||||
kprintf("task sleeping...\n");
|
int i = 5;
|
||||||
sleep(10000000);
|
while (i--) {
|
||||||
|
sleep(1000);
|
||||||
|
kprintf("task awake [%d]\n", i);
|
||||||
}
|
}
|
||||||
|
kprintf("exiting\n");
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmain(uint32_t magic, multiboot_info* mbi) {
|
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||||
|
disable_interrupts();
|
||||||
if (!(mbi->flags & (1 << 6))) {
|
if (!(mbi->flags & (1 << 6))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -54,9 +55,14 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
|
|
||||||
kprintf("basic initializations complete\n");
|
kprintf("basic initializations complete\n");
|
||||||
|
|
||||||
disable_interrupts();
|
disable_interrupts(); // just paranoid... do it again
|
||||||
init_scheduler();
|
init_scheduler();
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
||||||
while(1) yield();
|
create_task((uint32_t)first_task, fetch_cr3());
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
sleep(5000);
|
||||||
|
kprintf("kernel awake\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
STATE_READY,
|
STATE_READY,
|
||||||
STATE_SLEEPING,
|
STATE_SLEEPING,
|
||||||
|
STATE_BLOCKED,
|
||||||
STATE_DEAD
|
STATE_DEAD
|
||||||
} process_state_t;
|
} process_state_t;
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ typedef struct {
|
|||||||
uint32_t cr3;
|
uint32_t cr3;
|
||||||
process_state_t state;
|
process_state_t state;
|
||||||
uint32_t sleep;
|
uint32_t sleep;
|
||||||
|
void* next;
|
||||||
} __attribute__((packed)) process_t;
|
} __attribute__((packed)) process_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,12 +1,31 @@
|
|||||||
|
|
||||||
|
|
||||||
.code32
|
.code32
|
||||||
.extern schedule_next_task
|
|
||||||
.global yield
|
.global yield
|
||||||
yield:
|
.extern schedule_next_task
|
||||||
|
yield: # void yield()
|
||||||
cli
|
cli
|
||||||
|
|
||||||
|
pushfl
|
||||||
|
pushl %cs
|
||||||
|
|
||||||
|
movl 8(%esp), %eax
|
||||||
|
pushl %eax
|
||||||
|
|
||||||
|
movl 4(%esp), %ebx # Get CS
|
||||||
|
movl %ebx, 8(%esp) # Move CS over Old EIP
|
||||||
|
movl 0(%esp), %ebx # Get Return EIP
|
||||||
|
movl %ebx, 4(%esp) # Move Return EIP over CS
|
||||||
|
addl $4, %esp # Adjust stack pointer up.
|
||||||
|
|
||||||
|
# the stack now looks like a hardware interrupt just happened, even though we never called one.
|
||||||
|
|
||||||
pushal
|
pushal
|
||||||
push %esp
|
|
||||||
call schedule_next_task
|
pushl %esp
|
||||||
|
call switch_context
|
||||||
movl %eax, %esp
|
movl %eax, %esp
|
||||||
|
|
||||||
popal
|
popal
|
||||||
sti
|
sti
|
||||||
ret
|
iret
|
||||||
@@ -5,24 +5,30 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
|
||||||
static process_t* process_table;
|
static process_t* process_table;
|
||||||
static spinlock_t process_table_lock = {0};
|
|
||||||
|
|
||||||
static int current_process = 0;
|
static int current_process = 0;
|
||||||
static int total_processes = 0;
|
static int total_processes = 0;
|
||||||
|
|
||||||
extern uint32_t fetch_cr3();
|
|
||||||
|
|
||||||
#define IDLE_TASK_PID 1
|
#define IDLE_TASK_PID 1
|
||||||
static void idle_task() {
|
static void idle_task() {
|
||||||
while (1) asm volatile("hlt");
|
while (1) asm volatile("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t schedule_next_task(uint32_t current_esp) {
|
static void lock_scheduler() {
|
||||||
spin_lock(&process_table_lock);
|
disable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unlock_scheduler() {
|
||||||
|
enable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// called from isr and yield, interrupts are already disabled and re enabled in the isr/yield func
|
||||||
|
uint32_t switch_context(uint32_t current_esp) {
|
||||||
process_table[current_process].esp = current_esp;
|
process_table[current_process].esp = current_esp;
|
||||||
|
|
||||||
for (int i = 0; i < total_processes; i++) {
|
for (int i = 0; i < total_processes; i++) {
|
||||||
@@ -39,6 +45,7 @@ uint32_t schedule_next_task(uint32_t current_esp) {
|
|||||||
|
|
||||||
int next_process = current_process;
|
int next_process = current_process;
|
||||||
int found_ready = 0;
|
int found_ready = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
next_process = (next_process + 1) % total_processes;
|
next_process = (next_process + 1) % total_processes;
|
||||||
if (next_process != IDLE_TASK_PID && process_table[next_process].state == STATE_READY) {
|
if (next_process != IDLE_TASK_PID && process_table[next_process].state == STATE_READY) {
|
||||||
@@ -66,10 +73,7 @@ uint32_t schedule_next_task(uint32_t current_esp) {
|
|||||||
load_pd(process_table[current_process].cr3);
|
load_pd(process_table[current_process].cr3);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rtn = process_table[current_process].esp;
|
return process_table[current_process].esp;
|
||||||
spin_unlock(&process_table_lock);
|
|
||||||
|
|
||||||
return rtn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_scheduler() {
|
void init_scheduler() {
|
||||||
@@ -94,9 +98,19 @@ int create_task(uint32_t entry_point, uint32_t cr3) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&process_table_lock);
|
lock_scheduler();
|
||||||
|
|
||||||
|
// default to a new task, but if we find a dead one, re use it
|
||||||
process_t* process = &process_table[total_processes];
|
process_t* process = &process_table[total_processes];
|
||||||
process->pid = total_processes;
|
uint32_t pid = total_processes;
|
||||||
|
for (uint32_t i = 0; i < total_processes; i++) {
|
||||||
|
if (process_table[i].state == STATE_DEAD) {
|
||||||
|
process = &process_table[i];
|
||||||
|
pid = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process->pid = pid;
|
||||||
process->cr3 = cr3;
|
process->cr3 = cr3;
|
||||||
process->state = STATE_READY;
|
process->state = STATE_READY;
|
||||||
process->sleep = 0;
|
process->sleep = 0;
|
||||||
@@ -118,19 +132,24 @@ int create_task(uint32_t entry_point, uint32_t cr3) {
|
|||||||
*(--esp) = 0; // EDI
|
*(--esp) = 0; // EDI
|
||||||
|
|
||||||
process->esp = (uint32_t)esp;
|
process->esp = (uint32_t)esp;
|
||||||
spin_unlock(&process_table_lock);
|
|
||||||
|
|
||||||
total_processes++;
|
total_processes++;
|
||||||
|
unlock_scheduler();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep(uint32_t ticks) {
|
void sleep(uint32_t ms) {
|
||||||
if (ticks == 0) return;
|
if (ms == 0) return;
|
||||||
|
lock_scheduler();
|
||||||
spin_lock(&process_table_lock);
|
process_table[current_process].sleep = ms;
|
||||||
process_table[current_process].sleep = ticks;
|
|
||||||
process_table[current_process].state = STATE_SLEEPING;
|
process_table[current_process].state = STATE_SLEEPING;
|
||||||
spin_unlock(&process_table_lock);
|
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
|
unlock_scheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exit() {
|
||||||
|
lock_scheduler();
|
||||||
|
process_table[current_process].state = STATE_DEAD;
|
||||||
|
yield(); // yield forever
|
||||||
|
unlock_scheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ void init_scheduler();
|
|||||||
|
|
||||||
int create_task(uint32_t entry_point, uint32_t cr3);
|
int create_task(uint32_t entry_point, uint32_t cr3);
|
||||||
|
|
||||||
void sleep(uint32_t ticks);
|
void sleep(uint32_t ms);
|
||||||
void yield();
|
void yield();
|
||||||
|
void exit();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "lib/print.h"
|
#include "scheduler.h"
|
||||||
|
|
||||||
typedef struct registers {
|
typedef struct registers {
|
||||||
uint32_t gs, fs, es, ds; // Pushed manually
|
uint32_t gs, fs, es, ds; // Pushed manually
|
||||||
@@ -9,19 +9,35 @@ typedef struct registers {
|
|||||||
uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU
|
uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU
|
||||||
} registers_t;
|
} registers_t;
|
||||||
|
|
||||||
int32_t sys_vga_text_write(char* buf);
|
int32_t sys_exit();
|
||||||
|
int32_t sys_read();
|
||||||
|
int32_t sys_write();
|
||||||
|
int32_t sys_open();
|
||||||
|
int32_t sys_close();
|
||||||
|
int32_t sys_brk();
|
||||||
|
|
||||||
int32_t syscall(registers_t* regs) {
|
int32_t syscall(registers_t* regs) {
|
||||||
switch(regs->eax) {
|
switch(regs->eax) {
|
||||||
case 1: {
|
case 1: return sys_exit();
|
||||||
return sys_vga_text_write((char*)regs->ebx);
|
case 3: return sys_read();
|
||||||
}
|
case 4: return sys_write();
|
||||||
|
case 5: return sys_open();
|
||||||
|
case 6: return sys_close();
|
||||||
|
case 12: return sys_brk();
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sys_vga_text_write(char* buf) {
|
int32_t sys_exit() {
|
||||||
kprintf(buf);
|
exit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t sys_read() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t sys_write() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#ifndef LIBC_ROCK_H
|
|
||||||
#define LIBC_ROCK_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
static inline int32_t syscall(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) {
|
|
||||||
int32_t ret;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"int $0x80"
|
|
||||||
: "=a" (ret)
|
|
||||||
: "0" (num), "b" (arg1), "c" (arg2), "d" (arg3)
|
|
||||||
: "memory"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#ifndef LIBC_STRING_H
|
|
||||||
#define LIBC_STRING_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
void* memcpy(void* dst, const void* src, size_t n);
|
|
||||||
void* memset(void* dst, int c, size_t n);
|
|
||||||
void* memmove(void* dst, const void* src, size_t n);
|
|
||||||
int memcmp(const void* s1, const void* s2, size_t n);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
24
programs/crt0.S
Normal file
24
programs/crt0.S
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.global _start
|
||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
_start:
|
||||||
|
xor ebp, ebp
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
|
||||||
|
mov eax, [esp + 4]
|
||||||
|
lea ebx, [esp + 8]
|
||||||
|
lea ecx, [esp + 12]
|
||||||
|
|
||||||
|
push ecx
|
||||||
|
push ebx
|
||||||
|
push eax
|
||||||
|
|
||||||
|
call main
|
||||||
|
|
||||||
|
push eax
|
||||||
|
call exit
|
||||||
|
|
||||||
|
1: hlt
|
||||||
|
jmp 1b
|
||||||
28
programs/crt0.s
Normal file
28
programs/crt0.s
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# 0 "crt0.S"
|
||||||
|
# 0 "<built-in>"
|
||||||
|
# 0 "<command-line>"
|
||||||
|
# 1 "crt0.S"
|
||||||
|
.global _start
|
||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
_start:
|
||||||
|
xor ebp, ebp
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
|
||||||
|
mov eax, [esp + 4]
|
||||||
|
lea ebx, [esp + 8]
|
||||||
|
lea ecx, [esp + 12]
|
||||||
|
|
||||||
|
push ecx
|
||||||
|
push ebx
|
||||||
|
push eax
|
||||||
|
|
||||||
|
call main
|
||||||
|
|
||||||
|
push eax
|
||||||
|
call exit
|
||||||
|
|
||||||
|
1: hlt
|
||||||
|
jmp 1b
|
||||||
31
programs/linker.ld
Normal file
31
programs/linker.ld
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x40000000;
|
||||||
|
|
||||||
|
.text ALIGN(4K) :
|
||||||
|
{
|
||||||
|
/* Force the crt0.o entry code to be placed FIRST in memory */
|
||||||
|
KEEP(*crt0.o(.text))
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata ALIGN(4K) :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data ALIGN(4K) :
|
||||||
|
{
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss ALIGN(4K) :
|
||||||
|
{
|
||||||
|
_bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
_bss_end = .;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
programs/main.c
Normal file
8
programs/main.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
printf("Hello, World from RockOS!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,16 +1,23 @@
|
|||||||
CC = i686-elf-gcc
|
CC = i686-elf-gcc
|
||||||
LD = i686-elf-ld
|
LD = i686-elf-ld
|
||||||
|
|
||||||
CFLAGS := -ffreestanding -O2 -Wall -Wextra
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra -I../rocklibc/include
|
||||||
|
LDFLAGS = -m elf_i386 -nostdlib
|
||||||
|
|
||||||
all: origin.elf
|
TARGET = origin.elf
|
||||||
|
|
||||||
origin.o: origin.S
|
all: $(TARGET)
|
||||||
$(CC) -c origin.S -o origin.o $(CFLAGS)
|
|
||||||
|
|
||||||
origin.elf: origin.o
|
crt0.o: crt0.s
|
||||||
$(LD) -Ttext 0x40000000 origin.o -o origin.elf
|
$(CC) $(CFLAGS) -c crt0.s -o crt0.o
|
||||||
mv origin.elf ../isodir/boot
|
|
||||||
|
main.o: main.c
|
||||||
|
$(CC) $(CFLAGS) -c main.c -o main.o
|
||||||
|
|
||||||
|
$(TARGET): crt0.o main.o ../rocklibc/rlibc.a
|
||||||
|
$(LD) $(LDFLAGS) -T linker.ld crt0.o main.o ../rocklibc/rlibc.a $(shell $(CC) -print-libgcc-file-name) -o $(TARGET)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f origin.o origin.elf
|
rm -f *.o $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
.code32
|
|
||||||
|
|
||||||
.section .text
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
mov $1, %eax
|
|
||||||
mov $(message), %ebx
|
|
||||||
mov $0, %ecx
|
|
||||||
mov $0, %edx
|
|
||||||
int $0x80
|
|
||||||
loop:
|
|
||||||
jmp loop
|
|
||||||
|
|
||||||
.section .data
|
|
||||||
message:
|
|
||||||
.asciz "Hello, Userland!\n";
|
|
||||||
1
rocklibc/.gitignore
vendored
Normal file
1
rocklibc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.a
|
||||||
4937
rocklibc/compile_commands.json
Normal file
4937
rocklibc/compile_commands.json
Normal file
File diff suppressed because it is too large
Load Diff
50
rocklibc/include/assert.h
Normal file
50
rocklibc/include/assert.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* Diagnostics <assert.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ASSERT_H
|
||||||
|
#define _PDCLIB_ASSERT_H _PDCLIB_ASSERT_H
|
||||||
|
_PDCLIB_PUBLIC void _PDCLIB_assert99( const char * const, const char * const, const char * const );
|
||||||
|
_PDCLIB_PUBLIC void _PDCLIB_assert89( const char * const );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If NDEBUG is set, assert() is a null operation. */
|
||||||
|
#undef assert
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define assert( ignore ) ( (void) 0 )
|
||||||
|
#else
|
||||||
|
#if __STDC_VERSION__ >= 199901L
|
||||||
|
#define assert( expression ) ( ( expression ) ? (void) 0 \
|
||||||
|
: _PDCLIB_assert99( "Assertion failed: " #expression \
|
||||||
|
", function ", __func__, \
|
||||||
|
", file " __FILE__ \
|
||||||
|
", line " _PDCLIB_value2string( __LINE__ ) \
|
||||||
|
".\n" ) )
|
||||||
|
#else
|
||||||
|
#define assert( expression ) ( ( expression ) ? (void) 0 \
|
||||||
|
: _PDCLIB_assert89( "Assertion failed: " #expression \
|
||||||
|
", file " __FILE__ \
|
||||||
|
", line " _PDCLIB_value2string( __LINE__ ) \
|
||||||
|
".\n" ) )
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_ASSERT_H
|
||||||
|
#include _PDCLIB_EXTEND_ASSERT_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
110
rocklibc/include/ctype.h
Normal file
110
rocklibc/include/ctype.h
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/* Character handling <ctype.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_CTYPE_H
|
||||||
|
#define _PDCLIB_CTYPE_H _PDCLIB_CTYPE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* Character classification functions */
|
||||||
|
|
||||||
|
/* Note that there is a difference between "whitespace" (any printing, non-
|
||||||
|
graph character, like horizontal and vertical tab), and "blank" (the literal
|
||||||
|
' ' space character).
|
||||||
|
|
||||||
|
There will be masking macros for each of these later on, but right now I
|
||||||
|
focus on the functions only.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Returns isalpha( c ) || isdigit( c ) */
|
||||||
|
_PDCLIB_PUBLIC int isalnum( int c );
|
||||||
|
|
||||||
|
/* Returns isupper( c ) || islower( c ) in the "C" locale.
|
||||||
|
In any other locale, also returns true for a locale-specific set of
|
||||||
|
alphabetic characters which are neither control characters, digits,
|
||||||
|
punctation, or whitespace.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int isalpha( int c );
|
||||||
|
|
||||||
|
/* Returns true if the character isspace() and used for separating words within
|
||||||
|
a line of text. In the "C" locale, only ' ' and '\t' are considered blanks.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int isblank( int c );
|
||||||
|
|
||||||
|
/* Returns true if the character is a control character. */
|
||||||
|
_PDCLIB_PUBLIC int iscntrl( int c );
|
||||||
|
|
||||||
|
/* Returns true if the character is a decimal digit. Locale-independent. */
|
||||||
|
_PDCLIB_PUBLIC int isdigit( int c );
|
||||||
|
|
||||||
|
/* Returns true for every printing character except space (' ').
|
||||||
|
NOTE: This definition differs from that of iswgraph() in <wctype.h>,
|
||||||
|
which considers any iswspace() character, not only ' '.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int isgraph( int c );
|
||||||
|
|
||||||
|
/* Returns true for lowercase letters in the "C" locale.
|
||||||
|
In any other locale, also returns true for a locale-specific set of
|
||||||
|
characters which are neither control characters, digits, punctation, or
|
||||||
|
space (' '). In a locale other than the "C" locale, a character might test
|
||||||
|
true for both islower() and isupper().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int islower( int c );
|
||||||
|
|
||||||
|
/* Returns true for every printing character including space (' '). */
|
||||||
|
_PDCLIB_PUBLIC int isprint( int c );
|
||||||
|
|
||||||
|
/* Returns true for a locale-specific set of punctuation charcters; these
|
||||||
|
may not be whitespace or alphanumeric. In the "C" locale, returns true
|
||||||
|
for every printing character that is not whitespace or alphanumeric.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int ispunct( int c );
|
||||||
|
|
||||||
|
/* Returns true for every standard whitespace character (' ', '\f', '\n', '\r',
|
||||||
|
'\t', '\v') in the "C" locale. In any other locale, also returns true for a
|
||||||
|
locale-specific set of characters for which isalnum() is false.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int isspace( int c );
|
||||||
|
|
||||||
|
/* Returns true for uppercase letters in the "C" locale.
|
||||||
|
In any other locale, also returns true for a locale-specific set of
|
||||||
|
characters which are neither control characters, digits, punctation, or
|
||||||
|
space (' '). In a locale other than the "C" locale, a character might test
|
||||||
|
true for both islower() and isupper().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int isupper( int c );
|
||||||
|
|
||||||
|
/* Returns true for any hexadecimal-digit character. Locale-independent. */
|
||||||
|
_PDCLIB_PUBLIC int isxdigit( int c );
|
||||||
|
|
||||||
|
/* Character case mapping functions */
|
||||||
|
|
||||||
|
/* Converts an uppercase letter to a corresponding lowercase letter. Input that
|
||||||
|
is not an uppercase letter remains unchanged.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int tolower( int c );
|
||||||
|
|
||||||
|
/* Converts a lowercase letter to a corresponding uppercase letter. Input that
|
||||||
|
is not a lowercase letter remains unchanged.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int toupper( int c );
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_CTYPE_H
|
||||||
|
#include _PDCLIB_EXTEND_CTYPE_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
202
rocklibc/include/errno.h
Normal file
202
rocklibc/include/errno.h
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/* Errors <errno.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ERRNO_H
|
||||||
|
#define _PDCLIB_ERRNO_H _PDCLIB_ERRNO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* FIXME: With <threads.h>, this needs to be in thread-specific storage. */
|
||||||
|
#define errno (*_PDCLIB_errno_func())
|
||||||
|
|
||||||
|
/* C only requires the following three */
|
||||||
|
|
||||||
|
/* Result too large */
|
||||||
|
#define ERANGE _PDCLIB_ERANGE
|
||||||
|
/* Mathematics argument out of domain of function */
|
||||||
|
#define EDOM _PDCLIB_EDOM
|
||||||
|
/* Illegal byte sequence */
|
||||||
|
#define EILSEQ _PDCLIB_EILSEQ
|
||||||
|
|
||||||
|
/* C++ additionally requires the folloing */
|
||||||
|
|
||||||
|
/* Argument list too long */
|
||||||
|
#define E2BIG _PDCLIB_E2BIG
|
||||||
|
/* Permission denied */
|
||||||
|
#define EACCES _PDCLIB_EACCES
|
||||||
|
/* Address in use */
|
||||||
|
#define EADDRINUSE _PDCLIB_EADDRINUSE
|
||||||
|
/* Address not available */
|
||||||
|
#define EADDRNOTAVAIL _PDCLIB_EADDRNOTAVAIL
|
||||||
|
/* Address family not supported */
|
||||||
|
#define EAFNOSUPPORT _PDCLIB_EAFNOSUPPORT
|
||||||
|
/* Resource unavailable, try again */
|
||||||
|
#define EAGAIN _PDCLIB_EAGAIN
|
||||||
|
/* Connection already in progress */
|
||||||
|
#define EALREADY _PDCLIB_EALREADY
|
||||||
|
/* Bad file descriptor */
|
||||||
|
#define EBADF _PDCLIB_EBADF
|
||||||
|
/* Bad message */
|
||||||
|
#define EBADMSG _PDCLIB_EBADMSG
|
||||||
|
/* Device or resource busy */
|
||||||
|
#define EBUSY _PDCLIB_EBUSY
|
||||||
|
/* Operation canceled */
|
||||||
|
#define ECANCELED _PDCLIB_ECANCELED
|
||||||
|
/* No child processes */
|
||||||
|
#define ECHILD _PDCLIB_ECHILD
|
||||||
|
/* Connection aborted */
|
||||||
|
#define ECONNABORTED _PDCLIB_ECONNABORTED
|
||||||
|
/* Connection refused */
|
||||||
|
#define ECONNREFUSED _PDCLIB_ECONNREFUSED
|
||||||
|
/* Connection reset */
|
||||||
|
#define ECONNRESET _PDCLIB_ECONNRESET
|
||||||
|
/* Resource deadlock would occur */
|
||||||
|
#define EDEADLK _PDCLIB_EDEADLK
|
||||||
|
/* Destination address required */
|
||||||
|
#define EDESTADDRREQ _PDCLIB_EDESTADDRREQ
|
||||||
|
/* File exists */
|
||||||
|
#define EEXIST _PDCLIB_EEXIST
|
||||||
|
/* Bad address */
|
||||||
|
#define EFAULT _PDCLIB_EFAULT
|
||||||
|
/* File too large */
|
||||||
|
#define EFBIG _PDCLIB_EFBIG
|
||||||
|
/* Host is unreachable */
|
||||||
|
#define EHOSTUNREACH _PDCLIB_EHOSTUNREACH
|
||||||
|
/* Identifier removed */
|
||||||
|
#define EIDRM _PDCLIB_EIDRM
|
||||||
|
/* Operation in progress */
|
||||||
|
#define EINPROGRESS _PDCLIB_EINPROGRESS
|
||||||
|
/* Interrupted function */
|
||||||
|
#define EINTR _PDCLIB_EINTR
|
||||||
|
/* Invalid argument */
|
||||||
|
#define EINVAL _PDCLIB_EINVAL
|
||||||
|
/* I/O error */
|
||||||
|
#define EIO _PDCLIB_EIO
|
||||||
|
/* Socket is connected */
|
||||||
|
#define EISCONN _PDCLIB_EISCONN
|
||||||
|
/* Is a directory */
|
||||||
|
#define EISDIR _PDCLIB_EISDIR
|
||||||
|
/* Too many levels of symbolic links */
|
||||||
|
#define ELOOP _PDCLIB_ELOOP
|
||||||
|
/* File descriptor value too large */
|
||||||
|
#define EMFILE _PDCLIB_EMFILE
|
||||||
|
/* Too many links */
|
||||||
|
#define EMLINK _PDCLIB_EMLINK
|
||||||
|
/* Message too large */
|
||||||
|
#define EMSGSIZE _PDCLIB_EMSGSIZE
|
||||||
|
/* Filename too long */
|
||||||
|
#define ENAMETOOLONG _PDCLIB_ENAMETOOLONG
|
||||||
|
/* Network is down */
|
||||||
|
#define ENETDOWN _PDCLIB_ENETDOWN
|
||||||
|
/* Connection aborted by network */
|
||||||
|
#define ENETRESET _PDCLIB_ENETRESET
|
||||||
|
/* Network unreachable */
|
||||||
|
#define ENETUNREACH _PDCLIB_ENETUNREACH
|
||||||
|
/* Too many files open in system */
|
||||||
|
#define ENFILE _PDCLIB_ENFILE
|
||||||
|
/* No buffer space available */
|
||||||
|
#define ENOBUFS _PDCLIB_ENOBUFS
|
||||||
|
/* No message is available on the STREAM head read queue */
|
||||||
|
#define ENODATA _PDCLIB_ENODATA
|
||||||
|
/* No such device */
|
||||||
|
#define ENODEV _PDCLIB_ENODEV
|
||||||
|
/* No such file or directory */
|
||||||
|
#define ENOENT _PDCLIB_ENOENT
|
||||||
|
/* Executable file format error */
|
||||||
|
#define ENOEXEC _PDCLIB_ENOEXEC
|
||||||
|
/* No locks available */
|
||||||
|
#define ENOLCK _PDCLIB_ENOLCK
|
||||||
|
/* Link has been severed */
|
||||||
|
#define ENOLINK _PDCLIB_ENOLINK
|
||||||
|
/* Not enough space */
|
||||||
|
#define ENOMEM _PDCLIB_ENOMEM
|
||||||
|
/* No message of the desired type */
|
||||||
|
#define ENOMSG _PDCLIB_ENOMSG
|
||||||
|
/* Protocol not available */
|
||||||
|
#define ENOPROTOOPT _PDCLIB_ENOPROTOOPT
|
||||||
|
/* No space left on device */
|
||||||
|
#define ENOSPC _PDCLIB_ENOSPC
|
||||||
|
/* No STREAM resources */
|
||||||
|
#define ENOSR _PDCLIB_ENOSR
|
||||||
|
/* Not a STREAM */
|
||||||
|
#define ENOSTR _PDCLIB_ENOSTR
|
||||||
|
/* Function not supported */
|
||||||
|
#define ENOSYS _PDCLIB_ENOSYS
|
||||||
|
/* The socket is not connected */
|
||||||
|
#define ENOTCONN _PDCLIB_ENOTCONN
|
||||||
|
/* Not a directory */
|
||||||
|
#define ENOTDIR _PDCLIB_ENOTDIR
|
||||||
|
/* Directory not empty */
|
||||||
|
#define ENOTEMPTY _PDCLIB_ENOTEMPTY
|
||||||
|
/* State not recoverable */
|
||||||
|
#define ENOTRECOVERABLE _PDCLIB_ENOTRECOVERABLE
|
||||||
|
/* Not a socket */
|
||||||
|
#define ENOTSOCK _PDCLIB_ENOTSOCK
|
||||||
|
/* Not supported */
|
||||||
|
#define ENOTSUP _PDCLIB_ENOTSUP
|
||||||
|
/* Inappropriate I/O control operation */
|
||||||
|
#define ENOTTY _PDCLIB_ENOTTY
|
||||||
|
/* No such device or address */
|
||||||
|
#define ENXIO _PDCLIB_ENXIO
|
||||||
|
/* Operation not supported on socket */
|
||||||
|
#define EOPNOTSUPP _PDCLIB_EOPNOTSUPP
|
||||||
|
/* Value too large to be stored in data type */
|
||||||
|
#define EOVERFLOW _PDCLIB_EOVERFLOW
|
||||||
|
/* Previous owner died */
|
||||||
|
#define EOWNERDEAD _PDCLIB_EOWNERDEAD
|
||||||
|
/* Operation not permitted */
|
||||||
|
#define EPERM _PDCLIB_EPERM
|
||||||
|
/* Broken pipe */
|
||||||
|
#define EPIPE _PDCLIB_EPIPE
|
||||||
|
/* Protocol error */
|
||||||
|
#define EPROTO _PDCLIB_EPROTO
|
||||||
|
/* Protocol not supported */
|
||||||
|
#define EPROTONOSUPPORT _PDCLIB_EPROTONOSUPPORT
|
||||||
|
/* Protocol wrong type for socket */
|
||||||
|
#define EPROTOTYPE _PDCLIB_EPROTOTYPE
|
||||||
|
/* Read-only file system */
|
||||||
|
#define EROFS _PDCLIB_EROFS
|
||||||
|
/* Invalid seek */
|
||||||
|
#define ESPIPE _PDCLIB_ESPIPE
|
||||||
|
/* No such process */
|
||||||
|
#define ESRCH _PDCLIB_ESRCH
|
||||||
|
/* Stream ioctl() timeout */
|
||||||
|
#define ETIME _PDCLIB_ETIME
|
||||||
|
/* Connection timed out */
|
||||||
|
#define ETIMEDOUT _PDCLIB_ETIMEDOUT
|
||||||
|
/* Text file busy */
|
||||||
|
#define ETXTBSY _PDCLIB_ETXTBSY
|
||||||
|
/* Operation would block */
|
||||||
|
#define EWOULDBLOCK _PDCLIB_EWOULDBLOCK
|
||||||
|
/* Cross-device link */
|
||||||
|
#define EXDEV _PDCLIB_EXDEV
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
#ifndef _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
#define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
typedef int errno_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_ERRNO_H
|
||||||
|
#include _PDCLIB_EXTEND_ERRNO_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
19
rocklibc/include/fcntl.h
Normal file
19
rocklibc/include/fcntl.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _FCNTL_H
|
||||||
|
#define _FCNTL_H
|
||||||
|
|
||||||
|
/* File access modes for open() */
|
||||||
|
#define O_RDONLY 00000000
|
||||||
|
#define O_WRONLY 00000001
|
||||||
|
#define O_RDWR 00000002
|
||||||
|
|
||||||
|
/* File creation flags */
|
||||||
|
#define O_CREAT 00000100
|
||||||
|
#define O_EXCL 00000200
|
||||||
|
#define O_NOCTTY 00000400
|
||||||
|
#define O_TRUNC 00001000
|
||||||
|
#define O_APPEND 00002000
|
||||||
|
#define O_NONBLOCK 00004000
|
||||||
|
|
||||||
|
#define AT_FDCWD (-100)
|
||||||
|
|
||||||
|
#endif /* _FCNTL_H */
|
||||||
82
rocklibc/include/float.h
Normal file
82
rocklibc/include/float.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/* Characteristics of floating types <float.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_FLOAT_H
|
||||||
|
#define _PDCLIB_FLOAT_H _PDCLIB_FLOAT_H
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_config.h"
|
||||||
|
|
||||||
|
#define FLT_ROUNDS _PDCLIB_FLT_ROUNDS
|
||||||
|
#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD
|
||||||
|
#define DECIMAL_DIG _PDCLIB_DECIMAL_DIG
|
||||||
|
|
||||||
|
/* Radix of exponent representation */
|
||||||
|
#define FLT_RADIX __FLT_RADIX__
|
||||||
|
/* Number of base-FLT_RADIX digits in the significand of a float */
|
||||||
|
#define FLT_MANT_DIG __FLT_MANT_DIG__
|
||||||
|
/* Number of decimal digits of precision in a float */
|
||||||
|
#define FLT_DIG __FLT_DIG__
|
||||||
|
/* Difference between 1.0 and the minimum float greater than 1.0 */
|
||||||
|
#define FLT_EPSILON __FLT_EPSILON__
|
||||||
|
/* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
|
||||||
|
#define FLT_MIN_EXP __FLT_MIN_EXP__
|
||||||
|
/* Minimum normalised float */
|
||||||
|
#define FLT_MIN __FLT_MIN__
|
||||||
|
/* Minimum int x such that 10**x is a normalised float */
|
||||||
|
#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
|
||||||
|
/* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
|
||||||
|
#define FLT_MAX_EXP __FLT_MAX_EXP__
|
||||||
|
/* Maximum float */
|
||||||
|
#define FLT_MAX __FLT_MAX__
|
||||||
|
/* Maximum int x such that 10**x is a representable float */
|
||||||
|
#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
|
||||||
|
|
||||||
|
/* Number of base-FLT_RADIX digits in the significand of a double */
|
||||||
|
#define DBL_MANT_DIG __DBL_MANT_DIG__
|
||||||
|
/* Number of decimal digits of precision in a double */
|
||||||
|
#define DBL_DIG __DBL_DIG__
|
||||||
|
/* Difference between 1.0 and the minimum double greater than 1.0 */
|
||||||
|
#define DBL_EPSILON __DBL_EPSILON__
|
||||||
|
/* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
|
||||||
|
#define DBL_MIN_EXP __DBL_MIN_EXP__
|
||||||
|
/* Minimum normalised double */
|
||||||
|
#define DBL_MIN __DBL_MIN__
|
||||||
|
/* Minimum int x such that 10**x is a normalised double */
|
||||||
|
#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
|
||||||
|
/* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
|
||||||
|
#define DBL_MAX_EXP __DBL_MAX_EXP__
|
||||||
|
/* Maximum double */
|
||||||
|
#define DBL_MAX __DBL_MAX__
|
||||||
|
/* Maximum int x such that 10**x is a representable double */
|
||||||
|
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
|
||||||
|
|
||||||
|
/* Number of base-FLT_RADIX digits in the significand of a long double */
|
||||||
|
#define LDBL_MANT_DIG __LDBL_MANT_DIG__
|
||||||
|
/* Number of decimal digits of precision in a long double */
|
||||||
|
#define LDBL_DIG __LDBL_DIG__
|
||||||
|
/* Difference between 1.0 and the minimum long double greater than 1.0 */
|
||||||
|
#define LDBL_EPSILON __LDBL_EPSILON__
|
||||||
|
/* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
|
||||||
|
#define LDBL_MIN_EXP __LDBL_MIN_EXP__
|
||||||
|
/* Minimum normalised long double */
|
||||||
|
#define LDBL_MIN __LDBL_MIN__
|
||||||
|
/* Minimum int x such that 10**x is a normalised long double */
|
||||||
|
#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
|
||||||
|
/* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
|
||||||
|
#define LDBL_MAX_EXP __LDBL_MAX_EXP__
|
||||||
|
/* Maximum long double */
|
||||||
|
#define LDBL_MAX __LDBL_MAX__
|
||||||
|
/* Maximum int x such that 10**x is a representable long double */
|
||||||
|
#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_FLOAT_H
|
||||||
|
#include _PDCLIB_EXTEND_FLOAT_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
368
rocklibc/include/inttypes.h
Normal file
368
rocklibc/include/inttypes.h
Normal file
@@ -0,0 +1,368 @@
|
|||||||
|
/* Format conversion of integer types <inttypes.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_INTTYPES_H
|
||||||
|
#define _PDCLIB_INTTYPES_H _PDCLIB_INTTYPES_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct _PDCLIB_imaxdiv_t imaxdiv_t;
|
||||||
|
|
||||||
|
/* 7.8.1 Macros for format specifiers */
|
||||||
|
|
||||||
|
/* The various leastN_t, fastN_t, intmax_t, and intptr_t types are typedefs
|
||||||
|
to native types. But the user does not know which ones, which gives some
|
||||||
|
problems when trying to *printf() / *scanf() those types. The various
|
||||||
|
macros defined below allow to give the correct conversion specifiers
|
||||||
|
without knowing the actual native type they represent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST8_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, d ) )
|
||||||
|
#define PRIiLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, i ) )
|
||||||
|
#define PRIoLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, o ) )
|
||||||
|
#define PRIuLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, u ) )
|
||||||
|
#define PRIxLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, x ) )
|
||||||
|
#define PRIXLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdLEAST8 "d"
|
||||||
|
#define PRIiLEAST8 "i"
|
||||||
|
#define PRIoLEAST8 "o"
|
||||||
|
#define PRIuLEAST8 "u"
|
||||||
|
#define PRIxLEAST8 "x"
|
||||||
|
#define PRIXLEAST8 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST8_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, d ) )
|
||||||
|
#define PRIiFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, i ) )
|
||||||
|
#define PRIoFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, o ) )
|
||||||
|
#define PRIuFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, u ) )
|
||||||
|
#define PRIxFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, x ) )
|
||||||
|
#define PRIXFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdFAST8 "d"
|
||||||
|
#define PRIiFAST8 "i"
|
||||||
|
#define PRIoFAST8 "o"
|
||||||
|
#define PRIuFAST8 "u"
|
||||||
|
#define PRIxFAST8 "x"
|
||||||
|
#define PRIXFAST8 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST16_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, d ) )
|
||||||
|
#define PRIiLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, i ) )
|
||||||
|
#define PRIoLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, o ) )
|
||||||
|
#define PRIuLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, u ) )
|
||||||
|
#define PRIxLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, x ) )
|
||||||
|
#define PRIXLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdLEAST16 "d"
|
||||||
|
#define PRIiLEAST16 "i"
|
||||||
|
#define PRIoLEAST16 "o"
|
||||||
|
#define PRIuLEAST16 "u"
|
||||||
|
#define PRIxLEAST16 "x"
|
||||||
|
#define PRIXLEAST16 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST16_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, d ) )
|
||||||
|
#define PRIiFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, i ) )
|
||||||
|
#define PRIoFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, o ) )
|
||||||
|
#define PRIuFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, u ) )
|
||||||
|
#define PRIxFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, x ) )
|
||||||
|
#define PRIXFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdFAST16 "d"
|
||||||
|
#define PRIiFAST16 "i"
|
||||||
|
#define PRIoFAST16 "o"
|
||||||
|
#define PRIuFAST16 "u"
|
||||||
|
#define PRIxFAST16 "x"
|
||||||
|
#define PRIXFAST16 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST32_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, d ) )
|
||||||
|
#define PRIiLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, i ) )
|
||||||
|
#define PRIoLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, o ) )
|
||||||
|
#define PRIuLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, u ) )
|
||||||
|
#define PRIxLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, x ) )
|
||||||
|
#define PRIXLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdLEAST32 "d"
|
||||||
|
#define PRIiLEAST32 "i"
|
||||||
|
#define PRIoLEAST32 "o"
|
||||||
|
#define PRIuLEAST32 "u"
|
||||||
|
#define PRIxLEAST32 "x"
|
||||||
|
#define PRIXLEAST32 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST32_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, d ) )
|
||||||
|
#define PRIiFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, i ) )
|
||||||
|
#define PRIoFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, o ) )
|
||||||
|
#define PRIuFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, u ) )
|
||||||
|
#define PRIxFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, x ) )
|
||||||
|
#define PRIXFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdFAST32 "d"
|
||||||
|
#define PRIiFAST32 "i"
|
||||||
|
#define PRIoFAST32 "o"
|
||||||
|
#define PRIuFAST32 "u"
|
||||||
|
#define PRIxFAST32 "x"
|
||||||
|
#define PRIXFAST32 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST64_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, d ) )
|
||||||
|
#define PRIiLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, i ) )
|
||||||
|
#define PRIoLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, o ) )
|
||||||
|
#define PRIuLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, u ) )
|
||||||
|
#define PRIxLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, x ) )
|
||||||
|
#define PRIXLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdLEAST64 "d"
|
||||||
|
#define PRIiLEAST64 "i"
|
||||||
|
#define PRIoLEAST64 "o"
|
||||||
|
#define PRIuLEAST64 "u"
|
||||||
|
#define PRIxLEAST64 "x"
|
||||||
|
#define PRIXLEAST64 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST64_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, d ) )
|
||||||
|
#define PRIiFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, i ) )
|
||||||
|
#define PRIoFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, o ) )
|
||||||
|
#define PRIuFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, u ) )
|
||||||
|
#define PRIxFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, x ) )
|
||||||
|
#define PRIXFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdFAST64 "d"
|
||||||
|
#define PRIiFAST64 "i"
|
||||||
|
#define PRIoFAST64 "o"
|
||||||
|
#define PRIuFAST64 "u"
|
||||||
|
#define PRIxFAST64 "x"
|
||||||
|
#define PRIXFAST64 "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INTMAX_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, d ) )
|
||||||
|
#define PRIiMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, i ) )
|
||||||
|
#define PRIoMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, o ) )
|
||||||
|
#define PRIuMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, u ) )
|
||||||
|
#define PRIxMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, x ) )
|
||||||
|
#define PRIXMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdMAX "d"
|
||||||
|
#define PRIiMAX "i"
|
||||||
|
#define PRIoMAX "o"
|
||||||
|
#define PRIuMAX "u"
|
||||||
|
#define PRIxMAX "x"
|
||||||
|
#define PRIXMAX "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INTPTR_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRIdPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, d ) )
|
||||||
|
#define PRIiPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, i ) )
|
||||||
|
#define PRIoPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, o ) )
|
||||||
|
#define PRIuPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, u ) )
|
||||||
|
#define PRIxPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, x ) )
|
||||||
|
#define PRIXPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, X ) )
|
||||||
|
#else
|
||||||
|
#define PRIdPTR "d"
|
||||||
|
#define PRIiPTR "i"
|
||||||
|
#define PRIoPTR "o"
|
||||||
|
#define PRIuPTR "u"
|
||||||
|
#define PRIxPTR "x"
|
||||||
|
#define PRIXPTR "X"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SCNdLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, d ) )
|
||||||
|
#define SCNiLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, i ) )
|
||||||
|
#define SCNoLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, o ) )
|
||||||
|
#define SCNuLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, u ) )
|
||||||
|
#define SCNxLEAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, d ) )
|
||||||
|
#define SCNiFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, i ) )
|
||||||
|
#define SCNoFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, o ) )
|
||||||
|
#define SCNuFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, u ) )
|
||||||
|
#define SCNxFAST8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST8_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, d ) )
|
||||||
|
#define SCNiLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, i ) )
|
||||||
|
#define SCNoLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, o ) )
|
||||||
|
#define SCNuLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, u ) )
|
||||||
|
#define SCNxLEAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, d ) )
|
||||||
|
#define SCNiFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, i ) )
|
||||||
|
#define SCNoFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, o ) )
|
||||||
|
#define SCNuFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, u ) )
|
||||||
|
#define SCNxFAST16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST16_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, d ) )
|
||||||
|
#define SCNiLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, i ) )
|
||||||
|
#define SCNoLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, o ) )
|
||||||
|
#define SCNuLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, u ) )
|
||||||
|
#define SCNxLEAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, d ) )
|
||||||
|
#define SCNiFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, i ) )
|
||||||
|
#define SCNoFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, o ) )
|
||||||
|
#define SCNuFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, u ) )
|
||||||
|
#define SCNxFAST32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST32_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, d ) )
|
||||||
|
#define SCNiLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, i ) )
|
||||||
|
#define SCNoLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, o ) )
|
||||||
|
#define SCNuLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, u ) )
|
||||||
|
#define SCNxLEAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, d ) )
|
||||||
|
#define SCNiFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, i ) )
|
||||||
|
#define SCNoFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, o ) )
|
||||||
|
#define SCNuFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, u ) )
|
||||||
|
#define SCNxFAST64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_FAST64_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, d ) )
|
||||||
|
#define SCNiMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, i ) )
|
||||||
|
#define SCNoMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, o ) )
|
||||||
|
#define SCNuMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, u ) )
|
||||||
|
#define SCNxMAX _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTMAX_PREFIX, x ) )
|
||||||
|
|
||||||
|
#define SCNdPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, d ) )
|
||||||
|
#define SCNiPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, i ) )
|
||||||
|
#define SCNoPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, o ) )
|
||||||
|
#define SCNuPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, u ) )
|
||||||
|
#define SCNxPTR _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INTPTR_PREFIX, x ) )
|
||||||
|
|
||||||
|
/* The exact-width types (int8_t, int16_t, ...) are *optional*, as not all
|
||||||
|
architectures support the necessary 8-bits-per-byte two's complement
|
||||||
|
native types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if _PDCLIB_TWOS_COMPLEMENT == 1
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST8_MAX == 0x7f
|
||||||
|
#if _PDCLIB_INT_LEAST8_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRId8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, d ) )
|
||||||
|
#define PRIi8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, i ) )
|
||||||
|
#define PRIo8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, o ) )
|
||||||
|
#define PRIu8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, u ) )
|
||||||
|
#define PRIx8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, x ) )
|
||||||
|
#define PRIX8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, X ) )
|
||||||
|
#endif
|
||||||
|
#define SCNd8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, d ) )
|
||||||
|
#define SCNi8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, i ) )
|
||||||
|
#define SCNo8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, o ) )
|
||||||
|
#define SCNu8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, u ) )
|
||||||
|
#define SCNx8 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST8_PREFIX, x ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST16_MAX == 0x7fff
|
||||||
|
#if _PDCLIB_INT_LEAST16_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRId16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, d ) )
|
||||||
|
#define PRIi16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, i ) )
|
||||||
|
#define PRIo16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, o ) )
|
||||||
|
#define PRIu16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, u ) )
|
||||||
|
#define PRIx16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, x ) )
|
||||||
|
#define PRIX16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, X ) )
|
||||||
|
#endif
|
||||||
|
#define SCNd16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, d ) )
|
||||||
|
#define SCNi16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, i ) )
|
||||||
|
#define SCNo16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, o ) )
|
||||||
|
#define SCNu16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, u ) )
|
||||||
|
#define SCNx16 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST16_PREFIX, x ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST32_MAX == 0x7fffffffl
|
||||||
|
#if _PDCLIB_INT_LEAST32_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRId32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, d ) )
|
||||||
|
#define PRIi32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, i ) )
|
||||||
|
#define PRIo32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, o ) )
|
||||||
|
#define PRIu32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, u ) )
|
||||||
|
#define PRIx32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, x ) )
|
||||||
|
#define PRIX32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, X ) )
|
||||||
|
#endif
|
||||||
|
#define SCNd32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, d ) )
|
||||||
|
#define SCNi32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, i ) )
|
||||||
|
#define SCNo32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, o ) )
|
||||||
|
#define SCNu32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, u ) )
|
||||||
|
#define SCNx32 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST32_PREFIX, x ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST64_MAX == 0x7fffffffffffffffll
|
||||||
|
#if _PDCLIB_INT_LEAST64_MAX > _PDCLIB_INT_MAX
|
||||||
|
#define PRId64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, d ) )
|
||||||
|
#define PRIi64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, i ) )
|
||||||
|
#define PRIo64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, o ) )
|
||||||
|
#define PRIu64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, u ) )
|
||||||
|
#define PRIx64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, x ) )
|
||||||
|
#define PRIX64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, X ) )
|
||||||
|
#endif
|
||||||
|
#define SCNd64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, d ) )
|
||||||
|
#define SCNi64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, i ) )
|
||||||
|
#define SCNo64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, o ) )
|
||||||
|
#define SCNu64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, u ) )
|
||||||
|
#define SCNx64 _PDCLIB_value2string( _PDCLIB_concat( _PDCLIB_INT_LEAST64_PREFIX, x ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.8.2 Functions for greatest-width integer types */
|
||||||
|
|
||||||
|
/* Calculate the absolute value of j */
|
||||||
|
_PDCLIB_PUBLIC intmax_t imaxabs( intmax_t j );
|
||||||
|
|
||||||
|
/* Return quotient (quot) and remainder (rem) of an integer division in the
|
||||||
|
imaxdiv_t struct.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom );
|
||||||
|
|
||||||
|
/* Separate the character array nptr into three parts: A (possibly empty)
|
||||||
|
sequence of whitespace characters, a character representation of an integer
|
||||||
|
to the given base, and trailing invalid characters (including the terminating
|
||||||
|
null character). If base is 0, assume it to be 10, unless the integer
|
||||||
|
representation starts with 0x / 0X (setting base to 16) or 0 (setting base to
|
||||||
|
8). If given, base can be anything from 0 to 36, using the 26 letters of the
|
||||||
|
base alphabet (both lowercase and uppercase) as digits 10 through 35.
|
||||||
|
The integer representation is then converted into the return type of the
|
||||||
|
function. It can start with a '+' or '-' sign. If the sign is '-', the result
|
||||||
|
of the conversion is negated.
|
||||||
|
If the conversion is successful, the converted value is returned. If endptr
|
||||||
|
is not a NULL pointer, a pointer to the first trailing invalid character is
|
||||||
|
returned in *endptr.
|
||||||
|
If no conversion could be performed, zero is returned (and nptr in *endptr,
|
||||||
|
if endptr is not a NULL pointer). If the converted value does not fit into
|
||||||
|
the return type, the functions return INTMAX_MIN, INTMAX_MAX, or UINTMAX_MAX,
|
||||||
|
respectively, depending on the sign of the integer representation and the
|
||||||
|
return type, and errno is set to ERANGE.
|
||||||
|
*/
|
||||||
|
/* This function is equivalent to strtol() / strtoul() in <stdlib.h>, but on
|
||||||
|
the potentially larger type.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base );
|
||||||
|
_PDCLIB_PUBLIC uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base );
|
||||||
|
|
||||||
|
/* TODO: wcstoimax(), wcstoumax() */
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_INTTYPES_H
|
||||||
|
#include _PDCLIB_EXTEND_INTTYPES_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
31
rocklibc/include/iso646.h
Normal file
31
rocklibc/include/iso646.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* Alternative spellings <iso646.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ISO646_H
|
||||||
|
#define _PDCLIB_ISO646_H _PDCLIB_ISO646_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define and &&
|
||||||
|
#define and_eq &=
|
||||||
|
#define bitand &
|
||||||
|
#define bitor |
|
||||||
|
#define compl ~
|
||||||
|
#define not !
|
||||||
|
#define not_eq !=
|
||||||
|
#define or ||
|
||||||
|
#define or_eq |=
|
||||||
|
#define xor ^
|
||||||
|
#define xor_eq ^=
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_ISO646_H
|
||||||
|
#include _PDCLIB_EXTEND_ISO646_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
50
rocklibc/include/limits.h
Normal file
50
rocklibc/include/limits.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* Sizes of integer types <limits.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_LIMITS_H
|
||||||
|
#define _PDCLIB_LIMITS_H _PDCLIB_LIMITS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* TODO: Defined to 1 as multibyte characters are not supported yet. */
|
||||||
|
#define MB_LEN_MAX 1
|
||||||
|
|
||||||
|
#define LLONG_MIN _PDCLIB_LLONG_MIN
|
||||||
|
#define LLONG_MAX _PDCLIB_LLONG_MAX
|
||||||
|
#define ULLONG_MAX _PDCLIB_ULLONG_MAX
|
||||||
|
|
||||||
|
#define CHAR_BIT _PDCLIB_CHAR_BIT
|
||||||
|
#define CHAR_MAX _PDCLIB_CHAR_MAX
|
||||||
|
#define CHAR_MIN _PDCLIB_CHAR_MIN
|
||||||
|
#define SCHAR_MAX _PDCLIB_SCHAR_MAX
|
||||||
|
#define SCHAR_MIN _PDCLIB_SCHAR_MIN
|
||||||
|
#define UCHAR_MAX _PDCLIB_UCHAR_MAX
|
||||||
|
#define SHRT_MAX _PDCLIB_SHRT_MAX
|
||||||
|
#define SHRT_MIN _PDCLIB_SHRT_MIN
|
||||||
|
#define INT_MAX _PDCLIB_INT_MAX
|
||||||
|
#define INT_MIN _PDCLIB_INT_MIN
|
||||||
|
#define LONG_MAX _PDCLIB_LONG_MAX
|
||||||
|
#define LONG_MIN _PDCLIB_LONG_MIN
|
||||||
|
#define USHRT_MAX _PDCLIB_USHRT_MAX
|
||||||
|
#define UINT_MAX _PDCLIB_UINT_MAX
|
||||||
|
#define ULONG_MAX _PDCLIB_ULONG_MAX
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_LIMITS_H
|
||||||
|
#include _PDCLIB_EXTEND_LIMITS_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
114
rocklibc/include/locale.h
Normal file
114
rocklibc/include/locale.h
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/* Localization <locale.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_LOCALE_H
|
||||||
|
#define _PDCLIB_LOCALE_H _PDCLIB_LOCALE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NULL_DEFINED
|
||||||
|
#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
|
||||||
|
#define NULL _PDCLIB_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The structure returned by localeconv().
|
||||||
|
|
||||||
|
The values for *_sep_by_space:
|
||||||
|
0 - no space
|
||||||
|
1 - if symbol and sign are adjacent, a space separates them from the value;
|
||||||
|
otherwise a space separates the symbol from the value
|
||||||
|
2 - if symbol and sign are adjacent, a space separates them; otherwise a
|
||||||
|
space separates the sign from the value
|
||||||
|
|
||||||
|
The values for *_sign_posn:
|
||||||
|
0 - Parentheses surround value and symbol
|
||||||
|
1 - sign precedes value and symbol
|
||||||
|
2 - sign succeeds value and symbol
|
||||||
|
3 - sign immediately precedes symbol
|
||||||
|
4 - sign immediately succeeds symbol
|
||||||
|
*/
|
||||||
|
struct lconv
|
||||||
|
{
|
||||||
|
char * decimal_point; /* decimal point character */ /* LC_NUMERIC */
|
||||||
|
char * thousands_sep; /* character for separating groups of digits */ /* LC_NUMERIC */
|
||||||
|
char * grouping; /* string indicating the size of digit groups */ /* LC_NUMERIC */
|
||||||
|
char * mon_decimal_point; /* decimal point for monetary quantities */ /* LC_MONETARY */
|
||||||
|
char * mon_thousands_sep; /* thousands_sep for monetary quantities */ /* LC_MONETARY */
|
||||||
|
char * mon_grouping; /* grouping for monetary quantities */ /* LC_MONETARY */
|
||||||
|
char * positive_sign; /* string indicating nonnegative mty. qty. */ /* LC_MONETARY */
|
||||||
|
char * negative_sign; /* string indicating negative mty. qty. */ /* LC_MONETARY */
|
||||||
|
char * currency_symbol; /* local currency symbol (e.g. '$') */ /* LC_MONETARY */
|
||||||
|
char * int_curr_symbol; /* international currency symbol (e.g. "USD" */ /* LC_MONETARY */
|
||||||
|
char frac_digits; /* fractional digits in local monetary qty. */ /* LC_MONETARY */
|
||||||
|
char p_cs_precedes; /* if currency_symbol precedes positive qty. */ /* LC_MONETARY */
|
||||||
|
char n_cs_precedes; /* if currency_symbol precedes negative qty. */ /* LC_MONETARY */
|
||||||
|
char p_sep_by_space; /* if it is separated by space from pos. qty. */ /* LC_MONETARY */
|
||||||
|
char n_sep_by_space; /* if it is separated by space from neg. qty. */ /* LC_MONETARY */
|
||||||
|
char p_sign_posn; /* positioning of positive_sign for mon. qty. */ /* LC_MONETARY */
|
||||||
|
char n_sign_posn; /* positioning of negative_sign for mon. qty. */ /* LC_MONETARY */
|
||||||
|
char int_frac_digits; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_p_cs_precedes; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_n_cs_precedes; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_p_sep_by_space; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_n_sep_by_space; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_p_sign_posn; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_n_sign_posn; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* First arguments to setlocale().
|
||||||
|
NOTE: If you add to / modify these, look at functions/locale/setlocale.c
|
||||||
|
and keep things in sync.
|
||||||
|
*/
|
||||||
|
/* Entire locale */
|
||||||
|
#define LC_ALL _PDCLIB_LC_ALL
|
||||||
|
/* Collation (strcoll(), strxfrm()) */
|
||||||
|
#define LC_COLLATE _PDCLIB_LC_COLLATE
|
||||||
|
/* Character types (<ctype.h>, <wctype.h>) */
|
||||||
|
#define LC_CTYPE _PDCLIB_LC_CTYPE
|
||||||
|
/* Monetary formatting (as returned by localeconv) */
|
||||||
|
#define LC_MONETARY _PDCLIB_LC_MONETARY
|
||||||
|
/* Decimal-point character (for printf() / scanf() functions), string
|
||||||
|
conversions, nonmonetary formatting as returned by localeconv
|
||||||
|
*/
|
||||||
|
#define LC_NUMERIC _PDCLIB_LC_NUMERIC
|
||||||
|
/* Time formats (strftime(), wcsftime()) */
|
||||||
|
#define LC_TIME _PDCLIB_LC_TIME
|
||||||
|
/* Messages (not specified but allowed by C99, and specified by POSIX)
|
||||||
|
(used by perror() / strerror())
|
||||||
|
*/
|
||||||
|
#define LC_MESSAGES _PDCLIB_LC_MESSAGES
|
||||||
|
|
||||||
|
/* The category parameter can be any of the LC_* macros to specify if the call
|
||||||
|
to setlocale() shall affect the entire locale or only a portion thereof.
|
||||||
|
The category locale specifies which locale should be switched to, with "C"
|
||||||
|
being the minimal default locale, and "" being the locale-specific native
|
||||||
|
environment. A NULL pointer makes setlocale() return the *current* setting.
|
||||||
|
Otherwise, returns a pointer to a string associated with the specified
|
||||||
|
category for the new locale.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * setlocale( int category, const char * locale );
|
||||||
|
|
||||||
|
/* Returns a struct lconv initialized to the values appropriate for the current
|
||||||
|
locale setting.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC struct lconv * localeconv( void );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_LOCALE_H
|
||||||
|
#include _PDCLIB_EXTEND_LOCALE_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
467
rocklibc/include/math.h
Normal file
467
rocklibc/include/math.h
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
/* Mathematics <math.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_MATH_H
|
||||||
|
#define _PDCLIB_MATH_H _PDCLIB_MATH_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
typedef float float_t;
|
||||||
|
typedef double double_t;
|
||||||
|
|
||||||
|
#define HUGE_VALF _PDCLIB_HUGE_VALF;
|
||||||
|
#define HUGE_VAL _PDCLIB_HUGE_VAL;
|
||||||
|
#define HUGE_VALL _PDCLIB_HUGE_VALL;
|
||||||
|
|
||||||
|
#define INFINITY (_PDCLIB_FLT_MAX * 2)
|
||||||
|
#define NAN ( -(0.0f / 0.0f) )
|
||||||
|
|
||||||
|
#define FP_FAST_FMAF
|
||||||
|
#define FP_FAST_FMA
|
||||||
|
#define FP_FAST_FMAL
|
||||||
|
|
||||||
|
#define FP_ILOGB0 INT_MIN
|
||||||
|
#define FP_ILOGBNAN INT_MAX
|
||||||
|
|
||||||
|
#define MATH_ERRNO 1
|
||||||
|
#define MATH_ERREXCEPT 2
|
||||||
|
|
||||||
|
#define math_errhandling
|
||||||
|
|
||||||
|
/* Classification */
|
||||||
|
|
||||||
|
/* FP_ZERO, FP_SUBNORMAL, FP_NORMAL */
|
||||||
|
#define isfinite( x ) _PDCLIB_GENERIC( isfinite, x )
|
||||||
|
|
||||||
|
/* FP_INFINITE */
|
||||||
|
#define isinf( x ) _PDCLIB_GENERIC( isinf, x )
|
||||||
|
|
||||||
|
/* FP_NAN */
|
||||||
|
#define isnan( x ) _PDCLIB_GENERIC( isnan, x )
|
||||||
|
|
||||||
|
/* FP_NORMAL */
|
||||||
|
#define isnormal( x ) _PDCLIB_GENERIC( isnormal, x )
|
||||||
|
|
||||||
|
/* Negative */
|
||||||
|
#define signbit( x ) _PDCLIB_GENERIC( signbit, x )
|
||||||
|
|
||||||
|
/* See FP_* classes */
|
||||||
|
#define fpclassify( x ) _PDCLIB_GENERIC( fpclassify, x )
|
||||||
|
|
||||||
|
#define FP_INFINITE 1
|
||||||
|
#define FP_NAN 2
|
||||||
|
#define FP_NORMAL 3
|
||||||
|
#define FP_SUBNORMAL 4
|
||||||
|
#define FP_ZERO 5
|
||||||
|
|
||||||
|
/* Trigonometric functions */
|
||||||
|
|
||||||
|
/* The principal value of the arc cosine of x.
|
||||||
|
Domain error for arguments not in the interval -1..+1.
|
||||||
|
Returns the interval 0..Pi radians.
|
||||||
|
*/
|
||||||
|
double acos( double x );
|
||||||
|
float acosf( float x );
|
||||||
|
long double acosl( long double x );
|
||||||
|
|
||||||
|
/* The principal value of the arc sine of x.
|
||||||
|
Domain error for arguments not in the interval -1..+1.
|
||||||
|
Returns the interval -Pi/2..Pi/2 radians.
|
||||||
|
*/
|
||||||
|
double asin( double x );
|
||||||
|
float asinf( float x );
|
||||||
|
long double asinl( long double x );
|
||||||
|
|
||||||
|
/* The principal value of the arc tangent of x.
|
||||||
|
Returns the interval -Pi/2..Pi/2 radians.
|
||||||
|
*/
|
||||||
|
double atan( double x );
|
||||||
|
float atanf( float x );
|
||||||
|
long double atanl( long double x );
|
||||||
|
|
||||||
|
/* The value of the arc tangent of y/x, using the signs of both
|
||||||
|
arguments to determine the quadrant of the return value.
|
||||||
|
Domain error if both arguments are zero.
|
||||||
|
Returns the interval -Pi..Pi radians.
|
||||||
|
*/
|
||||||
|
double atan2( double y, double x );
|
||||||
|
float atan2f( float y, float x );
|
||||||
|
long double atan2l( long double y, long double x );
|
||||||
|
|
||||||
|
/* Cosine of x in radians. */
|
||||||
|
double cos( double x );
|
||||||
|
float cosf( float x );
|
||||||
|
long double cosl( long double x );
|
||||||
|
|
||||||
|
/* Sine of x in radians. */
|
||||||
|
double sin( double x );
|
||||||
|
float sinf( float x );
|
||||||
|
long double sinl( long double x );
|
||||||
|
|
||||||
|
/* Tangent of x in radians. */
|
||||||
|
double tan( double x );
|
||||||
|
float tanf( float x );
|
||||||
|
long double tanl( long double x );
|
||||||
|
|
||||||
|
/* Hyperbolic functions */
|
||||||
|
|
||||||
|
/* The (nonnegative) arc hyberbolic cosine of x.
|
||||||
|
Domain error for arguments less than 1.
|
||||||
|
Returns the interval 0..INF.
|
||||||
|
*/
|
||||||
|
double acosh( double x );
|
||||||
|
float acoshf( float x );
|
||||||
|
long double acoshl( long double x );
|
||||||
|
|
||||||
|
/* The arc hyberbolic sine of x.
|
||||||
|
*/
|
||||||
|
double asinh( double x );
|
||||||
|
float asinhf( float x );
|
||||||
|
long double asinhl( long double x );
|
||||||
|
|
||||||
|
/* The arc hyberbolic tangent of x.
|
||||||
|
Domain error for arguments not in -1..1.
|
||||||
|
Range error if -1 or +1.
|
||||||
|
*/
|
||||||
|
double atanh( double x );
|
||||||
|
float atanhf( float x );
|
||||||
|
long double atanhl( long double x );
|
||||||
|
|
||||||
|
/* The hyberbolic cosine of x.
|
||||||
|
Range error if magnitude of x is too large.
|
||||||
|
*/
|
||||||
|
double cosh( double x );
|
||||||
|
float coshf( float x );
|
||||||
|
long double coshl( long double x );
|
||||||
|
|
||||||
|
/* The hyberbolic sine of x.
|
||||||
|
Range error if magnitude of x is too large.
|
||||||
|
*/
|
||||||
|
double sinh( double x );
|
||||||
|
float sinhf( float x );
|
||||||
|
long double sinhl( long double x );
|
||||||
|
|
||||||
|
/* The hyberbolic tangent of x.
|
||||||
|
Range error if magnitude of x is too large.
|
||||||
|
*/
|
||||||
|
double tanh( double x );
|
||||||
|
float tanhf( float x );
|
||||||
|
long double tanhl( long double x );
|
||||||
|
|
||||||
|
/* Exponential and logarithmic functions */
|
||||||
|
|
||||||
|
/* The base-e exponential of x.
|
||||||
|
Range error if magnitude of x is too large.
|
||||||
|
*/
|
||||||
|
double exp( double x );
|
||||||
|
float expf( float x );
|
||||||
|
long double expl( long double x );
|
||||||
|
|
||||||
|
/* The base-2 exponential of x.
|
||||||
|
Range error if magnitude of x is too large.
|
||||||
|
*/
|
||||||
|
double exp2( double x );
|
||||||
|
float exp2f( float x );
|
||||||
|
long double exp2l( long double x );
|
||||||
|
|
||||||
|
/* The base-e exponential of x, minus 1.
|
||||||
|
Range error if magnitude of x is too large.
|
||||||
|
Returns e^x - 1.
|
||||||
|
*/
|
||||||
|
double expm1( double x );
|
||||||
|
float expm1f( float x );
|
||||||
|
long double expm1l( long double x );
|
||||||
|
|
||||||
|
/* Breaks a floating-point number into a normalized fraction
|
||||||
|
and an integral power of 2 (stored in the object pointed
|
||||||
|
to by exp).
|
||||||
|
*/
|
||||||
|
double frexp( double value, int * exp );
|
||||||
|
float frexpf( float value, int * exp );
|
||||||
|
long double frexpl( long double value, int * exp );
|
||||||
|
|
||||||
|
/* Extract the exponent of x as a signed int.
|
||||||
|
* Returns FP_ILOGB0 if x is zero, INT_MAX if x is infinite,
|
||||||
|
* FP_ILOGBNAN if x is a NaN. Range error may occur if x is 0.
|
||||||
|
*/
|
||||||
|
double ilogb( double x );
|
||||||
|
float ilogbf( float x );
|
||||||
|
long double ilogbl( long double x );
|
||||||
|
|
||||||
|
/* Multiply x by 2^exp. Range error may occur. */
|
||||||
|
double ldexp( double x, int exp );
|
||||||
|
float ldexpf( float x, int exp );
|
||||||
|
long double ldexpl( long double x, int exp );
|
||||||
|
|
||||||
|
/* Compute the base-e logarithm of x.
|
||||||
|
Domain error if argument is negative.
|
||||||
|
Range error if argument is zero.
|
||||||
|
*/
|
||||||
|
double log( double x );
|
||||||
|
float logf( float x );
|
||||||
|
long double logl( long double x );
|
||||||
|
|
||||||
|
/* Compute the base-10 logarithm of x.
|
||||||
|
Domain error if argument is negative.
|
||||||
|
Range error if argument is zero.
|
||||||
|
*/
|
||||||
|
double log10( double x );
|
||||||
|
float log10f( float x );
|
||||||
|
long double log10l( long double x );
|
||||||
|
|
||||||
|
/* Compute the base-e logarithm of 1 plus x.
|
||||||
|
Domain error if argument is less than -1.
|
||||||
|
Range error if argument is -1.
|
||||||
|
*/
|
||||||
|
double log1p( double x );
|
||||||
|
float log1pf( float x );
|
||||||
|
long double log1pl( long double x );
|
||||||
|
|
||||||
|
/* Compute the base-2 logarithm of x.
|
||||||
|
Domain error if argument is negative.
|
||||||
|
Range error if argument is zero.
|
||||||
|
*/
|
||||||
|
double log2( double x );
|
||||||
|
float log2f( float x );
|
||||||
|
long double log2l( long double x );
|
||||||
|
|
||||||
|
/* Extract exponent of x, as signed integer in floating-point format.
|
||||||
|
Subnormal is treated as though normalized.
|
||||||
|
Domain error if argument is zero.
|
||||||
|
*/
|
||||||
|
double logb( double x );
|
||||||
|
float logbf( float x );
|
||||||
|
long double logbl( long double x );
|
||||||
|
|
||||||
|
/* Breaks value into integral and fractional parts, each having
|
||||||
|
the same type and sign as the argument. The integral part is
|
||||||
|
stored in the object pointed to by iptr.
|
||||||
|
*/
|
||||||
|
double modf( double value, double * exp );
|
||||||
|
float modff( float value, float * exp );
|
||||||
|
long double modfl( long double value, long double * exp );
|
||||||
|
|
||||||
|
/* Compute x * FLT_RADIX^n efficiently. Range error may occur. */
|
||||||
|
double scalbn( double x, int n );
|
||||||
|
float scalbnf( float x, int n );
|
||||||
|
long double scalbnl( long double x, int n );
|
||||||
|
|
||||||
|
double scalbln( double x, long int * n );
|
||||||
|
float scalblnf( float x, long int * n );
|
||||||
|
long double scalblnl( long double x, long int * n );
|
||||||
|
|
||||||
|
/* Power and absolute-value functions */
|
||||||
|
|
||||||
|
/* Returns x^1/3. */
|
||||||
|
double cbrt( double x );
|
||||||
|
float cbrtf( float x );
|
||||||
|
long double cbrtl( long double x );
|
||||||
|
|
||||||
|
/* Returns absolute value of x. */
|
||||||
|
double fabs( double x );
|
||||||
|
float fabsf( float x );
|
||||||
|
long double fabsl( long double x );
|
||||||
|
|
||||||
|
/* Returns square root of the sum of squares of x and y.
|
||||||
|
Range error may occur.
|
||||||
|
*/
|
||||||
|
double hypot( double x, double y );
|
||||||
|
float hypotf( float x, float y );
|
||||||
|
long double hypotl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Returns x^y.
|
||||||
|
Domain error if x is finite and negative and y is finite and not
|
||||||
|
an integer value.
|
||||||
|
Domain error if x is zero and y is less or equal zero.
|
||||||
|
Range error may occur.
|
||||||
|
*/
|
||||||
|
double pow( double x, double y );
|
||||||
|
float powf( float x, float y );
|
||||||
|
long double powl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Returns x^1/2. */
|
||||||
|
double sqrt( double x );
|
||||||
|
float sqrtf( float x );
|
||||||
|
long double sqrtl( long double x );
|
||||||
|
|
||||||
|
/* Error and gamma functions */
|
||||||
|
|
||||||
|
/* Compute the error function of x. */
|
||||||
|
double erf( double x );
|
||||||
|
float erff( float x );
|
||||||
|
long double erfl( long double x );
|
||||||
|
|
||||||
|
/* Compute the complementary error function of x.
|
||||||
|
Range error if x is too large.
|
||||||
|
*/
|
||||||
|
double erfc( double x );
|
||||||
|
float erfcf( float x );
|
||||||
|
long double erfcl( long double x );
|
||||||
|
|
||||||
|
/* Compute the natural logarithm of the absolute value of gamma(x).
|
||||||
|
Range error if x is too lange, x is negative, or zero.
|
||||||
|
*/
|
||||||
|
double lgamma( double x );
|
||||||
|
float lgammaf( float x );
|
||||||
|
long double lgammal( long double x );
|
||||||
|
|
||||||
|
/* Compute the gamma function of x.
|
||||||
|
Range error if x is negative, or zero, too large or too small.
|
||||||
|
*/
|
||||||
|
double tgamma( double x );
|
||||||
|
float tgammaf( float x );
|
||||||
|
long double tgammal( long double x );
|
||||||
|
|
||||||
|
/* Nearest integer functions */
|
||||||
|
|
||||||
|
/* The smallest integer no less than x. */
|
||||||
|
double ceil( double x );
|
||||||
|
float ceilf( float x );
|
||||||
|
long double ceill( long double x );
|
||||||
|
|
||||||
|
/* The largest integer no greater than x. */
|
||||||
|
double floor( double x );
|
||||||
|
float floorf( float x );
|
||||||
|
long double floorl( long double x );
|
||||||
|
|
||||||
|
/* Round in current rounding direction. No "inexact" exception. */
|
||||||
|
double nearbyint( double x );
|
||||||
|
float nearbyintf( float x );
|
||||||
|
long double nearbyintl( long double x );
|
||||||
|
|
||||||
|
/* Round in current rounding direction. Raises "inexact" exception. */
|
||||||
|
double rint( double x );
|
||||||
|
float rintf( float x );
|
||||||
|
long double rintl( long double x );
|
||||||
|
|
||||||
|
/* Round in current rounding direction.
|
||||||
|
Range error if magnitude is too large.
|
||||||
|
*/
|
||||||
|
long int lrint( double x );
|
||||||
|
long int lrintf( float x );
|
||||||
|
long int lrintl( long double x );
|
||||||
|
long long int llrint( double x );
|
||||||
|
long long int llrintf( float x );
|
||||||
|
long long int llrintl( long double x );
|
||||||
|
|
||||||
|
/* Round to nearest, breaking ties away from zero. */
|
||||||
|
double round( double x );
|
||||||
|
float roundf( float x );
|
||||||
|
long double roundl( long double x );
|
||||||
|
|
||||||
|
/* Round to nearest, breaking ties away from zero.
|
||||||
|
Range error if magnitude is too large.
|
||||||
|
*/
|
||||||
|
long int lround( double x );
|
||||||
|
long int lroundf( float x );
|
||||||
|
long int lroundl( long double x );
|
||||||
|
long long int llround( double x );
|
||||||
|
long long int llroundf( float x );
|
||||||
|
long long int llroundl( long double x );
|
||||||
|
|
||||||
|
/* Round toward zero. */
|
||||||
|
double trunc( double x );
|
||||||
|
float truncf( float x );
|
||||||
|
long double truncl( long double x );
|
||||||
|
|
||||||
|
/* Remainder functions */
|
||||||
|
|
||||||
|
/* Compute the remainder of x / y. */
|
||||||
|
double fmod( double x, double y );
|
||||||
|
float fmodf( float x, float y );
|
||||||
|
long double fmodl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Compute the remainder of x REM y. */
|
||||||
|
double remainder( double x, double y );
|
||||||
|
float remainderf( float x, float y );
|
||||||
|
long double remainderl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Compute the remainder of x REM y. In quo store a value with
|
||||||
|
the sign of the quotient and magnitude congruent mod 2^n to
|
||||||
|
the magnitude of the integral quotient of x / y, with n
|
||||||
|
an implementation-defined integer greater than or equal to 3.
|
||||||
|
*/
|
||||||
|
double rmquo( double x, double y );
|
||||||
|
float rmquof( float x, float y );
|
||||||
|
long double rmquol( long double x, long double y );
|
||||||
|
|
||||||
|
/* Manipulation functions */
|
||||||
|
|
||||||
|
/* Returns a value with magnitude of x and sign of y. */
|
||||||
|
double copysign( double x, double y );
|
||||||
|
float copysignf( float x, float y );
|
||||||
|
long double copysignl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Returns a NaN value with the given n-char sequence. */
|
||||||
|
double nan( const char * tagp );
|
||||||
|
float nanf( const char * tagp );
|
||||||
|
long double nanl( const char * tagp );
|
||||||
|
|
||||||
|
/* Determine the next representable value after x in direction y.
|
||||||
|
Range error if result is not representable.
|
||||||
|
*/
|
||||||
|
double nextafter( double x, double y );
|
||||||
|
float nextafterf( float x, float y );
|
||||||
|
long double nextafterl( long double x, long double y );
|
||||||
|
|
||||||
|
/* As nextafter but with long double as second parameter. */
|
||||||
|
double nexttoward( double x, double y );
|
||||||
|
float nexttowardf( float x, float y );
|
||||||
|
long double nexttowardl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Maximum, minimum, and positive difference functions */
|
||||||
|
|
||||||
|
/* Positive difference. */
|
||||||
|
double fdim( double x, double y );
|
||||||
|
float fdimf( float x, float y );
|
||||||
|
long double fdiml( long double x, long double y );
|
||||||
|
|
||||||
|
/* Maximum. */
|
||||||
|
double fmax( double x, double y );
|
||||||
|
float fmaxf( float x, float y );
|
||||||
|
long double fmaxl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Minimum. */
|
||||||
|
double fmin( double x, double y );
|
||||||
|
float fminf( float x, float y );
|
||||||
|
long double fminl( long double x, long double y );
|
||||||
|
|
||||||
|
/* Multiply-add. */
|
||||||
|
double fma( double x, double y, double z );
|
||||||
|
float fmaf( float x, float y, float z );
|
||||||
|
long double fmal( long double x, long double y, long double z );
|
||||||
|
|
||||||
|
/* Comparison macros (without "invalid" FP exception) */
|
||||||
|
|
||||||
|
#define isgreater( x, y )
|
||||||
|
|
||||||
|
#define isgreaterequal( x, y )
|
||||||
|
|
||||||
|
#define isless( x, y )
|
||||||
|
|
||||||
|
#define islessequal( x, y )
|
||||||
|
|
||||||
|
#define islessgreater( x, y )
|
||||||
|
|
||||||
|
#define isunordered( x, y )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_MATH_H
|
||||||
|
#include _PDCLIB_EXTEND_MATH_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
915
rocklibc/include/pdclib/_PDCLIB_config.h
Normal file
915
rocklibc/include/pdclib/_PDCLIB_config.h
Normal file
@@ -0,0 +1,915 @@
|
|||||||
|
/* Internal PDCLib configuration <_PDCLIB_config.h>
|
||||||
|
("Example" platform target, for PDCLib development)
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_CONFIG_H
|
||||||
|
#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Misc */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Helper macros also documented in _PDCLIB_internal.h, but defined here as */
|
||||||
|
/* they are needed in this file already. */
|
||||||
|
/* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending. */
|
||||||
|
/* _PDCLIB_concat( x, y ) concatenates two preprocessor tokens with extending */
|
||||||
|
#define _PDCLIB_cc( x, y ) x ## y
|
||||||
|
#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
|
||||||
|
|
||||||
|
/* exit() can signal success to the host environment by the value of zero or */
|
||||||
|
/* the constant EXIT_SUCCESS. Failure is signaled by EXIT_FAILURE. Note that */
|
||||||
|
/* any other return value is "implementation-defined", i.e. your environment */
|
||||||
|
/* is not required to handle it gracefully. Set your definitions here. */
|
||||||
|
#define _PDCLIB_SUCCESS 0
|
||||||
|
#define _PDCLIB_FAILURE -1
|
||||||
|
|
||||||
|
/* qsort() in <stdlib.h> requires a function that swaps two memory areas. */
|
||||||
|
/* Below is a naive implementation that can be improved significantly for */
|
||||||
|
/* specific platforms, e.g. by swapping int instead of char. */
|
||||||
|
#define _PDCLIB_memswp( i, j, size ) \
|
||||||
|
char tmp; \
|
||||||
|
do { \
|
||||||
|
tmp = *i; \
|
||||||
|
*i++ = *j; \
|
||||||
|
*j++ = tmp; \
|
||||||
|
} while ( --size );
|
||||||
|
|
||||||
|
/* Define this to some compiler directive that can be written after the */
|
||||||
|
/* parameter list of a function declaration to indicate the function does */
|
||||||
|
/* never return. If your compiler does not support such a directive, define */
|
||||||
|
/* to nothing. (This is to avoid warnings with the exit functions under GCC */
|
||||||
|
/* when compiling with C99/C++ settings, where C11 _Noreturn is unavailable.) */
|
||||||
|
#define _PDCLIB_NORETURN __attribute__(( noreturn ))
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Symbol Visibility */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This defines _PDCLIB_PUBLIC to indicate external linkage, and _PDCLIB_LOCAL
|
||||||
|
to indicate local linkage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _PDCLIB_STATIC_DEFINE
|
||||||
|
#define _PDCLIB_PUBLIC
|
||||||
|
#define _PDCLIB_LOCAL
|
||||||
|
#else
|
||||||
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
#ifdef _PDCLIB_BUILD
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _PDCLIB_PUBLIC __attribute__ ((dllexport))
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_PUBLIC __declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _PDCLIB_PUBLIC __attribute__ ((dllimport))
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_PUBLIC __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#define _PDCLIB_LOCAL
|
||||||
|
#else
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define _PDCLIB_PUBLIC __attribute__ ((visibility ("default")))
|
||||||
|
#define _PDCLIB_LOCAL __attribute__ ((visibility ("hidden")))
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_PUBLIC
|
||||||
|
#define _PDCLIB_LOCAL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Integers */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* The defines below make use of predefines offered by GCC and clang. If you */
|
||||||
|
/* adapt PDCLib for a different compiler family, you will have to use what */
|
||||||
|
/* that compiler provides, or enter actual values. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* At the point of writing, PDCLib makes no provisions for, nor has it been */
|
||||||
|
/* tested, on a platform that uses signed magnitude or one's complement to */
|
||||||
|
/* encode its integers. Most importantly, there are no guarantees that the */
|
||||||
|
/* negative zero of those encodings is in any form handled gracefully. */
|
||||||
|
#define _PDCLIB_TWOS_COMPLEMENT 1
|
||||||
|
|
||||||
|
/* 1234 for little endian, 4321 for big endian; other types not supported. */
|
||||||
|
#define _PDCLIB_ENDIANESS __BYTE_ORDER__
|
||||||
|
|
||||||
|
/* Calculation of a minimum value from a given maximum for two's complement. */
|
||||||
|
/* (For convenience only, used only in this header file below.) */
|
||||||
|
#define _PDCLIB_MIN_CALC( max ) ( ( - max ) - 1 )
|
||||||
|
|
||||||
|
/* Now, introducting the various predefines to the _PDCLIB_* namespace, so */
|
||||||
|
/* the rest of PDCLib can work with that and adapting to a different compiler */
|
||||||
|
/* will require changes only in this one file. */
|
||||||
|
|
||||||
|
/* Bits in a char */
|
||||||
|
#define _PDCLIB_CHAR_BIT __CHAR_BIT__
|
||||||
|
|
||||||
|
/* Maximum and minimum values of signed / unsigned char */
|
||||||
|
#define _PDCLIB_SCHAR_MAX __SCHAR_MAX__
|
||||||
|
#define _PDCLIB_SCHAR_MIN _PDCLIB_MIN_CALC( __SCHAR_MAX__ )
|
||||||
|
#define _PDCLIB_UCHAR_MAX ( __SCHAR_MAX__ * 2 + 1 )
|
||||||
|
|
||||||
|
/* Whether the 'char' type is unsigned */
|
||||||
|
#ifdef __CHAR_UNSIGNED__
|
||||||
|
#define _PDCLIB_CHAR_MAX _PDCLIB_UCHAR_MAX
|
||||||
|
#define _PDCLIB_CHAR_MIN 0
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_CHAR_MAX _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_CHAR_MIN _PDCLIB_SCHAR_MIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maximum and minimum values of signed / unsigned short */
|
||||||
|
#define _PDCLIB_SHRT_MAX __SHRT_MAX__
|
||||||
|
#define _PDCLIB_SHRT_MIN _PDCLIB_MIN_CALC( __SHRT_MAX__ )
|
||||||
|
#define _PDCLIB_USHRT_MAX ( __SHRT_MAX__ * 2u + 1 )
|
||||||
|
|
||||||
|
/* Maximum and minimum values of signed / unsigned int */
|
||||||
|
#define _PDCLIB_INT_MAX __INT_MAX__
|
||||||
|
#define _PDCLIB_INT_MIN _PDCLIB_MIN_CALC( __INT_MAX__ )
|
||||||
|
#define _PDCLIB_UINT_MAX ( __INT_MAX__ * 2u + 1 )
|
||||||
|
|
||||||
|
/* Maximum and minimum values of signed / unsigned long */
|
||||||
|
#define _PDCLIB_LONG_MAX __LONG_MAX__
|
||||||
|
#define _PDCLIB_LONG_MIN _PDCLIB_MIN_CALC( __LONG_MAX__ )
|
||||||
|
#define _PDCLIB_ULONG_MAX ( __LONG_MAX__ * 2ul + 1 )
|
||||||
|
|
||||||
|
/* Maximum and minimum values of signed / unsigned long long */
|
||||||
|
#define _PDCLIB_LLONG_MAX __LONG_LONG_MAX__
|
||||||
|
#define _PDCLIB_LLONG_MIN _PDCLIB_MIN_CALC( __LONG_LONG_MAX__ )
|
||||||
|
#define _PDCLIB_ULLONG_MAX ( __LONG_LONG_MAX__ * 2ull + 1 )
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* <stdint.h> defines a set of integer types that are of a minimum width, and */
|
||||||
|
/* "usually fastest" on the system. (If, for example, accessing a single char */
|
||||||
|
/* requires the CPU to access a complete int and then mask out the char, the */
|
||||||
|
/* "usually fastest" type of at least 8 bits would be int, not char.) */
|
||||||
|
/* If you do not have information on the relative performance of the types, */
|
||||||
|
/* the standard allows you to define any type that meets minimum width and */
|
||||||
|
/* signedness requirements. */
|
||||||
|
/* The first define is the appropriate basic type (e.g. "long int"), second */
|
||||||
|
/* its max value, the third its min value (both expressed in the given type). */
|
||||||
|
/* The same follows for the unsigned type (for which the minimum value is */
|
||||||
|
/* obviously zero and need not be defined). */
|
||||||
|
/* There *are* predefines provided for the printf()/scanf() length specifiers */
|
||||||
|
/* but tunneling them through here would have added many lines of repetitive */
|
||||||
|
/* and mostly redundant defines. They are determined in <_PDCLIB_internal.h>. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* int_fast8_t / uint_fast8_t */
|
||||||
|
#define _PDCLIB_int_fast8_t __INT_FAST8_TYPE__
|
||||||
|
#define _PDCLIB_INT_FAST8_MAX __INT_FAST8_MAX__
|
||||||
|
#define _PDCLIB_INT_FAST8_MIN _PDCLIB_MIN_CALC( __INT_FAST8_MAX__ )
|
||||||
|
#define _PDCLIB_uint_fast8_t __UINT_FAST8_TYPE__
|
||||||
|
#define _PDCLIB_UINT_FAST8_MAX __UINT_FAST8_MAX__
|
||||||
|
|
||||||
|
/* int_least8_t / uint_least8_t */
|
||||||
|
#define _PDCLIB_int_least8_t __INT_LEAST8_TYPE__
|
||||||
|
#define _PDCLIB_INT_LEAST8_MAX __INT_LEAST8_MAX__
|
||||||
|
#define _PDCLIB_INT_LEAST8_MIN _PDCLIB_MIN_CALC( __INT_LEAST8_MAX__ )
|
||||||
|
#define _PDCLIB_uint_least8_t __UINT_LEAST8_TYPE__
|
||||||
|
#define _PDCLIB_UINT_LEAST8_MAX __UINT_LEAST8_MAX__
|
||||||
|
|
||||||
|
/* int_fast16_t / uint_fast16_t */
|
||||||
|
#define _PDCLIB_int_fast16_t __INT_FAST16_TYPE__
|
||||||
|
#define _PDCLIB_INT_FAST16_MAX __INT_FAST16_MAX__
|
||||||
|
#define _PDCLIB_INT_FAST16_MIN _PDCLIB_MIN_CALC( __INT_FAST16_MAX__ )
|
||||||
|
#define _PDCLIB_uint_fast16_t __UINT_FAST16_TYPE__
|
||||||
|
#define _PDCLIB_UINT_FAST16_MAX __UINT_FAST16_MAX__
|
||||||
|
|
||||||
|
/* int_least16_t / uint_least16_t */
|
||||||
|
#define _PDCLIB_int_least16_t __INT_LEAST16_TYPE__
|
||||||
|
#define _PDCLIB_INT_LEAST16_MAX __INT_LEAST16_MAX__
|
||||||
|
#define _PDCLIB_INT_LEAST16_MIN _PDCLIB_MIN_CALC( __INT_LEAST16_MAX__ )
|
||||||
|
#define _PDCLIB_uint_least16_t __UINT_LEAST16_TYPE__
|
||||||
|
#define _PDCLIB_UINT_LEAST16_MAX __UINT_LEAST16_MAX__
|
||||||
|
|
||||||
|
/* int_fast32_t / uint_fast32_t */
|
||||||
|
#define _PDCLIB_int_fast32_t __INT_FAST32_TYPE__
|
||||||
|
#define _PDCLIB_INT_FAST32_MAX __INT_FAST32_MAX__
|
||||||
|
#define _PDCLIB_INT_FAST32_MIN _PDCLIB_MIN_CALC( __INT_FAST32_MAX__ )
|
||||||
|
#define _PDCLIB_uint_fast32_t __UINT_FAST32_TYPE__
|
||||||
|
#define _PDCLIB_UINT_FAST32_MAX __UINT_FAST32_MAX__
|
||||||
|
|
||||||
|
/* int_least32_t / uint_least32_t */
|
||||||
|
#define _PDCLIB_int_least32_t __INT_LEAST32_TYPE__
|
||||||
|
#define _PDCLIB_INT_LEAST32_MAX __INT_LEAST32_MAX__
|
||||||
|
#define _PDCLIB_INT_LEAST32_MIN _PDCLIB_MIN_CALC( __INT_LEAST32_MAX__ )
|
||||||
|
#define _PDCLIB_uint_least32_t __UINT_LEAST32_TYPE__
|
||||||
|
#define _PDCLIB_UINT_LEAST32_MAX __UINT_LEAST32_MAX__
|
||||||
|
|
||||||
|
/* int_fast64_t / uint_fast64_t */
|
||||||
|
#define _PDCLIB_int_fast64_t __INT_FAST64_TYPE__
|
||||||
|
#define _PDCLIB_INT_FAST64_MAX __INT_FAST64_MAX__
|
||||||
|
#define _PDCLIB_INT_FAST64_MIN _PDCLIB_MIN_CALC( __INT_FAST64_MAX__ )
|
||||||
|
#define _PDCLIB_uint_fast64_t __UINT_FAST64_TYPE__
|
||||||
|
#define _PDCLIB_UINT_FAST64_MAX __UINT_FAST64_MAX__
|
||||||
|
|
||||||
|
/* int_least64_t / uint_least64_t */
|
||||||
|
#define _PDCLIB_int_least64_t __INT_LEAST64_TYPE__
|
||||||
|
#define _PDCLIB_INT_LEAST64_MAX __INT_LEAST64_MAX__
|
||||||
|
#define _PDCLIB_INT_LEAST64_MIN _PDCLIB_MIN_CALC( __INT_LEAST64_MAX__ )
|
||||||
|
#define _PDCLIB_uint_least64_t __UINT_LEAST64_TYPE__
|
||||||
|
#define _PDCLIB_UINT_LEAST64_MAX __UINT_LEAST64_MAX__
|
||||||
|
|
||||||
|
/* Exact-width integer types. These are *optional*. If your platform does not */
|
||||||
|
/* support types of these exact widths in two's complement encoding, just */
|
||||||
|
/* leave them undefined. */
|
||||||
|
#define _PDCLIB_int8_t __INT8_TYPE__
|
||||||
|
#define _PDCLIB_int16_t __INT16_TYPE__
|
||||||
|
#define _PDCLIB_int32_t __INT32_TYPE__
|
||||||
|
#define _PDCLIB_int64_t __INT64_TYPE__
|
||||||
|
#define _PDCLIB_uint8_t __UINT8_TYPE__
|
||||||
|
#define _PDCLIB_uint16_t __UINT16_TYPE__
|
||||||
|
#define _PDCLIB_uint32_t __UINT32_TYPE__
|
||||||
|
#define _PDCLIB_uint64_t __UINT64_TYPE__
|
||||||
|
|
||||||
|
/* INTn_C / UINTn_C macros to define int_leastN_t / uint_leastN_t literals. */
|
||||||
|
#if defined( __INT8_C )
|
||||||
|
/* GCC */
|
||||||
|
#define _PDCLIB_INT_LEAST8_C __INT8_C
|
||||||
|
#define _PDCLIB_UINT_LEAST8_C __UINT8_C
|
||||||
|
#define _PDCLIB_INT_LEAST16_C __INT16_C
|
||||||
|
#define _PDCLIB_UINT_LEAST16_C __UINT16_C
|
||||||
|
#define _PDCLIB_INT_LEAST32_C __INT32_C
|
||||||
|
#define _PDCLIB_UINT_LEAST32_C __UINT32_C
|
||||||
|
#define _PDCLIB_INT_LEAST64_C __INT64_C
|
||||||
|
#define _PDCLIB_UINT_LEAST64_C __UINT64_C
|
||||||
|
#elif defined( __INT8_C_SUFFIX__ )
|
||||||
|
/* Clang */
|
||||||
|
#define _PDCLIB_INT_LEAST8_C(c) _PDCLIB_concat( c, __INT8_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_UINT_LEAST8_C(c) _PDCLIB_concat( c, __UINT8_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_INT_LEAST16_C(c) _PDCLIB_concat( c, __INT16_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_UINT_LEAST16_C(c) _PDCLIB_concat( c, __UINT16_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_INT_LEAST32_C(c) _PDCLIB_concat( c, __INT32_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_UINT_LEAST32_C(c) _PDCLIB_concat( c, __UINT32_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_INT_LEAST64_C(c) _PDCLIB_concat( c, __INT64_C_SUFFIX__ )
|
||||||
|
#define _PDCLIB_UINT_LEAST64_C(c) _PDCLIB_concat( c, __UINT64_C_SUFFIX__ )
|
||||||
|
#else
|
||||||
|
#error Please create your own _PDCLIB_config.h. Using the existing one as-is will not work. (Unsupported *INTn_C macros.)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* <stdlib.h> defines the div() function family that allows taking quotient */
|
||||||
|
/* and remainder of an integer division in one operation. Many platforms */
|
||||||
|
/* support this in hardware / opcode, and the standard permits ordering of */
|
||||||
|
/* the return structure in any way to fit the hardware. That is why those */
|
||||||
|
/* structs can be configured here. */
|
||||||
|
|
||||||
|
struct _PDCLIB_div_t
|
||||||
|
{
|
||||||
|
int quot;
|
||||||
|
int rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_ldiv_t
|
||||||
|
{
|
||||||
|
long int quot;
|
||||||
|
long int rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lldiv_t
|
||||||
|
{
|
||||||
|
long long int quot;
|
||||||
|
long long int rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* What follows are a couple of "special" typedefs and their limits. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The result type of substracting two pointers */
|
||||||
|
#define _PDCLIB_ptrdiff_t __PTRDIFF_TYPE__
|
||||||
|
#define _PDCLIB_PTRDIFF_MAX __PTRDIFF_MAX__
|
||||||
|
#define _PDCLIB_PTRDIFF_MIN _PDCLIB_MIN_CALC( __PTRDIFF_MAX__ )
|
||||||
|
|
||||||
|
/* An integer type that can be accessed as atomic entity (think asynchronous */
|
||||||
|
/* interrupts). In a freestanding environment, the type itself need not be */
|
||||||
|
/* defined, but its limits must. (Don't ask.) GCC is so kind to predefine it, */
|
||||||
|
/* but clang is only giving us its MAX value, so we use that to identify the */
|
||||||
|
/* type in _PDCLIB_int.h if the type definition is unavailable. */
|
||||||
|
#ifdef __SIG_ATOMIC_TYPE__
|
||||||
|
#define _PDCLIB_sig_atomic_t __SIG_ATOMIC_TYPE__
|
||||||
|
#endif
|
||||||
|
#define _PDCLIB_SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
|
||||||
|
#define _PDCLIB_SIG_ATOMIC_MIN _PDCLIB_MIN_CALC( __SIG_ATOMIC_MAX__ )
|
||||||
|
|
||||||
|
/* Result type of the 'sizeof' operator (must be unsigned). */
|
||||||
|
/* Note: In <stdint.h>, this is taken as the base for RSIZE_MAX, the limit */
|
||||||
|
/* for the bounds-checking interfaces of Annex K. The recommendation by the */
|
||||||
|
/* standard is to use ( SIZE_MAX >> 1 ) when "targeting machines with large */
|
||||||
|
/* addess spaces", whereas small address spaces should use SIZE_MAX directly. */
|
||||||
|
#define _PDCLIB_size_t __SIZE_TYPE__
|
||||||
|
#define _PDCLIB_SIZE_MAX __SIZE_MAX__
|
||||||
|
|
||||||
|
/* Large enough an integer to hold all character codes of the widest */
|
||||||
|
/* supported locale. */
|
||||||
|
#define _PDCLIB_wchar_t __WCHAR_TYPE__
|
||||||
|
#define _PDCLIB_WCHAR_MAX __WCHAR_MAX__
|
||||||
|
#define _PDCLIB_WCHAR_MIN __WCHAR_MIN__
|
||||||
|
|
||||||
|
/* Large enough an integer to hold all character codes of the widest */
|
||||||
|
/* supported locale plus WEOF (which needs not to be equal to EOF, nor needs */
|
||||||
|
/* to be of negative value). */
|
||||||
|
#define _PDCLIB_wint_t __WINT_TYPE__
|
||||||
|
#define _PDCLIB_WINT_MAX __WINT_MAX__
|
||||||
|
#define _PDCLIB_WINT_MIN __WINT_MIN__
|
||||||
|
|
||||||
|
/* Integer types capable of taking the (cast) value of a void *, and having */
|
||||||
|
/* the value cast back to void *, comparing equal to the original. */
|
||||||
|
#define _PDCLIB_intptr_t __INTPTR_TYPE__
|
||||||
|
#define _PDCLIB_INTPTR_MAX __INTPTR_MAX__
|
||||||
|
#define _PDCLIB_INTPTR_MIN _PDCLIB_MIN_CALC( __INTPTR_MAX__ )
|
||||||
|
#define _PDCLIB_uintptr_t __UINTPTR_TYPE__
|
||||||
|
#define _PDCLIB_UINTPTR_MAX __UINTPTR_MAX__
|
||||||
|
|
||||||
|
/* Largest supported integer type. Implementation note: see _PDCLIB_atomax(). */
|
||||||
|
#define _PDCLIB_intmax_t __INTMAX_TYPE__
|
||||||
|
#define _PDCLIB_INTMAX_MAX __INTMAX_MAX__
|
||||||
|
#define _PDCLIB_INTMAX_MIN _PDCLIB_MIN_CALC( __INTMAX_MAX__ )
|
||||||
|
#define _PDCLIB_INTMAX_C __INTMAX_C
|
||||||
|
#define _PDCLIB_uintmax_t __UINTMAX_TYPE__
|
||||||
|
#define _PDCLIB_UINTMAX_MAX __UINTMAX_MAX__
|
||||||
|
#define _PDCLIB_UINTMAX_C __UINTMAX_C
|
||||||
|
|
||||||
|
/* <inttypes.h> defines imaxdiv(), which is equivalent to the div() function */
|
||||||
|
/* family (see further above) with intmax_t as basis. */
|
||||||
|
struct _PDCLIB_imaxdiv_t
|
||||||
|
{
|
||||||
|
_PDCLIB_intmax_t quot;
|
||||||
|
_PDCLIB_intmax_t rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Time types, limits, constants, and paths */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* _PDCLIB_time is the type for type_t; _PDCLIB_clock for clock_t. Both types */
|
||||||
|
/* are defined as "real types capable of representing times". The "range and */
|
||||||
|
/* precision of times representable" is implementation-defined. */
|
||||||
|
|
||||||
|
/* For clock_t, the standard defines that dividing the result of clock() by */
|
||||||
|
/* CLOCKS_PER_SEC gives the seconds elapsed. */
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#define _PDCLIB_clock_t unsigned long
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_clock_t long
|
||||||
|
#endif
|
||||||
|
#define _PDCLIB_CLOCKS_PER_SEC 1000000
|
||||||
|
|
||||||
|
/* For time_t, no such divider exists. Most implementations use a count of */
|
||||||
|
/* seconds since a specified epoch. While PDCLib really should support other */
|
||||||
|
/* encodings as well, for now "count of seconds" is the only supported one. */
|
||||||
|
/* MIN / MAX values for time_t are not required by the standard (and they are */
|
||||||
|
/* not "exported" from the _PDCLIB namespace), but they are useful in support */
|
||||||
|
/* of the _tzcode implementation. */
|
||||||
|
#ifdef __MINGW64__
|
||||||
|
#define _PDCLIB_time_t long long
|
||||||
|
#define _PDCLIB_TIME_MAX __LONG_LONG_MAX__
|
||||||
|
#define _PDCLIB_TIME_MIN _PDCLIB_MIN_CALC( __LONG_LONG_MAX__ )
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_time_t long
|
||||||
|
#define _PDCLIB_TIME_MAX __LONG_MAX__
|
||||||
|
#define _PDCLIB_TIME_MIN _PDCLIB_MIN_CALC( __LONG_MAX__ )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* "Unix time" uses 1970-01-01T00:00:00 as "epoch". If your system uses a */
|
||||||
|
/* different "zero point" for its timestamps, set this to the offset between */
|
||||||
|
/* your epoch and Unix epoch. (For example, NTP uses 1900-01-01T00:00:00 as */
|
||||||
|
/* epoch, giving an offset of (70 * 365 + 17) * 86400 = 220898800 seconds.) */
|
||||||
|
#define _PDCLIB_EPOCH_BIAS INT64_C( 0 )
|
||||||
|
|
||||||
|
/* Leave this alone for now. */
|
||||||
|
#define _PDCLIB_TIME_UTC 1
|
||||||
|
|
||||||
|
/* Path to TZ data. */
|
||||||
|
/* IMPORTANT: *Must* end with separator character! */
|
||||||
|
/* It does make it much easier for the time data handling code if this detail */
|
||||||
|
/* can be relied upon and need not be handled in code. */
|
||||||
|
#define _PDCLIB_TZDIR "/usr/share/zoneinfo/"
|
||||||
|
|
||||||
|
/* Path to default (local) timezone */
|
||||||
|
#define _PDCLIB_TZDEFAULT "/etc/localtime"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Floating Point */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Whether the implementation rounds toward zero (0), to nearest (1), toward */
|
||||||
|
/* positive infinity (2), or toward negative infinity (3). (-1) signifies */
|
||||||
|
/* indeterminable rounding, any other value implementation-specific rounding. */
|
||||||
|
#define _PDCLIB_FLT_ROUNDS -1
|
||||||
|
|
||||||
|
/* Check <float.h> for explanations on each of these values. */
|
||||||
|
#define _PDCLIB_FLT_EVAL_METHOD __FLT_EVAL_METHOD__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_HAS_SUBNORM __FLT_HAS_DENORM__
|
||||||
|
#define _PDCLIB_DBL_HAS_SUBNORM __DBL_HAS_DENORM__
|
||||||
|
#define _PDCLIB_LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_RADIX __FLT_RADIX__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MANT_DIG __FLT_MANT_DIG__
|
||||||
|
#define _PDCLIB_DBL_MANT_DIG __DBL_MANT_DIG__
|
||||||
|
#define _PDCLIB_LDBL_MANT_DIG __LDBL_MANT_DIG__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
|
||||||
|
#define _PDCLIB_DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
|
||||||
|
#define _PDCLIB_LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
|
||||||
|
|
||||||
|
#define _PDCLIB_DECIMAL_DIG __DECIMAL_DIG__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_DIG __FLT_DIG__
|
||||||
|
#define _PDCLIB_DBL_DIG __DBL_DIG__
|
||||||
|
#define _PDCLIB_LDBL_DIG __LDBL_DIG__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MIN_EXP __FLT_MIN_EXP__
|
||||||
|
#define _PDCLIB_DBL_MIN_EXP __DBL_MIN_EXP__
|
||||||
|
#define _PDCLIB_LDBL_MIN_EXP __LDBL_MIN_EXP__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MIN_10_EXP __FLT_MIN_10_EXP__
|
||||||
|
#define _PDCLIB_DBL_MIN_10_EXP __DBL_MIN_10_EXP__
|
||||||
|
#define _PDCLIB_LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MAX_EXP __FLT_MAX_EXP__
|
||||||
|
#define _PDCLIB_DBL_MAX_EXP __DBL_MAX_EXP__
|
||||||
|
#define _PDCLIB_LDBL_MAX_EXP __LDBL_MAX_EXP__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MAX_10_EXP __FLT_MAX_10_EXP__
|
||||||
|
#define _PDCLIB_DBL_MAX_10_EXP __DBL_MAX_10_EXP__
|
||||||
|
#define _PDCLIB_LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MAX __FLT_MAX__
|
||||||
|
#define _PDCLIB_DBL_MAX __DBL_MAX__
|
||||||
|
#define _PDCLIB_LDBL_MAX __LDBL_MAX__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_EPSILON __FLT_EPSILON__
|
||||||
|
#define _PDCLIB_DBL_EPSILON __DBL_EPSILON__
|
||||||
|
#define _PDCLIB_LDBL_EPSILON __LDBL_EPSILON__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_MIN __FLT_MIN__
|
||||||
|
#define _PDCLIB_DBL_MIN __DBL_MIN__
|
||||||
|
#define _PDCLIB_LDBL_MIN __LDBL_MIN__
|
||||||
|
|
||||||
|
#define _PDCLIB_FLT_TRUE_MIN __FLT_DENORM_MIN__
|
||||||
|
#define _PDCLIB_DBL_TRUE_MIN __DBL_DENORM_MIN__
|
||||||
|
#define _PDCLIB_LDBL_TRUE_MIN __LDBL_DENORM_MIN__
|
||||||
|
|
||||||
|
/* Macros for deconstructing floating point values */
|
||||||
|
/* This assumes that the floating point value has been memcpy'd into an array */
|
||||||
|
/* of _PDCLIB_bigint_digit_t (see _PDCLIB_bigint_from_*dbl.c with the array */
|
||||||
|
/* passed to the macro as parameter. */
|
||||||
|
#define _PDCLIB_FLT_SIGN( data ) ( ( data[1] & 0x8000 ) >> 15 )
|
||||||
|
#define _PDCLIB_FLT_EXP( data ) ( ( data[1] & 0x7f80 ) >> 7 )
|
||||||
|
#define _PDCLIB_FLT_SIZE( data ) ( data[1] &= 0x007f, 2 )
|
||||||
|
|
||||||
|
#define _PDCLIB_DBL_SIGN( data ) ( ( data[3] & 0x8000 ) >> 15 )
|
||||||
|
#define _PDCLIB_DBL_EXP( data ) ( ( data[3] & 0x7ff0u ) >> 4 )
|
||||||
|
#define _PDCLIB_DBL_SIZE( data ) ( data[3] &= 0x000fu, 4 )
|
||||||
|
|
||||||
|
/* Most platforms today use IEEE 754 single precision for 'float', and double */
|
||||||
|
/* precision for 'double'. But type 'long double' varies. We use what the */
|
||||||
|
/* compiler states about LDBL_MANT_DIG to determine the type. */
|
||||||
|
#if _PDCLIB_LDBL_MANT_DIG == 64
|
||||||
|
|
||||||
|
/* Intel "Extended Precision" format, using 80 bits (64bit mantissa) */
|
||||||
|
#define _PDCLIB_LDBL_SIGN( data ) ( ( data[4] & 0x8000u ) >> 15 )
|
||||||
|
#define _PDCLIB_LDBL_EXP( data ) ( data[4] & 0x7fffu )
|
||||||
|
#define _PDCLIB_LDBL_SIZE( data ) ( data[3] &= 0x7fffu, 4 )
|
||||||
|
|
||||||
|
#elif _PDCLIB_LDBL_MANT_DIG == 113
|
||||||
|
|
||||||
|
/* IEEE "Quadruple Precision" format, using 128 bits (113bit mantissa) */
|
||||||
|
#define _PDCLIB_LDBL_SIGN( data ) ( ( data[7] & 0x8000u ) >> 15 )
|
||||||
|
#define _PDCLIB_LDBL_EXP( data ) ( data[7] & 0x7fffu )
|
||||||
|
#define _PDCLIB_LDBL_SIZE( data ) 7
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* IEEE "Double Precision" format, using 64 bits (53bit mantissa) */
|
||||||
|
/* (Same as DBL above) */
|
||||||
|
#define _PDCLIB_LDBL_SIGN( data ) ( ( data[3] & 0x8000 ) >> 15 )
|
||||||
|
#define _PDCLIB_LDBL_EXP( data ) ( ( data[3] & 0x7ff0u ) >> 4 )
|
||||||
|
#define _PDCLIB_LDBL_SIZE( data ) ( data[3] &= 0x000fu, 4 )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Given the definitions for *_MANT_START above, which resolve to "pointer
|
||||||
|
to most dignificant byte of mantissa", the operand to use to get at the
|
||||||
|
less significant bytes. (That would be - for i386, x86_64, and ARM.)
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_FLT_OP -
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Big Integer Arithmetic */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* In support of the floating point converstions required by printf() etc., */
|
||||||
|
/* PDCLib provides rudimentary big integer arithmetics. The _PDCLIB_bigint_t */
|
||||||
|
/* type stores values in a sequence of integer "digits", which may be of any */
|
||||||
|
/* uint_leastN_t type with N being 32 or 16. Note that multiplication and */
|
||||||
|
/* division require the help of the next larger type. So set the define to */
|
||||||
|
/* 32 if efficient 64bit integer arithmetics are available on your platform, */
|
||||||
|
/* and to 16 otherwise. */
|
||||||
|
/* (The value range of _PDCLIB_bigint_t is not affected by this setting.) */
|
||||||
|
|
||||||
|
#define _PDCLIB_BIGINT_DIGIT_BITS 16
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Platform-dependent macros defined by the standard headers. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The offsetof macro */
|
||||||
|
/* Contract: Expand to an integer constant expression of type size_t, which */
|
||||||
|
/* represents the offset in bytes to the structure member from the beginning */
|
||||||
|
/* of the structure. If the specified member is a bitfield, behaviour is */
|
||||||
|
/* undefined. */
|
||||||
|
/* There is no standard-compliant way to do this. */
|
||||||
|
/* This implementation casts an integer zero to 'pointer to type', and then */
|
||||||
|
/* takes the address of member. This is undefined behaviour but should work */
|
||||||
|
/* on most compilers. */
|
||||||
|
#define _PDCLIB_offsetof( type, member ) ( (size_t) &( ( (type *) 0 )->member ) )
|
||||||
|
|
||||||
|
/* Variable Length Parameter List Handling (<stdarg.h>) */
|
||||||
|
/* The macros defined by <stdarg.h> are highly dependent on the calling */
|
||||||
|
/* conventions used, and you probably have to replace them with builtins of */
|
||||||
|
/* your compiler. */
|
||||||
|
|
||||||
|
#if defined( __i386 )
|
||||||
|
|
||||||
|
/* The following generic implementation works only for pure stack-based */
|
||||||
|
/* architectures, and only if arguments are aligned to pointer type. Credits */
|
||||||
|
/* to Michael Moody, who contributed this to the Public Domain. */
|
||||||
|
|
||||||
|
/* Internal helper macro. va_round is not part of <stdarg.h>. */
|
||||||
|
#define _PDCLIB_va_round( type ) ( (sizeof(type) + sizeof(void *) - 1) & ~(sizeof(void *) - 1) )
|
||||||
|
|
||||||
|
typedef char * _PDCLIB_va_list;
|
||||||
|
#define _PDCLIB_va_arg( ap, type ) ( (ap) += (_PDCLIB_va_round(type)), ( *(type*) ( (ap) - (_PDCLIB_va_round(type)) ) ) )
|
||||||
|
#define _PDCLIB_va_copy( dest, src ) ( (dest) = (src), (void)0 )
|
||||||
|
#define _PDCLIB_va_end( ap ) ( (ap) = (void *)0, (void)0 )
|
||||||
|
#define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 )
|
||||||
|
|
||||||
|
#elif defined( __x86_64 ) || defined( __arm__ ) || defined( __ARM_NEON )
|
||||||
|
|
||||||
|
/* No way to cover x86_64 or arm with a generic implementation, as it uses */
|
||||||
|
/* register-based parameter passing. Using compiler builtins here. */
|
||||||
|
typedef __builtin_va_list _PDCLIB_va_list;
|
||||||
|
#define _PDCLIB_va_arg( ap, type ) ( __builtin_va_arg( ap, type ) )
|
||||||
|
#define _PDCLIB_va_copy( dest, src ) ( __builtin_va_copy( dest, src ) )
|
||||||
|
#define _PDCLIB_va_end( ap ) ( __builtin_va_end( ap ) )
|
||||||
|
#define _PDCLIB_va_start( ap, parmN ) ( __builtin_va_start( ap, parmN ) )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Please create your own _PDCLIB_config.h. Using the existing one as-is will not work. (Unsupported varargs.)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* OS "glue", part 1 */
|
||||||
|
/* These are values and data type definitions that you would have to adapt to */
|
||||||
|
/* the capabilities and requirements of your OS. */
|
||||||
|
/* The actual *functions* of the OS interface are declared in _PDCLIB_glue.h. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* I/O ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The type of the file descriptor returned by _PDCLIB_open(), i.e. whatever */
|
||||||
|
/* the underlying kernel uses for stream identification. */
|
||||||
|
typedef int _PDCLIB_fd_t;
|
||||||
|
|
||||||
|
/* The value of type _PDCLIB_fd_t returned by _PDCLIB_open() if the operation */
|
||||||
|
/* failed. */
|
||||||
|
#define _PDCLIB_NOHANDLE ( (_PDCLIB_fd_t) -1 )
|
||||||
|
|
||||||
|
/* The default size for file buffers. Must be at least 256. */
|
||||||
|
#define _PDCLIB_BUFSIZ 1024
|
||||||
|
|
||||||
|
/* The minimum number of files the implementation guarantees can opened */
|
||||||
|
/* simultaneously. Must be at least 8. Depends largely on how the platform */
|
||||||
|
/* does the bookkeeping in whatever is called by _PDCLIB_open(). PDCLib puts */
|
||||||
|
/* no further limits on the number of open files other than available memory. */
|
||||||
|
#define _PDCLIB_FOPEN_MAX 8
|
||||||
|
|
||||||
|
/* Length of the longest filename the implementation guarantees to support. */
|
||||||
|
#define _PDCLIB_FILENAME_MAX 128
|
||||||
|
|
||||||
|
/* Maximum length of filenames generated by tmpnam(). (See tmpfile.c.) */
|
||||||
|
#define _PDCLIB_L_tmpnam 52
|
||||||
|
|
||||||
|
/* Number of distinct file names that can be generated by tmpnam(). */
|
||||||
|
#define _PDCLIB_TMP_MAX 50
|
||||||
|
|
||||||
|
/* The values of SEEK_SET, SEEK_CUR and SEEK_END, used by fseek(). */
|
||||||
|
/* Since at least one platform (POSIX) uses the same symbols for its own */
|
||||||
|
/* "seek" function, you should use whatever the host defines (if it does */
|
||||||
|
/* define them). */
|
||||||
|
#define _PDCLIB_SEEK_SET 0
|
||||||
|
#define _PDCLIB_SEEK_CUR 1
|
||||||
|
#define _PDCLIB_SEEK_END 2
|
||||||
|
|
||||||
|
/* The number of characters that can be buffered with ungetc(). The standard */
|
||||||
|
/* guarantees only one (1); PDCLib supports larger values, but applications */
|
||||||
|
/* relying on this would rely on implementation-defined behaviour (not good). */
|
||||||
|
#define _PDCLIB_UNGETCBUFSIZE 1
|
||||||
|
|
||||||
|
/* The number of functions that can be registered with atexit(). Needs to be */
|
||||||
|
/* at least 33 (32 guaranteed by the standard, plus _PDCLIB_closeall() which */
|
||||||
|
/* is used internally by PDCLib to close all open streams). */
|
||||||
|
/* TODO: Should expand dynamically. */
|
||||||
|
#define _PDCLIB_ATEXIT_SLOTS 40
|
||||||
|
|
||||||
|
/* errno -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* These are the values that _PDCLIB_errno can be set to by the library. */
|
||||||
|
/* */
|
||||||
|
/* By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is */
|
||||||
|
/* capable of "translating" between errno values used by the hosting OS and */
|
||||||
|
/* those used and passed out by the library. */
|
||||||
|
/* */
|
||||||
|
/* Example: In the example platform, the remove() function uses the unlink() */
|
||||||
|
/* system call as backend. Linux sets its errno to EISDIR if you try to */
|
||||||
|
/* unlink() a directory, but POSIX demands EPERM. Within the remove() */
|
||||||
|
/* function, you can catch 'errno == EISDIR', and set '*_PDCLIB_errno_func() */
|
||||||
|
/* = _PDCLIB_EPERM'. Anyone using PDCLib's <errno.h> will "see" EPERM instead */
|
||||||
|
/* of EISDIR. */
|
||||||
|
/* */
|
||||||
|
/* If you do not want that kind of translation, you might want to "match" the */
|
||||||
|
/* values used by PDCLib with those used by the host OS, to avoid confusion. */
|
||||||
|
/* auxiliary/errno/errno_readout.c provides a convenience program to read */
|
||||||
|
/* those errno values mandated by the standard from a platform's <errno.h>, */
|
||||||
|
/* giving output that can readily be pasted here. */
|
||||||
|
/* Either way, note that the list below, the list in PDCLib's <errno.h>, and */
|
||||||
|
/* the list in _PDCLIB_stdinit.h, need to be kept in sync. */
|
||||||
|
/* */
|
||||||
|
/* The values below are read from a Linux system. */
|
||||||
|
|
||||||
|
/* Argument list too long */
|
||||||
|
#define _PDCLIB_E2BIG 7
|
||||||
|
/* Permission denied */
|
||||||
|
#define _PDCLIB_EACCES 13
|
||||||
|
/* Address in use */
|
||||||
|
#define _PDCLIB_EADDRINUSE 98
|
||||||
|
/* Address not available */
|
||||||
|
#define _PDCLIB_EADDRNOTAVAIL 99
|
||||||
|
/* Address family not supported */
|
||||||
|
#define _PDCLIB_EAFNOSUPPORT 97
|
||||||
|
/* Resource unavailable, try again */
|
||||||
|
#define _PDCLIB_EAGAIN 11
|
||||||
|
/* Connection already in progress */
|
||||||
|
#define _PDCLIB_EALREADY 114
|
||||||
|
/* Bad file descriptor */
|
||||||
|
#define _PDCLIB_EBADF 9
|
||||||
|
/* Bad message */
|
||||||
|
#define _PDCLIB_EBADMSG 74
|
||||||
|
/* Device or resource busy */
|
||||||
|
#define _PDCLIB_EBUSY 16
|
||||||
|
/* Operation canceled */
|
||||||
|
#define _PDCLIB_ECANCELED 125
|
||||||
|
/* No child processes */
|
||||||
|
#define _PDCLIB_ECHILD 10
|
||||||
|
/* Connection aborted */
|
||||||
|
#define _PDCLIB_ECONNABORTED 103
|
||||||
|
/* Connection refused */
|
||||||
|
#define _PDCLIB_ECONNREFUSED 111
|
||||||
|
/* Connection reset */
|
||||||
|
#define _PDCLIB_ECONNRESET 104
|
||||||
|
/* Resource deadlock would occur */
|
||||||
|
#define _PDCLIB_EDEADLK 35
|
||||||
|
/* Destination address required */
|
||||||
|
#define _PDCLIB_EDESTADDRREQ 89
|
||||||
|
/* Mathematics argument out of domain of function */
|
||||||
|
#define _PDCLIB_EDOM 33
|
||||||
|
/* File exists */
|
||||||
|
#define _PDCLIB_EEXIST 17
|
||||||
|
/* Bad address */
|
||||||
|
#define _PDCLIB_EFAULT 14
|
||||||
|
/* File too large */
|
||||||
|
#define _PDCLIB_EFBIG 27
|
||||||
|
/* Host is unreachable */
|
||||||
|
#define _PDCLIB_EHOSTUNREACH 113
|
||||||
|
/* Identifier removed */
|
||||||
|
#define _PDCLIB_EIDRM 43
|
||||||
|
/* Illegal byte sequence */
|
||||||
|
#define _PDCLIB_EILSEQ 84
|
||||||
|
/* Operation in progress */
|
||||||
|
#define _PDCLIB_EINPROGRESS 115
|
||||||
|
/* Interrupted function */
|
||||||
|
#define _PDCLIB_EINTR 4
|
||||||
|
/* Invalid argument */
|
||||||
|
#define _PDCLIB_EINVAL 22
|
||||||
|
/* I/O error */
|
||||||
|
#define _PDCLIB_EIO 5
|
||||||
|
/* Socket is connected */
|
||||||
|
#define _PDCLIB_EISCONN 106
|
||||||
|
/* Is a directory */
|
||||||
|
#define _PDCLIB_EISDIR 21
|
||||||
|
/* Too many levels of symbolic links */
|
||||||
|
#define _PDCLIB_ELOOP 40
|
||||||
|
/* File descriptor value too large */
|
||||||
|
#define _PDCLIB_EMFILE 24
|
||||||
|
/* Too many links */
|
||||||
|
#define _PDCLIB_EMLINK 31
|
||||||
|
/* Message too large */
|
||||||
|
#define _PDCLIB_EMSGSIZE 90
|
||||||
|
/* Filename too long */
|
||||||
|
#define _PDCLIB_ENAMETOOLONG 36
|
||||||
|
/* Network is down */
|
||||||
|
#define _PDCLIB_ENETDOWN 100
|
||||||
|
/* Connection aborted by network */
|
||||||
|
#define _PDCLIB_ENETRESET 102
|
||||||
|
/* Network unreachable */
|
||||||
|
#define _PDCLIB_ENETUNREACH 101
|
||||||
|
/* Too many files open in system */
|
||||||
|
#define _PDCLIB_ENFILE 23
|
||||||
|
/* No buffer space available */
|
||||||
|
#define _PDCLIB_ENOBUFS 105
|
||||||
|
/* No message is available on the STREAM head read queue */
|
||||||
|
#define _PDCLIB_ENODATA 61
|
||||||
|
/* No such device */
|
||||||
|
#define _PDCLIB_ENODEV 19
|
||||||
|
/* No such file or directory */
|
||||||
|
#define _PDCLIB_ENOENT 2
|
||||||
|
/* Executable file format error */
|
||||||
|
#define _PDCLIB_ENOEXEC 8
|
||||||
|
/* No locks available */
|
||||||
|
#define _PDCLIB_ENOLCK 37
|
||||||
|
/* Link has been severed */
|
||||||
|
#define _PDCLIB_ENOLINK 67
|
||||||
|
/* Not enough space */
|
||||||
|
#define _PDCLIB_ENOMEM 12
|
||||||
|
/* No message of the desired type */
|
||||||
|
#define _PDCLIB_ENOMSG 42
|
||||||
|
/* Protocol not available */
|
||||||
|
#define _PDCLIB_ENOPROTOOPT 92
|
||||||
|
/* No space left on device */
|
||||||
|
#define _PDCLIB_ENOSPC 28
|
||||||
|
/* No STREAM resources */
|
||||||
|
#define _PDCLIB_ENOSR 63
|
||||||
|
/* Not a STREAM */
|
||||||
|
#define _PDCLIB_ENOSTR 60
|
||||||
|
/* Function not supported */
|
||||||
|
#define _PDCLIB_ENOSYS 38
|
||||||
|
/* The socket is not connected */
|
||||||
|
#define _PDCLIB_ENOTCONN 107
|
||||||
|
/* Not a directory */
|
||||||
|
#define _PDCLIB_ENOTDIR 20
|
||||||
|
/* Directory not empty */
|
||||||
|
#define _PDCLIB_ENOTEMPTY 39
|
||||||
|
/* State not recoverable */
|
||||||
|
#define _PDCLIB_ENOTRECOVERABLE 131
|
||||||
|
/* Not a socket */
|
||||||
|
#define _PDCLIB_ENOTSOCK 88
|
||||||
|
/* Not supported */
|
||||||
|
#define _PDCLIB_ENOTSUP 95
|
||||||
|
/* Inappropriate I/O control operation */
|
||||||
|
#define _PDCLIB_ENOTTY 25
|
||||||
|
/* No such device or address */
|
||||||
|
#define _PDCLIB_ENXIO 6
|
||||||
|
/* Operation not supported on socket */
|
||||||
|
#define _PDCLIB_EOPNOTSUPP 95
|
||||||
|
/* Value too large to be stored in data type */
|
||||||
|
#define _PDCLIB_EOVERFLOW 75
|
||||||
|
/* Previous owner died */
|
||||||
|
#define _PDCLIB_EOWNERDEAD 130
|
||||||
|
/* Operation not permitted */
|
||||||
|
#define _PDCLIB_EPERM 1
|
||||||
|
/* Broken pipe */
|
||||||
|
#define _PDCLIB_EPIPE 32
|
||||||
|
/* Protocol error */
|
||||||
|
#define _PDCLIB_EPROTO 71
|
||||||
|
/* Protocol not supported */
|
||||||
|
#define _PDCLIB_EPROTONOSUPPORT 93
|
||||||
|
/* Protocol wrong type for socket */
|
||||||
|
#define _PDCLIB_EPROTOTYPE 91
|
||||||
|
/* Result too large */
|
||||||
|
#define _PDCLIB_ERANGE 34
|
||||||
|
/* Read-only file system */
|
||||||
|
#define _PDCLIB_EROFS 30
|
||||||
|
/* Invalid seek */
|
||||||
|
#define _PDCLIB_ESPIPE 29
|
||||||
|
/* No such process */
|
||||||
|
#define _PDCLIB_ESRCH 3
|
||||||
|
/* Stream ioctl() timeout */
|
||||||
|
#define _PDCLIB_ETIME 62
|
||||||
|
/* Connection timed out */
|
||||||
|
#define _PDCLIB_ETIMEDOUT 110
|
||||||
|
/* Text file busy */
|
||||||
|
#define _PDCLIB_ETXTBSY 26
|
||||||
|
/* Operation would block */
|
||||||
|
#define _PDCLIB_EWOULDBLOCK 11
|
||||||
|
/* Cross-device link */
|
||||||
|
#define _PDCLIB_EXDEV 18
|
||||||
|
|
||||||
|
/* The highest defined errno value, plus one. This is used to set the size */
|
||||||
|
/* of the array in struct _PDCLIB_lc_text_t holding error messages for the */
|
||||||
|
/* strerror() and perror() functions. (If you change this value because you */
|
||||||
|
/* are using additional errno values, you *HAVE* to provide appropriate error */
|
||||||
|
/* messages for *ALL* locales.) */
|
||||||
|
#define _PDCLIB_ERRNO_MAX 132
|
||||||
|
|
||||||
|
/* The error message used for unknown error codes (generated by errno_readout */
|
||||||
|
/* for consistency between the 'holes' in the list of defined error messages */
|
||||||
|
/* and the text generated by e.g. strerror() for out-of-range error values.) */
|
||||||
|
#define _PDCLIB_EUNKNOWN_TEXT (char*)"unknown error"
|
||||||
|
|
||||||
|
/* locale data -------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The default path where PDCLib should look for its locale data. */
|
||||||
|
/* Must end with the appropriate separator character. */
|
||||||
|
#define _PDCLIB_LOCALE_PATH "/usr/share/pdclib/i18n/"
|
||||||
|
|
||||||
|
/* The name of the environment variable that can be used to override that */
|
||||||
|
/* path setting. */
|
||||||
|
#define _PDCLIB_LOCALE_PATH_ENV PDCLIB_I18N
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
typedef unsigned int wint_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* threads ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/* This is relying on underlying <pthread.h> implementation to provide thread */
|
||||||
|
/* support. */
|
||||||
|
/* The problem here is we cannot just #include <pthread.h> and access the */
|
||||||
|
/* original definitions. The standard library must not drag identifiers into */
|
||||||
|
/* the user's namespace, so we have to set our own definitions in the _PDCLIB */
|
||||||
|
/* namespace. Which are, obviously, platform-specific. */
|
||||||
|
/* If you do NOT want to provide threads support, define __STDC_NO_THREADS__ */
|
||||||
|
/* to 1 and simply delete the threads.h header and the corresponding files in */
|
||||||
|
/* functions/threads/. This makes PDCLib non-thread-safe (obviously), as the */
|
||||||
|
/* safeguards against race conditions (e.g. in <stdio.h>) will be omitted. */
|
||||||
|
|
||||||
|
/* auxiliary/pthread/pthread_readout.c provides a convenience program to read */
|
||||||
|
/* appropriate definitions from a platform's <pthread.h>, giving output that */
|
||||||
|
/* can be copy & pasted here. */
|
||||||
|
|
||||||
|
#define __STDC_NO_THREADS__
|
||||||
|
|
||||||
|
#ifndef __STDC_NO_THREADS__
|
||||||
|
|
||||||
|
typedef unsigned long int _PDCLIB_thrd_t;
|
||||||
|
typedef union { unsigned char _PDCLIB_cnd_t_data[ 48 ]; long long int _PDCLIB_cnd_t_align; } _PDCLIB_cnd_t;
|
||||||
|
#if defined( __arm__ ) || defined( __ARM_NEON )
|
||||||
|
typedef union { unsigned char _PDCLIB_mtx_t_data[ 24 ]; long int _PDCLIB_mtx_t_align; } _PDCLIB_mtx_t;
|
||||||
|
#else
|
||||||
|
typedef union { unsigned char _PDCLIB_mtx_t_data[ 40 ]; long int _PDCLIB_mtx_t_align; } _PDCLIB_mtx_t;
|
||||||
|
#endif
|
||||||
|
typedef unsigned int _PDCLIB_tss_t;
|
||||||
|
typedef int _PDCLIB_once_flag;
|
||||||
|
#define _PDCLIB_ONCE_FLAG_INIT 0
|
||||||
|
#define _PDCLIB_RECURSIVE_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
|
||||||
|
/* This one is actually hidden in <limits.h>, and only if __USE_POSIX is */
|
||||||
|
/* defined prior to #include <limits.h> (PTHREAD_DESTRUCTOR_ITERATIONS). */
|
||||||
|
#define _PDCLIB_TSS_DTOR_ITERATIONS 4
|
||||||
|
/* The following are not made public in any header, but used internally for */
|
||||||
|
/* interfacing with the pthread API. */
|
||||||
|
typedef union { unsigned char _PDCLIB_cnd_attr_t_data[ 4 ]; int _PDCLIB_cnd_attr_t_align; } _PDCLIB_cnd_attr_t;
|
||||||
|
typedef union { unsigned char _PDCLIB_mtx_attr_t_data[ 4 ]; int _PDCLIB_mtx_attr_t_align; } _PDCLIB_mtx_attr_t;
|
||||||
|
#if defined( __arm__ ) || defined( __ARM_NEON )
|
||||||
|
typedef union { unsigned char _PDCLIB_thrd_attr_t_data[ 36 ]; long int _PDCLIB_thrd_attr_t_align; } _PDCLIB_thrd_attr_t;
|
||||||
|
#else
|
||||||
|
typedef union { unsigned char _PDCLIB_thrd_attr_t_data[ 56 ]; long int _PDCLIB_thrd_attr_t_align; } _PDCLIB_thrd_attr_t;
|
||||||
|
#endif
|
||||||
|
/* Static initialization of recursive mutex. */
|
||||||
|
#if defined( __arm__ ) || defined( __ARM_NEON )
|
||||||
|
#define _PDCLIB_MTX_RECURSIVE_INIT { {\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||||
|
/* Static initialization of plain / timeout mutex (identical with pthread). */
|
||||||
|
#define _PDCLIB_MTX_PLAIN_INIT { {\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_MTX_RECURSIVE_INIT { {\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||||
|
/* Static initialization of plain / timeout mutex (identical with pthread). */
|
||||||
|
#define _PDCLIB_MTX_PLAIN_INIT { {\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Termux defines atexit in crtbegin_so.o leading to a multiple definition */
|
||||||
|
/* error from the linker. This is a crude workaround, which does NOT fix */
|
||||||
|
/* various run-time issues on Termux likely also related to crt linkage. But */
|
||||||
|
/* at least things compile OK, and SOME tests can be run. */
|
||||||
|
#if defined( __ARM_NEON )
|
||||||
|
#define atexit _PDCLIB_atexit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
29
rocklibc/include/pdclib/_PDCLIB_defguard.h
Normal file
29
rocklibc/include/pdclib/_PDCLIB_defguard.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/* Definition guard <_PDCLIB_defguard.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_DEFGUARD_H
|
||||||
|
#define _PDCLIB_DEFGUARD_H _PDCLIB_DEFGUARD_H
|
||||||
|
|
||||||
|
#if defined( __ANDROID__ )
|
||||||
|
/* typedef sigset_t */
|
||||||
|
#include "bits/signal_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Linux defines its own version of struct timespec (from <time.h>) in
|
||||||
|
some internal header (depending on clib implementation), which leads
|
||||||
|
to problems when accessing e.g. sys/time.h (type redefinition).
|
||||||
|
The solution is to set the Linux header's include guard (to avoid
|
||||||
|
Linux' definition), and to include PDCLib's <time.h> to define the
|
||||||
|
type unambiguously.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _TIMESPEC_DEFINED
|
||||||
|
#define _SYS__TIMESPEC_H_
|
||||||
|
#define _STRUCT_TIMESPEC
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
93
rocklibc/include/pdclib/_PDCLIB_glue.h
Normal file
93
rocklibc/include/pdclib/_PDCLIB_glue.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/* OS glue functions declaration <_PDCLIB_glue.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_GLUE_H
|
||||||
|
#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* OS "glue", part 2 */
|
||||||
|
/* These are the functions you will have to touch, as they are where PDCLib */
|
||||||
|
/* interfaces with the operating system. */
|
||||||
|
/* They operate on data types partially defined by _PDCLIB_config.h. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* stdlib.h */
|
||||||
|
|
||||||
|
/* A system call that terminates the calling process, returning a given status
|
||||||
|
to the environment.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL _PDCLIB_Noreturn void _PDCLIB_Exit( int status ) _PDCLIB_NORETURN;
|
||||||
|
|
||||||
|
|
||||||
|
/* stdio.h */
|
||||||
|
|
||||||
|
/* A system call that opens a file identified by name in a given mode. Return
|
||||||
|
a file descriptor uniquely identifying that file.
|
||||||
|
(The mode is the return value of the _PDCLIB_filemode() function.)
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL _PDCLIB_fd_t _PDCLIB_open( const char * const filename, unsigned int mode );
|
||||||
|
|
||||||
|
/* A system call that writes a stream's buffer.
|
||||||
|
Returns 0 on success, EOF on write error.
|
||||||
|
Sets stream error flags and errno appropriately on error.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* A system call that fills a stream's buffer.
|
||||||
|
Returns 0 on success, EOF on read error / EOF.
|
||||||
|
Sets stream EOF / error flags and errno appropriately on error.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* A system call that repositions within a file. Returns new offset on success,
|
||||||
|
-1 / errno on error.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL _PDCLIB_int_least64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int_least64_t offset, int whence );
|
||||||
|
|
||||||
|
/* A system call that closes a file identified by given file descriptor. Return
|
||||||
|
zero on success, non-zero otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_close( _PDCLIB_fd_t fd );
|
||||||
|
|
||||||
|
/* A system call that changes the mode of a given stream to that passed as
|
||||||
|
argument (the argument being the value returned by _PDCLIB_filemode()),
|
||||||
|
*without* closing the stream. See comments in example implementation
|
||||||
|
for details. Return zero if the requested mode change is not supported
|
||||||
|
for this stream and freopen() should try to close and reopen the stream;
|
||||||
|
return INT_MIN if the change is not supported and freopen() should close
|
||||||
|
and NOT try to close / reopen (i.e., fail). Return any other value on
|
||||||
|
success.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_changemode( struct _PDCLIB_file_t * stream, unsigned int mode );
|
||||||
|
|
||||||
|
/* A system call that returns a canonicalized absolute filename in
|
||||||
|
dynamically allocated memory, or NULL if the file does not exist.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL char * _PDCLIB_realpath( const char * path );
|
||||||
|
|
||||||
|
/* A system call that removes a file. Return zero on success, non-zero
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_remove( const char * pathname );
|
||||||
|
|
||||||
|
/* A system call that renames a file from given old name to given new name.
|
||||||
|
Return zero on success, non-zero otherwise. In case of failure, the file
|
||||||
|
must still be accessible by old name. Any handling of open files etc. is
|
||||||
|
done by standard rename() already.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_rename( const char * oldpath, const char * newpath );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
686
rocklibc/include/pdclib/_PDCLIB_internal.h
Normal file
686
rocklibc/include/pdclib/_PDCLIB_internal.h
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
/* PDCLib internal logic <_PDCLIB_internal.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_INTERNAL_H
|
||||||
|
#define _PDCLIB_INTERNAL_H _PDCLIB_INTERNAL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* You should not have to edit anything in this file; if you DO have to, it */
|
||||||
|
/* would be considered a bug / missing feature: notify the author(s). */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_config.h"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Standard Version */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Many a compiler gets this wrong, so you might have to hardcode it instead. */
|
||||||
|
|
||||||
|
#if __STDC__ != 1
|
||||||
|
#error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STDC_HOSTED__
|
||||||
|
#error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)!
|
||||||
|
#elif __STDC_HOSTED__ != 0 && __STDC_HOSTED__ != 1
|
||||||
|
#error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* null pointer constant -- ((void *)0) in C, 0 in C++98, nullptr since C++11 */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
#define _PDCLIB_NULL nullptr
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_NULL 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* restrict / inline enabled for C99 onward only */
|
||||||
|
#if defined( __cplusplus ) || ! defined( __STDC_VERSION ) || __STDC_VERSION__ < 199901L
|
||||||
|
#define _PDCLIB_restrict
|
||||||
|
#define _PDCLIB_inline
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_restrict restrict
|
||||||
|
#define _PDCLIB_inline inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* noreturn enabled for C11 onward only */
|
||||||
|
#if defined( __cplusplus ) && __cplusplus >= 201103L
|
||||||
|
#define _PDCLIB_Noreturn [[noreturn]]
|
||||||
|
#else
|
||||||
|
#if defined( __STDC_VERSION__ ) >= 201112L
|
||||||
|
#define _PDCLIB_Noreturn _Noreturn
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_Noreturn
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Helper macros: */
|
||||||
|
/* */
|
||||||
|
/* (defined in _PDCLIB_config.h) */
|
||||||
|
/* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending. */
|
||||||
|
/* _PDCLIB_concat( x, y ) concatenates two preprocessor tokens with extending */
|
||||||
|
/* */
|
||||||
|
/* (defined below) */
|
||||||
|
/* _PDCLIB_static_assert( e, m ) does a compile-time assertion of expression */
|
||||||
|
/* e, with m as the failure message. */
|
||||||
|
/* _PDCLIB_symbol2string( x ) turn symbol into string literal (by adding ""). */
|
||||||
|
/* _PDCLIB_value2string( x ) expands a preprocessor token and turns it into a */
|
||||||
|
/* string literal (by adding ""). */
|
||||||
|
/* _PDCLIB_TYPE_SIGNED( type ) resolves to true if type is signed. */
|
||||||
|
/* _PDCLIB_LOCK( mtx ) lock a mutex if library has threads support. */
|
||||||
|
/* _PDCLIB_UNLOCK( mtx ) unlock a mutex if library has threads support. */
|
||||||
|
/* _PDCLIB_CONSTRAINT_VIOLATION( e ) expand errno number e to parameter list */
|
||||||
|
/* fit for Annex K constraint violation */
|
||||||
|
/* handler. */
|
||||||
|
/* _PDCLIB_Generic( f, fp ) expand to _PDCLIB_f, _PDCLIB_ff, _PDCLIB_fl */
|
||||||
|
/* depending on fp being sizeof double, float, or */
|
||||||
|
/* long double. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define _PDCLIB_static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
|
||||||
|
|
||||||
|
#define _PDCLIB_TYPE_SIGNED( type ) (((type) -1) < 0)
|
||||||
|
|
||||||
|
#define _PDCLIB_symbol2string( x ) #x
|
||||||
|
#define _PDCLIB_value2string( x ) _PDCLIB_symbol2string( x )
|
||||||
|
|
||||||
|
#ifndef __STDC_NO_THREADS__
|
||||||
|
#define _PDCLIB_LOCK( mtx ) mtx_lock( &mtx )
|
||||||
|
#define _PDCLIB_UNLOCK( mtx ) mtx_unlock( &mtx )
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_LOCK( mtx )
|
||||||
|
#define _PDCLIB_UNLOCK( mtx )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _PDCLIB_CONSTRAINT_VIOLATION( e ) _PDCLIB_lc_messages->errno_texts[e], NULL, e
|
||||||
|
|
||||||
|
#define _PDCLIB_GETC( fh ) ( ( fh->ungetidx == 0 ) ? ( unsigned char )fh->buffer[ fh->bufidx++ ] : ( unsigned char )fh->ungetbuf[ --fh->ungetidx ] )
|
||||||
|
|
||||||
|
#define _PDCLIB_CHECKBUFFER( fh ) ( ( ( fh->bufidx == fh->bufend ) && ( fh->ungetidx == 0 ) ) ? _PDCLIB_fillbuffer( fh ) : 0 )
|
||||||
|
|
||||||
|
#define _PDCLIB_GENERIC( func, x ) ( ( sizeof( x ) == sizeof( double ) ) ? _PDCLIB_ ## func ## d( x ) : \
|
||||||
|
( sizeof( x ) == sizeof( float ) ) ? _PDCLIB_ ## func ## f( x ) : \
|
||||||
|
( _PDCLIB_ ## func ## l( x ) ) )
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Preparing the length modifiers used in <inttypes.h>. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* We use the _MAX value as a proxy for the actual type here. That is crude
|
||||||
|
but the best we can do, cross-platform wise.
|
||||||
|
Identifying which type the leastN_t / fastN_t / intmax_t / intptr_t are
|
||||||
|
and providing the appropriate printf()/scanf() length modifier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST8_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_FAST8_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_FAST8_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST8_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_FAST8_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST8_PREFIX
|
||||||
|
#elif _PDCLIB_INT_FAST8_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST8_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_FAST8_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST8_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_fast8_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST16_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_FAST16_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_FAST16_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST16_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_FAST16_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST16_PREFIX
|
||||||
|
#elif _PDCLIB_INT_FAST16_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST16_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_FAST16_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST16_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_fast16_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST32_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_FAST32_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_FAST32_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST32_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_FAST32_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST32_PREFIX
|
||||||
|
#elif _PDCLIB_INT_FAST32_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST32_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_FAST32_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST32_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_fast32_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_FAST64_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_FAST64_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_FAST64_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST64_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_FAST64_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_FAST64_PREFIX
|
||||||
|
#elif _PDCLIB_INT_FAST64_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST64_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_FAST64_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_FAST64_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_fast64_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Many of the combinations below can very likely be ruled out logically.
|
||||||
|
All combinations are still listed for simplicity's sake (and to not fall
|
||||||
|
into the trap of false assumptions).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST8_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST8_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_LEAST8_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST8_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_LEAST8_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST8_PREFIX
|
||||||
|
#elif _PDCLIB_INT_LEAST8_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST8_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_LEAST8_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST8_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_least8_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST16_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST16_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_LEAST16_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST16_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_LEAST16_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST16_PREFIX
|
||||||
|
#elif _PDCLIB_INT_LEAST16_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST16_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_LEAST16_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST16_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_least16_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST32_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST32_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_LEAST32_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST32_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_LEAST32_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST32_PREFIX
|
||||||
|
#elif _PDCLIB_INT_LEAST32_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST32_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_LEAST32_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST32_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_least32_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST64_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST64_PREFIX hh
|
||||||
|
#elif _PDCLIB_INT_LEAST64_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST64_PREFIX h
|
||||||
|
#elif _PDCLIB_INT_LEAST64_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST64_PREFIX
|
||||||
|
#elif _PDCLIB_INT_LEAST64_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST64_PREFIX l
|
||||||
|
#elif _PDCLIB_INT_LEAST64_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INT_LEAST64_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for int_least64_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INTMAX_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INTMAX_PREFIX hh
|
||||||
|
#elif _PDCLIB_INTMAX_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INTMAX_PREFIX h
|
||||||
|
#elif _PDCLIB_INTMAX_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INTMAX_PREFIX
|
||||||
|
#elif _PDCLIB_INTMAX_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INTMAX_PREFIX l
|
||||||
|
#elif _PDCLIB_INTMAX_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INTMAX_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for intmax_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INTPTR_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_INTPTR_PREFIX hh
|
||||||
|
#elif _PDCLIB_INTPTR_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_INTPTR_PREFIX h
|
||||||
|
#elif _PDCLIB_INTPTR_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_INTPTR_PREFIX
|
||||||
|
#elif _PDCLIB_INTPTR_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_INTPTR_PREFIX l
|
||||||
|
#elif _PDCLIB_INTPTR_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_INTPTR_PREFIX ll
|
||||||
|
#else
|
||||||
|
#error No matching native type for intptr_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We might not have a type definition for sig_atomic_t at this point. The */
|
||||||
|
/* clang compiler does not provide an appropriate predefine for it. So if we */
|
||||||
|
/* do not have _PDCLIB_sig_atomic_t, identify the type trough its MAX value. */
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_sig_atomic_t
|
||||||
|
|
||||||
|
#if _PDCLIB_SIG_ATOMIC_MAX == _PDCLIB_SCHAR_MAX
|
||||||
|
#define _PDCLIB_sig_atomic_t char
|
||||||
|
#elif _PDCLIB_SIG_ATOMIC_MAX == _PDCLIB_SHRT_MAX
|
||||||
|
#define _PDCLIB_sig_atomic_t short
|
||||||
|
#elif _PDCLIB_SIG_ATOMIC_MAX == _PDCLIB_INT_MAX
|
||||||
|
#define _PDCLIB_sig_atomic_t int
|
||||||
|
#elif _PDCLIB_SIG_ATOMIC_MAX == _PDCLIB_LONG_MAX
|
||||||
|
#define _PDCLIB_sig_atomic_t long
|
||||||
|
#elif _PDCLIB_SIG_ATOMIC_MAX == _PDCLIB_LLONG_MAX
|
||||||
|
#define _PDCLIB_sig_atomic_t long long
|
||||||
|
#else
|
||||||
|
#error No matching native type for sig_atomic_t. Please check your setup.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Various <stdio.h> internals */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Flags for representing mode (see fopen()). Note these must fit the same
|
||||||
|
status field as the _IO?BF flags in <stdio.h> and the internal flags below.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_FREAD (1u<<3)
|
||||||
|
#define _PDCLIB_FWRITE (1u<<4)
|
||||||
|
#define _PDCLIB_FAPPEND (1u<<5)
|
||||||
|
#define _PDCLIB_FRW (1u<<6)
|
||||||
|
#define _PDCLIB_FBIN (1u<<7)
|
||||||
|
|
||||||
|
/* Internal flags, made to fit the same status field as the flags above. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* free() the buffer memory on closing (setvbuf()) */
|
||||||
|
#define _PDCLIB_FREEBUFFER (1u<<8)
|
||||||
|
/* stream has encountered error / EOF */
|
||||||
|
#define _PDCLIB_ERRORFLAG (1u<<9)
|
||||||
|
#define _PDCLIB_EOFFLAG (1u<<10)
|
||||||
|
/* stream is wide-oriented */
|
||||||
|
#define _PDCLIB_WIDESTREAM (1u<<11)
|
||||||
|
/* stream is byte-oriented */
|
||||||
|
#define _PDCLIB_BYTESTREAM (1u<<12)
|
||||||
|
/* file associated with stream should be remove()d on closing (tmpfile()) */
|
||||||
|
#define _PDCLIB_DELONCLOSE (1u<<13)
|
||||||
|
|
||||||
|
/* Position / status structure for getpos() / fsetpos(). */
|
||||||
|
struct _PDCLIB_fpos_t
|
||||||
|
{
|
||||||
|
_PDCLIB_uint_least64_t offset; /* File position offset */
|
||||||
|
int status; /* Multibyte parsing state (unused, reserved) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FILE structure */
|
||||||
|
struct _PDCLIB_file_t
|
||||||
|
{
|
||||||
|
_PDCLIB_fd_t handle; /* OS file handle */
|
||||||
|
char * buffer; /* Pointer to buffer memory */
|
||||||
|
_PDCLIB_size_t bufsize; /* Size of buffer */
|
||||||
|
_PDCLIB_size_t bufidx; /* Index of current position in buffer */
|
||||||
|
_PDCLIB_size_t bufend; /* Index of last pre-read character in buffer */
|
||||||
|
struct _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */
|
||||||
|
_PDCLIB_size_t ungetidx; /* Number of ungetc()'ed characters */
|
||||||
|
unsigned char ungetbuf[_PDCLIB_UNGETCBUFSIZE]; /* ungetc() buffer */
|
||||||
|
unsigned int status; /* Status flags; see above */
|
||||||
|
/* multibyte parsing status to be added later */
|
||||||
|
#ifndef __STDC_NO_THREADS__
|
||||||
|
_PDCLIB_mtx_t mtx; /* Multithreading safety */
|
||||||
|
#endif
|
||||||
|
char * filename; /* Name the current stream has been opened with */
|
||||||
|
struct _PDCLIB_file_t * next; /* Pointer to next struct (internal) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Internal data types */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Structure required by both atexit() and exit() for handling atexit functions */
|
||||||
|
struct _PDCLIB_exitfunc_t
|
||||||
|
{
|
||||||
|
struct _PDCLIB_exitfunc_t * next;
|
||||||
|
void ( *func )( void );
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Status structure required by _PDCLIB_print(). */
|
||||||
|
struct _PDCLIB_status_t
|
||||||
|
{
|
||||||
|
int base; /* base to which the value shall be converted */
|
||||||
|
_PDCLIB_int_fast32_t flags; /* flags and length modifiers */
|
||||||
|
_PDCLIB_size_t n; /* print: maximum characters to be written */
|
||||||
|
/* scan: number matched conversion specifiers */
|
||||||
|
_PDCLIB_size_t i; /* number of characters read/written */
|
||||||
|
_PDCLIB_size_t current;/* chars read/written in the CURRENT conversion */
|
||||||
|
char * s; /* *sprintf(): target buffer */
|
||||||
|
/* *sscanf(): source string */
|
||||||
|
_PDCLIB_size_t width; /* specified field width */
|
||||||
|
int prec; /* specified field precision */
|
||||||
|
struct _PDCLIB_file_t * stream; /* *fprintf() / *fscanf() stream */
|
||||||
|
_PDCLIB_va_list arg; /* argument stack */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Declaration of helper functions (implemented in functions/_PDCLIB). */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This is the main function called by atoi(), atol() and atoll(). */
|
||||||
|
_PDCLIB_LOCAL _PDCLIB_intmax_t _PDCLIB_atomax( const char * s );
|
||||||
|
|
||||||
|
/* Two helper functions used by strtol(), strtoul() and long long variants. */
|
||||||
|
_PDCLIB_LOCAL const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base );
|
||||||
|
_PDCLIB_LOCAL _PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, _PDCLIB_uintmax_t error, _PDCLIB_uintmax_t limit, char * sign );
|
||||||
|
|
||||||
|
/* Helper function used by strtof(), strtod(), and strtold(). */
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_strtod_prelim( const char * p, char * sign, char ** endptr );
|
||||||
|
|
||||||
|
/* Digits arrays used by various integer conversion functions */
|
||||||
|
extern const char _PDCLIB_digits[];
|
||||||
|
extern const char _PDCLIB_Xdigits[];
|
||||||
|
|
||||||
|
/* The worker for all printf() type of functions. The pointer spec should point
|
||||||
|
to the introducing '%' of a conversion specifier. The status structure is to
|
||||||
|
be that of the current printf() function, of which the members n, s, stream
|
||||||
|
and arg will be preserved; i will be updated; and all others will be trashed
|
||||||
|
by the function.
|
||||||
|
Returns a pointer to the first character not parsed as conversion specifier.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );
|
||||||
|
|
||||||
|
/* The worker for all scanf() type of functions. The pointer spec should point
|
||||||
|
to the introducing '%' of a conversion specifier. The status structure is to
|
||||||
|
be that of the current scanf() function, of which the member stream will be
|
||||||
|
preserved; n, i, and s will be updated; and all others will be trashed by
|
||||||
|
the function.
|
||||||
|
Returns a pointer to the first character not parsed as conversion specifier,
|
||||||
|
or NULL in case of error.
|
||||||
|
FIXME: Should distinguish between matching and input error
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );
|
||||||
|
|
||||||
|
/* Parsing any fopen() style filemode string into a number of flags. */
|
||||||
|
_PDCLIB_LOCAL unsigned int _PDCLIB_filemode( const char * mode );
|
||||||
|
|
||||||
|
/* Initialize a FILE structure. If the parameter is NULL, a new FILE structure
|
||||||
|
is malloc'ed. Returns a pointer to the stream if successful, NULL otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_file_t * _PDCLIB_init_file_t( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* Sanity checking and preparing of read buffer, should be called first thing
|
||||||
|
by any stdio read-data function.
|
||||||
|
Returns 0 on success, EOF on error.
|
||||||
|
On error, EOF / error flags and errno are set appropriately.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_prepread( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* Sanity checking, should be called first thing by any stdio write-data
|
||||||
|
function.
|
||||||
|
Returns 0 on success, EOF on error.
|
||||||
|
On error, error flags and errno are set appropriately.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* Closing all streams on program exit */
|
||||||
|
_PDCLIB_LOCAL void _PDCLIB_closeall( void );
|
||||||
|
|
||||||
|
/* Check if a given year is a leap year. Parameter is offset to 1900. */
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_is_leap( int year_offset );
|
||||||
|
|
||||||
|
/* Read a specified number of lines from a file stream; return a pointer to
|
||||||
|
allocated memory holding the lines (newlines replaced with zero terminators)
|
||||||
|
or NULL in case of error.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL char * _PDCLIB_load_lines( struct _PDCLIB_file_t * stream, _PDCLIB_size_t lines );
|
||||||
|
|
||||||
|
/* Returns the (locale dependent) error message associated with the argument
|
||||||
|
errno value.
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL char * _PDCLIB_geterrtext( int errnum );
|
||||||
|
|
||||||
|
/* Returns non-zero if the given stream is on the internal list of open files,
|
||||||
|
zero otherwise. Sets the second paramenter (if not NULL) to the previous
|
||||||
|
stream on the list (or NULL if the given stream is the first on the list).
|
||||||
|
This function does not lock _PDCLIB_filelist_mtx, this needs to be done by
|
||||||
|
the calling function (_PDCLIB_getstream() or freopen()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_isstream( struct _PDCLIB_file_t * stream, struct _PDCLIB_file_t ** previous );
|
||||||
|
|
||||||
|
/* Removes the given stream from the internal list of open files. Returns zero
|
||||||
|
if successful, non-zero otherwise. In case of error, sets errno to EBADF.
|
||||||
|
This function does not lock _PDCLIB_filelist_mtx, this needs to be done by
|
||||||
|
the calling function (fclose()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_LOCAL int _PDCLIB_getstream( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* Backend for strtok and strtok_s (plus potential extensions like strtok_r). */
|
||||||
|
_PDCLIB_LOCAL char * _PDCLIB_strtok( char * _PDCLIB_restrict s1, _PDCLIB_size_t * _PDCLIB_restrict s1max, const char * _PDCLIB_restrict s2, char ** _PDCLIB_restrict ptr );
|
||||||
|
|
||||||
|
/* Conversion of exponent notation to floating point */
|
||||||
|
_PDCLIB_LOCAL long double _PDCLIB_naive_etod( const char * s, char ** endptr );
|
||||||
|
|
||||||
|
/* Conversion of hexadecimal notation to floating point */
|
||||||
|
_PDCLIB_LOCAL long double _PDCLIB_naive_ptod( const char * s, char ** endptr );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Declaration of math helper functions (implemented in functions/math). */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int _PDCLIB_isnand( double x );
|
||||||
|
int _PDCLIB_isnanf( float x );
|
||||||
|
int _PDCLIB_isnanl( long double x );
|
||||||
|
|
||||||
|
int _PDCLIB_isinfd( double x );
|
||||||
|
int _PDCLIB_isinff( float x );
|
||||||
|
int _PDCLIB_isinfl( long double x );
|
||||||
|
|
||||||
|
int _PDCLIB_signbitd( double x );
|
||||||
|
int _PDCLIB_signbitf( float x );
|
||||||
|
int _PDCLIB_signbitl( long double x );
|
||||||
|
|
||||||
|
int _PDCLIB_isfinited( double x );
|
||||||
|
int _PDCLIB_isfinitef( float x );
|
||||||
|
int _PDCLIB_isfinitel( long double x );
|
||||||
|
|
||||||
|
int _PDCLIB_isnormald( double x );
|
||||||
|
int _PDCLIB_isnormalf( float x );
|
||||||
|
int _PDCLIB_isnormall( long double x );
|
||||||
|
|
||||||
|
int _PDCLIB_fpclassifyd( double x );
|
||||||
|
int _PDCLIB_fpclassifyf( float x );
|
||||||
|
int _PDCLIB_fpclassifyl( long double x );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* errno */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* A mechanism for delayed evaluation.
|
||||||
|
If PDCLib would call its error number "errno" directly, there would be no way
|
||||||
|
to catch its value from underlying system calls that also use it (i.e., POSIX
|
||||||
|
operating systems). That is why we use an internal name, providing a means to
|
||||||
|
access it through <errno.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int * _PDCLIB_errno_func( void );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* <locale.h> support */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define _PDCLIB_LC_ALL 0
|
||||||
|
#define _PDCLIB_LC_COLLATE 1
|
||||||
|
#define _PDCLIB_LC_CTYPE 2
|
||||||
|
#define _PDCLIB_LC_MONETARY 3
|
||||||
|
#define _PDCLIB_LC_NUMERIC 4
|
||||||
|
#define _PDCLIB_LC_TIME 5
|
||||||
|
#define _PDCLIB_LC_MESSAGES 6
|
||||||
|
#define _PDCLIB_LC_COUNT 7
|
||||||
|
|
||||||
|
#define _PDCLIB_CTYPE_ALPHA 1
|
||||||
|
#define _PDCLIB_CTYPE_BLANK 2
|
||||||
|
#define _PDCLIB_CTYPE_CNTRL 4
|
||||||
|
#define _PDCLIB_CTYPE_GRAPH 8
|
||||||
|
#define _PDCLIB_CTYPE_PUNCT 16
|
||||||
|
#define _PDCLIB_CTYPE_SPACE 32
|
||||||
|
#define _PDCLIB_CTYPE_LOWER 64
|
||||||
|
#define _PDCLIB_CTYPE_UPPER 128
|
||||||
|
|
||||||
|
#define _PDCLIB_CHARSET_SIZE ( 1 << _PDCLIB_CHAR_BIT )
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t
|
||||||
|
{
|
||||||
|
char * decimal_point;
|
||||||
|
char * thousands_sep;
|
||||||
|
char * grouping;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t
|
||||||
|
{
|
||||||
|
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 p_cs_precedes;
|
||||||
|
char n_cs_precedes;
|
||||||
|
char p_sep_by_space;
|
||||||
|
char n_sep_by_space;
|
||||||
|
char p_sign_posn;
|
||||||
|
char n_sign_posn;
|
||||||
|
char int_frac_digits;
|
||||||
|
char int_p_cs_precedes;
|
||||||
|
char int_n_cs_precedes;
|
||||||
|
char int_p_sep_by_space;
|
||||||
|
char int_n_sep_by_space;
|
||||||
|
char int_p_sign_posn;
|
||||||
|
char int_n_sign_posn;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_numeric_monetary_t
|
||||||
|
{
|
||||||
|
struct lconv * lconv;
|
||||||
|
int numeric_alloced;
|
||||||
|
int monetary_alloced;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_numeric_monetary_t _PDCLIB_lc_numeric_monetary;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_collate_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
/* 1..3 code points */
|
||||||
|
/* 1..8, 18 collation elements of 3 16-bit integers */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_collate_t _PDCLIB_lc_collate_C;
|
||||||
|
extern struct _PDCLIB_lc_collate_t * _PDCLIB_lc_collate;
|
||||||
|
|
||||||
|
/* One entry to the _PDCLIB_lc_ctype_t.entry data table */
|
||||||
|
struct _PDCLIB_lc_ctype_entry_t
|
||||||
|
{
|
||||||
|
_PDCLIB_uint_least16_t flags; /* Whether a character is of a given CTYPE */
|
||||||
|
unsigned char upper; /* Result for toupper() */
|
||||||
|
unsigned char lower; /* Result for tolower() */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_ctype_t
|
||||||
|
{
|
||||||
|
int alloced; /* .entry dynamically allocated? */
|
||||||
|
int digits_low; /* Where decimal digits start */
|
||||||
|
int digits_high; /* Where decimal digits end */
|
||||||
|
int Xdigits_low; /* Where A..F start */
|
||||||
|
int Xdigits_high; /* Where A..F end */
|
||||||
|
int xdigits_low; /* Where a..f start */
|
||||||
|
int xdigits_high; /* Where a..f end */
|
||||||
|
struct _PDCLIB_lc_ctype_entry_t * entry; /* The data table */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_ctype_t _PDCLIB_lc_ctype_C;
|
||||||
|
extern struct _PDCLIB_lc_ctype_t * _PDCLIB_lc_ctype;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_messages_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
char * errno_texts[_PDCLIB_ERRNO_MAX]; /* strerror() / perror() */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_messages_t _PDCLIB_lc_messages_C;
|
||||||
|
extern struct _PDCLIB_lc_messages_t * _PDCLIB_lc_messages;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_time_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
char * month_name_abbr[12]; /* month names, abbreviated */
|
||||||
|
char * month_name_full[12]; /* month names, full */
|
||||||
|
char * day_name_abbr[7]; /* weekday names, abbreviated */
|
||||||
|
char * day_name_full[7]; /* weekday names, full */
|
||||||
|
char * date_time_format; /* date / time format for strftime( "%c" ) */
|
||||||
|
char * time_format_12h; /* 12-hour time format for strftime( "%r" ) */
|
||||||
|
char * date_format; /* date format for strftime( "%x" ) */
|
||||||
|
char * time_format; /* time format for strftime( "%X" ) */
|
||||||
|
char * am_pm[2]; /* AM / PM designation */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_time_t _PDCLIB_lc_time_C;
|
||||||
|
extern struct _PDCLIB_lc_time_t * _PDCLIB_lc_time;
|
||||||
|
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_lc_lconv_numeric_t * _PDCLIB_load_lc_numeric( const char * path, const char * locale );
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_lc_lconv_monetary_t * _PDCLIB_load_lc_monetary( const char * path, const char * locale );
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_lc_collate_t * _PDCLIB_load_lc_collate( const char * path, const char * locale );
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_lc_ctype_t * _PDCLIB_load_lc_ctype( const char * path, const char * locale );
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_lc_time_t * _PDCLIB_load_lc_time( const char * path, const char * locale );
|
||||||
|
_PDCLIB_LOCAL struct _PDCLIB_lc_messages_t * _PDCLIB_load_lc_messages( const char * path, const char * locale );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Sanity checks */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* signed-ness of char */
|
||||||
|
_PDCLIB_static_assert( _PDCLIB_CHAR_MIN == ((((char) -1) < 0) ? _PDCLIB_SCHAR_MIN : 0), "Compiler disagrees on signed-ness of 'char'." );
|
||||||
|
|
||||||
|
/* two's complement */
|
||||||
|
#if _PDCLIB_TWOS_COMPLEMENT == 1
|
||||||
|
#if _PDCLIB_CHAR_MIN < 0
|
||||||
|
_PDCLIB_static_assert( ((char) ~ (char) 0 < 0), "Not two's complement on 'char'." );
|
||||||
|
#endif
|
||||||
|
_PDCLIB_static_assert( ((short) ~ (short) 0 < 0), "Not two's complement on 'short'." );
|
||||||
|
_PDCLIB_static_assert( ((int) ~ (int) 0 < 0), "Not two's complement on 'int'." );
|
||||||
|
_PDCLIB_static_assert( ((long) ~ (long) 0 < 0), "Not two's complement on 'long'." );
|
||||||
|
_PDCLIB_static_assert( ((long long) ~ (long long) 0 < 0), "Not two's complement on 'long long'." );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* size_t as the result of sizeof */
|
||||||
|
_PDCLIB_static_assert( sizeof( sizeof( int ) ) == sizeof( _PDCLIB_size_t ), "Compiler disagrees on size_t." );
|
||||||
|
|
||||||
|
/* wchar_t as the type of wide character literals */
|
||||||
|
_PDCLIB_static_assert( sizeof( _PDCLIB_wchar_t ) == sizeof( L'x' ), "Compiler disagrees on wchar_t." );
|
||||||
|
#ifdef __cplusplus
|
||||||
|
_PDCLIB_static_assert( sizeof( _PDCLIB_wchar_t ) == sizeof( wchar_t ), "Compiler disagrees on wchar_t (C++)." );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* intptr_t/uintptr_t being wide enough to store the value of a pointer */
|
||||||
|
_PDCLIB_static_assert( sizeof( void * ) == sizeof( _PDCLIB_intptr_t ), "Compiler disagrees on intptr_t." );
|
||||||
|
_PDCLIB_static_assert( sizeof( void * ) == sizeof( _PDCLIB_uintptr_t ), "Compiler disagrees on uintptr_t." );
|
||||||
|
|
||||||
|
/* ptrdiff_t as the result of pointer arithmetic */
|
||||||
|
_PDCLIB_static_assert( sizeof( &_PDCLIB_digits[1] - &_PDCLIB_digits[0] ) == sizeof( _PDCLIB_ptrdiff_t ), "Compiler disagrees on ptrdiff_t." );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
32
rocklibc/include/pdclib/_PDCLIB_lib_ext1.h
Normal file
32
rocklibc/include/pdclib/_PDCLIB_lib_ext1.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* __STDC_WANT_LIB_EXT1__ redefinition guard
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STDC_WANT_LIB_EXT1__
|
||||||
|
#ifdef __STDC_WANT_LIB_EXT1_PREVIOUS__
|
||||||
|
#if __STDC_WANT_LIB_EXT1_PREVIOUS__ != -1
|
||||||
|
#error __STDC_WANT_LIB_EXT1__ undefined when it was defined earlier.
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ -1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) == 0 && ( 0 - __STDC_WANT_LIB_EXT1__ - 1 ) == 1
|
||||||
|
#error __STDC_WANT_LIB_EXT1__ defined but empty. Should be an integer value.
|
||||||
|
#endif
|
||||||
|
#ifdef __STDC_WANT_LIB_EXT1_PREVIOUS__
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != __STDC_WANT_LIB_EXT1_PREVIOUS__
|
||||||
|
#error __STDC_WANT_LIB_EXT1__ redefined from previous value.
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) == 0
|
||||||
|
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ 0
|
||||||
|
#elif ( __STDC_WANT_LIB_EXT1__ + 0 ) == 1
|
||||||
|
#define __STDC_WANT_LIB_EXT1_PREVIOUS__ 1
|
||||||
|
#else
|
||||||
|
#error __STDC_WANT_LIB_EXT1__ set to value other than 0,1 -- undefined behavior
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
6
rocklibc/include/pdclib/_PDCLIB_platform_errno.h
Normal file
6
rocklibc/include/pdclib/_PDCLIB_platform_errno.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _PDCLIB_PLATFORM_ERRNO
|
||||||
|
#define _PDCLIB_PLATFORM_ERRNO
|
||||||
|
|
||||||
|
#include "errno.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
6
rocklibc/include/pdclib/_PDCLIB_platform_fcntl.h
Normal file
6
rocklibc/include/pdclib/_PDCLIB_platform_fcntl.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _PDCLIB_PLATFORM_FCNTL
|
||||||
|
#define _PDCLIB_PLATFORM_FCNTL
|
||||||
|
|
||||||
|
#include "fcntl.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
145
rocklibc/include/pdclib/_PDCLIB_print.h
Normal file
145
rocklibc/include/pdclib/_PDCLIB_print.h
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/* PDCLib printf logic <_PDCLIB_print.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_PRINT_H
|
||||||
|
#define _PDCLIB_PRINT_H _PDCLIB_PRINT_H
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* This macro delivers a given character to either a memory buffer or a stream,
|
||||||
|
depending on the contents of 'status' (struct _PDCLIB_status_t).
|
||||||
|
x - the character to be delivered
|
||||||
|
i - pointer to number of characters already delivered in this call
|
||||||
|
n - pointer to maximum number of characters to be delivered in this call
|
||||||
|
s - the buffer into which the character shall be delivered
|
||||||
|
*/
|
||||||
|
#define PUT( x ) \
|
||||||
|
do { \
|
||||||
|
int character = x; \
|
||||||
|
if ( status->i < status->n ) { \
|
||||||
|
if ( status->stream != NULL ) \
|
||||||
|
putc( character, status->stream ); \
|
||||||
|
else \
|
||||||
|
status->s[status->i] = character; \
|
||||||
|
} \
|
||||||
|
++(status->i); \
|
||||||
|
} while ( 0 )
|
||||||
|
|
||||||
|
|
||||||
|
/* Using an integer's bits as flags for both the conversion flags and length
|
||||||
|
modifiers.
|
||||||
|
*/
|
||||||
|
#define E_minus (INT32_C(1)<<0)
|
||||||
|
#define E_plus (INT32_C(1)<<1)
|
||||||
|
#define E_alt (INT32_C(1)<<2)
|
||||||
|
#define E_space (INT32_C(1)<<3)
|
||||||
|
|
||||||
|
#define E_zero (INT32_C(1)<<4)
|
||||||
|
#define E_done (INT32_C(1)<<5)
|
||||||
|
#define E_char (INT32_C(1)<<6)
|
||||||
|
#define E_short (INT32_C(1)<<7)
|
||||||
|
|
||||||
|
#define E_long (INT32_C(1)<<8)
|
||||||
|
#define E_llong (INT32_C(1)<<9)
|
||||||
|
#define E_intmax (INT32_C(1)<<10)
|
||||||
|
#define E_size (INT32_C(1)<<11)
|
||||||
|
|
||||||
|
#define E_ptrdiff (INT32_C(1)<<12)
|
||||||
|
#define E_pointer (INT32_C(1)<<13)
|
||||||
|
#define E_double (INT32_C(1)<<14)
|
||||||
|
#define E_ldouble (INT32_C(1)<<15)
|
||||||
|
|
||||||
|
#define E_lower (INT32_C(1)<<16)
|
||||||
|
#define E_unsigned (INT32_C(1)<<17)
|
||||||
|
#define E_decimal (INT32_C(1)<<18)
|
||||||
|
#define E_exponent (INT32_C(1)<<19)
|
||||||
|
|
||||||
|
#define E_generic (INT32_C(1)<<20)
|
||||||
|
#define E_hexa (INT32_C(1)<<21)
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* _PDCLIB_bigint_t support (required for floating point conversions) */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Must be divisible by 32. */
|
||||||
|
/* 1120 is enough for 64bit floats. A 128 float takes 16544 bits. */
|
||||||
|
#define _PDCLIB_BIGINT_BITS 1120
|
||||||
|
|
||||||
|
#if _PDCLIB_BIGINT_DIGIT_BITS == 32
|
||||||
|
#define _PDCLIB_BIGINT_DIGIT_MAX _PDCLIB_UINT_LEAST32_C( 0xFFFFFFFF )
|
||||||
|
typedef _PDCLIB_uint_least32_t _PDCLIB_bigint_digit_t;
|
||||||
|
typedef _PDCLIB_int_least32_t _PDCLIB_bigint_sdigit_t;
|
||||||
|
typedef _PDCLIB_uint_least64_t _PDCLIB_bigint_arith_t;
|
||||||
|
#elif _PDCLIB_BIGINT_DIGIT_BITS == 16
|
||||||
|
#define _PDCLIB_BIGINT_DIGIT_MAX _PDCLIB_UINT_LEAST16_C( 0xFFFF )
|
||||||
|
typedef _PDCLIB_uint_least16_t _PDCLIB_bigint_digit_t;
|
||||||
|
typedef _PDCLIB_int_least16_t _PDCLIB_bigint_sdigit_t;
|
||||||
|
typedef _PDCLIB_uint_least32_t _PDCLIB_bigint_arith_t;
|
||||||
|
#else
|
||||||
|
#error _PDCLIB_BIGINT_DIGIT_BITS.needs to be 16 or 32.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* How many "digits" a _PDCLIB_bigint_t holds. */
|
||||||
|
#define _PDCLIB_BIGINT_DIGITS _PDCLIB_BIGINT_BITS / _PDCLIB_BIGINT_DIGIT_BITS
|
||||||
|
|
||||||
|
/* Maximum number of characters needed for _PDCLIB_bigint_tostring() */
|
||||||
|
#define _PDCLIB_BIGINT_CHARS ( _PDCLIB_BIGINT_BITS / 4 + _PDCLIB_BIGINT_DIGITS + 2 )
|
||||||
|
|
||||||
|
/* Type */
|
||||||
|
/* ---- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Number of digits used; zero value == zero size */
|
||||||
|
_PDCLIB_size_t size;
|
||||||
|
/* Least significant digit first */
|
||||||
|
_PDCLIB_bigint_digit_t data[ _PDCLIB_BIGINT_DIGITS ];
|
||||||
|
} _PDCLIB_bigint_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_t mantissa;
|
||||||
|
_PDCLIB_int_least16_t exponent;
|
||||||
|
_PDCLIB_int_least16_t scale;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
_PDCLIB_FP_NORMAL,
|
||||||
|
_PDCLIB_FP_SUBNORMAL,
|
||||||
|
_PDCLIB_FP_INF,
|
||||||
|
_PDCLIB_FP_NAN
|
||||||
|
} state;
|
||||||
|
char sign;
|
||||||
|
} _PDCLIB_fp_t;
|
||||||
|
|
||||||
|
void _PDCLIB_fp_from_dbl( _PDCLIB_fp_t * fp, double value );
|
||||||
|
void _PDCLIB_fp_from_ldbl( _PDCLIB_fp_t * fp, long double value );
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_from_digit( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_digit_t digit );
|
||||||
|
void _PDCLIB_bigint_from_pow2( _PDCLIB_bigint_t * bigint, unsigned pow );
|
||||||
|
void _PDCLIB_bigint_from_pow10( _PDCLIB_bigint_t * bigint, unsigned pow );
|
||||||
|
void _PDCLIB_bigint_from_bigint( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other );
|
||||||
|
void _PDCLIB_bigint_add( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other );
|
||||||
|
void _PDCLIB_bigint_mul( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other );
|
||||||
|
void _PDCLIB_bigint_mul_pow10( _PDCLIB_bigint_t * bigint, int pow10 );
|
||||||
|
int _PDCLIB_bigint_cmp( _PDCLIB_bigint_t const * lhs, _PDCLIB_bigint_t const * rhs );
|
||||||
|
void _PDCLIB_bigint_shl( _PDCLIB_bigint_t * bigint, _PDCLIB_size_t bits );
|
||||||
|
void _PDCLIB_bigint_mul10( _PDCLIB_bigint_t * bigint );
|
||||||
|
int _PDCLIB_bigint_digit_log2( _PDCLIB_bigint_digit_t digit );
|
||||||
|
int _PDCLIB_bigint_log2( _PDCLIB_bigint_t const * bigint );
|
||||||
|
unsigned _PDCLIB_bigint_div( _PDCLIB_bigint_t * dividend, _PDCLIB_bigint_t const * divisor );
|
||||||
|
|
||||||
|
void _PDCLIB_print_integer( struct _PDCLIB_imaxdiv_t div, struct _PDCLIB_status_t * status );
|
||||||
|
void _PDCLIB_print_string( const char * s, struct _PDCLIB_status_t * status );
|
||||||
|
void _PDCLIB_print_fp( _PDCLIB_fp_t * fp, struct _PDCLIB_status_t * status );
|
||||||
|
int _PDCLIB_print_fp_deci( _PDCLIB_fp_t * fp, struct _PDCLIB_status_t * status, char * buffer );
|
||||||
|
void _PDCLIB_print_fp_hexa( _PDCLIB_fp_t * fp, struct _PDCLIB_status_t * status, char * buffer );
|
||||||
|
void _PDCLIB_print_fp_dragon4( _PDCLIB_bigint_t * fp, struct _PDCLIB_status_t * status );
|
||||||
|
|
||||||
|
#endif
|
||||||
153
rocklibc/include/pdclib/_PDCLIB_tzcode.h
Normal file
153
rocklibc/include/pdclib/_PDCLIB_tzcode.h
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/* TZ Code declarations and definitions <_PDCLIB_tzcode.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_TZCODE_H
|
||||||
|
#define _PDCLIB_TZCODE_H _PDCLIB_TZCODE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pdclib/_PDCLIB_config.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/* Handy macros that are independent of tzfile implementation. */
|
||||||
|
#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
|
||||||
|
|
||||||
|
#define SECSPERMIN 60
|
||||||
|
#define MINSPERHOUR 60
|
||||||
|
#define HOURSPERDAY 24
|
||||||
|
#define DAYSPERWEEK 7
|
||||||
|
#define DAYSPERNYEAR 365
|
||||||
|
#define DAYSPERLYEAR 366
|
||||||
|
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
|
||||||
|
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
|
||||||
|
#define MONSPERYEAR 12
|
||||||
|
|
||||||
|
#define AVGSECSPERYEAR 31556952L
|
||||||
|
#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
|
||||||
|
#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
|
||||||
|
|
||||||
|
#define TM_SUNDAY 0
|
||||||
|
#define TM_MONDAY 1
|
||||||
|
#define TM_TUESDAY 2
|
||||||
|
#define TM_WEDNESDAY 3
|
||||||
|
#define TM_THURSDAY 4
|
||||||
|
#define TM_FRIDAY 5
|
||||||
|
#define TM_SATURDAY 6
|
||||||
|
|
||||||
|
#define TM_YEAR_BASE 1900
|
||||||
|
|
||||||
|
#define EPOCH_YEAR 1970
|
||||||
|
#define EPOCH_WDAY TM_THURSDAY
|
||||||
|
|
||||||
|
extern struct tm _PDCLIB_tm;
|
||||||
|
extern int lcl_is_set;
|
||||||
|
|
||||||
|
static const char gmt[] = "GMT";
|
||||||
|
|
||||||
|
static const int mon_lengths[ 2 ][ MONSPERYEAR ] =
|
||||||
|
{
|
||||||
|
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||||
|
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int year_lengths[2] =
|
||||||
|
{
|
||||||
|
DAYSPERNYEAR, DAYSPERLYEAR
|
||||||
|
};
|
||||||
|
|
||||||
|
/* time type information */
|
||||||
|
struct ttinfo
|
||||||
|
{
|
||||||
|
int_fast32_t utoff; /* UT offset in seconds */
|
||||||
|
bool isdst; /* used to set tm_isdst */
|
||||||
|
int desigidx; /* abbreviation list index */
|
||||||
|
bool ttisstd; /* transition is std time */
|
||||||
|
bool ttisut; /* transition is UT */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* leap second information */
|
||||||
|
struct lsinfo
|
||||||
|
{
|
||||||
|
time_t trans; /* transition time */
|
||||||
|
int_fast64_t corr; /* correction to apply */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BIGGEST( a, b ) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
#ifndef TZ_MAX_TIMES
|
||||||
|
#define TZ_MAX_TIMES 2000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TZ_MAX_TYPES
|
||||||
|
/* This must be at least 17 for Europe/Vilnius. */
|
||||||
|
/* Limited by what (unsigned char)s can hold */
|
||||||
|
#define TZ_MAX_TYPES 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TZ_MAX_CHARS
|
||||||
|
/* Maximum number of abbreviation characters */
|
||||||
|
/* Limited by what (unsigned char)s can hold */
|
||||||
|
#define TZ_MAX_CHARS 50
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TZ_MAX_LEAPS
|
||||||
|
/* Maximum number of leap second corrections */
|
||||||
|
#define TZ_MAX_LEAPS 50
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TZNAME_MAX
|
||||||
|
#define MY_TZNAME_MAX TZNAME_MAX
|
||||||
|
#else
|
||||||
|
#define MY_TZNAME_MAX 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct state
|
||||||
|
{
|
||||||
|
int leapcnt;
|
||||||
|
int timecnt;
|
||||||
|
int typecnt;
|
||||||
|
int charcnt;
|
||||||
|
bool goback;
|
||||||
|
bool goahead;
|
||||||
|
time_t ats[ TZ_MAX_TIMES ];
|
||||||
|
unsigned char types[ TZ_MAX_TIMES ];
|
||||||
|
struct ttinfo ttis[ TZ_MAX_TYPES ];
|
||||||
|
char chars[ BIGGEST( BIGGEST( TZ_MAX_CHARS + 1, sizeof gmt ), ( 2 * ( MY_TZNAME_MAX + 1 ) ) ) ];
|
||||||
|
struct lsinfo lsis[ TZ_MAX_LEAPS ];
|
||||||
|
|
||||||
|
/* The time type to use for early times or if no transitions.
|
||||||
|
It is always zero for recent tzdb releases.
|
||||||
|
It might be nonzero for data from tzdb 2018e or earlier.
|
||||||
|
*/
|
||||||
|
int defaulttype;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct state _PDCLIB_lclmem;
|
||||||
|
extern struct state _PDCLIB_gmtmem;
|
||||||
|
|
||||||
|
void _PDCLIB_gmtcheck(void);
|
||||||
|
struct tm * _PDCLIB_gmtsub( struct state const * sp, time_t const * timep, int_fast32_t offset, struct tm * tmp );
|
||||||
|
bool _PDCLIB_increment_overflow( int * ip, int j );
|
||||||
|
void _PDCLIB_init_ttinfo( struct ttinfo * s, int_fast32_t utoff, bool isdst, int desigidx );
|
||||||
|
struct tm * _PDCLIB_localsub( struct state const * sp, time_t const * timep, int_fast32_t setname, struct tm * const tmp );
|
||||||
|
struct tm * _PDCLIB_localtime_tzset( time_t const * timep, struct tm * tmp, bool setname );
|
||||||
|
time_t _PDCLIB_mktime_tzname( struct state * sp, struct tm * tmp, bool setname );
|
||||||
|
struct tm * _PDCLIB_timesub( const time_t * timep, int_fast32_t offset, const struct state * sp, struct tm * tmp );
|
||||||
|
int _PDCLIB_tzload( char const * name, struct state * sp, bool doextend );
|
||||||
|
bool _PDCLIB_tzparse(char const *, struct state *, bool);
|
||||||
|
void _PDCLIB_tzset_unlocked( void );
|
||||||
|
void _PDCLIB_update_tzname_etc( struct state const * sp, struct ttinfo const * ttisp );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
91
rocklibc/include/signal.h
Normal file
91
rocklibc/include/signal.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/* Signal handling <signal.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_SIGNAL_H
|
||||||
|
#define _PDCLIB_SIGNAL_H _PDCLIB_SIGNAL_H
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* Signals ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/* A word on signals, to the people using PDCLib in their OS projects.
|
||||||
|
|
||||||
|
The definitions of the C standard leave about everything that *could* be
|
||||||
|
useful to be "implementation defined". Without additional, non-standard
|
||||||
|
arrangements, it is not possible to turn them into a useful tool.
|
||||||
|
|
||||||
|
This example implementation chose to "not generate any of these signals,
|
||||||
|
except as a result of explicit calls to the raise function", which is
|
||||||
|
allowed by the standard but of course does nothing for the usefulness of
|
||||||
|
<signal.h>.
|
||||||
|
|
||||||
|
A useful signal handling would:
|
||||||
|
1) make signal() a system call that registers the signal handler with the OS
|
||||||
|
2) make raise() a system call triggering an OS signal to the running process
|
||||||
|
3) make provisions that further signals of the same type are blocked until
|
||||||
|
the signal handler returns (optional for SIGILL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* These are the values used by Linux. */
|
||||||
|
|
||||||
|
/* Abnormal termination / abort() */
|
||||||
|
#define SIGABRT 6
|
||||||
|
/* Arithmetic exception / division by zero / overflow */
|
||||||
|
#define SIGFPE 8
|
||||||
|
/* Illegal instruction */
|
||||||
|
#define SIGILL 4
|
||||||
|
/* Interactive attention signal */
|
||||||
|
#define SIGINT 2
|
||||||
|
/* Invalid memory access */
|
||||||
|
#define SIGSEGV 11
|
||||||
|
/* Termination request */
|
||||||
|
#define SIGTERM 15
|
||||||
|
|
||||||
|
/* The following should be defined to pointer values that could NEVER point to
|
||||||
|
a valid signal handler function. (They are used as special arguments to
|
||||||
|
signal().) Again, these are the values used by Linux.
|
||||||
|
*/
|
||||||
|
#define SIG_DFL (void (*)( int ))0
|
||||||
|
#define SIG_ERR (void (*)( int ))-1
|
||||||
|
#define SIG_IGN (void (*)( int ))1
|
||||||
|
|
||||||
|
typedef _PDCLIB_sig_atomic_t sig_atomic_t;
|
||||||
|
|
||||||
|
/* Installs a signal handler "func" for the given signal.
|
||||||
|
A signal handler is a function that takes an integer as argument (the signal
|
||||||
|
number) and returns void.
|
||||||
|
|
||||||
|
Note that a signal handler can do very little else than:
|
||||||
|
1) assign a value to a static object of type "volatile sig_atomic_t",
|
||||||
|
2) call signal() with the value of sig equal to the signal received,
|
||||||
|
3) call _Exit(),
|
||||||
|
4) call abort().
|
||||||
|
Virtually everything else is undefind.
|
||||||
|
|
||||||
|
The signal() function returns the previous installed signal handler, which
|
||||||
|
at program start may be SIG_DFL or SIG_ILL. (This implementation uses
|
||||||
|
SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is
|
||||||
|
returned and errno is set to an unspecified positive value.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void ( *signal( int sig, void ( *func )( int ) ) )( int );
|
||||||
|
|
||||||
|
/* Raises the given signal (executing the registered signal handler with the
|
||||||
|
given signal number as parameter).
|
||||||
|
This implementation does not prevent further signals of the same time from
|
||||||
|
occuring, but executes signal( sig, SIG_DFL ) before entering the signal
|
||||||
|
handler (i.e., a second signal before the signal handler re-registers itself
|
||||||
|
or SIG_IGN will end the program).
|
||||||
|
Returns zero if successful, nonzero otherwise. */
|
||||||
|
_PDCLIB_PUBLIC int raise( int sig );
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_SIGNAL_H
|
||||||
|
#include _PDCLIB_EXTEND_SIGNAL_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
30
rocklibc/include/stdalign.h
Normal file
30
rocklibc/include/stdalign.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* Alignment <stdalign.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDALIGN_H
|
||||||
|
#define _PDCLIB_STDALIGN_H _PDCLIB_STDALIGN_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define __alignas_is_defined 1
|
||||||
|
#define __alignof_is_defined 1
|
||||||
|
|
||||||
|
#if ! defined( __STDC_VERSION__ ) || ( __STDC_VERSION__ < 202311L )
|
||||||
|
#define alignas _Alignas
|
||||||
|
#define alignof _Alignof
|
||||||
|
#elif __STDC_VERSION__ >= 202311L
|
||||||
|
#warning <stdalign.h> has been deprecated as of C23.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDALIGN_H
|
||||||
|
#include _PDCLIB_EXTEND_STDALIGN_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
34
rocklibc/include/stdarg.h
Normal file
34
rocklibc/include/stdarg.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/* Variable arguments <stdarg.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDARG_H
|
||||||
|
#define _PDCLIB_STDARG_H _PDCLIB_STDARG_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_config.h"
|
||||||
|
|
||||||
|
typedef _PDCLIB_va_list va_list;
|
||||||
|
|
||||||
|
#define va_arg( ap, type ) _PDCLIB_va_arg( ap, type )
|
||||||
|
#define va_copy( dest, src ) _PDCLIB_va_copy( dest, src )
|
||||||
|
#define va_end( ap ) _PDCLIB_va_end( ap )
|
||||||
|
#define va_start( ap, parmN ) _PDCLIB_va_start( ap, parmN )
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDARG_H
|
||||||
|
#include _PDCLIB_EXTEND_STDARG_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
24
rocklibc/include/stdbool.h
Normal file
24
rocklibc/include/stdbool.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* Boolean type and values <stdbool.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDBOOL_H
|
||||||
|
#define _PDCLIB_STDBOOL_H _PDCLIB_STDBOOL_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define bool _Bool
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
#define __bool_true_false_are_defined 1
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDBOOL_H
|
||||||
|
#include _PDCLIB_EXTEND_STDBOOL_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
55
rocklibc/include/stddef.h
Normal file
55
rocklibc/include/stddef.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/* Common definitions <stddef.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDDEF_H
|
||||||
|
#define _PDCLIB_STDDEF_H _PDCLIB_STDDEF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
typedef _PDCLIB_ptrdiff_t ptrdiff_t;
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_SIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
typedef _PDCLIB_wchar_t wchar_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NULL_DEFINED
|
||||||
|
#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
|
||||||
|
#define NULL _PDCLIB_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define offsetof( type, member ) _PDCLIB_offsetof( type, member )
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
#ifndef _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
typedef size_t rsize_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDDEF_H
|
||||||
|
#include _PDCLIB_EXTEND_STDDEF_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
236
rocklibc/include/stdint.h
Normal file
236
rocklibc/include/stdint.h
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/* Integer types <stdint.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDINT_H
|
||||||
|
#define _PDCLIB_STDINT_H _PDCLIB_STDINT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* 7.18.1.1 Exact-width integer types. */
|
||||||
|
|
||||||
|
#ifdef _PDCLIB_int8_t
|
||||||
|
typedef _PDCLIB_int8_t int8_t;
|
||||||
|
typedef _PDCLIB_uint8_t uint8_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _PDCLIB_int16_t
|
||||||
|
typedef _PDCLIB_int16_t int16_t;
|
||||||
|
typedef _PDCLIB_uint16_t uint16_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _PDCLIB_int32_t
|
||||||
|
typedef _PDCLIB_int32_t int32_t;
|
||||||
|
typedef _PDCLIB_uint32_t uint32_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _PDCLIB_int64_t
|
||||||
|
typedef _PDCLIB_int64_t int64_t;
|
||||||
|
typedef _PDCLIB_uint64_t uint64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.1.2 Minimum-width integer types */
|
||||||
|
|
||||||
|
/* You are allowed to add more types here, e.g. int_least24_t. */
|
||||||
|
|
||||||
|
typedef _PDCLIB_int_least8_t int_least8_t;
|
||||||
|
typedef _PDCLIB_int_least16_t int_least16_t;
|
||||||
|
typedef _PDCLIB_int_least32_t int_least32_t;
|
||||||
|
typedef _PDCLIB_int_least64_t int_least64_t;
|
||||||
|
|
||||||
|
typedef _PDCLIB_uint_least8_t uint_least8_t;
|
||||||
|
typedef _PDCLIB_uint_least16_t uint_least16_t;
|
||||||
|
typedef _PDCLIB_uint_least32_t uint_least32_t;
|
||||||
|
typedef _PDCLIB_uint_least64_t uint_least64_t;
|
||||||
|
|
||||||
|
/* 7.18.1.3 Fastest minimum-width integer types */
|
||||||
|
|
||||||
|
/* You are allowed to add more types here, e.g. int_fast24_t. */
|
||||||
|
|
||||||
|
typedef _PDCLIB_int_fast8_t int_fast8_t;
|
||||||
|
typedef _PDCLIB_int_fast16_t int_fast16_t;
|
||||||
|
typedef _PDCLIB_int_fast32_t int_fast32_t;
|
||||||
|
typedef _PDCLIB_int_fast64_t int_fast64_t;
|
||||||
|
|
||||||
|
typedef _PDCLIB_uint_fast8_t uint_fast8_t;
|
||||||
|
typedef _PDCLIB_uint_fast16_t uint_fast16_t;
|
||||||
|
typedef _PDCLIB_uint_fast32_t uint_fast32_t;
|
||||||
|
typedef _PDCLIB_uint_fast64_t uint_fast64_t;
|
||||||
|
|
||||||
|
/* 7.18.1.4 Integer types capable of holding object pointers */
|
||||||
|
|
||||||
|
typedef _PDCLIB_intptr_t intptr_t;
|
||||||
|
typedef _PDCLIB_uintptr_t uintptr_t;
|
||||||
|
|
||||||
|
/* 7.18.1.5 Greatest-width integer types */
|
||||||
|
|
||||||
|
typedef _PDCLIB_intmax_t intmax_t;
|
||||||
|
typedef _PDCLIB_uintmax_t uintmax_t;
|
||||||
|
|
||||||
|
/* 7.18.2 Limits of specified-width integer types */
|
||||||
|
|
||||||
|
#if defined( __cplusplus ) && __cplusplus < 201103L
|
||||||
|
#ifndef __STDC_LIMIT_MACROS
|
||||||
|
#define _PDCLIB_NO_LIMIT_MACROS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NO_LIMIT_MACROS
|
||||||
|
|
||||||
|
/* 7.18.2.1 Limits of exact-width integer types */
|
||||||
|
|
||||||
|
#if _PDCLIB_TWOS_COMPLEMENT == 1
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST8_MAX == 0x7f
|
||||||
|
#define INT8_MAX _PDCLIB_INT_LEAST8_MAX
|
||||||
|
#define INT8_MIN _PDCLIB_INT_LEAST8_MIN
|
||||||
|
#define UINT8_MAX _PDCLIB_UINT_LEAST8_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST16_MAX == 0x7fff
|
||||||
|
#define INT16_MAX _PDCLIB_INT_LEAST16_MAX
|
||||||
|
#define INT16_MIN _PDCLIB_INT_LEAST16_MIN
|
||||||
|
#define UINT16_MAX _PDCLIB_UINT_LEAST16_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST32_MAX == 0x7fffffffl
|
||||||
|
#define INT32_MAX _PDCLIB_INT_LEAST32_MAX
|
||||||
|
#define INT32_MIN _PDCLIB_INT_LEAST32_MIN
|
||||||
|
#define UINT32_MAX _PDCLIB_UINT_LEAST32_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _PDCLIB_INT_LEAST64_MAX == 0x7fffffffffffffffll
|
||||||
|
#define INT64_MAX _PDCLIB_INT_LEAST64_MAX
|
||||||
|
#define INT64_MIN _PDCLIB_INT_LEAST64_MIN
|
||||||
|
#define UINT64_MAX _PDCLIB_UINT_LEAST64_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.2.2 Limits of minimum-width integer types */
|
||||||
|
|
||||||
|
#define INT_LEAST8_MIN _PDCLIB_INT_LEAST8_MIN
|
||||||
|
#define INT_LEAST8_MAX _PDCLIB_INT_LEAST8_MAX
|
||||||
|
#define UINT_LEAST8_MAX _PDCLIB_UINT_LEAST8_MAX
|
||||||
|
|
||||||
|
#define INT_LEAST16_MIN _PDCLIB_INT_LEAST16_MIN
|
||||||
|
#define INT_LEAST16_MAX _PDCLIB_INT_LEAST16_MAX
|
||||||
|
#define UINT_LEAST16_MAX _PDCLIB_UINT_LEAST16_MAX
|
||||||
|
|
||||||
|
#define INT_LEAST32_MIN _PDCLIB_INT_LEAST32_MIN
|
||||||
|
#define INT_LEAST32_MAX _PDCLIB_INT_LEAST32_MAX
|
||||||
|
#define UINT_LEAST32_MAX _PDCLIB_UINT_LEAST32_MAX
|
||||||
|
|
||||||
|
#define INT_LEAST64_MIN _PDCLIB_INT_LEAST64_MIN
|
||||||
|
#define INT_LEAST64_MAX _PDCLIB_INT_LEAST64_MAX
|
||||||
|
#define UINT_LEAST64_MAX _PDCLIB_UINT_LEAST64_MAX
|
||||||
|
|
||||||
|
/* 7.18.2.3 Limits of fastest minimum-width integer types */
|
||||||
|
|
||||||
|
#define INT_FAST8_MIN _PDCLIB_INT_FAST8_MIN
|
||||||
|
#define INT_FAST8_MAX _PDCLIB_INT_FAST8_MAX
|
||||||
|
#define UINT_FAST8_MAX _PDCLIB_UINT_FAST8_MAX
|
||||||
|
|
||||||
|
#define INT_FAST16_MIN _PDCLIB_INT_FAST16_MIN
|
||||||
|
#define INT_FAST16_MAX _PDCLIB_INT_FAST16_MAX
|
||||||
|
#define UINT_FAST16_MAX _PDCLIB_UINT_FAST16_MAX
|
||||||
|
|
||||||
|
#define INT_FAST32_MIN _PDCLIB_INT_FAST32_MIN
|
||||||
|
#define INT_FAST32_MAX _PDCLIB_INT_FAST32_MAX
|
||||||
|
#define UINT_FAST32_MAX _PDCLIB_UINT_FAST32_MAX
|
||||||
|
|
||||||
|
#define INT_FAST64_MIN _PDCLIB_INT_FAST64_MIN
|
||||||
|
#define INT_FAST64_MAX _PDCLIB_INT_FAST64_MAX
|
||||||
|
#define UINT_FAST64_MAX _PDCLIB_UINT_FAST64_MAX
|
||||||
|
|
||||||
|
/* 7.18.2.4 Limits of integer types capable of holding object pointers */
|
||||||
|
|
||||||
|
#define INTPTR_MIN _PDCLIB_INTPTR_MIN
|
||||||
|
#define INTPTR_MAX _PDCLIB_INTPTR_MAX
|
||||||
|
#define UINTPTR_MAX _PDCLIB_UINTPTR_MAX
|
||||||
|
|
||||||
|
/* 7.18.2.5 Limits of greatest-width integer types */
|
||||||
|
|
||||||
|
#define INTMAX_MIN _PDCLIB_INTMAX_MIN
|
||||||
|
#define INTMAX_MAX _PDCLIB_INTMAX_MAX
|
||||||
|
#define UINTMAX_MAX _PDCLIB_UINTMAX_MAX
|
||||||
|
|
||||||
|
/* 7.18.3 Limits of other integer types */
|
||||||
|
|
||||||
|
#define PTRDIFF_MIN _PDCLIB_PTRDIFF_MIN
|
||||||
|
#define PTRDIFF_MAX _PDCLIB_PTRDIFF_MAX
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_MIN _PDCLIB_SIG_ATOMIC_MIN
|
||||||
|
#define SIG_ATOMIC_MAX _PDCLIB_SIG_ATOMIC_MAX
|
||||||
|
|
||||||
|
#define SIZE_MAX _PDCLIB_SIZE_MAX
|
||||||
|
|
||||||
|
#define WCHAR_MIN _PDCLIB_WCHAR_MIN
|
||||||
|
#define WCHAR_MAX _PDCLIB_WCHAR_MAX
|
||||||
|
|
||||||
|
#define WINT_MIN _PDCLIB_WINT_MIN
|
||||||
|
#define WINT_MAX _PDCLIB_WINT_MAX
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.4 Macros for integer constants */
|
||||||
|
|
||||||
|
#if defined( __cplusplus ) && __cplusplus < 201103L
|
||||||
|
#ifndef __STDC_CONSTANT_MACROS
|
||||||
|
#define _PDCLIB_NO_CONSTANT_MACROS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NO_CONSTANT_MACROS
|
||||||
|
|
||||||
|
/* 7.18.4.1 Macros for minimum-width integer constants */
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type int_leastN_t */
|
||||||
|
|
||||||
|
#define INT8_C _PDCLIB_INT_LEAST8_C
|
||||||
|
#define INT16_C _PDCLIB_INT_LEAST16_C
|
||||||
|
#define INT32_C _PDCLIB_INT_LEAST32_C
|
||||||
|
#define INT64_C _PDCLIB_INT_LEAST64_C
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type uint_leastN_t */
|
||||||
|
|
||||||
|
#define UINT8_C _PDCLIB_UINT_LEAST8_C
|
||||||
|
#define UINT16_C _PDCLIB_UINT_LEAST16_C
|
||||||
|
#define UINT32_C _PDCLIB_UINT_LEAST32_C
|
||||||
|
#define UINT64_C _PDCLIB_UINT_LEAST64_C
|
||||||
|
|
||||||
|
/* 7.18.4.2 Macros for greatest-width integer constants */
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type intmax_t */
|
||||||
|
#define INTMAX_C( value ) _PDCLIB_INTMAX_C( value )
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type uintmax_t */
|
||||||
|
#define UINTMAX_C( value ) _PDCLIB_UINTMAX_C( value )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
#define RSIZE_MAX ( _PDCLIB_SIZE_MAX >> 1 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDINT_H
|
||||||
|
#include _PDCLIB_EXTEND_STDINT_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
935
rocklibc/include/stdio.h
Normal file
935
rocklibc/include/stdio.h
Normal file
@@ -0,0 +1,935 @@
|
|||||||
|
/* Input/output <stdio.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDIO_H
|
||||||
|
#define _PDCLIB_STDIO_H _PDCLIB_STDIO_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_SIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NULL_DEFINED
|
||||||
|
#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
|
||||||
|
#define NULL _PDCLIB_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* See setvbuf(), third argument */
|
||||||
|
#define _IOFBF (1u<<0)
|
||||||
|
#define _IOLBF (1u<<1)
|
||||||
|
#define _IONBF (1u<<2)
|
||||||
|
|
||||||
|
/* The following are platform-dependent, and defined in _PDCLIB_config.h. */
|
||||||
|
typedef struct _PDCLIB_fpos_t fpos_t;
|
||||||
|
typedef struct _PDCLIB_file_t FILE;
|
||||||
|
#define EOF (-1)
|
||||||
|
#define BUFSIZ _PDCLIB_BUFSIZ
|
||||||
|
#define FOPEN_MAX _PDCLIB_FOPEN_MAX
|
||||||
|
#define FILENAME_MAX _PDCLIB_FILENAME_MAX
|
||||||
|
#define L_tmpnam _PDCLIB_L_tmpnam
|
||||||
|
#define TMP_MAX _PDCLIB_TMP_MAX
|
||||||
|
|
||||||
|
/* See fseek(), third argument */
|
||||||
|
#define SEEK_CUR _PDCLIB_SEEK_CUR
|
||||||
|
#define SEEK_END _PDCLIB_SEEK_END
|
||||||
|
#define SEEK_SET _PDCLIB_SEEK_SET
|
||||||
|
|
||||||
|
extern FILE * stdin;
|
||||||
|
extern FILE * stdout;
|
||||||
|
extern FILE * stderr;
|
||||||
|
|
||||||
|
/* Operations on files */
|
||||||
|
|
||||||
|
/* Remove the given file.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
This implementation does detect if a file of that name is currently open,
|
||||||
|
and fails the remove in this case. This does not detect two distinct names
|
||||||
|
that merely result in the same file (e.g. "/home/user/foo" vs. "~/foo").
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int remove( const char * filename );
|
||||||
|
|
||||||
|
/* Rename the given old file to the given new name.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
This implementation does detect if the old filename corresponds to an open
|
||||||
|
file, and fails the rename in this case.
|
||||||
|
If there already is a file with the new filename, behaviour is defined by
|
||||||
|
the glue code (see functions/_PDCLIB/rename.c).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int rename( const char * oldpath, const char * newpath );
|
||||||
|
|
||||||
|
/* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file
|
||||||
|
automatically if it is closed or the program exits normally (by returning
|
||||||
|
from main() or calling exit()).
|
||||||
|
Returns a pointer to a FILE handle for this file.
|
||||||
|
This implementation does not remove temporary files if the process aborts
|
||||||
|
abnormally (e.g. abort()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC FILE * tmpfile( void );
|
||||||
|
|
||||||
|
/* Generate a file name that is not equal to any existing filename AT THE TIME
|
||||||
|
OF GENERATION. Generate a different name each time it is called.
|
||||||
|
Returns a pointer to an internal static buffer containing the filename if s
|
||||||
|
is a NULL pointer. (This is not thread-safe!)
|
||||||
|
Returns s if it is not a NULL pointer (s is then assumed to point to an array
|
||||||
|
of at least L_tmpnam characters).
|
||||||
|
Returns NULL if unable to generate a suitable name (because all possible
|
||||||
|
names already exist, or the function has been called TMP_MAX times already).
|
||||||
|
Note that this implementation cannot guarantee a file of the name generated
|
||||||
|
is not generated between the call to this function and a subsequent fopen().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * tmpnam( char * s );
|
||||||
|
|
||||||
|
/* File access functions */
|
||||||
|
|
||||||
|
/* Close the file associated with the given stream (after flushing its buffers).
|
||||||
|
Returns zero if successful, EOF if any errors occur.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fclose( FILE * stream );
|
||||||
|
|
||||||
|
/* Flush the buffers of the given output stream. If the stream is an input
|
||||||
|
stream, or an update stream with the last operation being an input operation,
|
||||||
|
behaviour is undefined.
|
||||||
|
If stream is a NULL pointer, perform the buffer flushing for all applicable
|
||||||
|
streams.
|
||||||
|
Returns zero if successful, EOF if a write error occurs.
|
||||||
|
Sets the error indicator of the stream if a write error occurs.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fflush( FILE * stream );
|
||||||
|
|
||||||
|
/* Open the file with the given filename in the given mode, and return a stream
|
||||||
|
handle for it in which error and end-of-file indicator are cleared. Defined
|
||||||
|
values for mode are:
|
||||||
|
|
||||||
|
READ MODES
|
||||||
|
text files binary files
|
||||||
|
without update "r" "rb"
|
||||||
|
with update "r+" "rb+" or "r+b"
|
||||||
|
|
||||||
|
Opening in read mode fails if no file with the given filename exists, or if
|
||||||
|
cannot be read.
|
||||||
|
|
||||||
|
WRITE MODES
|
||||||
|
text files binary files
|
||||||
|
without update "w" "wb"
|
||||||
|
with update "w+" "wb+" or "w+b"
|
||||||
|
|
||||||
|
With write modes, if a file with the given filename already exists, it is
|
||||||
|
truncated to zero length.
|
||||||
|
|
||||||
|
APPEND MODES
|
||||||
|
text files binary files
|
||||||
|
without update "a" "ab"
|
||||||
|
with update "a+" "ab+" or "a+b"
|
||||||
|
|
||||||
|
With update modes, if a file with the given filename already exists, it is
|
||||||
|
not truncated to zero length, but all writes are forced to end-of-file (this
|
||||||
|
regardless to fseek() calls). Note that binary files opened in append mode
|
||||||
|
might have their end-of-file padded with '\0' characters.
|
||||||
|
|
||||||
|
Update modes mean that both input and output functions can be performed on
|
||||||
|
the stream, but output must be terminated with a call to either fflush(),
|
||||||
|
fseek(), fsetpos(), or rewind() before input is performed, and input must
|
||||||
|
be terminated with a call to either fseek(), fsetpos(), or rewind() before
|
||||||
|
output is performed, unless input encountered end-of-file.
|
||||||
|
|
||||||
|
If a text file is opened with update mode, the implementation is at liberty
|
||||||
|
to open a binary stream instead. This implementation honors the exact mode
|
||||||
|
given.
|
||||||
|
|
||||||
|
The stream is fully buffered if and only if it can be determined not to
|
||||||
|
refer to an interactive device.
|
||||||
|
|
||||||
|
If the mode string begins with but is longer than one of the above sequences
|
||||||
|
the implementation is at liberty to ignore the additional characters, or do
|
||||||
|
implementation-defined things. This implementation only accepts the exact
|
||||||
|
modes above.
|
||||||
|
|
||||||
|
Returns a pointer to the stream handle if successfull, NULL otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode );
|
||||||
|
|
||||||
|
/* Close any file currently associated with the given stream. Open the file
|
||||||
|
identified by the given filename with the given mode (equivalent to fopen()),
|
||||||
|
and associate it with the given stream. If filename is a NULL pointer,
|
||||||
|
attempt to change the mode of the given stream.
|
||||||
|
This implementation allows any mode changes on "real" files, and associating
|
||||||
|
of the standard streams with files. It does *not* support mode changes on
|
||||||
|
standard streams.
|
||||||
|
(Primary use of this function is to redirect stdin, stdout, and stderr.)
|
||||||
|
|
||||||
|
Returns a pointer to the stream handle if successfull, NULL otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC FILE * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream );
|
||||||
|
|
||||||
|
/* If buf is a NULL pointer, call setvbuf( stream, NULL, _IONBF, BUFSIZ ).
|
||||||
|
If buf is not a NULL pointer, call setvbuf( stream, buf, _IOFBF, BUFSIZ ).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void setbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf );
|
||||||
|
|
||||||
|
/* Set the given stream to the given buffering mode. If buf is not a NULL
|
||||||
|
pointer, use buf as file buffer (of given size). If buf is a NULL pointer,
|
||||||
|
use a buffer of given size allocated internally. _IONBF causes unbuffered
|
||||||
|
behaviour, _IOLBF causes line-buffered behaviour, _IOFBF causes fully
|
||||||
|
buffered behaviour. Calling this function is only valid right after a file is
|
||||||
|
opened, and before any other operation (except for any unsuccessful calls to
|
||||||
|
setvbuf()) has been performed.
|
||||||
|
Returns zero if successful, nonzero otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size );
|
||||||
|
|
||||||
|
/* Formatted input/output functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write output to the given stream, as defined by the given format string and
|
||||||
|
0..n subsequent arguments (the argument stack).
|
||||||
|
|
||||||
|
The format string is written to the given stream verbatim, except for any
|
||||||
|
conversion specifiers included, which start with the letter '%' and are
|
||||||
|
documented below. If the given conversion specifiers require more arguments
|
||||||
|
from the argument stack than provided, behaviour is undefined. Additional
|
||||||
|
arguments not required by conversion specifiers are evaluated but otherwise
|
||||||
|
ignored.
|
||||||
|
|
||||||
|
(The standard specifies the format string is allowed to contain multibyte
|
||||||
|
character sequences as long as it starts and ends in initial shift state,
|
||||||
|
but this is not yet supported by this implementation, which interprets the
|
||||||
|
format string as sequence of char.)
|
||||||
|
TODO: Add multibyte support to printf() functions.
|
||||||
|
|
||||||
|
A conversion specifier consists of:
|
||||||
|
- Zero or more flags (one of the characters "-+ #0").
|
||||||
|
- Optional minimum field width as decimal integer. Default is padding to the
|
||||||
|
left, using spaces. Note that 0 is taken as a flag, not the beginning of a
|
||||||
|
field width. Note also that a small field width will not result in the
|
||||||
|
truncation of a value.
|
||||||
|
- Optional precision (given as ".#" with # being a decimal integer),
|
||||||
|
specifying:
|
||||||
|
- the min. number of digits to appear (diouxX),
|
||||||
|
- the max. number of digits after the decimal point (aAeEfF),
|
||||||
|
- the max. number of significant digits (gG),
|
||||||
|
- the max. number of bytes to be written (s).
|
||||||
|
- behaviour with other conversion specifiers is undefined.
|
||||||
|
- Optional length modifier specifying the size of the argument (one of "hh",
|
||||||
|
"ll", or one of the characters "hljztL").
|
||||||
|
- Conversion specifier character specifying the type of conversion to be
|
||||||
|
applied (and the type of the next argument from the argument stack). One
|
||||||
|
of the characters "diouxXfFeEgGaAcspn%".
|
||||||
|
|
||||||
|
Minimum field width and/or precision may be given as asterisk ('*') instead
|
||||||
|
of a decimal integer. In this case, the next argument from the argument
|
||||||
|
stack is assumed to be an int value specifying the width / precision. A
|
||||||
|
negative field width is interpreted as flag '-' followed by a positive field
|
||||||
|
width. A negative precision is interpreted as if no precision was given.
|
||||||
|
|
||||||
|
FLAGS
|
||||||
|
- Left-justify the conversion result within its field width.
|
||||||
|
+ Prefix a '+' on positive signed conversion results. Prefix a '-' on
|
||||||
|
floating conversions resulting in negative zero, or negative values
|
||||||
|
rounding to zero.
|
||||||
|
space Prefix a space on positive signed conversion results, or if a signed
|
||||||
|
conversion results in no characters. If both '+' and ' ' are given,
|
||||||
|
' ' is ignored.
|
||||||
|
# Use an "alternative form" for
|
||||||
|
- 'o' conversion, increasing precision until the first digit of the
|
||||||
|
result is a zero;
|
||||||
|
- 'x' or 'X' conversion, prefixing "0x" or "0X" to nonzero results;
|
||||||
|
- "aAeEfF" conversions, always printing a decimal point even if no
|
||||||
|
digits are following;
|
||||||
|
- 'g' or 'G' conversions, always printing a decimal point even if no
|
||||||
|
digits are following, and not removing trailing zeroes.
|
||||||
|
- behaviour for other conversions is unspecified.
|
||||||
|
0 Use leading zeroes instead of spaces for field width padding. If both
|
||||||
|
'-' and '0' are given, '0' is ignored. If a precision is specified for
|
||||||
|
any of the "diouxX" conversions, '0' is ignored. Behaviour is only
|
||||||
|
defined for "diouxXaAeEfFgG".
|
||||||
|
|
||||||
|
LENGTH MODIFIERS
|
||||||
|
hh For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of char width. (It will have been subject to integer
|
||||||
|
promotion but will be converted back.) For 'n' conversions, the argument
|
||||||
|
is assumed to be a pointer to signed char.
|
||||||
|
h For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of short int width. (It will have been subject to integer
|
||||||
|
promotion but will be converted back.) For 'n' conversions, the argument
|
||||||
|
is assumed to be a pointer to short int.
|
||||||
|
l For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of long int width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to short int. For 'c' conversions, the argument
|
||||||
|
is assumed to be a wint_t. For 's' conversions, the argument is assumed
|
||||||
|
to be a pointer to wchar_t. No effect on "aAeEfFgG" conversions.
|
||||||
|
ll For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of long long int width. For 'n' conversions, the argument
|
||||||
|
is assumed to be a pointer to long long int.
|
||||||
|
j For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of intmax_t width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to intmax_t.
|
||||||
|
z For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of size_t width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to size_t.
|
||||||
|
t For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of ptrdiff_t width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to ptrdiff_t.
|
||||||
|
L For "aAeEfFgG" conversions, the argument from the argument stack is
|
||||||
|
assumed to be a long double.
|
||||||
|
Length modifiers appearing for any conversions not mentioned above will have
|
||||||
|
undefined behaviour.
|
||||||
|
If a length modifier appears with any conversion specifier other than as
|
||||||
|
specified above, the behavior is undefined.
|
||||||
|
|
||||||
|
CONVERSION SPECIFIERS
|
||||||
|
d,i The argument from the argument stack is assumed to be of type int, and
|
||||||
|
is converted to a signed decimal value with a minimum number of digits
|
||||||
|
as specified by the precision (default 1), padded with leading zeroes.
|
||||||
|
A zero value converted with precision zero yields no output.
|
||||||
|
o The argument from the argument stack is assumed to be of type unsigned
|
||||||
|
int, and is converted to an unsigned octal value, other behaviour being
|
||||||
|
as above.
|
||||||
|
u The argument from the argument stack is assumed to be of type unsigned
|
||||||
|
int, and converted to an unsigned decimal value, other behaviour being
|
||||||
|
as above.
|
||||||
|
x,X The argument from the argument stack is assumed to be of type unsigned
|
||||||
|
int, and converted to an unsigned hexadecimal value, using lowercase
|
||||||
|
"abcdef" for 'x' and uppercase "ABCDEF" for 'X' conversion, other
|
||||||
|
behaviour being as above.
|
||||||
|
f,F The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted to a decimal floating point in decimal-point notation,
|
||||||
|
with the number of digits after the decimal point as specified by the
|
||||||
|
precision (default 6) and the value being rounded appropriately. If
|
||||||
|
precision is zero (and the '#' flag is not given), no decimal point is
|
||||||
|
printed. At least one digit is always printed before the decimal point.
|
||||||
|
For 'f' conversions, an infinity value is printed as either [-]inf or
|
||||||
|
[-]infinity (, depending on the configuration of this implementation. A
|
||||||
|
NaN value is printed as [-]nan. For 'F' conversions uppercase characters
|
||||||
|
are used for these special values. The flags '-', '+' and ' ' apply as
|
||||||
|
usual to these special values, '#' and '0' have no effect.
|
||||||
|
e,E The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted to a decimal floating point in normalized exponential
|
||||||
|
notation ([?]d.ddd edd). "Normalized" means one nonzero digit before
|
||||||
|
the decimal point, unless the value is zero. The number of digits after
|
||||||
|
the decimal point is specified by the precision (default 6), the value
|
||||||
|
being rounded appropriately. If precision is zero (and the '#' flag is
|
||||||
|
not given), no decimal point is printed. The exponent has at least two
|
||||||
|
digits, and not more than necessary to represent the exponent. If the
|
||||||
|
value is zero, the exponent is zero. The 'e' written to indicate the
|
||||||
|
exponend is uppercase for 'E' conversions.
|
||||||
|
Infinity or NaN values are represented as for 'f' and 'F' conversions,
|
||||||
|
respectively.
|
||||||
|
g,G The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted according to either 'f' or 'e' format for 'g' conversions,
|
||||||
|
or 'F' or 'E' format for 'G' conversions, respectively, with the actual
|
||||||
|
conversion chosen depending on the value. 'e' / 'E' conversion is chosen
|
||||||
|
if the resulting exponent is < -4 or >= the precision (default 1).
|
||||||
|
Trailing zeroes are removed (unless the '#' flag is given). A decimal
|
||||||
|
point appears only if followed by a digit.
|
||||||
|
Infinity or NaN values are represented as for 'f' and 'F' conversions,
|
||||||
|
respectively.
|
||||||
|
a,A The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted to a floating point hexadecimal notation ([?]0xh.hhhh pd)
|
||||||
|
with one hexadecimal digit (being nonzero if the value is normalized,
|
||||||
|
and otherwise unspecified) before the decimal point, and the number of
|
||||||
|
digits after the decimal point being specified by the precision. If no
|
||||||
|
precision is given, the default is to print as many digits as nevessary
|
||||||
|
to give an exact representation of the value (if FLT_RADIX is a power of
|
||||||
|
2). If no precision is given and FLT_RADIX is not a power of 2, the
|
||||||
|
default is to print as many digits to distinguish values of type double
|
||||||
|
(possibly omitting trailing zeroes). (A precision p is sufficient to
|
||||||
|
distinguish values of the source type if 16^p-1 > b^n where b is
|
||||||
|
FLT_RADIX and n is the number of digits in the significand (to base b)
|
||||||
|
of the source type. A smaller p might suffice depending on the
|
||||||
|
implementation's scheme for determining the digit to the left of the
|
||||||
|
decimal point.) The error has the correct sign for the current rounding
|
||||||
|
direction.
|
||||||
|
Unless the '#' flag is given, no decimal-point is given for zero
|
||||||
|
precision.
|
||||||
|
The 'a' conversion uses lowercase "abcdef", "0x" and 'p', the 'A'
|
||||||
|
conversion uppercase "ABCDEF", "0X" and 'P'.
|
||||||
|
The exponent always has at least one digit, and not more than necessary
|
||||||
|
to represent the decimal exponent of 2. If the value is zero, the
|
||||||
|
exponent is zero.
|
||||||
|
Infinity or NaN values are represented as for 'f' and 'F' conversions,
|
||||||
|
respectively.
|
||||||
|
Binary implementations are at liberty to chose the hexadecimal digit to
|
||||||
|
the left of the decimal point so that subsequent digits align to nibble
|
||||||
|
boundaries.
|
||||||
|
c The argument from the argument stack is assumed to be of type int, and
|
||||||
|
converted to a character after the value has been cast to unsigned char.
|
||||||
|
If the 'l' length modifier is given, the argument is assumed to be of
|
||||||
|
type wint_t, and converted as by a "%ls" conversion with no precision
|
||||||
|
and a pointer to a two-element wchar_t array, with the first element
|
||||||
|
being the wint_t argument and the second a '\0' wide character.
|
||||||
|
s The argument from the argument stack is assumed to be a char array (i.e.
|
||||||
|
pointer to char). Characters from that array are printed until a zero
|
||||||
|
byte is encountered or as many bytes as specified by a given precision
|
||||||
|
have been written.
|
||||||
|
If the l length modifier is given, the argument from the argument stack
|
||||||
|
is assumed to be a wchar_t array (i.e. pointer to wchar_t). Wide
|
||||||
|
characters from that array are converted to multibyte characters as by
|
||||||
|
calls to wcrtomb() (using a mbstate_t object initialized to zero prior
|
||||||
|
to the first conversion), up to and including the terminating null wide
|
||||||
|
character. The resulting multibyte character sequence is then printed up
|
||||||
|
to but not including the terminating null character. If a precision is
|
||||||
|
given, it specifies the maximum number of bytes to be written (including
|
||||||
|
shift sequences). If the given precision would require access to a wide
|
||||||
|
character one past the end of the array, the array shall contain a '\0'
|
||||||
|
wide character. In no case is a partial multibyte character written.
|
||||||
|
Redundant shift sequences may result if the multibyte characters have a
|
||||||
|
state-dependent encoding.
|
||||||
|
TODO: Clarify these statements regarding %ls.
|
||||||
|
p The argument from the argument stack is assumed to be a void pointer,
|
||||||
|
and converted to a sequence of printing characters in an implementation-
|
||||||
|
defined manner.
|
||||||
|
This implementation casts the pointer to type intptr_t, and prints the
|
||||||
|
value as if a %#x conversion specifier was given.
|
||||||
|
n The argument from the argument stack is assumed to be a pointer to a
|
||||||
|
signed integer, into which the number of characters written so far by
|
||||||
|
this call to fprintf is stored. The behaviour, should any flags, field
|
||||||
|
widths, or precisions be given is undefined.
|
||||||
|
% A verbatim '%' character is written. No argument is taken from the
|
||||||
|
argument stack.
|
||||||
|
|
||||||
|
Returns the number of characters written if successful, a negative value
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* TODO: fscanf() documentation */
|
||||||
|
/*
|
||||||
|
Read input from a given stream, as defined by the given format string, and
|
||||||
|
store converted input in the objects pointed to by 0..n subsequent arguments
|
||||||
|
(the argument stack).
|
||||||
|
|
||||||
|
The format string contains a sequence of directives that are expected to
|
||||||
|
match the input. If such a directive fails to match, the function returns
|
||||||
|
(matching error). It also returns if an input error occurs (input error).
|
||||||
|
|
||||||
|
Directives can be:
|
||||||
|
- one or more whitespaces, matching any number of whitespaces in the input;
|
||||||
|
- printing characters, matching the input verbatim;
|
||||||
|
- conversion specifications, which convert an input sequence into a value as
|
||||||
|
defined by the individual specifier, and store that value in a memory
|
||||||
|
location pointed to by the next pointer on the argument stack. Details are
|
||||||
|
documented below. If there is an insufficient number of pointers on the
|
||||||
|
argument stack, behaviour is undefined. Additional arguments not required
|
||||||
|
by any conversion specifications are evaluated, but otherwise ignored.
|
||||||
|
|
||||||
|
(The standard specifies the format string is allowed to contain multibyte
|
||||||
|
character sequences as long as it starts and ends in initial shift state,
|
||||||
|
but this is not yet supported by this implementation, which interprets the
|
||||||
|
format string as sequence of char.)
|
||||||
|
TODO: Add multibyte support to scanf() functions.
|
||||||
|
|
||||||
|
A conversion specifier consists of:
|
||||||
|
- Optional assignment-suppressing character ('*') that makes the conversion
|
||||||
|
read input as usual, but does not assign the conversion result.
|
||||||
|
- Optional maximum field width as decimal integer.
|
||||||
|
- Optional length modifier specifying the size of the argument (one of "hh",
|
||||||
|
"ll", or one of the characters "hljztL").
|
||||||
|
- Conversion specifier character specifying the type of conversion to be
|
||||||
|
applied (and the type of the next argument from the argument stack). One
|
||||||
|
of the characters "diouxXaAeEfFgGcs[pn%".
|
||||||
|
|
||||||
|
LENGTH MODIFIERS
|
||||||
|
hh For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of of char width.
|
||||||
|
h For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of short int width.
|
||||||
|
l For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of long int width.
|
||||||
|
For "aAeEfFgG" conversions, it is assumed to point to a variable of type
|
||||||
|
double.
|
||||||
|
For "cs[" conversions, it is assumed to point to a variable of type
|
||||||
|
wchar_t.
|
||||||
|
ll For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of long long int width.
|
||||||
|
j For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of intmax_t width.
|
||||||
|
z For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of size_t width.
|
||||||
|
t For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of ptrdiff_t width.
|
||||||
|
L For "aAeEfFgG" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of type long double.
|
||||||
|
Length modifiers appearing for any conversions not mentioned above will have
|
||||||
|
undefined behaviour.
|
||||||
|
If a length modifier appears with any conversion specifier other than as
|
||||||
|
specified above, the behavior is undefined.
|
||||||
|
|
||||||
|
CONVERSION SPECIFIERS
|
||||||
|
d Matches an (optionally signed) decimal integer of the format expected
|
||||||
|
by strtol() with base 10. The next pointer from the argument stack is
|
||||||
|
assumed to point to a signed integer.
|
||||||
|
i Matches an (optionally signed) integer of the format expected by
|
||||||
|
strtol() with base 0. The next pointer from the argument stack is
|
||||||
|
assumed to point to a signed integer.
|
||||||
|
o Matches an (optionally signed) octal integer of the format expected by
|
||||||
|
strtoul() with base 8. The next pointer from the argument stack is
|
||||||
|
assumed to point to an unsigned integer.
|
||||||
|
u Matches an (optionally signed) decimal integer of the format expected
|
||||||
|
by strtoul() with base 10. The next pointer from the argument stack is
|
||||||
|
assumed to point to an unsigned integer.
|
||||||
|
x Matches an (optionally signed) hexadecimal integer of the format
|
||||||
|
expected by strtoul() with base 16. The next pointer from the argument
|
||||||
|
stack is assumed to point to an unsigned integer.
|
||||||
|
aefg Matches an (optionally signed) floating point number, infinity, or not-
|
||||||
|
a-number-value of the format expected by strtod(). The next pointer
|
||||||
|
from the argument stack is assumed to point to a float.
|
||||||
|
c Matches a number of characters as specified by the field width (default
|
||||||
|
1). The next pointer from the argument stack is assumed to point to a
|
||||||
|
character array large enough to hold that many characters.
|
||||||
|
If the 'l' length modifier is given, the input is assumed to match a
|
||||||
|
sequence of multibyte characters (starting in the initial shift state),
|
||||||
|
which will be converted to a wide character sequence as by successive
|
||||||
|
calls to mbrtowc() with a mbstate_t object initialized to zero prior to
|
||||||
|
the first conversion. The next pointer from the argument stack is
|
||||||
|
assumed to point to a wchar_t array large enough to hold that many
|
||||||
|
characters.
|
||||||
|
In either case, note that no '\0' character is added to terminate the
|
||||||
|
sequence.
|
||||||
|
s Matches a sequence of non-white-space characters. The next pointer from
|
||||||
|
the argument stack is assumed to point to a character array large
|
||||||
|
enough to hold the sequence including terminating '\0' character.
|
||||||
|
If the 'l' length modifier is given, the input is assumed to match a
|
||||||
|
sequence of multibyte characters (starting in the initial shift state),
|
||||||
|
which will be converted to a wide character sequence as by a call to
|
||||||
|
mbrtowc() with a mbstate_t object initialized to zero prior to the
|
||||||
|
first conversion. The next pointer from the argument stack is assumed
|
||||||
|
to point to a wchar_t array large enough to hold the sequence including
|
||||||
|
terminating '\0' character.
|
||||||
|
[ Matches a nonempty sequence consisting of any of those characters
|
||||||
|
specified between itself and a corresponding closing bracket (']').
|
||||||
|
If the first character in the list is a circumflex ('^'), this matches
|
||||||
|
a nonempty sequence consisting of any characters NOT specified. If the
|
||||||
|
closing bracket appears as the first character in the scanset ("[]" or
|
||||||
|
"[^]", it is assumed to belong to the scanset, which then ends with the
|
||||||
|
NEXT closing bracket.
|
||||||
|
If there is a '-' character in the scanset which is not the first after
|
||||||
|
the opening bracket (or the circumflex, see above) or the last in the
|
||||||
|
scanset, behaviour is implementation-defined. This implementation
|
||||||
|
handles this character like any other.
|
||||||
|
|
||||||
|
The extend of the input field is determined byte-by-byte for the above
|
||||||
|
conversions ('c', 's', '['), with no special provisions being made for
|
||||||
|
multibyte characters. The resulting field is nevertheless a multibyte
|
||||||
|
sequence begining in intial shift state.
|
||||||
|
|
||||||
|
p Matches a sequence of characters as produced by the printf() "%p"
|
||||||
|
conversion. The next pointer from the argument stack is assumed to
|
||||||
|
point to a void pointer, which will be filled with the same location
|
||||||
|
as the pointer used in the printf() statement. Note that behaviour is
|
||||||
|
undefined if the input value is not the result of an earlier printf()
|
||||||
|
call.
|
||||||
|
n Does not read input. The next pointer from the argument stack is
|
||||||
|
assumed to point to a signed integer, into which the number of
|
||||||
|
characters read from input so far by this call to fscanf() is stored.
|
||||||
|
This does not affect the return value of fscanf(). The behaviour,
|
||||||
|
should an assignment-supressing character of field width be given,
|
||||||
|
is undefined.
|
||||||
|
This can be used to test the success of literal matches and suppressed
|
||||||
|
assignments.
|
||||||
|
% Matches a single, verbatim '%' character.
|
||||||
|
|
||||||
|
A, E, F, G and X are valid, and equivalent to their lowercase counterparts.
|
||||||
|
|
||||||
|
All conversions except [, c, or n imply that whitespace characters from the
|
||||||
|
input stream are consumed until a non-whitespace character is encountered.
|
||||||
|
Such whitespaces do not count against a maximum field width.
|
||||||
|
|
||||||
|
Conversions push at most one character back into the input stream. That
|
||||||
|
implies that some character sequences converted by the strtol() and strtod()
|
||||||
|
function families are not converted identically by the scnaf() function
|
||||||
|
family.
|
||||||
|
|
||||||
|
Returns the number of input items successfully assigned. This can be zero if
|
||||||
|
an early mismatch occurs. Returns EOF if an input failure occurs before the
|
||||||
|
first conversion.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ). */
|
||||||
|
_PDCLIB_PUBLIC int printf( const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ). */
|
||||||
|
_PDCLIB_PUBLIC int scanf( const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the result is
|
||||||
|
written into the buffer pointed to by s, instead of stdout, and that any
|
||||||
|
characters beyond the (n-1)th are discarded. The (n)th character is
|
||||||
|
replaced by a '\0' character in this case.
|
||||||
|
Returns the number of characters that would have been written (not counting
|
||||||
|
the terminating '\0' character) if n had been sufficiently large, if
|
||||||
|
successful, and a negative number if an encoding error ocurred.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int snprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the result is
|
||||||
|
written into the buffer pointed to by s, instead of stdout.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int sprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ), except that the input is read
|
||||||
|
from the buffer pointed to by s, instead of stdin.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stream, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vfprintf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stream, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vscanf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to snprintf( s, n, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vsnprintf( char * _PDCLIB_restrict s, size_t n, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter, and the result is written to the buffer
|
||||||
|
pointed to by s, instead of stdout. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vsprintf( char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter, and the input is read from the buffer
|
||||||
|
pointed to by s, instead of stdin. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Character input/output functions */
|
||||||
|
|
||||||
|
/* Retrieve the next character from given stream.
|
||||||
|
Returns the character, EOF otherwise.
|
||||||
|
If end-of-file is reached, the EOF indicator of the stream is set.
|
||||||
|
If a read error occurs, the error indicator of the stream is set.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fgetc( FILE * stream );
|
||||||
|
|
||||||
|
/* Read at most n-1 characters from given stream into the array s, stopping at
|
||||||
|
\n or EOF. Terminate the read string with \n. If EOF is encountered before
|
||||||
|
any characters are read, leave the contents of s unchanged.
|
||||||
|
Returns s if successful, NULL otherwise.
|
||||||
|
If a read error occurs, the error indicator of the stream is set. In this
|
||||||
|
case, the contents of s are indeterminate.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * fgets( char * _PDCLIB_restrict s, int n, FILE * _PDCLIB_restrict stream );
|
||||||
|
|
||||||
|
/* Write the value c (cast to unsigned char) to the given stream.
|
||||||
|
Returns c if successful, EOF otherwise.
|
||||||
|
If a write error occurs, sets the error indicator of the stream is set.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fputc( int c, FILE * stream );
|
||||||
|
|
||||||
|
/* Write the string s (not including the terminating \0) to the given stream.
|
||||||
|
Returns a value >=0 if successful, EOF otherwise.
|
||||||
|
This implementation does set the error indicator of the stream if a write
|
||||||
|
error occurs.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fputs( const char * _PDCLIB_restrict s, FILE * _PDCLIB_restrict stream );
|
||||||
|
|
||||||
|
/* Equivalent to fgetc( stream ), but may be overloaded by a macro that
|
||||||
|
evaluates its parameter more than once.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int getc( FILE * stream );
|
||||||
|
|
||||||
|
/* Equivalent to fgetc( stdin ). */
|
||||||
|
_PDCLIB_PUBLIC int getchar( void );
|
||||||
|
|
||||||
|
/* Equivalent to fputc( c, stream ), but may be overloaded by a macro that
|
||||||
|
evaluates its parameter more than once.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int putc( int c, FILE * stream );
|
||||||
|
|
||||||
|
/* Equivalent to fputc( c, stdout ), but may be overloaded by a macro that
|
||||||
|
evaluates its parameter more than once.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int putchar( int c );
|
||||||
|
|
||||||
|
/* Write the string s (not including the terminating \0) to stdout, and append
|
||||||
|
a newline to the output. Returns a value >= 0 when successful, EOF if a
|
||||||
|
write error occurred.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int puts( const char * s );
|
||||||
|
|
||||||
|
/* Push the value c (cast to unsigned char) back onto the given (input) stream.
|
||||||
|
A character pushed back in this way will be delivered by subsequent read
|
||||||
|
operations (and skipped by subsequent file positioning operations) as if it
|
||||||
|
has not been read. The external representation of the stream is unaffected
|
||||||
|
by this pushback (it is a buffer operation). One character of pushback is
|
||||||
|
guaranteed, further pushbacks may fail. EOF as value for c does not change
|
||||||
|
the input stream and results in failure of the function.
|
||||||
|
For text files, the file position indicator is indeterminate until all
|
||||||
|
pushed-back characters are read. For binary files, the file position
|
||||||
|
indicator is decremented by each successful call of ungetc(). If the file
|
||||||
|
position indicator for a binary file was zero before the call of ungetc(),
|
||||||
|
behaviour is undefined. (Older versions of the library allowed such a call.)
|
||||||
|
Returns the pushed-back character if successful, EOF if it fails.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int ungetc( int c, FILE * stream );
|
||||||
|
|
||||||
|
/* Direct input/output functions */
|
||||||
|
|
||||||
|
/* Read up to nmemb elements of given size from given stream into the buffer
|
||||||
|
pointed to by ptr. Returns the number of elements successfully read, which
|
||||||
|
may be less than nmemb if a read error or EOF is encountered. If a read
|
||||||
|
error is encountered, the value of the file position indicator is
|
||||||
|
indeterminate. If a partial element is read, its value is indeterminate.
|
||||||
|
If size or nmemb are zero, the function does nothing and returns zero.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t fread( void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream );
|
||||||
|
|
||||||
|
/* Write up to nmemb elements of given size from buffer pointed to by ptr to
|
||||||
|
the given stream. Returns the number of elements successfully written, which
|
||||||
|
will be less than nmemb only if a write error is encountered. If a write
|
||||||
|
error is encountered, the value of the file position indicator is
|
||||||
|
indeterminate. If size or nmemb are zero, the function does nothing and
|
||||||
|
returns zero.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, FILE * _PDCLIB_restrict stream );
|
||||||
|
|
||||||
|
/* File positioning functions */
|
||||||
|
|
||||||
|
/* Store the current position indicator (and, where appropriate, the current
|
||||||
|
mbstate_t status object) for the given stream into the given pos object. The
|
||||||
|
actual contents of the object are unspecified, but it can be used as second
|
||||||
|
parameter to fsetpos() to reposition the stream to the exact position and
|
||||||
|
parse state at the time fgetpos() was called.
|
||||||
|
Returns zero if successful, nonzero otherwise.
|
||||||
|
TODO: Implementation-defined errno setting for fgetpos().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fgetpos( FILE * _PDCLIB_restrict stream, fpos_t * _PDCLIB_restrict pos );
|
||||||
|
|
||||||
|
/* Set the position indicator for the given stream to the given offset from:
|
||||||
|
- the beginning of the file if whence is SEEK_SET,
|
||||||
|
- the current value of the position indicator if whence is SEEK_CUR,
|
||||||
|
- end-of-file if whence is SEEK_END.
|
||||||
|
On text streams, non-zero offsets are only allowed with SEEK_SET, and must
|
||||||
|
have been returned by ftell() for the same file.
|
||||||
|
Any characters buffered by ungetc() are dropped, the end-of-file indicator
|
||||||
|
for the stream is cleared. If the given stream is an update stream, the next
|
||||||
|
operation after a successful fseek() may be either input or output.
|
||||||
|
Returns zero if successful, nonzero otherwise. If a read/write error occurs,
|
||||||
|
the error indicator for the given stream is set.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fseek( FILE * stream, long int offset, int whence );
|
||||||
|
|
||||||
|
/* Set the position indicator (and, where appropriate the mbstate_t status
|
||||||
|
object) for the given stream to the given pos object (created by an earlier
|
||||||
|
call to fgetpos() on the same file).
|
||||||
|
Any characters buffered by ungetc() are dropped, the end-of-file indicator
|
||||||
|
for the stream is cleared. If the given stream is an update stream, the next
|
||||||
|
operation after a successful fsetpos() may be either input or output.
|
||||||
|
Returns zero if successful, nonzero otherwise. If a read/write error occurs,
|
||||||
|
the error indicator for the given stream is set.
|
||||||
|
TODO: Implementation-defined errno setting for fsetpos().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int fsetpos( FILE * stream, const fpos_t * pos );
|
||||||
|
|
||||||
|
/* Return the current offset of the given stream from the beginning of the
|
||||||
|
associated file. For text streams, the exact value returned is unspecified
|
||||||
|
(and may not be equal to the number of characters), but may be used in
|
||||||
|
subsequent calls to fseek().
|
||||||
|
Returns -1L if unsuccessful.
|
||||||
|
TODO: Implementation-defined errno setting for ftell().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC long int ftell( FILE * stream );
|
||||||
|
|
||||||
|
/* Equivalent to (void)fseek( stream, 0L, SEEK_SET ), except that the error
|
||||||
|
indicator for the stream is also cleared.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void rewind( FILE * stream );
|
||||||
|
|
||||||
|
/* Error-handling functions */
|
||||||
|
|
||||||
|
/* Clear the end-of-file and error indicators for the given stream. */
|
||||||
|
_PDCLIB_PUBLIC void clearerr( FILE * stream );
|
||||||
|
|
||||||
|
/* Return zero if the end-of-file indicator for the given stream is not set,
|
||||||
|
nonzero otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int feof( FILE * stream );
|
||||||
|
|
||||||
|
/* Return zero if the error indicator for the given stream is not set, nonzero
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int ferror( FILE * stream );
|
||||||
|
|
||||||
|
/* If s is neither a NULL pointer nor an empty string, print the string to
|
||||||
|
stderr (with appended colon (':') and a space) first. In any case, print an
|
||||||
|
error message depending on the current value of errno (being the same as if
|
||||||
|
strerror( errno ) had been called).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void perror( const char * s );
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
|
||||||
|
#define L_tmpnam_s _PDCLIB_L_tmpnam
|
||||||
|
#define TMP_MAX_S _PDCLIB_TMP_MAX
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
#define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
typedef int errno_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t rsize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file
|
||||||
|
automatically if it is closed or the program exits normally (by returning
|
||||||
|
from main() or calling exit()).
|
||||||
|
If successful, the FILE * pointed to by streamptr will be set to point at
|
||||||
|
the opened file handle, and the function returns zero. If unsuccessful,
|
||||||
|
the FILE * pointed to by streamptr will be set to NULL and a non-zero
|
||||||
|
value is returned.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- streamptr being NULL.
|
||||||
|
In case of a constraint violation, no file is being created.
|
||||||
|
This implementation does not remove temporary files if the process aborts
|
||||||
|
abnormally (e.g. abort()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t tmpfile_s( FILE * _PDCLIB_restrict * _PDCLIB_restrict streamptr );
|
||||||
|
|
||||||
|
/* Open the file with the given filename in the given mode, and sets the given
|
||||||
|
streamptr to point at the file handle for that file, in which error and
|
||||||
|
end-of-file indicator are cleared. Defined values for mode are:
|
||||||
|
|
||||||
|
READ MODES
|
||||||
|
text files binary files
|
||||||
|
without update "r" "rb"
|
||||||
|
with update "r+" "rb+" or "r+b"
|
||||||
|
|
||||||
|
Opening in read mode fails if no file with the given filename exists, or if
|
||||||
|
cannot be read.
|
||||||
|
|
||||||
|
WRITE MODES
|
||||||
|
text files binary files
|
||||||
|
without update "w" "wb"
|
||||||
|
with update "w+" "wb+" or "w+b"
|
||||||
|
|
||||||
|
With write modes, if a file with the given filename already exists, it is
|
||||||
|
truncated to zero length.
|
||||||
|
|
||||||
|
APPEND MODES
|
||||||
|
text files binary files
|
||||||
|
without update "a" "ab"
|
||||||
|
with update "a+" "ab+" or "a+b"
|
||||||
|
|
||||||
|
With update modes, if a file with the given filename already exists, it is
|
||||||
|
not truncated to zero length, but all writes are forced to end-of-file (this
|
||||||
|
regardless to fseek() calls). Note that binary files opened in append mode
|
||||||
|
might have their end-of-file padded with '\0' characters.
|
||||||
|
|
||||||
|
Update modes mean that both input and output functions can be performed on
|
||||||
|
the stream, but output must be terminated with a call to either fflush(),
|
||||||
|
fseek(), fsetpos(), or rewind() before input is performed, and input must
|
||||||
|
be terminated with a call to either fseek(), fsetpos(), or rewind() before
|
||||||
|
output is performed, unless input encountered end-of-file.
|
||||||
|
|
||||||
|
If a text file is opened with update mode, the implementation is at liberty
|
||||||
|
to open a binary stream instead. This implementation honors the exact mode
|
||||||
|
given.
|
||||||
|
|
||||||
|
The stream is fully buffered if and only if it can be determined not to
|
||||||
|
refer to an interactive device.
|
||||||
|
|
||||||
|
If the mode string begins with but is longer than one of the above sequences
|
||||||
|
the implementation is at liberty to ignore the additional characters, or do
|
||||||
|
implementation-defined things. This implementation only accepts the exact
|
||||||
|
modes above.
|
||||||
|
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- streamptr being NULL.
|
||||||
|
- filename being NULL.
|
||||||
|
- mode being NULL.
|
||||||
|
In case of a constraint violation, no file is opened. If streamptr is not
|
||||||
|
NULL, *streamptr is set to NULL.
|
||||||
|
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t fopen_s( FILE * _PDCLIB_restrict * _PDCLIB_restrict streamptr, const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode );
|
||||||
|
|
||||||
|
/* Close any file currently associated with the given stream. Open the file
|
||||||
|
identified by the given filename with the given mode (equivalent to fopen()),
|
||||||
|
and associate it with the given stream. If filename is a NULL pointer,
|
||||||
|
attempt to change the mode of the given stream.
|
||||||
|
This implementation allows any mode changes on "real" files, and associating
|
||||||
|
of the standard streams with files. It does *not* support mode changes on
|
||||||
|
standard streams.
|
||||||
|
(Primary use of this function is to redirect stdin, stdout, and stderr.)
|
||||||
|
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- newstreamptr being NULL.
|
||||||
|
- mode being NULL.
|
||||||
|
- stream being NULL.
|
||||||
|
In case of a constraint violation, no attempt is made to close or open any
|
||||||
|
file. If newstreamptr is not NULL, *newstreamptr is set to NULL.
|
||||||
|
|
||||||
|
Returns zero if successfull, non-zero otherwise.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t freopen_s( FILE * _PDCLIB_restrict * _PDCLIB_restrict newstreamptr, const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream );
|
||||||
|
|
||||||
|
/* None of these are implemented yet. Placeholder declarations. */
|
||||||
|
_PDCLIB_PUBLIC errno_t tmpnam_s( char * s, rsize_t maxsize );
|
||||||
|
_PDCLIB_PUBLIC int fprintf_s( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int fscanf_s( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int printf_s( const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int scanf_s( const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int snprintf_s( char * _PDCLIB_restrict s, rsize_t n, const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int sprintf_s( char * _PDCLIB_restrict s, rsize_t n, const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int sscanf_s( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... );
|
||||||
|
_PDCLIB_PUBLIC int vfprintf_s( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC int vfscanf_s( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC int vprintf_s( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC int vscanf_s( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC int vsnprintf_s( char * _PDCLIB_restrict s, rsize_t n, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC int vsprintf_s( char * _PDCLIB_restrict s, rsize_t n, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC int vsscanf_s( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg );
|
||||||
|
_PDCLIB_PUBLIC char * gets_s( char * s, rsize_t n );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDIO_H
|
||||||
|
#include _PDCLIB_EXTEND_STDIO_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
379
rocklibc/include/stdlib.h
Normal file
379
rocklibc/include/stdlib.h
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
/* General utilities <stdlib.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDLIB_H
|
||||||
|
#define _PDCLIB_STDLIB_H _PDCLIB_STDLIB_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_SIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NULL_DEFINED
|
||||||
|
#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
|
||||||
|
#define NULL _PDCLIB_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Numeric conversion functions */
|
||||||
|
|
||||||
|
/* TODO: atof(), strtof(), strtod(), strtold() */
|
||||||
|
|
||||||
|
_PDCLIB_PUBLIC double atof( const char * nptr );
|
||||||
|
_PDCLIB_PUBLIC double strtod( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr );
|
||||||
|
_PDCLIB_PUBLIC float strtof( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr );
|
||||||
|
_PDCLIB_PUBLIC long double strtold( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr );
|
||||||
|
|
||||||
|
/* Separate the character array nptr into three parts: A (possibly empty)
|
||||||
|
sequence of whitespace characters, a character representation of an integer
|
||||||
|
to the given base, and trailing invalid characters (including the terminating
|
||||||
|
null character). If base is 0, assume it to be 10, unless the integer
|
||||||
|
representation starts with 0x / 0X (setting base to 16) or 0 (setting base to
|
||||||
|
8). If given, base can be anything from 0 to 36, using the 26 letters of the
|
||||||
|
base alphabet (both lowercase and uppercase) as digits 10 through 35.
|
||||||
|
The integer representation is then converted into the return type of the
|
||||||
|
function. It can start with a '+' or '-' sign. If the sign is '-', the result
|
||||||
|
of the conversion is negated.
|
||||||
|
If the conversion is successful, the converted value is returned. If endptr
|
||||||
|
is not a NULL pointer, a pointer to the first trailing invalid character is
|
||||||
|
returned in *endptr.
|
||||||
|
If no conversion could be performed, zero is returned (and nptr in *endptr,
|
||||||
|
if endptr is not a NULL pointer). If the converted value does not fit into
|
||||||
|
the return type, the functions return LONG_MIN, LONG_MAX, ULONG_MAX,
|
||||||
|
LLONG_MIN, LLONG_MAX, or ULLONG_MAX respectively, depending on the sign of
|
||||||
|
the integer representation and the return type, and errno is set to ERANGE.
|
||||||
|
*/
|
||||||
|
/* There is strtoimax() and strtoumax() in <inttypes.h> operating on intmax_t /
|
||||||
|
uintmax_t, if the long long versions do not suit your needs.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC long int strtol( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base );
|
||||||
|
_PDCLIB_PUBLIC long long int strtoll( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base );
|
||||||
|
_PDCLIB_PUBLIC unsigned long int strtoul( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base );
|
||||||
|
_PDCLIB_PUBLIC unsigned long long int strtoull( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base );
|
||||||
|
|
||||||
|
/* These functions are the equivalent of (int)strtol( nptr, NULL, 10 ),
|
||||||
|
strtol( nptr, NULL, 10 ) and strtoll(nptr, NULL, 10 ) respectively, with the
|
||||||
|
exception that they do not have to handle overflow situations in any defined
|
||||||
|
way.
|
||||||
|
(PDCLib does not simply forward these to their strtox() equivalents, but
|
||||||
|
provides a simpler atox() function that saves a couple of tests and simply
|
||||||
|
continues with the conversion in case of overflow.)
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int atoi( const char * nptr );
|
||||||
|
_PDCLIB_PUBLIC long int atol( const char * nptr );
|
||||||
|
_PDCLIB_PUBLIC long long int atoll( const char * nptr );
|
||||||
|
|
||||||
|
/* Pseudo-random sequence generation functions */
|
||||||
|
|
||||||
|
extern unsigned long int _PDCLIB_seed;
|
||||||
|
|
||||||
|
#define RAND_MAX 32767
|
||||||
|
|
||||||
|
/* Returns the next number in a pseudo-random sequence, which is between 0 and
|
||||||
|
RAND_MAX.
|
||||||
|
(PDCLib uses the implementation suggested by the standard document, which is
|
||||||
|
next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;)
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int rand( void );
|
||||||
|
|
||||||
|
/* Initialize a new pseudo-random sequence with the starting seed. Same seeds
|
||||||
|
result in the same pseudo-random sequence. The default seed is 1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void srand( unsigned int seed );
|
||||||
|
|
||||||
|
/* Memory management functions */
|
||||||
|
|
||||||
|
/* Allocate a chunk of heap memory of given size. If request could not be
|
||||||
|
satisfied, return NULL. Otherwise, return a pointer to the allocated
|
||||||
|
memory. Memory contents are undefined.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * malloc( size_t size );
|
||||||
|
|
||||||
|
/* Allocate a chunk of heap memory that is large enough to hold nmemb elements
|
||||||
|
of the given size, and zero-initialize that memory. If request could not be
|
||||||
|
satisfied, return NULL. Otherwise, return a pointer to the allocated
|
||||||
|
memory.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * calloc( size_t nmemb, size_t size );
|
||||||
|
|
||||||
|
/* De-allocate a chunk of heap memory previously allocated using malloc(),
|
||||||
|
calloc(), or realloc(), and pointed to by ptr. If ptr does not match a
|
||||||
|
pointer previously returned by the mentioned allocation functions, or
|
||||||
|
free() has already been called for this ptr, behaviour is undefined.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void free( void * ptr );
|
||||||
|
|
||||||
|
/* Resize a chunk of memory previously allocated with malloc() and pointed to
|
||||||
|
by ptr to the given size (which might be larger or smaller than the original
|
||||||
|
size). Returns a pointer to the reallocated memory, or NULL if the request
|
||||||
|
could not be satisfied. Note that the resizing might include a memcpy()
|
||||||
|
from the original location to a different one, so the return value might or
|
||||||
|
might not equal ptr. If size is larger than the original size, the value of
|
||||||
|
memory beyond the original size is undefined. If ptr is NULL, realloc()
|
||||||
|
behaves like malloc().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * realloc( void * ptr, size_t size );
|
||||||
|
|
||||||
|
/* Communication with the environment */
|
||||||
|
|
||||||
|
/* These two can be passed to exit() or _Exit() as status values, to signal
|
||||||
|
successful and unsuccessful program termination, respectively. EXIT_SUCCESS
|
||||||
|
can be replaced by 0. How successful or unsuccessful program termination are
|
||||||
|
signaled to the environment, and what happens if exit() or _Exit() are being
|
||||||
|
called with a value that is neither of the three, is defined by the hosting
|
||||||
|
OS and its glue function.
|
||||||
|
*/
|
||||||
|
#define EXIT_SUCCESS _PDCLIB_SUCCESS
|
||||||
|
#define EXIT_FAILURE _PDCLIB_FAILURE
|
||||||
|
|
||||||
|
/* Initiate abnormal process termination, unless programm catches SIGABRT and
|
||||||
|
does not return from the signal handler.
|
||||||
|
This implementantion flushes all streams, closes all files, and removes any
|
||||||
|
temporary files before exiting with EXIT_FAILURE.
|
||||||
|
abort() does not return.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC _PDCLIB_Noreturn void abort( void ) _PDCLIB_NORETURN;
|
||||||
|
|
||||||
|
/* Register a function that will be called on quick_exit().
|
||||||
|
At least 32 functions can be registered this way, and will be called in
|
||||||
|
reverse order of registration (last-in, first-out).
|
||||||
|
Returns zero if registration is successfull, nonzero if it failed.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int at_quick_exit( void ( *func )( void ) );
|
||||||
|
|
||||||
|
/* Register a function that will be called on exit(), or when main() returns.
|
||||||
|
At least 32 functions can be registered this way, and will be called in
|
||||||
|
reverse order of registration (last-in, first-out).
|
||||||
|
Returns zero if registration is successfull, nonzero if it failed.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int atexit( void ( *func )( void ) );
|
||||||
|
|
||||||
|
/* Normal process termination. Functions registered by atexit() (see above) are
|
||||||
|
called, streams flushed, files closed and temporary files removed before the
|
||||||
|
program is terminated with the given status. (See comment for EXIT_SUCCESS
|
||||||
|
and EXIT_FAILURE above.)
|
||||||
|
exit() does not return.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC _PDCLIB_Noreturn void exit( int status ) _PDCLIB_NORETURN;
|
||||||
|
|
||||||
|
/* Normal process termination. Functions registered by at_quick_exit() (see
|
||||||
|
above) are called, streams flushed, files closed and temporary files removed
|
||||||
|
before the program is terminated with the given status. (See comment for
|
||||||
|
EXIT_SUCCESS and EXIT_FAILURE above.)
|
||||||
|
quick_exit() does not return.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC _PDCLIB_Noreturn void quick_exit( int status ) _PDCLIB_NORETURN;
|
||||||
|
|
||||||
|
/* Normal process termination. Functions registered by atexit()/at_quick_exit()
|
||||||
|
(see above) are NOT CALLED. This implementation DOES flush streams, close
|
||||||
|
files and removes temporary files before the program is teminated with the
|
||||||
|
given status. (See comment for EXIT_SUCCESS and EXIT_FAILURE above.)
|
||||||
|
_Exit() does not return.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC _PDCLIB_Noreturn void _Exit( int status ) _PDCLIB_NORETURN;
|
||||||
|
|
||||||
|
/* Search an environment-provided key-value map for the given key name, and
|
||||||
|
return a pointer to the associated value string (or NULL if key name cannot
|
||||||
|
be found). The value string pointed to might be overwritten by a subsequent
|
||||||
|
call to getenv(). The library never calls getenv() itself.
|
||||||
|
Details on the provided keys and how to set / change them are determined by
|
||||||
|
the hosting OS and its glue function.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * getenv( const char * name );
|
||||||
|
|
||||||
|
/* If string is a NULL pointer, system() returns nonzero if a command processor
|
||||||
|
is available, and zero otherwise. If string is not a NULL pointer, it is
|
||||||
|
passed to the command processor. If system() returns, it does so with a
|
||||||
|
value that is determined by the hosting OS and its glue function.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int system( const char * string );
|
||||||
|
|
||||||
|
/* Searching and sorting */
|
||||||
|
|
||||||
|
/* Do a binary search for a given key in the array with a given base pointer,
|
||||||
|
which consists of nmemb elements that are of the given size each. To compare
|
||||||
|
the given key with an element from the array, the given function compar is
|
||||||
|
called (with key as first parameter and a pointer to the array member as
|
||||||
|
second parameter); the function should return a value less than, equal to,
|
||||||
|
or greater than 0 if the key is considered to be less than, equal to, or
|
||||||
|
greater than the array element, respectively.
|
||||||
|
The function returns a pointer to a matching element found, or NULL if no
|
||||||
|
match is found.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int ( *compar )( const void *, const void * ) );
|
||||||
|
|
||||||
|
/* Do a quicksort on an array with a given base pointer, which consists of
|
||||||
|
nmemb elements that are of the given size each. To compare two elements from
|
||||||
|
the array, the given function compar is called, which should return a value
|
||||||
|
less than, equal to, or greater than 0 if the first argument is considered
|
||||||
|
to be less than, equal to, or greater than the second argument, respectively.
|
||||||
|
If two elements are compared equal, their order in the sorted array is not
|
||||||
|
specified.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void qsort( void * base, size_t nmemb, size_t size, int ( *compar )( const void *, const void * ) );
|
||||||
|
|
||||||
|
/* Integer arithmetic functions */
|
||||||
|
|
||||||
|
/* Return the absolute value of the argument. Note that on machines using two-
|
||||||
|
complement's notation (most modern CPUs), the largest negative value cannot
|
||||||
|
be represented as positive value. In this case, behaviour is unspecified.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int abs( int j );
|
||||||
|
_PDCLIB_PUBLIC long int labs( long int j );
|
||||||
|
_PDCLIB_PUBLIC long long int llabs( long long int j );
|
||||||
|
|
||||||
|
/* These structures each have a member quot and a member rem, of type int (for
|
||||||
|
div_t), long int (for ldiv_t) and long long it (for lldiv_t) respectively.
|
||||||
|
The order of the members is platform-defined to allow the div() functions
|
||||||
|
below to be implemented efficiently.
|
||||||
|
*/
|
||||||
|
typedef struct _PDCLIB_div_t div_t;
|
||||||
|
typedef struct _PDCLIB_ldiv_t ldiv_t;
|
||||||
|
typedef struct _PDCLIB_lldiv_t lldiv_t;
|
||||||
|
|
||||||
|
/* Return quotient (quot) and remainder (rem) of an integer division in one of
|
||||||
|
the structs above.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC div_t div( int numer, int denom );
|
||||||
|
_PDCLIB_PUBLIC ldiv_t ldiv( long int numer, long int denom );
|
||||||
|
_PDCLIB_PUBLIC lldiv_t lldiv( long long int numer, long long int denom );
|
||||||
|
|
||||||
|
/* TODO: Multibyte / wide character conversion functions */
|
||||||
|
|
||||||
|
/* TODO: Macro MB_CUR_MAX */
|
||||||
|
|
||||||
|
/*
|
||||||
|
_PDCLIB_PUBLIC int mblen( const char * s, size_t n );
|
||||||
|
_PDCLIB_PUBLIC int mbtowc( wchar_t * _PDCLIB_restrict pwc, const char * _PDCLIB_restrict s, size_t n );
|
||||||
|
_PDCLIB_PUBLIC int wctomb( char * s, wchar_t wc );
|
||||||
|
_PDCLIB_PUBLIC size_t mbstowcs( wchar_t * _PDCLIB_restrict pwcs, const char * _PDCLIB_restrict s, size_t n );
|
||||||
|
_PDCLIB_PUBLIC size_t wcstombs( char * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict pwcs, size_t n );
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
#define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
typedef int errno_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
typedef size_t rsize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A function type that can serve as a constraint handler (see below). The
|
||||||
|
first parameter is an error message on the constraint violation, the
|
||||||
|
second parameter a pointer to an implementation-defined object, the
|
||||||
|
third an error code related to the constraint violation.
|
||||||
|
If the function calling the constraint handler is defined to return
|
||||||
|
errno_t, the third parameter will be identical to the return value of
|
||||||
|
that function.
|
||||||
|
This implementation sets the second parameter of the constraint handler
|
||||||
|
call to NULL.
|
||||||
|
*/
|
||||||
|
typedef void ( *constraint_handler_t )( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error );
|
||||||
|
|
||||||
|
/* The currently active constraint violation handler. This implementation
|
||||||
|
sets abort_handler_s as the default constraint violation handler.
|
||||||
|
*/
|
||||||
|
extern constraint_handler_t _PDCLIB_constraint_handler;
|
||||||
|
|
||||||
|
/* Set the given function as the new constraint violation handler. */
|
||||||
|
_PDCLIB_PUBLIC constraint_handler_t set_constraint_handler_s( constraint_handler_t handler );
|
||||||
|
|
||||||
|
/* One of two predefined constraint violation handlers. When called, it will
|
||||||
|
print an error message (including the message passed as the first
|
||||||
|
parameter to the handler function) and call abort().
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void abort_handler_s( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error );
|
||||||
|
|
||||||
|
/* One of two predefined constraint violation handlers. Simply returns,
|
||||||
|
ignoring the constraint violation.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void ignore_handler_s( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error );
|
||||||
|
|
||||||
|
/* Search an environment-provided key-value map for the given key name.
|
||||||
|
If the name is found,
|
||||||
|
- if len is not NULL, the length of the associated value string is stored
|
||||||
|
in that location.
|
||||||
|
- if len < maxsize, the value string is copied to the indicated location.
|
||||||
|
If the name is not found,
|
||||||
|
- if len is not NULL, a zero is stored in that location.
|
||||||
|
- if maxsize > 0, value[0] is set to the null character.
|
||||||
|
Details on the provided keys and how to set / change them are determined by
|
||||||
|
the hosting OS and its glue function.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- value being a NULL pointer.
|
||||||
|
- maxsize == 0 or maxsize > RSIZE_MAX.
|
||||||
|
In case of a constraint violation, if len is not NULL a zero will be
|
||||||
|
stored at that location, and the environment key-value map not searched.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t getenv_s( size_t * _PDCLIB_restrict len, char * _PDCLIB_restrict value, rsize_t maxsize, const char * _PDCLIB_restrict name );
|
||||||
|
|
||||||
|
/* Do a binary search for a given key in the array with a given base pointer,
|
||||||
|
which consists of nmemb elements that are of the given size each. To compare
|
||||||
|
the given key with an element from the array, the given function compar is
|
||||||
|
called (with key as first parameter, a pointer to the array member as
|
||||||
|
second parameter, and the context parameter passed to bsearch_s() as third
|
||||||
|
parameter); the function should return a value less than, equal to,
|
||||||
|
or greater than 0 if the key is considered to be less than, equal to, or
|
||||||
|
greater than the array element, respectively.
|
||||||
|
The function returns a pointer to a matching element found, or NULL if no
|
||||||
|
match is found.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- nmemb or size > RSIZE_MAX.
|
||||||
|
- nmemb > 0 and either of key, base, or compar being a null pointer.
|
||||||
|
In case of a constraint violation, the array will not be searched.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * bsearch_s( const void * key, const void * base, rsize_t nmemb, rsize_t size, int ( *compar )( const void * k, const void * y, void * context ), void * context );
|
||||||
|
|
||||||
|
/* Do a quicksort on an array with a given base pointer, which consists of
|
||||||
|
nmemb elements that are of the given size each. To compare two elements from
|
||||||
|
the array, the given function compar is called, with the first two arguments
|
||||||
|
being pointers to the two objects to be compared, and the third argument
|
||||||
|
being the context parameter passed to qsort_s. The compar function should
|
||||||
|
return a value less than, equal to, or greater than 0 if the first argument
|
||||||
|
is considered to be less than, equal to, or greater than the second argument,
|
||||||
|
respectively. If two elements are compared equal, their order in the sorted
|
||||||
|
array is not specified.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- nmemb or size > RSIZE_MAX.
|
||||||
|
- nmemb > 0 and either of base or compar being a null pointer.
|
||||||
|
In case of a constraint violation, the array will not be sorted.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t qsort_s( void * base, rsize_t nmemb, rsize_t size, int ( *compar )( const void * x, const void * y, void * context ), void * context );
|
||||||
|
|
||||||
|
/* TODO: Multibyte / wide character functions */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDLIB_H
|
||||||
|
#include _PDCLIB_EXTEND_STDLIB_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
26
rocklibc/include/stdnoreturn.h
Normal file
26
rocklibc/include/stdnoreturn.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* _Noreturn <stdnoreturn.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STDNORETURN_H
|
||||||
|
#define _PDCLIB_STDNORETURN_H _PDCLIB_STDNORETURN_H
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
/* This basically breaks the letter of the standard (which states that
|
||||||
|
noreturn be defined to _Noreturn). This defines noreturn -> _Noreturn
|
||||||
|
on C11 compliant compilers only (as older compilers do not know about
|
||||||
|
_Noreturn).
|
||||||
|
*/
|
||||||
|
#define noreturn _PDCLIB_Noreturn
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STDNORETURN_H
|
||||||
|
#include _PDCLIB_EXTEND_STDNORETURN_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
394
rocklibc/include/string.h
Normal file
394
rocklibc/include/string.h
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
/* String handling <string.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_STRING_H
|
||||||
|
#define _PDCLIB_STRING_H _PDCLIB_STRING_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_SIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NULL_DEFINED
|
||||||
|
#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
|
||||||
|
#define NULL _PDCLIB_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* String function conventions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
In any of the following functions taking a size_t n to specify the length of
|
||||||
|
an array or size of a memory region, n may be 0, but the pointer arguments to
|
||||||
|
the call shall still be valid unless otherwise stated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copying functions */
|
||||||
|
|
||||||
|
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||||
|
area pointed to by s1. If the two areas overlap, behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * memcpy( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||||
|
area pointed to by s1. The two areas may overlap.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * memmove( void * _PDCLIB_restrict s1, const void * _PDCLIB_restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Copy the character array s2 (including terminating '\0' byte) into the
|
||||||
|
character array s1.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strcpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
|
||||||
|
|
||||||
|
/* Copy a maximum of n characters from the character array s2 into the character
|
||||||
|
array s1. If s2 is shorter than n characters, '\0' bytes will be appended to
|
||||||
|
the copy in s1 until n characters have been written. If s2 is longer than n
|
||||||
|
characters, NO terminating '\0' will be written to s1. If the arrays overlap,
|
||||||
|
behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strncpy( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Concatenation functions */
|
||||||
|
|
||||||
|
/* Append the contents of the character array s2 (including terminating '\0') to
|
||||||
|
the character array s1 (first character of s2 overwriting the '\0' of s1). If
|
||||||
|
the arrays overlap, behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strcat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
|
||||||
|
|
||||||
|
/* Append a maximum of n characters from the character array s2 to the character
|
||||||
|
array s1 (first character of s2 overwriting the '\0' of s1). A terminating
|
||||||
|
'\0' is ALWAYS appended, even if the full n characters have already been
|
||||||
|
written. If the arrays overlap, behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strncat( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Comparison functions */
|
||||||
|
|
||||||
|
/* Compare the first n characters of the memory areas pointed to by s1 and s2.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int memcmp( const void * s1, const void * s2, size_t n );
|
||||||
|
|
||||||
|
/* Compare the character arrays s1 and s2.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int strcmp( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Compare the character arrays s1 and s2, interpreted as specified by the
|
||||||
|
LC_COLLATE category of the current locale.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
TODO: Currently a dummy wrapper for strcmp() as PDCLib does not yet support
|
||||||
|
locales.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int strcoll( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Compare no more than the first n characters of the character arrays s1 and
|
||||||
|
s2.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int strncmp( const char * s1, const char * s2, size_t n );
|
||||||
|
|
||||||
|
/* Transform the character array s2 as appropriate for the LC_COLLATE setting of
|
||||||
|
the current locale. If length of resulting string is less than n, store it in
|
||||||
|
the character array pointed to by s1. Return the length of the resulting
|
||||||
|
string.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Search functions */
|
||||||
|
|
||||||
|
/* Search the first n characters in the memory area pointed to by s for the
|
||||||
|
character c (interpreted as unsigned char).
|
||||||
|
Returns a pointer to the first instance found, or NULL.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * memchr( const void * s, int c, size_t n );
|
||||||
|
|
||||||
|
/* Search the character array s (including terminating '\0') for the character c
|
||||||
|
(interpreted as char).
|
||||||
|
Returns a pointer to the first instance found, or NULL.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strchr( const char * s, int c );
|
||||||
|
|
||||||
|
/* Determine the length of the initial substring of character array s1 which
|
||||||
|
consists only of characters not from the character array s2.
|
||||||
|
Returns the length of that substring.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strcspn( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Search the character array s1 for any character from the character array s2.
|
||||||
|
Returns a pointer to the first occurrence, or NULL.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strpbrk( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Search the character array s (including terminating '\0') for the character c
|
||||||
|
(interpreted as char).
|
||||||
|
Returns a pointer to the last instance found, or NULL.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strrchr( const char * s, int c );
|
||||||
|
|
||||||
|
/* Determine the length of the initial substring of character array s1 which
|
||||||
|
consists only of characters from the character array s2.
|
||||||
|
Returns the length of that substring.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strspn( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Search the character array s1 for the substring in character array s2.
|
||||||
|
Returns a pointer to that sbstring, or NULL. If s2 is of length zero,
|
||||||
|
returns s1.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strstr( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* In a series of subsequent calls, parse a C string into tokens.
|
||||||
|
On the first call to strtok(), the first argument is a pointer to the to-be-
|
||||||
|
parsed C string. On subsequent calls, the first argument is NULL unless you
|
||||||
|
want to start parsing a new string. s2 holds an array of separator characters
|
||||||
|
which can differ from call to call. Leading separators are skipped, the first
|
||||||
|
trailing separator overwritten with '\0'.
|
||||||
|
Returns a pointer to the next token.
|
||||||
|
WARNING: This function uses static storage, and as such is not reentrant.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strtok( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2 );
|
||||||
|
|
||||||
|
/* Miscellaneous functions */
|
||||||
|
|
||||||
|
/* Write the character c (interpreted as unsigned char) to the first n
|
||||||
|
characters of the memory area pointed to by s.
|
||||||
|
Returns s.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC void * memset( void * s, int c, size_t n );
|
||||||
|
|
||||||
|
/* Map an error number to a (locale-specific) error message string. Error
|
||||||
|
numbers are typically errno values, but any number is mapped to a message.
|
||||||
|
TODO: PDCLib does not yet support locales.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strerror( int errnum );
|
||||||
|
|
||||||
|
/* Returns the length of the string s (excluding terminating '\0').
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strlen( const char * s );
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
#define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
typedef int errno_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t rsize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||||
|
area pointed to by s1 of size s1max.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1 or s2 being NULL.
|
||||||
|
- s1max or n being > RSIZE_MAX.
|
||||||
|
- n > s1max (not enough space in s1).
|
||||||
|
- copying between overlapping objects.
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max <= RSIZE_MAX
|
||||||
|
then the first s1max characters of s1 will be set to zero.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t memcpy_s( void * _PDCLIB_restrict s1, rsize_t s1max, const void * _PDCLIB_restrict s2, rsize_t n );
|
||||||
|
|
||||||
|
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||||
|
area pointed to by s1 of size s1max. The two areas may overlap.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1 or s2 being NULL.
|
||||||
|
- s1max or n being > RSIZE_MAX.
|
||||||
|
- n > s1max (not enough space in s1).
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max <= RSIZE_MAX
|
||||||
|
then the first s1max characters of s1 will be set to zero.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t memmove_s( void * _PDCLIB_restrict s1, rsize_t s1max, const void * _PDCLIB_restrict s2, rsize_t n );
|
||||||
|
|
||||||
|
/* Copy the character array s2 (including terminating '\0' byte) into the
|
||||||
|
character array s1.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1 or s2 being NULL.
|
||||||
|
- s1max being zero or > RSIZE_MAX.
|
||||||
|
- s1max not greater than strnlen_s( s2, s1max ) (not enough space in s1).
|
||||||
|
- copying between overlapping objects.
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max <= RSIZE_MAX
|
||||||
|
then s1[0] will be set to '\0'.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t strcpy_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2 );
|
||||||
|
|
||||||
|
/* Copy a maximum of n characters from the character array s2 into the character
|
||||||
|
array s1. If s2 is longer than n, s1[n] will be set to '\0'.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
|
||||||
|
ATTENTION ATTENTION ATTENTION
|
||||||
|
|
||||||
|
This function differs in two fundamental ways from strncpy():
|
||||||
|
- remaining space in s1 will NOT be zeroed. Their value is unspecified.
|
||||||
|
- s1 WILL be zero-terminated even if there is not enough space to hold
|
||||||
|
all n characters from s2.
|
||||||
|
|
||||||
|
THANK YOU FOR YOUR ATTENTION.
|
||||||
|
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1 or s2 being NULL.
|
||||||
|
- s1max or n being > RSIZE_MAX.
|
||||||
|
- s1max being zero.
|
||||||
|
- n >= s1max and s1max <= strnlen_s( s2, s1max ) (not enough space in s1).
|
||||||
|
- copying between overlapping objects.
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max is greater
|
||||||
|
zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t strncpy_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2, rsize_t n );
|
||||||
|
|
||||||
|
/* Append the contents of the character array s2 (including terminating '\0') to
|
||||||
|
the character array s1 (first character of s2 overwriting the '\0' of s1).
|
||||||
|
Elements following the terminating null character (if any) take unspecified
|
||||||
|
values.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1 or s2 being NULL.
|
||||||
|
- s1max being > RSIZE_MAX.
|
||||||
|
- s1max being zero.
|
||||||
|
- not enough space in s1 for both s1 and the characters copied from s2.
|
||||||
|
- copying between overlapping objects.
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max is greater
|
||||||
|
zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t strcat_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2 );
|
||||||
|
|
||||||
|
/* Append a maximum of n characters from the character array s2 to the
|
||||||
|
character array s1 (first character of s2 overwriting the '\0' of s1). A
|
||||||
|
terminating '\0' is ALWAYS appended, even if the full n characters have
|
||||||
|
already been written.
|
||||||
|
Elements following the terminating null character (if any) take unspecified
|
||||||
|
values.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1 or s2 being NULL.
|
||||||
|
- s1max or n being > RSIZE_MAX.
|
||||||
|
- s1max being zero.
|
||||||
|
- not enough space in s1 for both s1 and the characters copied from s2.
|
||||||
|
- copying between overlapping objects.
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max is greater
|
||||||
|
zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t strncat_s( char * _PDCLIB_restrict s1, rsize_t s1max, const char * _PDCLIB_restrict s2, rsize_t n );
|
||||||
|
|
||||||
|
/* In a series of subsequent calls, parse a C string into tokens.
|
||||||
|
On the first call to strtok(), the first argument is a pointer to the to-be-
|
||||||
|
parsed C string of size *s1max. On subsequent calls, the first argument is
|
||||||
|
NULL unless you want to start parsing a new string. s2 holds an array of
|
||||||
|
separator characters which can differ from call to call. Leading separators
|
||||||
|
are skipped, the first trailing separator overwritten with '\0'.
|
||||||
|
Returns a pointer to the next token.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s1max, s2, or ptr being NULL.
|
||||||
|
- s1max or n being > RSIZE_MAX.
|
||||||
|
- s1max being zero.
|
||||||
|
- not enough space in s1 for both s1 and the characters copied from s2.
|
||||||
|
- copying between overlapping objects.
|
||||||
|
In case of a constraint violation, if s1 is not NULL and s1max is greater
|
||||||
|
zero and <= RSIZE_MAX, s1[0] will be set to '\0'.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * strtok_s( char * _PDCLIB_restrict s1, rsize_t * _PDCLIB_restrict s1max, const char * _PDCLIB_restrict s2, char ** _PDCLIB_restrict ptr );
|
||||||
|
|
||||||
|
/* Write the character c (interpreted as unsigned char) to the first n
|
||||||
|
characters of the memory area pointed to by s of size smax.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s being NULL.
|
||||||
|
- smax or n being > RSIZE_MAX.
|
||||||
|
- n being > smax.
|
||||||
|
In case of a constraint violation, if s is not NULL and smax is <= RSIZE_MAX
|
||||||
|
the value of c (interpreted as unsigned char) is written to the first smax
|
||||||
|
characters of s.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t memset_s( void * s, rsize_t smax, int c, rsize_t n );
|
||||||
|
|
||||||
|
/* Map an error number to a (locale-specific) error message string. Error
|
||||||
|
numbers are typically errno values, but any number is mapped to a message.
|
||||||
|
TODO: PDCLib does not yet support locales.
|
||||||
|
If the length of the mapped string is < maxsize, the string is copied to s.
|
||||||
|
Otherwise, if maxsize is greater than zero, as much of the string as does
|
||||||
|
fit is copied, and s[maxsize-1] set to '\0'. If maxsize is greater than 3,
|
||||||
|
the partial string is made to end in "...".
|
||||||
|
Returns zero if the string was copied successfully in full, non-zero
|
||||||
|
otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s being NULL.
|
||||||
|
- maxsize being zero or > RSIZE_MAX.
|
||||||
|
In case of a constraint violation, s is not modified.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t strerror_s( char * s, rsize_t maxsize, errno_t errnum );
|
||||||
|
|
||||||
|
/* Map an error number to a (locale-specific) error message string, the same
|
||||||
|
way as strerror_s() would do. Error numbers are typically errno values,
|
||||||
|
but any number is mapped to a message.
|
||||||
|
TODO: PDCLib does not yet support locales.
|
||||||
|
Returns the length of the mapped string.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strerrorlen_s( errno_t errnum );
|
||||||
|
|
||||||
|
/* Returns the length of the string s (excluding terminating '\0').
|
||||||
|
If there is no null character in the first maxsize characters of s,
|
||||||
|
rerturns maxsize. If s is NULL, returns zero.
|
||||||
|
At most the first maxsize characters of s shall be accessed by the
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strnlen_s( const char * s, size_t maxsize );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_STRING_H
|
||||||
|
#include _PDCLIB_EXTEND_STRING_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
50
rocklibc/include/sys/stat.h
Normal file
50
rocklibc/include/sys/stat.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef _SYS_STAT_H
|
||||||
|
#define _SYS_STAT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Basic POSIX types for i686 execution
|
||||||
|
typedef uint32_t dev_t;
|
||||||
|
typedef uint32_t ino_t;
|
||||||
|
typedef uint32_t mode_t;
|
||||||
|
typedef uint32_t nlink_t;
|
||||||
|
typedef uint32_t uid_t;
|
||||||
|
typedef uint32_t gid_t;
|
||||||
|
typedef int32_t off_t;
|
||||||
|
typedef int32_t time_t;
|
||||||
|
|
||||||
|
// The stat layout expected by standard C files
|
||||||
|
struct stat {
|
||||||
|
dev_t st_dev; /* ID of device containing file */
|
||||||
|
ino_t st_ino; /* Inode number */
|
||||||
|
mode_t st_mode; /* File type and mode flags */
|
||||||
|
nlink_t st_nlink; /* Number of hard links */
|
||||||
|
uid_t st_uid; /* User ID of owner */
|
||||||
|
gid_t st_gid; /* Group ID of owner */
|
||||||
|
dev_t st_rdev; /* Device ID (if special file) */
|
||||||
|
off_t st_size; /* Total size, in bytes */
|
||||||
|
time_t st_atime; /* Time of last access */
|
||||||
|
time_t st_mtime; /* Time of last modification */
|
||||||
|
time_t st_ctime; /* Time of last status change */
|
||||||
|
};
|
||||||
|
|
||||||
|
// Traditional POSIX file permission/type bitmasks
|
||||||
|
#define S_IFMT 0170000 /* Bitmask for the file type bit fields */
|
||||||
|
#define S_IFSOCK 0140000 /* Socket */
|
||||||
|
#define S_IFLNK 0120000 /* Symbolic link */
|
||||||
|
#define S_IFREG 0100000 /* Regular file */
|
||||||
|
#define S_IFBLK 0060000 /* Block device */
|
||||||
|
#define S_IFDIR 0040000 /* Directory */
|
||||||
|
#define S_IFCHR 0020000 /* Character device */
|
||||||
|
#define S_IFIFO 0010000 /* FIFO */
|
||||||
|
|
||||||
|
#define S_IRUSR 00400 /* Owner has read permission */
|
||||||
|
#define S_IWUSR 00200 /* Owner has write permission */
|
||||||
|
#define S_IXUSR 00100 /* Owner has execute permission */
|
||||||
|
#define S_IRWXU 00700 /* Owner has read, write, and execute permission */
|
||||||
|
|
||||||
|
// Helper check macros commonly used in PDCLib
|
||||||
|
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||||
|
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||||
|
|
||||||
|
#endif /* _SYS_STAT_H */
|
||||||
21
rocklibc/include/sys/time.h
Normal file
21
rocklibc/include/sys/time.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _SYS_TIME_H
|
||||||
|
#define _SYS_TIME_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
// Represents an exact elapsed time signature
|
||||||
|
struct timeval {
|
||||||
|
time_t tv_sec; /* Seconds since Unix Epoch */
|
||||||
|
int32_t tv_usec; /* Microseconds component */
|
||||||
|
};
|
||||||
|
|
||||||
|
// Represents traditional timezone offsets (largely obsolete but required)
|
||||||
|
struct timezone {
|
||||||
|
int tz_minuteswest; /* Minutes west of Greenwich */
|
||||||
|
int tz_dsttime; /* Type of DST correction */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Prototype for time fetching system operation */
|
||||||
|
int gettimeofday(struct timeval *restrict tv, void *restrict tz);
|
||||||
|
|
||||||
|
#endif /* _SYS_TIME_H */
|
||||||
17
rocklibc/include/sys/times.h
Normal file
17
rocklibc/include/sys/times.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _SYS_TIMES_H
|
||||||
|
#define _SYS_TIMES_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* Structure describing CPU time used by a process and its children */
|
||||||
|
struct tms {
|
||||||
|
clock_t tms_utime; /* User CPU time */
|
||||||
|
clock_t tms_stime; /* System CPU time */
|
||||||
|
clock_t tms_cutime; /* User CPU time of dead children */
|
||||||
|
clock_t tms_cstime; /* System CPU time of dead children */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Function prototype for timing system call */
|
||||||
|
clock_t times(struct tms *buffer);
|
||||||
|
|
||||||
|
#endif /* _SYS_TIMES_H */
|
||||||
29
rocklibc/include/sys/types.h
Normal file
29
rocklibc/include/sys/types.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _SYS_TYPES_H
|
||||||
|
#define _SYS_TYPES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Standard signed and unsigned size primitives
|
||||||
|
typedef int32_t ssize_t;
|
||||||
|
typedef uint32_t size_t;
|
||||||
|
|
||||||
|
// Process and Thread IDs
|
||||||
|
typedef int32_t pid_t;
|
||||||
|
typedef int32_t id_t;
|
||||||
|
|
||||||
|
// File system block and reference markers
|
||||||
|
typedef int32_t blkcnt_t;
|
||||||
|
typedef int32_t blksize_t;
|
||||||
|
typedef uint32_t dev_t;
|
||||||
|
typedef uint32_t gid_t;
|
||||||
|
typedef uint32_t ino_t;
|
||||||
|
typedef uint32_t mode_t;
|
||||||
|
typedef uint32_t nlink_t;
|
||||||
|
typedef int32_t off_t;
|
||||||
|
typedef uint32_t uid_t;
|
||||||
|
|
||||||
|
// Clock and Timing fields
|
||||||
|
typedef int32_t time_t;
|
||||||
|
typedef int32_t clock_t;
|
||||||
|
|
||||||
|
#endif /* _SYS_TYPES_H */
|
||||||
191
rocklibc/include/time.h
Normal file
191
rocklibc/include/time.h
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
/* Date and time <time.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_TIME_H
|
||||||
|
#define _PDCLIB_TIME_H _PDCLIB_TIMEH
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_lib_ext1.h"
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_SIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NULL_DEFINED
|
||||||
|
#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
|
||||||
|
#define NULL _PDCLIB_NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* See comments in _PDCLIB_config.h on the semantics of time_t and clock_t. */
|
||||||
|
|
||||||
|
typedef _PDCLIB_time_t time_t;
|
||||||
|
typedef _PDCLIB_clock_t clock_t;
|
||||||
|
|
||||||
|
#define CLOCKS_PER_SEC _PDCLIB_CLOCKS_PER_SEC
|
||||||
|
#define TIME_UTC _PDCLIB_TIME_UTC
|
||||||
|
|
||||||
|
/* Implementor's note: If you change this structure, and are using Pthread
|
||||||
|
threading support, check auxiliary/pthread/pthread_readout.c for its
|
||||||
|
twin. It is imperative that Pthread and PDCLib use identical layouts for
|
||||||
|
struct timespec, as they are implicitly cast from one to the other. This
|
||||||
|
cannot be checked for in this header (as we may not include host system
|
||||||
|
headers here), so the assert()s are in pthread_readout.c (which, in turn,
|
||||||
|
cannot include *this* header, which is why this admonishment to keep the
|
||||||
|
definitions in sync exists...).
|
||||||
|
*/
|
||||||
|
struct timespec
|
||||||
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_nsec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tm
|
||||||
|
{
|
||||||
|
int tm_sec; /* 0-60 */
|
||||||
|
int tm_min; /* 0-59 */
|
||||||
|
int tm_hour; /* 0-23 */
|
||||||
|
int tm_mday; /* 1-31 */
|
||||||
|
int tm_mon; /* 0-11 */
|
||||||
|
int tm_year; /* years since 1900 */
|
||||||
|
int tm_wday; /* 0-6 */
|
||||||
|
int tm_yday; /* 0-365 */
|
||||||
|
int tm_isdst; /* >0 DST, 0 no DST, <0 information unavailable */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Returns the number of "clocks" in processor time since the invocation
|
||||||
|
of the program. Divide by CLOCKS_PER_SEC to get the value in seconds.
|
||||||
|
Returns -1 if the value cannot be represented in the return type or is
|
||||||
|
not available.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC clock_t clock( void );
|
||||||
|
|
||||||
|
/* Returns the difference between two calendar times in seconds. */
|
||||||
|
_PDCLIB_PUBLIC double difftime( time_t time1, time_t time0 );
|
||||||
|
|
||||||
|
/* Normalizes the values in the broken-down time pointed to by timeptr.
|
||||||
|
Returns the calender time specified by the broken-down time.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC time_t mktime( struct tm * timeptr );
|
||||||
|
|
||||||
|
/* Returns the current calender time. If timer is not a NULL pointer, stores
|
||||||
|
the current calender time at that address as well.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC time_t time( time_t * timer );
|
||||||
|
|
||||||
|
/* Sets the interval pointed to by ts to the current calender time, based
|
||||||
|
on the specified base.
|
||||||
|
Returns base, if successful, otherwise zero.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int timespec_get( struct timespec * ts, int base );
|
||||||
|
|
||||||
|
/* Converts the broken-down time pointed to by timeptr into a string in the
|
||||||
|
form "Sun Sep 16 01:03:52 1973\n\0".
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC char * asctime( const struct tm * timeptr );
|
||||||
|
|
||||||
|
/* Equivalent to asctime( localtime( timer ) ). */
|
||||||
|
_PDCLIB_PUBLIC char * ctime( const time_t * timer );
|
||||||
|
|
||||||
|
/* Converts the calender time pointed to by timer into a broken-down time
|
||||||
|
expressed as UTC.
|
||||||
|
Returns a pointer to the broken-down time, or a NULL pointer if it
|
||||||
|
cannot be represented.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC struct tm * gmtime( const time_t * timer );
|
||||||
|
|
||||||
|
/* Converts the calender time pointed to by timer into a broken-down time
|
||||||
|
expressed as local time.
|
||||||
|
Returns a pointer to the broken-down time, or a NULL pointer if if
|
||||||
|
cannot be represented.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC struct tm * localtime( const time_t * timer );
|
||||||
|
|
||||||
|
/* Writes the broken-down time pointed to by timeptr into the character
|
||||||
|
array pointed to by s. The string pointed to by format controls the
|
||||||
|
exact output. No more than maxsize charactrs will be written.
|
||||||
|
Returns the number of characters written (excluding the terminating
|
||||||
|
null character), or zero on failure.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC size_t strftime( char * _PDCLIB_restrict s, size_t maxsize, const char * _PDCLIB_restrict format, const struct tm * _PDCLIB_restrict timeptr );
|
||||||
|
|
||||||
|
/* Annex K -- Bounds-checking interfaces */
|
||||||
|
|
||||||
|
#if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
#define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED
|
||||||
|
typedef int errno_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
#define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED
|
||||||
|
typedef _PDCLIB_size_t rsize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Converts the broken-down time pointed to by timeptr into a string in the
|
||||||
|
form "Sun Sep 16 01:03:52 1973\n\0", which is stored in buffer s of maxsize.
|
||||||
|
Returns zero if the time was successfully converted and stored, non-zero
|
||||||
|
otherwise.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- s or timeptr being NULL.
|
||||||
|
- maxsize being < 26 or > RSIZE_MAX.
|
||||||
|
- the broken-down time pointed to by timeptr not being normalized.
|
||||||
|
- the year represented by the broken-down time pointed to by timeptr
|
||||||
|
being < 0 or > 9999.
|
||||||
|
In case of a constraint violation, the time will not be converted. If
|
||||||
|
s is not NULL and maxsize is neither zero nor > RSIZE_MAX, s[0] will be
|
||||||
|
set to '\0'.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC errno_t asctime_s( char * s, rsize_t maxsize, const struct tm * timeptr );
|
||||||
|
|
||||||
|
/* Equivalent to asctime_s( s, maxsize, localtime( timer ) ). */
|
||||||
|
_PDCLIB_PUBLIC errno_t ctime_s( char * s, rsize_t maxsize, const time_t * timer );
|
||||||
|
|
||||||
|
/* Converts the calender time pointed to by timer into a broken-down time
|
||||||
|
expressed as UTC, which gets stored in the result struct.
|
||||||
|
Returns a pointer to the broken-down time, or a NULL pointer if if
|
||||||
|
cannot be represented or stored.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- timer or result being NULL.
|
||||||
|
In case of a constraint violation, the time will not be converted.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC struct tm * gmtime_s( const time_t * _PDCLIB_restrict timer, struct tm * _PDCLIB_restrict result );
|
||||||
|
|
||||||
|
/* Converts the calender time pointed to by timer into a broken-down time
|
||||||
|
expressed as local time, which gets stored in the result struct.
|
||||||
|
Returns a pointer to the broken-down time, or a NULL pointer if if
|
||||||
|
cannot be represented or stored.
|
||||||
|
The following conditions will be considered runtime constraint violations:
|
||||||
|
- timer or result being NULL.
|
||||||
|
In case of a constraint violation, the time will not be converted.
|
||||||
|
The currently active constraint violation handler function will be called
|
||||||
|
(see set_constraint_handler_s()).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC struct tm * localtime_s( const time_t * _PDCLIB_restrict timer, struct tm * _PDCLIB_restrict result );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_TIME_H
|
||||||
|
#include _PDCLIB_EXTEND_TIME_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
28
rocklibc/include/unistd.h
Normal file
28
rocklibc/include/unistd.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _UNISTD_H
|
||||||
|
#define _UNISTD_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* Standard file descriptors used by streams */
|
||||||
|
#define STDIN_FILENO 0 /* Standard input */
|
||||||
|
#define STDOUT_FILENO 1 /* Standard output */
|
||||||
|
#define STDERR_FILENO 2 /* Standard error output */
|
||||||
|
|
||||||
|
/* Seek constants for lseek() / _PDCLIB_lseek() */
|
||||||
|
#ifndef SEEK_SET
|
||||||
|
#define SEEK_SET 0 /* Seek from beginning of file */
|
||||||
|
#define SEEK_CUR 1 /* Seek from current position */
|
||||||
|
#define SEEK_END 2 /* Seek from end of file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Null pointer declaration constant */
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int open(const char *pathname, int flags, ...);
|
||||||
|
int read(int fd, void *buf, size_t count);
|
||||||
|
int close(int fd);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _UNISTD_H */
|
||||||
152
rocklibc/include/wctype.h
Normal file
152
rocklibc/include/wctype.h
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/* Wide character classification and mapping utilities <wctype.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_WCTYPE_H
|
||||||
|
#define _PDCLIB_WCTYPE_H _PDCLIB_WCTYPE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
typedef _PDCLIB_wint_t wint_t;
|
||||||
|
typedef int wctrans_t;
|
||||||
|
typedef int wctype_t;
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_WEOF_DEFINED
|
||||||
|
#define _PDCLIB_WEOF_DEFINED _PDCLIB_WEOF_DEFINED
|
||||||
|
#define WEOF (wint_t)-1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wide character classification functions */
|
||||||
|
|
||||||
|
/* Returns iswalpha( wc ) || iswdigit( wc ) */
|
||||||
|
_PDCLIB_PUBLIC int iswalnum( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for wide characters for which either isupper( wc ) or
|
||||||
|
islower( wc ) is true, as well as a set of locale-specific wide
|
||||||
|
characters which are neither control characters, digits, punctuation,
|
||||||
|
or whitespace.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswalpha( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the character iswspace() and used for separating words
|
||||||
|
within a line of text. In the "C" locale, only L' ' and L'\t' are
|
||||||
|
considered blanks.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswblank( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the wide character is a control character. */
|
||||||
|
_PDCLIB_PUBLIC int iswcntrl( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the wide character is a decimal digit. Locale-
|
||||||
|
independent. */
|
||||||
|
_PDCLIB_PUBLIC int iswdigit( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns iswprint( wc ) && ! iswspace( wc ).
|
||||||
|
NOTE: This definition differs from that of isgraph() in <ctype.h>,
|
||||||
|
which considers only ' ', not all isspace() characters.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswgraph( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for lowerspace wide characters, as well as a set of
|
||||||
|
locale-specific wide characters which are neither control charcters,
|
||||||
|
digits, punctuation, or whitespace.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswlower( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for every printing wide character. */
|
||||||
|
_PDCLIB_PUBLIC int iswprint( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for a locale-specific set of punctuation characters that
|
||||||
|
are neither whitespace nor alphanumeric.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswpunct( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for a locale-specific set of whitespace characters that
|
||||||
|
are neither alphanumeric, graphic, or punctuation.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswspace( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for upperspace wide characters, as well as a set of
|
||||||
|
locale-specific wide characters which are neither control charcters,
|
||||||
|
digits, punctuation, or whitespace.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswupper( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the wide character is a hexadecimal digit. Locale-
|
||||||
|
independent. */
|
||||||
|
_PDCLIB_PUBLIC int iswxdigit( wint_t wc );
|
||||||
|
|
||||||
|
/* Extensible wide character classification functions */
|
||||||
|
|
||||||
|
/* Returns true if the wide character wc has the property described by
|
||||||
|
desc (which was retrieved by a previous call to wctype() without
|
||||||
|
changing the LC_CTYPE locale setting between the two calls).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC int iswctype( wint_t wc, wctype_t desc );
|
||||||
|
|
||||||
|
/* Returns a description object for a named character property, to be
|
||||||
|
used as parameter to the iswctype() function. Supported property
|
||||||
|
names are:
|
||||||
|
"alnum" -- alphanumeric, as per iswalnum()
|
||||||
|
"alpha" -- alphabetic, as per iswalpha()
|
||||||
|
"blank" -- blank, as per iswblank()
|
||||||
|
"cntrl" -- control, as per iswcntrl()
|
||||||
|
"digit" -- decimal digit, as per iswdigit()
|
||||||
|
"graph" -- graphic, as per iswgraph()
|
||||||
|
"lower" -- lowercase, as per iswlower()
|
||||||
|
"print" -- printing, as per iswprint()
|
||||||
|
"punct" -- punctuation, as per iswprint()
|
||||||
|
"space" -- whitespace, as per iswspace()
|
||||||
|
"upper" -- uppercase, as per iswupper()
|
||||||
|
"xdigit" -- hexadecimal digit, as per iswxdigit()
|
||||||
|
For unsupported properties, the function returns zero.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC wctype_t wctype( const char * property );
|
||||||
|
|
||||||
|
/* Wide character case mapping utilities */
|
||||||
|
|
||||||
|
/* Converts an uppercase letter to a corresponding lowercase letter. Input for
|
||||||
|
which no corresponding lowercase letter exists remains unchanged.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC wint_t towlower( wint_t wc );
|
||||||
|
|
||||||
|
/* Converts a lowercase letter to a corresponding uppercase letter. Input for
|
||||||
|
which no corresponding uppercase letter exists remains unchanged.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC wint_t towupper( wint_t wc );
|
||||||
|
|
||||||
|
/* Extensible wide character case mapping utilities */
|
||||||
|
|
||||||
|
/* Converts the wide character wc according to the transition described
|
||||||
|
by desc (which was retrieved by a previous call to wctrans() without
|
||||||
|
changing the LC_CTYPE locale setting between the two calls).
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC wint_t towctrans( wint_t wc, wctrans_t desc );
|
||||||
|
|
||||||
|
/* Returns a description object for a named character transformation, to
|
||||||
|
be used as parameter to the towctrans() function. Supported transformation
|
||||||
|
properties are:
|
||||||
|
"tolower" -- lowercase mapping, as per towlower()
|
||||||
|
"toupper" -- uppercase mapping, as per towupper()
|
||||||
|
For unsupported properties, the function returns zero.
|
||||||
|
*/
|
||||||
|
_PDCLIB_PUBLIC wctrans_t wctrans( const char * property );
|
||||||
|
|
||||||
|
/* Extension hook for downstream projects that want to have non-standard
|
||||||
|
extensions to standard headers.
|
||||||
|
*/
|
||||||
|
#ifdef _PDCLIB_EXTEND_WCTYPE_H
|
||||||
|
#include _PDCLIB_EXTEND_WCTYPE_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
20
rocklibc/makefile
Normal file
20
rocklibc/makefile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
CC = i686-elf-gcc
|
||||||
|
AR = i686-elf-ar
|
||||||
|
CFLAGS = -ffreestanding -O2 -Wall -Wextra -Iinclude -DHAVE_MMAP=0 -DLACKS_SYS_MMAN_H=1 -DUSE_LOCKS=0 -DLACKS_SYS_PARAM_H=1
|
||||||
|
TARGET = rlibc.a
|
||||||
|
|
||||||
|
SRCS = $(shell find src -name "*.c")
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(AR) rcs $@ $(OBJS)
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJS) $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
10
rocklibc/src/_PDCLIB/Readme.txt
Normal file
10
rocklibc/src/_PDCLIB/Readme.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
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 _PDCLIB_digits) and specified by
|
||||||
|
the standard (_PDCLIB_errno);
|
||||||
|
|
||||||
|
- test drivers for functionality that does not have its own implementation
|
||||||
|
file to put the test driver in (stdarg).
|
||||||
48
rocklibc/src/_PDCLIB/_PDCLIB_Exit.c
Normal file
48
rocklibc/src/_PDCLIB/_PDCLIB_Exit.c
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* _PDCLIB_Exit( 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 an example implementation of _PDCLIB_Exit() fit for use with POSIX
|
||||||
|
kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_glue.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern _PDCLIB_Noreturn void _exit( int status ) _PDCLIB_NORETURN;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _PDCLIB_Exit( int status )
|
||||||
|
{
|
||||||
|
_exit( status );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
int UNEXPECTED_RETURN = 0;
|
||||||
|
_PDCLIB_Exit( 0 );
|
||||||
|
TESTCASE( UNEXPECTED_RETURN );
|
||||||
|
#endif
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
59
rocklibc/src/_PDCLIB/_PDCLIB_atomax.c
Normal file
59
rocklibc/src/_PDCLIB/_PDCLIB_atomax.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* _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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
_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( (unsigned char)*s ) )
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *s == '+' )
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
else if ( *s == '-' )
|
||||||
|
{
|
||||||
|
sign = *( s++ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Earlier version was missing tolower() but was not caught by tests */
|
||||||
|
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)*( 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
|
||||||
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_add.c
Normal file
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_add.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* _PDCLIB_bigint_add( bigint_t *, bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_add( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other )
|
||||||
|
{
|
||||||
|
unsigned i = 0;
|
||||||
|
_PDCLIB_bigint_arith_t arith = 0;
|
||||||
|
|
||||||
|
for ( i = bigint->size; i < other->size; ++i )
|
||||||
|
{
|
||||||
|
bigint->data[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bigint->size = i;
|
||||||
|
|
||||||
|
for ( i = 0; i < bigint->size; ++i )
|
||||||
|
{
|
||||||
|
arith += bigint->data[i] + other->data[i];
|
||||||
|
bigint->data[i] = arith & ( ( (_PDCLIB_bigint_arith_t)1 << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 );
|
||||||
|
arith >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( arith > 0 )
|
||||||
|
{
|
||||||
|
bigint->data[i] = arith;
|
||||||
|
--(bigint->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
{ 1, { 0x0001u } },
|
||||||
|
{ 2, { (_PDCLIB_bigint_digit_t)( ( (_PDCLIB_bigint_arith_t)1 << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 ), 0x0001u } },
|
||||||
|
{ 1, { 0x0002u } },
|
||||||
|
{ 2, { 0x0001u, 0x0002u } },
|
||||||
|
{ 2, { 0x0000u, 0x0002u } }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 1 + 1 */
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 1 );
|
||||||
|
_PDCLIB_bigint_add( &bigint, &bigint );
|
||||||
|
_PDCLIB_bigint_cmp( &bigint, &testdata[2] );
|
||||||
|
|
||||||
|
/* 1 + 0x0001 0xFFFF -- carry */
|
||||||
|
_PDCLIB_bigint_add( &bigint, &testdata[1] );
|
||||||
|
_PDCLIB_bigint_cmp( &bigint, &testdata[3] );
|
||||||
|
|
||||||
|
/* 0x0001 0xFFFF + 1 -- carry */
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[1] );
|
||||||
|
_PDCLIB_bigint_add( &bigint, &testdata[0] );
|
||||||
|
_PDCLIB_bigint_cmp( &bigint, &testdata[4] );
|
||||||
|
|
||||||
|
/* 0 + 0 */
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 0 );
|
||||||
|
_PDCLIB_bigint_add( &bigint, &bigint );
|
||||||
|
TESTCASE( bigint.size == 0 );
|
||||||
|
|
||||||
|
/* 0 + 1 */
|
||||||
|
_PDCLIB_bigint_add( &bigint, &testdata[0] );
|
||||||
|
_PDCLIB_bigint_cmp( &bigint, &testdata[0] );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
74
rocklibc/src/_PDCLIB/_PDCLIB_bigint_cmp.c
Normal file
74
rocklibc/src/_PDCLIB/_PDCLIB_bigint_cmp.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/* _PDCLIB_bigint_cmp( bigint_t const *, bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
int _PDCLIB_bigint_cmp( _PDCLIB_bigint_t const * lhs, _PDCLIB_bigint_t const * rhs )
|
||||||
|
{
|
||||||
|
_PDCLIB_size_t i = lhs->size;
|
||||||
|
|
||||||
|
if ( i != rhs->size )
|
||||||
|
{
|
||||||
|
return i > rhs->size ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( i-- > 0 )
|
||||||
|
{
|
||||||
|
if ( lhs->data[i] != rhs->data[i] )
|
||||||
|
{
|
||||||
|
return lhs->data[i] > rhs->data[i] ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t lhs, rhs;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
{ 2, { 0, 0x0001u } },
|
||||||
|
{ 1, { 1 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_digit( &lhs, 0 );
|
||||||
|
_PDCLIB_bigint_from_digit( &rhs, 0 );
|
||||||
|
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_add( &lhs, &testdata[1] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) > 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_add( &rhs, &testdata[1] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_add( &rhs, &testdata[1] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) < 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &lhs, &testdata[0] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) > 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &rhs, &testdata[0] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_add( &rhs, &testdata[1] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) < 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_digit_log2.c
Normal file
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_digit_log2.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* _PDCLIB_bigint_digit_log2( bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int _PDCLIB_bigint_digit_log2( _PDCLIB_bigint_digit_t digit )
|
||||||
|
{
|
||||||
|
unsigned char log2_lookup[] =
|
||||||
|
{
|
||||||
|
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
|
||||||
|
};
|
||||||
|
_PDCLIB_bigint_digit_t t;
|
||||||
|
|
||||||
|
#if _PDCLIB_BIGINT_DIGIT_BITS > 16
|
||||||
|
if ( ( t = ( digit >> 24 ) ) )
|
||||||
|
{
|
||||||
|
return log2_lookup[ t ] + 24;
|
||||||
|
}
|
||||||
|
else if ( ( t = ( digit >> 16 ) ) )
|
||||||
|
{
|
||||||
|
return log2_lookup[ t ] + 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if ( ( t = ( digit >> 8 ) ) )
|
||||||
|
{
|
||||||
|
return log2_lookup[ t ] + 8;
|
||||||
|
}
|
||||||
|
else if ( digit > 0 )
|
||||||
|
{
|
||||||
|
return log2_lookup[ digit ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for ( i = 1; i < (1 << _PDCLIB_BIGINT_DIGIT_BITS); ++i )
|
||||||
|
{
|
||||||
|
//TESTCASE( _PDCLIB_bigint_digit_log2( i ) == (int)log2( i ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
135
rocklibc/src/_PDCLIB/_PDCLIB_bigint_div.c
Normal file
135
rocklibc/src/_PDCLIB/_PDCLIB_bigint_div.c
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/* _PDCLIB_bigint_div( bigint_t *, bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
unsigned _PDCLIB_bigint_div( _PDCLIB_bigint_t * dividend, _PDCLIB_bigint_t const * divisor )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_digit_t quotient;
|
||||||
|
_PDCLIB_size_t s = dividend->size;
|
||||||
|
_PDCLIB_size_t i;
|
||||||
|
|
||||||
|
assert( divisor->size > 0 );
|
||||||
|
assert( s <= divisor->size );
|
||||||
|
assert( divisor->data[ divisor->size - 1 ] < _PDCLIB_BIGINT_DIGIT_MAX );
|
||||||
|
|
||||||
|
if ( s < divisor->size || dividend->data[ s - 1 ] < divisor->data[ s - 1 ])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* With dividend truncated, and divisor + 1,
|
||||||
|
this quotient might be one short of correct.
|
||||||
|
*/
|
||||||
|
quotient = dividend->data[ s - 1 ] / ( divisor->data[ s - 1 ] + 1 );
|
||||||
|
|
||||||
|
if ( quotient > 0 )
|
||||||
|
{
|
||||||
|
/* dividend = dividend - (divisor * quotient) */
|
||||||
|
_PDCLIB_bigint_arith_t t = 0;
|
||||||
|
_PDCLIB_bigint_arith_t d = 0;
|
||||||
|
|
||||||
|
for ( i = 0; i < s; ++i )
|
||||||
|
{
|
||||||
|
t += (_PDCLIB_bigint_arith_t)divisor->data[i] * quotient;
|
||||||
|
d = (_PDCLIB_bigint_arith_t)dividend->data[i] - ( t & _PDCLIB_BIGINT_DIGIT_MAX ) - d;
|
||||||
|
|
||||||
|
dividend->data[i] = d & _PDCLIB_BIGINT_DIGIT_MAX;
|
||||||
|
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
d >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
d &= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dividend might have leading zero digits here,
|
||||||
|
but that does not matter for the compare or
|
||||||
|
the subsequent substraction.
|
||||||
|
*/
|
||||||
|
if ( _PDCLIB_bigint_cmp( dividend, divisor ) >= 0 )
|
||||||
|
{
|
||||||
|
/* quotient was too small, substract divisor once more. */
|
||||||
|
_PDCLIB_bigint_arith_t d = 0;
|
||||||
|
++quotient;
|
||||||
|
|
||||||
|
for ( i = 0; i < s; ++i )
|
||||||
|
{
|
||||||
|
d = (_PDCLIB_bigint_arith_t)dividend->data[i] - divisor->data[i] - d;
|
||||||
|
dividend->data[i] = d & _PDCLIB_BIGINT_DIGIT_MAX;
|
||||||
|
d >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
d &= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* size down dividend if it has leading zero digits. */
|
||||||
|
while ( dividend->size > 0 && dividend->data[ dividend->size - 1 ] == 0 )
|
||||||
|
{
|
||||||
|
--dividend->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quotient;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t dividend;
|
||||||
|
_PDCLIB_bigint_t divisor;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
{ 1, { 0x1234 } },
|
||||||
|
{ 2, { 0x2345, 0x0001 } },
|
||||||
|
{ 1, { 0x4000 } },
|
||||||
|
{ 1, { 0x3FFF } },
|
||||||
|
{ 1, { 0x0001 } },
|
||||||
|
{ 1, { _PDCLIB_BIGINT_DIGIT_MAX } },
|
||||||
|
{ 1, { 0xFFF9 } },
|
||||||
|
{ 1, { 0x1C71 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* dividend < divisor */
|
||||||
|
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[0] );
|
||||||
|
_PDCLIB_bigint_from_bigint( &divisor, &testdata[1] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 0 );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( ÷nd, &testdata[0] ) == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[3] );
|
||||||
|
_PDCLIB_bigint_from_bigint( &divisor, &testdata[2] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 0 );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( ÷nd, &testdata[3] ) == 0 );
|
||||||
|
|
||||||
|
/* dividend = divisor + 1 */
|
||||||
|
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[2] );
|
||||||
|
_PDCLIB_bigint_from_bigint( &divisor, &testdata[3] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 1 );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( ÷nd, &testdata[4] ) == 0 );
|
||||||
|
|
||||||
|
/* dividend = divisor * 9 */
|
||||||
|
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[6] );
|
||||||
|
_PDCLIB_bigint_from_bigint( &divisor, &testdata[7] );
|
||||||
|
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 9 );
|
||||||
|
TESTCASE( dividend.size == 0 );
|
||||||
|
|
||||||
|
/* dividend = divisor * 9 + rem */
|
||||||
|
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[5] );
|
||||||
|
_PDCLIB_bigint_from_digit( &divisor, testdata[5].data[0] / 9 );
|
||||||
|
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 9 );
|
||||||
|
TESTCASE( dividend.data[0] == ( testdata[5].data[0] % 9 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_bigint.c
Normal file
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_bigint.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/* _PDCLIB_bigint_from_bigint( bigint_t *, bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_from_bigint( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other )
|
||||||
|
{
|
||||||
|
_PDCLIB_size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < other->size; ++i )
|
||||||
|
{
|
||||||
|
bigint->data[i] = other->data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bigint->size = other->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
/* Only 16bit, works with 32bit digits as well. */
|
||||||
|
{ 0, { 0u } },
|
||||||
|
{ 1, { 0xFFFFu } },
|
||||||
|
{ 2, { 0xAAAAu, 0xFFFFu } }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
|
||||||
|
TESTCASE( bigint.size == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[1] );
|
||||||
|
_PDCLIB_bigint_cmp( &bigint, &testdata[1] );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[2] );
|
||||||
|
_PDCLIB_bigint_cmp( &bigint, &testdata[2] );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
43
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_digit.c
Normal file
43
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_digit.c
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* _PDCLIB_bigint_from_digit( bigint_t *, digit_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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_from_digit( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_digit_t digit )
|
||||||
|
{
|
||||||
|
bigint->size = ( digit > 0 );
|
||||||
|
bigint->data[0] = digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 0 );
|
||||||
|
TESTCASE( bigint.size == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 1 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 1 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, _PDCLIB_BIGINT_DIGIT_MAX );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == _PDCLIB_BIGINT_DIGIT_MAX );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
131
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow10.c
Normal file
131
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow10.c
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/* _PDCLIB_bigint_from_pow10( bigint_t *, unsigned )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_from_pow10( _PDCLIB_bigint_t * bigint, unsigned pow )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_t powers_of_10[] =
|
||||||
|
{
|
||||||
|
{ 1, { 0x0001u } },
|
||||||
|
{ 1, { 0x000au } },
|
||||||
|
{ 1, { 0x0064u } },
|
||||||
|
{ 1, { 0x03e8u } },
|
||||||
|
{ 1, { 0x2710u } },
|
||||||
|
{ 2, { 0x86a0u, 0x0001u } },
|
||||||
|
{ 2, { 0x4240u, 0x000fu } },
|
||||||
|
{ 2, { 0x9680u, 0x0098u } },
|
||||||
|
{ 2, { 0xe100u, 0x05f5u } },
|
||||||
|
{ 4, { 0x0000u, 0x6fc1u, 0x86f2u, 0x0023u } },
|
||||||
|
{ 7, { 0x0000u, 0x0000u, 0xef81u, 0x85acu,
|
||||||
|
0x415bu, 0x2d6du, 0x04eeu } },
|
||||||
|
{ 14, { 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x1f01u, 0xbf6au, 0xed64u, 0x6e38u,
|
||||||
|
0x97edu, 0xdaa7u, 0xf9f4u, 0xe93fu,
|
||||||
|
0x4f03u, 0x0018u } },
|
||||||
|
{ 27, { 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x3e01u, 0x2e95u, 0x9909u, 0x03dfu,
|
||||||
|
0x38fdu, 0x0f15u, 0xe42fu, 0x2374u,
|
||||||
|
0xf5ecu, 0xd3cfu, 0xdc08u, 0xc404u,
|
||||||
|
0xb0dau, 0xbccdu, 0x7f19u, 0xa633u,
|
||||||
|
0x2603u, 0xe91fu, 0x024eu } },
|
||||||
|
{ 54, { 0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x0000u, 0x0000u, 0x0000u, 0x0000u,
|
||||||
|
0x7c01u, 0x982eu, 0x875bu, 0xbed3u,
|
||||||
|
0x9f72u, 0xd8d9u, 0x2f87u, 0x1215u,
|
||||||
|
0x50c6u, 0x6bdeu, 0x6e70u, 0xcf4au,
|
||||||
|
0xd80fu, 0xd595u, 0x716eu, 0x26b2u,
|
||||||
|
0x66b0u, 0xadc6u, 0x3624u, 0x1d15u,
|
||||||
|
0xd35au, 0x3c42u, 0x540eu, 0x63ffu,
|
||||||
|
0x73c0u, 0xcc55u, 0xef17u, 0x65f9u,
|
||||||
|
0x28f2u, 0x55bcu, 0xc7f7u, 0x80dcu,
|
||||||
|
0xeddcu, 0xf46eu, 0xefceu, 0x5fdcu,
|
||||||
|
0x53f7u, 0x0005u } }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PDCLIB_size_t index = 8;
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( bigint, &powers_of_10[ pow & 7 ] );
|
||||||
|
pow >>= 3;
|
||||||
|
|
||||||
|
while ( pow > 0 )
|
||||||
|
{
|
||||||
|
if ( pow & 1 )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_mul( bigint, &powers_of_10[ index ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
pow >>= 1;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 0 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 1 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 1 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 10 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 2 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 100 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 3 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 1000 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 4 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 10000 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 5 );
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[1] == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 34464 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 6 );
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[1] == 15 );
|
||||||
|
TESTCASE( bigint.data[0] == 16960 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 7 );
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[1] == 152 );
|
||||||
|
TESTCASE( bigint.data[0] == 38528 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 8 );
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[1] == 1525 );
|
||||||
|
TESTCASE( bigint.data[0] == 57600 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow10( &bigint, 9 );
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[1] == 15258 );
|
||||||
|
TESTCASE( bigint.data[0] == 51712 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow2.c
Normal file
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow2.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/* _PDCLIB_bigint_from_pow2( bigint_t *, unsigned )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_from_pow2( _PDCLIB_bigint_t * bigint, unsigned pow )
|
||||||
|
{
|
||||||
|
ldiv_t dv = ldiv( pow, _PDCLIB_BIGINT_DIGIT_BITS );
|
||||||
|
long i;
|
||||||
|
|
||||||
|
for ( i = 0; i < dv.quot; ++i )
|
||||||
|
{
|
||||||
|
bigint->data[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bigint->data[i] = 1u << dv.rem;
|
||||||
|
bigint->size = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow2( &bigint, 0 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 1 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow2( &bigint, 1 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 2 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_pow2( &bigint, 2 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 4 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
64
rocklibc/src/_PDCLIB/_PDCLIB_bigint_log2.c
Normal file
64
rocklibc/src/_PDCLIB/_PDCLIB_bigint_log2.c
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/* _PDCLIB_bigint_log2( bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
int _PDCLIB_bigint_log2( _PDCLIB_bigint_t const * bigint )
|
||||||
|
{
|
||||||
|
_PDCLIB_size_t s = bigint->size;
|
||||||
|
|
||||||
|
if ( s == 0 )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
--s;
|
||||||
|
|
||||||
|
return _PDCLIB_bigint_digit_log2( bigint->data[ s ] ) + s * _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
_PDCLIB_bigint_t one;
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 0 );
|
||||||
|
_PDCLIB_bigint_from_digit( &one, 1 );
|
||||||
|
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &bigint ) == -1 );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul10( &one );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 3 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul10( &one );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 6 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul10( &one );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 9 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul10( &one );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 13 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul10( &one );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 16 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul10( &one );
|
||||||
|
TESTCASE( _PDCLIB_bigint_log2( &one ) == 19 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
121
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul.c
Normal file
121
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul.c
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/* _PDCLIB_bigint_mul( bigint_t *, bigint_t const * )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_mul( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other )
|
||||||
|
{
|
||||||
|
_PDCLIB_size_t s = other->size;
|
||||||
|
_PDCLIB_size_t b = bigint->size;
|
||||||
|
|
||||||
|
if ( s == 0 || b == 0 )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_from_digit( bigint, 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_t result = { s + b, { 0 } };
|
||||||
|
_PDCLIB_bigint_t const * small;
|
||||||
|
_PDCLIB_bigint_t const * big;
|
||||||
|
|
||||||
|
if ( s <= b )
|
||||||
|
{
|
||||||
|
small = other;
|
||||||
|
big = bigint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
small = bigint;
|
||||||
|
big = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( s = 0; s < small->size; ++s )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_arith_t t = 0;
|
||||||
|
|
||||||
|
for ( b = 0; b < big->size; ++b )
|
||||||
|
{
|
||||||
|
t += result.data[ s + b ]
|
||||||
|
+ (_PDCLIB_bigint_arith_t)small->data[ s ]
|
||||||
|
* (_PDCLIB_bigint_arith_t)big->data[ b ];
|
||||||
|
result.data[ s + b ] = t & ( ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 );
|
||||||
|
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.data[ s + b ] = t & ( ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( result.data[ result.size - 1 ] == 0 )
|
||||||
|
{
|
||||||
|
--result.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( bigint, &result );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
{ 1, { 0x0001u } },
|
||||||
|
{ 1, { 0x0002u } },
|
||||||
|
{ 1, { ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 1 } },
|
||||||
|
{ 2, { ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 1, 1u } }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
|
||||||
|
_PDCLIB_bigint_mul( &bigint, &testdata[0] );
|
||||||
|
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 1u );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul( &bigint, &testdata[1] );
|
||||||
|
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 2u );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul( &bigint, &testdata[2] );
|
||||||
|
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[0] == ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 2 );
|
||||||
|
TESTCASE( bigint.data[1] == 1u );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_mul( &bigint, &testdata[1] );
|
||||||
|
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
TESTCASE( bigint.data[0] == ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 4 );
|
||||||
|
TESTCASE( bigint.data[1] == 3u );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[3] );
|
||||||
|
_PDCLIB_bigint_mul( &bigint, &bigint );
|
||||||
|
|
||||||
|
TESTCASE( bigint.data[0] == 1 );
|
||||||
|
TESTCASE( bigint.data[1] == ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 4 );
|
||||||
|
|
||||||
|
#if _PDCLIB_BIGINT_DIGIT_BITS == 16
|
||||||
|
TESTCASE( bigint.size == 3 );
|
||||||
|
TESTCASE( bigint.data[2] == 3 );
|
||||||
|
#else
|
||||||
|
TESTCASE( bigint.size == 2 );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
58
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul10.c
Normal file
58
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul10.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* _PDCLIB_bigint_mul10( bigint_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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_mul10( _PDCLIB_bigint_t * bigint )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_arith_t t = 0;
|
||||||
|
_PDCLIB_size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < bigint->size; ++i )
|
||||||
|
{
|
||||||
|
t = (_PDCLIB_bigint_arith_t)bigint->data[ i ] * 10 + t;
|
||||||
|
bigint->data[ i ] = t & _PDCLIB_BIGINT_DIGIT_MAX;
|
||||||
|
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( t > 0 )
|
||||||
|
{
|
||||||
|
bigint->data[ bigint->size++ ] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
{ 2, { 0x8080u, 0x0101u } },
|
||||||
|
{ 2, { 0x0500u, 0x0a0fu } },
|
||||||
|
{ 1, { 0x000au } }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 1 );
|
||||||
|
_PDCLIB_bigint_mul10( &bigint );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &bigint, &testdata[2] ) == 0 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
|
||||||
|
_PDCLIB_bigint_mul10( &bigint );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &bigint, &testdata[1] ) == 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
30
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul_pow10.c
Normal file
30
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul_pow10.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* _PDCLIB_bigint_mul_pow10( bigint_t *, int pow10 )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_mul_pow10( _PDCLIB_bigint_t * bigint, int pow10 )
|
||||||
|
{
|
||||||
|
_PDCLIB_bigint_t multiplier;
|
||||||
|
_PDCLIB_bigint_from_pow10( &multiplier, pow10 );
|
||||||
|
_PDCLIB_bigint_mul( bigint, &multiplier );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
TESTCASE( NO_TESTDRIVER );
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_shl.c
Normal file
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_shl.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* _PDCLIB_bigint_shl( bigint_t *, size_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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void _PDCLIB_bigint_shl( _PDCLIB_bigint_t * bigint, _PDCLIB_size_t bits )
|
||||||
|
{
|
||||||
|
ldiv_t dv = ldiv( bits, _PDCLIB_BIGINT_DIGIT_BITS );
|
||||||
|
_PDCLIB_bigint_arith_t t = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if ( dv.quot > 0 )
|
||||||
|
{
|
||||||
|
i = bigint->size;
|
||||||
|
|
||||||
|
/* shifting whole digits */
|
||||||
|
while ( i-- > 0 )
|
||||||
|
{
|
||||||
|
bigint->data[ i + dv.quot ] = bigint->data[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
bigint->size += dv.quot;
|
||||||
|
|
||||||
|
/* zero out shifted low digits */
|
||||||
|
while ( (long)i < dv.quot )
|
||||||
|
{
|
||||||
|
bigint->data[ i++ ] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = dv.quot; i < bigint->size; ++i )
|
||||||
|
{
|
||||||
|
t = ( (_PDCLIB_bigint_arith_t)bigint->data[ i ] << dv.rem ) + t;
|
||||||
|
bigint->data[ i ] = t & _PDCLIB_BIGINT_DIGIT_MAX;
|
||||||
|
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( t > 0 )
|
||||||
|
{
|
||||||
|
bigint->data[ bigint->size++ ] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_bigint_t bigint;
|
||||||
|
_PDCLIB_bigint_t testdata[] =
|
||||||
|
{
|
||||||
|
{ 2, { 0x8080u, 0x0101u } },
|
||||||
|
{ 3, { 0x0000u, 0x0100u, 0x0203u } }
|
||||||
|
};
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_digit( &bigint, 1 );
|
||||||
|
_PDCLIB_bigint_shl( &bigint, 2 );
|
||||||
|
TESTCASE( bigint.size == 1 );
|
||||||
|
TESTCASE( bigint.data[0] == 4 );
|
||||||
|
|
||||||
|
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
|
||||||
|
_PDCLIB_bigint_shl( &bigint, _PDCLIB_BIGINT_DIGIT_BITS + 1 );
|
||||||
|
TESTCASE( bigint.size == 3 );
|
||||||
|
TESTCASE( bigint.data[0] == 0 );
|
||||||
|
TESTCASE( bigint.data[1] == 0x0100 );
|
||||||
|
TESTCASE( bigint.data[2] == 0x0203 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
73
rocklibc/src/_PDCLIB/_PDCLIB_changemode.c
Normal file
73
rocklibc/src/_PDCLIB/_PDCLIB_changemode.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/* _PDCLIB_changemode( FILE * stream, int mode )
|
||||||
|
|
||||||
|
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 utility function used by freopen, to allow for a rather
|
||||||
|
specific bit of trickery.
|
||||||
|
ISO/IEC 9899:2011 (i.e., the ISO C standard) is ambiguous in the case
|
||||||
|
of the filename argument being NULL. It states that the mode of the
|
||||||
|
open stream could be _changed_ in implementation-defined circumstances.
|
||||||
|
While it goes on to state that freopen will "first attempt to close any
|
||||||
|
file that is associated with the specified stream", it is not quite
|
||||||
|
clear if the "implementation-defined circumstances" mentioned earlier
|
||||||
|
would include changing the mode without actually closing the file.
|
||||||
|
IEEE Std 1003.1, 2004 Edition (POSIX) on the other hand is less
|
||||||
|
ambiguous, as it states that "the file descriptor associated with the
|
||||||
|
stream need not be closed if the call to freopen() succeeds" for the
|
||||||
|
same case (filename being NULL).
|
||||||
|
This function gets called by PDCLib's freopen() in just that case,
|
||||||
|
allowing you to perform whatever mode changes YOUR implementation
|
||||||
|
decides to support. Return zero if the change requested is not
|
||||||
|
supported and freopen() should attempt the close-and-open-again way.
|
||||||
|
Return INT_MIN if the change request is not supported and freopen()
|
||||||
|
should fail. Return any other value if the requested mode change was
|
||||||
|
supported and successful.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is a dummy implementation of _PDCLIB_open() not supporting any
|
||||||
|
mode changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_glue.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int _PDCLIB_changemode( struct _PDCLIB_file_t * stream, unsigned int mode )
|
||||||
|
{
|
||||||
|
if ( mode == 0 )
|
||||||
|
{
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt mode change without closing the stream */
|
||||||
|
|
||||||
|
if ( stream->filename == NULL )
|
||||||
|
{
|
||||||
|
/* Standard stream, no filename for reopen */
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Stream with file associated, attempt reopen */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* No test drivers. */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
44
rocklibc/src/_PDCLIB/_PDCLIB_close.c
Normal file
44
rocklibc/src/_PDCLIB/_PDCLIB_close.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* _PDCLIB_close( _PDCLIB_fd_t )
|
||||||
|
|
||||||
|
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 implementation of _PDCLIB_close() fit for use with POSIX
|
||||||
|
kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_glue.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int close( int fd );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int _PDCLIB_close( int fd )
|
||||||
|
{
|
||||||
|
return close( fd );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* No testdriver; tested in driver for _PDCLIB_open(). */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
38
rocklibc/src/_PDCLIB/_PDCLIB_closeall.c
Normal file
38
rocklibc/src/_PDCLIB/_PDCLIB_closeall.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* _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
|
||||||
|
|
||||||
|
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
|
||||||
|
|
||||||
|
void _PDCLIB_closeall( void )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_file_t * stream = _PDCLIB_filelist;
|
||||||
|
struct _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
|
||||||
33
rocklibc/src/_PDCLIB/_PDCLIB_digits.c
Normal file
33
rocklibc/src/_PDCLIB/_PDCLIB_digits.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/* _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/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
const char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
/* For _PDCLIB/print.c only; obsolete with ctype.h */
|
||||||
|
const char _PDCLIB_Xdigits[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
114
rocklibc/src/_PDCLIB/_PDCLIB_filemode.c
Normal file
114
rocklibc/src/_PDCLIB/_PDCLIB_filemode.c
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/* _PDCLIB_filemode( 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 <stddef.h>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
/* Helper function that parses the C-style mode string passed to fopen() into
|
||||||
|
the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary
|
||||||
|
mode).
|
||||||
|
*/
|
||||||
|
unsigned int _PDCLIB_filemode( const char * const mode )
|
||||||
|
{
|
||||||
|
unsigned rc = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if ( mode == NULL )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( mode[0] )
|
||||||
|
{
|
||||||
|
case 'r':
|
||||||
|
rc |= _PDCLIB_FREAD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
rc |= _PDCLIB_FWRITE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
rc |= _PDCLIB_FAPPEND | _PDCLIB_FWRITE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Other than read, write, or append - invalid */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 1; i < 4; ++i )
|
||||||
|
{
|
||||||
|
switch ( mode[i] )
|
||||||
|
{
|
||||||
|
case '+':
|
||||||
|
if ( rc & _PDCLIB_FRW )
|
||||||
|
{
|
||||||
|
/* Duplicates are invalid */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc |= _PDCLIB_FRW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
if ( rc & _PDCLIB_FBIN )
|
||||||
|
{
|
||||||
|
/* Duplicates are invalid */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc |= _PDCLIB_FBIN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\0':
|
||||||
|
/* End of mode */
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Other than read/write or binary - invalid. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Longer than three chars - invalid. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
TESTCASE( _PDCLIB_filemode( "r" ) == _PDCLIB_FREAD );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "w" ) == _PDCLIB_FWRITE );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "a" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "r+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "w+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "a+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "rb" ) == ( _PDCLIB_FREAD | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "wb" ) == ( _PDCLIB_FWRITE | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "ab" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "r+b" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "w+b" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "a+b" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "rb+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "wb+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "ab+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "x" ) == 0 );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "r++" ) == 0 );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "wbb" ) == 0 );
|
||||||
|
TESTCASE( _PDCLIB_filemode( "a+bx" ) == 0 );
|
||||||
|
#endif
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
77
rocklibc/src/_PDCLIB/_PDCLIB_fillbuffer.c
Normal file
77
rocklibc/src/_PDCLIB/_PDCLIB_fillbuffer.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/* _PDCLIB_fillbuffer( struct _PDCLIB_file_t * )
|
||||||
|
|
||||||
|
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 implementation of _PDCLIB_fillbuffer() fit for
|
||||||
|
use with POSIX kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_glue.h"
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_platform_errno.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef long ssize_t;
|
||||||
|
extern ssize_t read( int fd, void * buf, size_t count );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
/* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */
|
||||||
|
ssize_t rc = read( stream->handle, stream->buffer, stream->bufsize );
|
||||||
|
|
||||||
|
if ( rc > 0 )
|
||||||
|
{
|
||||||
|
/* Reading successful. */
|
||||||
|
if ( !( stream->status & _PDCLIB_FBIN ) )
|
||||||
|
{
|
||||||
|
/* TODO: Text stream conversion here */
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->pos.offset += rc;
|
||||||
|
stream->bufend = rc;
|
||||||
|
stream->bufidx = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rc < 0 )
|
||||||
|
{
|
||||||
|
/* The 1:1 mapping done in _PDCLIB_config.h ensures
|
||||||
|
this works.
|
||||||
|
*/
|
||||||
|
*_PDCLIB_errno_func() = errno;
|
||||||
|
/* Flag the stream */
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End-of-File */
|
||||||
|
stream->status |= _PDCLIB_EOFFLAG;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* Testing covered by ftell.c */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
103
rocklibc/src/_PDCLIB/_PDCLIB_flushbuffer.c
Normal file
103
rocklibc/src/_PDCLIB/_PDCLIB_flushbuffer.c
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
|
||||||
|
|
||||||
|
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 implementation of _PDCLIB_flushbuffer() fit for
|
||||||
|
use with POSIX kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_glue.h"
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_platform_errno.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef long ssize_t;
|
||||||
|
extern ssize_t write( int fd, const void * buf, size_t count );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The number of attempts of output buffer flushing before giving up. */
|
||||||
|
#define _PDCLIB_IO_RETRIES 1
|
||||||
|
|
||||||
|
/* What the system should do after an I/O operation did not succeed, before */
|
||||||
|
/* trying again. (Empty by default.) */
|
||||||
|
#define _PDCLIB_IO_RETRY_OP( stream )
|
||||||
|
|
||||||
|
int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
/* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */
|
||||||
|
_PDCLIB_size_t written = 0;
|
||||||
|
int rc;
|
||||||
|
unsigned int retries;
|
||||||
|
|
||||||
|
if ( !( stream->status & _PDCLIB_FBIN ) )
|
||||||
|
{
|
||||||
|
/* TODO: Text stream conversion here */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep trying to write data until everything is written, an error
|
||||||
|
occurs, or the configured number of retries is exceeded.
|
||||||
|
*/
|
||||||
|
for ( retries = _PDCLIB_IO_RETRIES; retries > 0; --retries )
|
||||||
|
{
|
||||||
|
rc = ( int )write( stream->handle, stream->buffer + written, stream->bufidx - written );
|
||||||
|
|
||||||
|
if ( rc < 0 )
|
||||||
|
{
|
||||||
|
/* The 1:1 mapping done in _PDCLIB_config.h ensures
|
||||||
|
this works.
|
||||||
|
*/
|
||||||
|
*_PDCLIB_errno_func() = errno;
|
||||||
|
/* Flag the stream */
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
/* Move unwritten remains to begin of buffer. */
|
||||||
|
stream->bufidx -= written;
|
||||||
|
memmove( stream->buffer, stream->buffer + written, stream->bufidx );
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
written += ( _PDCLIB_size_t )rc;
|
||||||
|
stream->pos.offset += rc;
|
||||||
|
|
||||||
|
if ( written == stream->bufidx )
|
||||||
|
{
|
||||||
|
/* Buffer written completely. */
|
||||||
|
stream->bufidx = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Number of retries exceeded. */
|
||||||
|
*_PDCLIB_errno_func() = _PDCLIB_EAGAIN;
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
/* Move unwritten remains to begin of buffer. */
|
||||||
|
stream->bufidx -= written;
|
||||||
|
memmove( stream->buffer, stream->buffer + written, stream->bufidx );
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* Testing covered by ftell.c */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_dbl.c
Normal file
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_dbl.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/* _PDCLIB_fp_from_dbl( _PDCLIB_fp_t *, double )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void _PDCLIB_fp_from_dbl( _PDCLIB_fp_t * fp, double d )
|
||||||
|
{
|
||||||
|
memcpy( fp->mantissa.data, &d, sizeof( double ) );
|
||||||
|
|
||||||
|
fp->sign = _PDCLIB_DBL_SIGN( fp->mantissa.data );
|
||||||
|
fp->exponent = _PDCLIB_DBL_EXP( fp->mantissa.data );
|
||||||
|
fp->mantissa.size = _PDCLIB_DBL_SIZE( fp->mantissa.data );
|
||||||
|
|
||||||
|
switch ( fp->exponent )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
fp->state = _PDCLIB_FP_SUBNORMAL;
|
||||||
|
fp->exponent = 1 - ( _PDCLIB_DBL_MAX_EXP - 1 );
|
||||||
|
fp->scale = _PDCLIB_DBL_MANT_DIG - 1;
|
||||||
|
break;
|
||||||
|
case ( _PDCLIB_DBL_MAX_EXP - 1 ) + _PDCLIB_DBL_MAX_EXP:
|
||||||
|
fp->state = _PDCLIB_FP_NAN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
div_t dv = div( _PDCLIB_DBL_MANT_DIG - 1, _PDCLIB_BIGINT_DIGIT_BITS );
|
||||||
|
fp->state = _PDCLIB_FP_NORMAL;
|
||||||
|
|
||||||
|
if ( dv.rem == 0 )
|
||||||
|
{
|
||||||
|
fp->mantissa.data[ fp->mantissa.size++ ] = 1u;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fp->mantissa.data[ dv.quot ] |= ( 1u << dv.rem );
|
||||||
|
}
|
||||||
|
|
||||||
|
fp->exponent -= ( _PDCLIB_DBL_MAX_EXP - 1 );
|
||||||
|
fp->scale = _PDCLIB_DBL_MANT_DIG - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( fp->mantissa.size > 0 && fp->mantissa.data[ fp->mantissa.size - 1 ] == 0 )
|
||||||
|
{
|
||||||
|
--fp->mantissa.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( fp->state == _PDCLIB_FP_NAN ) && ( fp->mantissa.size == 0 ) )
|
||||||
|
{
|
||||||
|
fp->state = _PDCLIB_FP_INF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_fp_t fp;
|
||||||
|
_PDCLIB_bigint_t t;
|
||||||
|
|
||||||
|
/* Normal */
|
||||||
|
_PDCLIB_fp_from_dbl( &fp, -1.0 );
|
||||||
|
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_DBL_MANT_DIG - 1 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_NORMAL );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
|
||||||
|
TESTCASE( fp.scale == ( _PDCLIB_DBL_MANT_DIG - 1 ) );
|
||||||
|
TESTCASE( fp.exponent == 0 );
|
||||||
|
|
||||||
|
/* Inf */
|
||||||
|
_PDCLIB_fp_from_dbl( &fp, 1e500 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_INF );
|
||||||
|
TESTCASE( fp.mantissa.size == 0 );
|
||||||
|
|
||||||
|
/* NaN */
|
||||||
|
_PDCLIB_fp_from_dbl( &fp, -0.0/0.0 );
|
||||||
|
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_DBL_MANT_DIG - 2 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_NAN );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
|
||||||
|
|
||||||
|
/* Subnormal */
|
||||||
|
_PDCLIB_fp_from_dbl( &fp, _PDCLIB_DBL_MIN / 2 );
|
||||||
|
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_DBL_MANT_DIG - 2 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_SUBNORMAL );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
|
||||||
|
TESTCASE( fp.scale == ( _PDCLIB_DBL_MANT_DIG - 1 ) );
|
||||||
|
TESTCASE( fp.exponent == (_PDCLIB_int_least16_t)(1 - ( _PDCLIB_DBL_MAX_EXP - 1 ) ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_ldbl.c
Normal file
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_ldbl.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/* _PDCLIB_fp_from_ldbl( _PDCLIB_fp_t *, long double )
|
||||||
|
|
||||||
|
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/_PDCLIB_print.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void _PDCLIB_fp_from_ldbl( _PDCLIB_fp_t * fp, long double ld )
|
||||||
|
{
|
||||||
|
memcpy( fp->mantissa.data, &ld, sizeof( long double ) );
|
||||||
|
|
||||||
|
fp->sign = _PDCLIB_LDBL_SIGN( fp->mantissa.data );
|
||||||
|
fp->exponent = _PDCLIB_LDBL_EXP( fp->mantissa.data );
|
||||||
|
fp->mantissa.size = _PDCLIB_LDBL_SIZE( fp->mantissa.data );
|
||||||
|
|
||||||
|
switch ( fp->exponent )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
fp->state = _PDCLIB_FP_SUBNORMAL;
|
||||||
|
fp->exponent = 1 - ( _PDCLIB_LDBL_MAX_EXP - 1 );
|
||||||
|
fp->scale = _PDCLIB_LDBL_MANT_DIG - 1;
|
||||||
|
break;
|
||||||
|
case ( _PDCLIB_LDBL_MAX_EXP - 1 ) + _PDCLIB_LDBL_MAX_EXP:
|
||||||
|
fp->state = _PDCLIB_FP_NAN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
div_t dv = div( _PDCLIB_LDBL_MANT_DIG - 1, _PDCLIB_BIGINT_DIGIT_BITS );
|
||||||
|
fp->state = _PDCLIB_FP_NORMAL;
|
||||||
|
|
||||||
|
if ( dv.rem == 0 )
|
||||||
|
{
|
||||||
|
fp->mantissa.data[ fp->mantissa.size++ ] = 1u;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fp->mantissa.data[ dv.quot ] |= ( 1u << dv.rem );
|
||||||
|
}
|
||||||
|
|
||||||
|
fp->exponent -= ( _PDCLIB_LDBL_MAX_EXP - 1 );
|
||||||
|
fp->scale = _PDCLIB_LDBL_MANT_DIG - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( fp->mantissa.size > 0 && fp->mantissa.data[ fp->mantissa.size - 1 ] == 0 )
|
||||||
|
{
|
||||||
|
--fp->mantissa.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( fp->state == _PDCLIB_FP_NAN ) && ( fp->mantissa.size == 0 ) )
|
||||||
|
{
|
||||||
|
fp->state = _PDCLIB_FP_INF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
_PDCLIB_fp_t fp;
|
||||||
|
_PDCLIB_bigint_t t;
|
||||||
|
|
||||||
|
/* Normal */
|
||||||
|
_PDCLIB_fp_from_ldbl( &fp, -1.0L );
|
||||||
|
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_LDBL_MANT_DIG - 1 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_NORMAL );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
|
||||||
|
TESTCASE( fp.scale == ( _PDCLIB_LDBL_MANT_DIG - 1 ) );
|
||||||
|
TESTCASE( fp.exponent == 0 );
|
||||||
|
|
||||||
|
/* Inf */
|
||||||
|
_PDCLIB_fp_from_ldbl( &fp, 1e5000L );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_INF );
|
||||||
|
TESTCASE( fp.mantissa.size == 0 );
|
||||||
|
|
||||||
|
/* NaN */
|
||||||
|
_PDCLIB_fp_from_ldbl( &fp, -0.0L/0.0L );
|
||||||
|
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_LDBL_MANT_DIG - 2 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_NAN );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
|
||||||
|
|
||||||
|
/* Subnormal */
|
||||||
|
_PDCLIB_fp_from_ldbl( &fp, _PDCLIB_LDBL_MIN / 2L );
|
||||||
|
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_LDBL_MANT_DIG - 2 );
|
||||||
|
TESTCASE( fp.state == _PDCLIB_FP_SUBNORMAL );
|
||||||
|
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
|
||||||
|
TESTCASE( fp.scale == ( _PDCLIB_LDBL_MANT_DIG - 1 ) );
|
||||||
|
TESTCASE( fp.exponent == (_PDCLIB_int_least16_t)(1 - ( _PDCLIB_LDBL_MAX_EXP - 1 ) ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
49
rocklibc/src/_PDCLIB/_PDCLIB_getstream.c
Normal file
49
rocklibc/src/_PDCLIB/_PDCLIB_getstream.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* _PDCLIB_getstream( FILE * )
|
||||||
|
|
||||||
|
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/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
|
||||||
|
|
||||||
|
int _PDCLIB_getstream( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_file_t * previous;
|
||||||
|
|
||||||
|
if ( ! _PDCLIB_isstream( stream, &previous ) )
|
||||||
|
{
|
||||||
|
*_PDCLIB_errno_func() = _PDCLIB_EBADF;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( previous != NULL )
|
||||||
|
{
|
||||||
|
previous->next = stream->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_PDCLIB_filelist = stream->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* No testdriver */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
82
rocklibc/src/_PDCLIB/_PDCLIB_init_file_t.c
Normal file
82
rocklibc/src/_PDCLIB/_PDCLIB_init_file_t.c
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/* _PDCLIB_init_file_t( _PDCLIB_file_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 <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef __STDC_NO_THREADS__
|
||||||
|
#include <threads.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct _PDCLIB_file_t * _PDCLIB_init_file_t( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_file_t * rc = stream;
|
||||||
|
|
||||||
|
if ( rc == NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_file_t *)malloc( sizeof( struct _PDCLIB_file_t ) ) ) == NULL )
|
||||||
|
{
|
||||||
|
/* No memory */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( rc->buffer = (char *)malloc( BUFSIZ ) ) == NULL )
|
||||||
|
{
|
||||||
|
/* No memory */
|
||||||
|
free( rc );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->bufsize = BUFSIZ;
|
||||||
|
rc->bufidx = 0;
|
||||||
|
rc->bufend = 0;
|
||||||
|
rc->pos.offset = 0;
|
||||||
|
rc->pos.status = 0;
|
||||||
|
rc->ungetidx = 0;
|
||||||
|
rc->status = _PDCLIB_FREEBUFFER;
|
||||||
|
|
||||||
|
#ifndef __STDC_NO_THREADS__
|
||||||
|
|
||||||
|
if ( stream == NULL )
|
||||||
|
{
|
||||||
|
/* If called by freopen() (stream not NULL), mutex is already
|
||||||
|
initialized.
|
||||||
|
*/
|
||||||
|
if ( mtx_init( &rc->mtx, mtx_plain | mtx_recursive ) != thrd_success )
|
||||||
|
{
|
||||||
|
/* could not initialize stream mutex */
|
||||||
|
free( rc->buffer );
|
||||||
|
free( rc );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TODO: Setting mbstate */
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
TESTCASE( NO_TESTDRIVER );
|
||||||
|
#endif
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
39
rocklibc/src/_PDCLIB/_PDCLIB_is_leap.c
Normal file
39
rocklibc/src/_PDCLIB/_PDCLIB_is_leap.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* _PDCLIB_is_leap( int )
|
||||||
|
|
||||||
|
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/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
int _PDCLIB_is_leap( int year_offset )
|
||||||
|
{
|
||||||
|
/* year given as offset from 1900, matching tm.tm_year in <time.h> */
|
||||||
|
long long year = year_offset + 1900ll;
|
||||||
|
return ( ( year % 4 ) == 0 && ( ( year % 25 ) != 0 || ( year % 400 ) == 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
/* 1901 not leap */
|
||||||
|
TESTCASE( ! _PDCLIB_is_leap( 1 ) );
|
||||||
|
/* 1904 leap */
|
||||||
|
TESTCASE( _PDCLIB_is_leap( 4 ) );
|
||||||
|
/* 1900 not leap */
|
||||||
|
TESTCASE( ! _PDCLIB_is_leap( 0 ) );
|
||||||
|
/* 2000 leap */
|
||||||
|
TESTCASE( _PDCLIB_is_leap( 100 ) );
|
||||||
|
#endif
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
49
rocklibc/src/_PDCLIB/_PDCLIB_isstream.c
Normal file
49
rocklibc/src/_PDCLIB/_PDCLIB_isstream.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* _PDCLIB_isstream( FILE *, FILE ** )
|
||||||
|
|
||||||
|
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/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
|
||||||
|
|
||||||
|
int _PDCLIB_isstream( struct _PDCLIB_file_t * stream, struct _PDCLIB_file_t ** previous )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_file_t * current = _PDCLIB_filelist;
|
||||||
|
|
||||||
|
if ( previous != NULL )
|
||||||
|
{
|
||||||
|
*previous = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( ( current != NULL ) && ( current != stream ) )
|
||||||
|
{
|
||||||
|
if ( previous != NULL )
|
||||||
|
{
|
||||||
|
*previous = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return current != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* No testdriver */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
63
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_collate.c
Normal file
63
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_collate.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* _PDCLIB_load_lc_collate( 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_collate_t * _PDCLIB_load_lc_collate( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_collate_t * rc = NULL;
|
||||||
|
const char * extension = "_collate.dat";
|
||||||
|
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_lc_collate_t *)malloc( sizeof( struct _PDCLIB_lc_collate_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
/* TODO: Collation data */
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
TESTCASE( NO_TESTDRIVER );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
365
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_ctype.c
Normal file
365
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_ctype.c
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
/* _PDCLIB_load_lc_ctype( 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_ctype_t * _PDCLIB_load_lc_ctype( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_ctype_t * rc = NULL;
|
||||||
|
const char * extension = "_ctype.dat";
|
||||||
|
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_lc_ctype_t *)malloc( sizeof( struct _PDCLIB_lc_ctype_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_ctype_entry_t * entry;
|
||||||
|
|
||||||
|
if ( ( entry = (struct _PDCLIB_lc_ctype_entry_t *)malloc( sizeof( struct _PDCLIB_lc_ctype_entry_t ) * _PDCLIB_CHARSET_SIZE + 1 ) ) != NULL )
|
||||||
|
{
|
||||||
|
rc->entry = entry + 1;
|
||||||
|
rc->entry[ -1 ].flags = rc->entry[ -1 ].upper = rc->entry[ -1 ].lower = 0;
|
||||||
|
|
||||||
|
if ( fscanf( fh, "%x %x %x %x %x %x", &rc->digits_low, &_PDCLIB_lc_ctype->digits_high, &_PDCLIB_lc_ctype->Xdigits_low, &_PDCLIB_lc_ctype->Xdigits_high, &_PDCLIB_lc_ctype->xdigits_low, &_PDCLIB_lc_ctype->xdigits_high ) == 6 )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < _PDCLIB_CHARSET_SIZE; ++i )
|
||||||
|
{
|
||||||
|
if ( fscanf( fh, "%" SCNx16 " %hhx %hhx", &rc->entry[ i ].flags, &rc->entry[ i ].upper, &rc->entry[ i ].lower ) != 3 )
|
||||||
|
{
|
||||||
|
fclose( fh );
|
||||||
|
free( file );
|
||||||
|
free( rc->entry - 1 );
|
||||||
|
free( rc );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
FILE * fh = fopen( "test_ctype.dat", "wb" );
|
||||||
|
TESTCASE( fh != NULL );
|
||||||
|
/* For test purposes, let's set up a charset that only has the hex digits */
|
||||||
|
/* 0x00..0x09 - digits */
|
||||||
|
/* 0x11..0x16 - Xdigits */
|
||||||
|
/* 0x21..0x26 - xdigits */
|
||||||
|
TESTCASE( fprintf( fh, "%x %x\n", 0x00, 0x09 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x %x\n", 0x11, 0x16, 0x21, 0x26 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x00, 0x00 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x01, 0x01 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x02, 0x02 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x03, 0x03 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x04, 0x04 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x05, 0x05 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x06, 0x06 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x07, 0x07 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x08, 0x08 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x09, 0x09 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0A, 0x0A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0B, 0x0B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0C, 0x0C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0D, 0x0D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0E, 0x0E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0F, 0x0F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x10, 0x10 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x11, 0x11 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x12, 0x12 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x13, 0x13 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x14, 0x14 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x15, 0x15 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x16, 0x16 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x17, 0x17 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x18, 0x18 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x19, 0x19 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1A, 0x1A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1B, 0x1B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1C, 0x1C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1D, 0x1D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1E, 0x1E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1F, 0x1F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x20, 0x20 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x21, 0x21 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x22, 0x22 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x23, 0x23 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x24, 0x24 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x25, 0x25 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x26, 0x26 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x27, 0x27 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x28, 0x28 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x29, 0x29 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2A, 0x2A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2B, 0x2B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2C, 0x2C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2D, 0x2D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2E, 0x2E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2F, 0x2F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x30, 0x30 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x31, 0x31 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x32, 0x32 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x33, 0x33 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x34, 0x34 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x35, 0x35 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x36, 0x36 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x37, 0x37 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x38, 0x38 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x39, 0x39 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3A, 0x3A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3B, 0x3B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3C, 0x3C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3D, 0x3D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3E, 0x3E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3F, 0x3F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x40, 0x40 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x41, 0x41 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x42, 0x42 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x43, 0x43 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x44, 0x44 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x45, 0x45 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x46, 0x46 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x47, 0x47 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x48, 0x48 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x49, 0x49 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4A, 0x4A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4B, 0x4B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4C, 0x4C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4D, 0x4D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4E, 0x4E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4F, 0x4F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x50, 0x50 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x51, 0x51 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x52, 0x52 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x53, 0x53 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x54, 0x54 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x55, 0x55 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x56, 0x56 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x57, 0x57 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x58, 0x58 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x59, 0x59 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5A, 0x5A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5B, 0x5B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5C, 0x5C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5D, 0x5D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5E, 0x5E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5F, 0x5F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x60, 0x60 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x61, 0x61 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x62, 0x62 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x63, 0x63 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x64, 0x64 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x65, 0x65 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x66, 0x66 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x67, 0x67 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x68, 0x68 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x69, 0x69 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6A, 0x6A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6B, 0x6B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6C, 0x6C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6D, 0x6D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6E, 0x6E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6F, 0x6F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x70, 0x70 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x71, 0x71 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x72, 0x72 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x73, 0x73 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x74, 0x74 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x75, 0x75 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x76, 0x76 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x77, 0x77 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x78, 0x78 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x79, 0x79 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7A, 0x7A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7B, 0x7B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7C, 0x7C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7D, 0x7D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7E, 0x7E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7F, 0x7F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x80, 0x80 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x81, 0x81 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x82, 0x82 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x83, 0x83 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x84, 0x84 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x85, 0x85 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x86, 0x86 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x87, 0x87 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x88, 0x88 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x89, 0x89 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8A, 0x8A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8B, 0x8B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8C, 0x8C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8D, 0x8D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8E, 0x8E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8F, 0x8F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x90, 0x90 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x91, 0x91 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x92, 0x92 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x93, 0x93 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x94, 0x94 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x95, 0x95 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x96, 0x96 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x97, 0x97 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x98, 0x98 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x99, 0x99 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9A, 0x9A ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9B, 0x9B ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9C, 0x9C ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9D, 0x9D ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9E, 0x9E ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9F, 0x9F ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA0, 0xA0 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA1, 0xA1 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA2, 0xA2 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA3, 0xA3 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA4, 0xA4 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA5, 0xA5 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA6, 0xA6 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA7, 0xA7 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA8, 0xA8 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA9, 0xA9 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAA, 0xAA ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAB, 0xAB ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAC, 0xAC ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAD, 0xAD ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAE, 0xAE ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAF, 0xAF ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB0, 0xB0 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB1, 0xB1 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB2, 0xB2 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB3, 0xB3 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB4, 0xB4 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB5, 0xB5 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB6, 0xB6 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB7, 0xB7 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB8, 0xB8 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB9, 0xB9 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBA, 0xBA ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBB, 0xBB ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBC, 0xBC ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBD, 0xBD ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBE, 0xBE ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBF, 0xBF ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC0, 0xC0 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC1, 0xC1 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC2, 0xC2 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC3, 0xC3 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC4, 0xC4 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC5, 0xC5 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC6, 0xC6 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC7, 0xC7 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC8, 0xC8 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC9, 0xC9 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCA, 0xCA ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCB, 0xCB ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCC, 0xCC ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCD, 0xCD ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCE, 0xCE ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCF, 0xCF ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD0, 0xD0 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD1, 0xD1 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD2, 0xD2 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD3, 0xD3 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD4, 0xD4 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD5, 0xD5 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD6, 0xD6 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD7, 0xD7 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD8, 0xD8 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD9, 0xD9 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDA, 0xDA ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDB, 0xDB ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDC, 0xDC ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDD, 0xDD ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDE, 0xDE ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDF, 0xDF ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE0, 0xE0 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE1, 0xE1 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE2, 0xE2 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE3, 0xE3 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE4, 0xE4 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE5, 0xE5 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE6, 0xE6 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE7, 0xE7 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE8, 0xE8 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE9, 0xE9 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEA, 0xEA ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEB, 0xEB ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEC, 0xEC ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xED, 0xED ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEE, 0xEE ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEF, 0xEF ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF0, 0xF0 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF1, 0xF1 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF2, 0xF2 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF3, 0xF3 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF4, 0xF4 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF5, 0xF5 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF6, 0xF6 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF7, 0xF7 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF8, 0xF8 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF9, 0xF9 ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFA, 0xFA ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFB, 0xFB ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFC, 0xFC ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFD, 0xFD ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFE, 0xFE ) );
|
||||||
|
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFF, 0xFF ) );
|
||||||
|
fclose( fh );
|
||||||
|
TESTCASE( _PDCLIB_load_lc_ctype( "./", "test" ) != NULL );
|
||||||
|
remove( "test_ctype.dat" );
|
||||||
|
/*
|
||||||
|
TESTCASE( isdigit( 0x00 ) && ! isxdigit( 0x00 ) && ! isalpha( 0x00 ) );
|
||||||
|
TESTCASE( ! isdigit( 0x11 ) && isxdigit( 0x11 ) && isalpha( 0x11 ) && isupper( 0x11 ) && ! islower( 0x11 ) );
|
||||||
|
TESTCASE( ! isdigit( 0x21 ) && isxdigit( 0x21 ) && isalpha( 0x21 ) && ! isupper( 0x11 ) && islower( 0x11 ) );
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
88
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_messages.c
Normal file
88
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_messages.c
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/* _PDCLIB_load_lc_messages( 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_messages_t * _PDCLIB_load_lc_messages( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_messages_t * rc = NULL;
|
||||||
|
const char * extension = "_messages.dat";
|
||||||
|
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_lc_messages_t *)malloc( sizeof( struct _PDCLIB_lc_messages_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char * data = _PDCLIB_load_lines( fh, _PDCLIB_ERRNO_MAX );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < _PDCLIB_ERRNO_MAX; ++i )
|
||||||
|
{
|
||||||
|
rc->errno_texts[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
FILE * fh = fopen( "test_numeric.dat", "wb" );
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * lc;
|
||||||
|
TESTCASE( fh != NULL );
|
||||||
|
TESTCASE( fputs( ",\n.\n\n", fh ) != EOF );
|
||||||
|
fclose( fh );
|
||||||
|
TESTCASE( ( lc = _PDCLIB_load_lc_numeric( "./", "test" ) ) );
|
||||||
|
remove( "test_numeric.dat" );
|
||||||
|
TESTCASE( strcmp( lc->decimal_point, "," ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->thousands_sep, "." ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->grouping, "" ) == 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
158
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_monetary.c
Normal file
158
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_monetary.c
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/* _PDCLIB_load_lc_monetary( 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * _PDCLIB_load_lc_monetary( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * rc = NULL;
|
||||||
|
const char * extension = "_monetary.dat";
|
||||||
|
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_lc_lconv_monetary_t *)malloc( sizeof( struct _PDCLIB_lc_lconv_monetary_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char buffer[ 14 ];
|
||||||
|
char * data = _PDCLIB_load_lines( fh, 7 );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
if ( fread( buffer, 1, 14, fh ) == 14 )
|
||||||
|
{
|
||||||
|
rc->mon_decimal_point = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->mon_thousands_sep = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->mon_grouping = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->positive_sign = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->negative_sign = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->currency_symbol = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->int_curr_symbol = data;
|
||||||
|
|
||||||
|
rc->frac_digits = buffer[ 0 ];
|
||||||
|
rc->p_cs_precedes = buffer[ 1 ];
|
||||||
|
rc->n_cs_precedes = buffer[ 2 ];
|
||||||
|
rc->p_sep_by_space = buffer[ 3 ];
|
||||||
|
rc->n_sep_by_space = buffer[ 4 ];
|
||||||
|
rc->p_sign_posn = buffer[ 5 ];
|
||||||
|
rc->n_sign_posn = buffer[ 6 ];
|
||||||
|
rc->int_frac_digits = buffer[ 7 ];
|
||||||
|
rc->int_p_cs_precedes = buffer[ 8 ];
|
||||||
|
rc->int_n_cs_precedes = buffer[ 9 ];
|
||||||
|
rc->int_p_sep_by_space = buffer[ 10 ];
|
||||||
|
rc->int_n_sep_by_space = buffer[ 11 ];
|
||||||
|
rc->int_p_sign_posn = buffer[ 12 ];
|
||||||
|
rc->int_n_sign_posn = buffer[ 13 ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( data );
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
FILE * fh = fopen( "test_monetary.dat", "wb" );
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * lc;
|
||||||
|
TESTCASE( fh != NULL );
|
||||||
|
fprintf( fh, "%s\n", "," ); /* mon_decimal_point */
|
||||||
|
fprintf( fh, "%s\n", "." ); /* mon_thousands_sep */
|
||||||
|
fprintf( fh, "%s\n", "3" ); /* mon_grouping */
|
||||||
|
fprintf( fh, "%s\n", "" ); /* positive_sign */
|
||||||
|
fprintf( fh, "%s\n", "-" ); /* negative_sign */
|
||||||
|
fprintf( fh, "%s\n", "\xa4" ); /* currency_symbol */
|
||||||
|
fprintf( fh, "%s\n", "EUR" ); /* int_curr_symbol */
|
||||||
|
fputc( 2, fh ); /* frac_digits */
|
||||||
|
fputc( 0, fh ); /* p_cs_precedes */
|
||||||
|
fputc( 0, fh ); /* n_cs_precedes */
|
||||||
|
fputc( 1, fh ); /* p_sep_by_space */
|
||||||
|
fputc( 1, fh ); /* n_sep_by_space */
|
||||||
|
fputc( 1, fh ); /* p_sign_posn */
|
||||||
|
fputc( 1, fh ); /* n_sign_posn */
|
||||||
|
fputc( 2, fh ); /* int_frac_digits */
|
||||||
|
fputc( 0, fh ); /* int_p_cs_precedes */
|
||||||
|
fputc( 0, fh ); /* int_n_cs_precedes */
|
||||||
|
fputc( 1, fh ); /* int_p_sep_by_space */
|
||||||
|
fputc( 1, fh ); /* int_n_sep_by_space */
|
||||||
|
fputc( 1, fh ); /* int_p_sign_posn */
|
||||||
|
fputc( 1, fh ); /* int_n_sign_posn */
|
||||||
|
fprintf( fh, "\n" );
|
||||||
|
fclose( fh );
|
||||||
|
TESTCASE( ( lc = _PDCLIB_load_lc_monetary( "./", "test" ) ) );
|
||||||
|
remove( "test_monetary.dat" );
|
||||||
|
TESTCASE( strcmp( lc->mon_decimal_point, "," ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->mon_thousands_sep, "." ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->mon_grouping, "3" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->positive_sign, "" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->negative_sign, "-" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->currency_symbol, "\xa4" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->int_curr_symbol, "EUR" ) == 0 );
|
||||||
|
|
||||||
|
TESTCASE( lc->frac_digits == 2 );
|
||||||
|
TESTCASE( lc->p_cs_precedes == 0 );
|
||||||
|
TESTCASE( lc->n_cs_precedes == 0 );
|
||||||
|
TESTCASE( lc->p_sep_by_space == 1 );
|
||||||
|
TESTCASE( lc->n_sep_by_space == 1 );
|
||||||
|
TESTCASE( lc->p_sign_posn == 1 );
|
||||||
|
TESTCASE( lc->n_sign_posn == 1 );
|
||||||
|
TESTCASE( lc->int_frac_digits == 2 );
|
||||||
|
TESTCASE( lc->int_p_cs_precedes == 0 );
|
||||||
|
TESTCASE( lc->int_n_cs_precedes == 0 );
|
||||||
|
TESTCASE( lc->int_p_sep_by_space == 1 );
|
||||||
|
TESTCASE( lc->int_n_sep_by_space == 1 );
|
||||||
|
TESTCASE( lc->int_p_sign_posn == 1 );
|
||||||
|
TESTCASE( lc->int_n_sign_posn == 1 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
84
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_numeric.c
Normal file
84
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_numeric.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* _PDCLIB_load_lc_numeric( 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * _PDCLIB_load_lc_numeric( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * rc = NULL;
|
||||||
|
const char * extension = "_numeric.dat";
|
||||||
|
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_lc_lconv_numeric_t *)malloc( sizeof( struct _PDCLIB_lc_lconv_numeric_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char * data = _PDCLIB_load_lines( fh, 3 );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
rc->decimal_point = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->thousands_sep = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->grouping = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
FILE * fh = fopen( "test_numeric.dat", "wb" );
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * lc;
|
||||||
|
TESTCASE( fh != NULL );
|
||||||
|
TESTCASE( fputs( ",\n.\n\n", fh ) != EOF );
|
||||||
|
fclose( fh );
|
||||||
|
TESTCASE( ( lc = _PDCLIB_load_lc_numeric( "./", "test" ) ) );
|
||||||
|
remove( "test_numeric.dat" );
|
||||||
|
TESTCASE( strcmp( lc->decimal_point, "," ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->thousands_sep, "." ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->grouping, "" ) == 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
165
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_time.c
Normal file
165
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_time.c
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/* _PDCLIB_load_lc_time( 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pdclib/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_time_t * _PDCLIB_load_lc_time( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_time_t * rc = NULL;
|
||||||
|
const char * extension = "_time.dat";
|
||||||
|
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = (struct _PDCLIB_lc_time_t *)malloc( sizeof( struct _PDCLIB_lc_time_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char * data = _PDCLIB_load_lines( fh, 44 );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < 12; ++i )
|
||||||
|
{
|
||||||
|
rc->month_name_abbr[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 12; ++i )
|
||||||
|
{
|
||||||
|
rc->month_name_full[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 7; ++i )
|
||||||
|
{
|
||||||
|
rc->day_name_abbr[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 7; ++i )
|
||||||
|
{
|
||||||
|
rc->day_name_full[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
FILE * fh = fopen( "test_time.dat", "wb" );
|
||||||
|
struct _PDCLIB_lc_time_t * lc;
|
||||||
|
|
||||||
|
TESTCASE( fh != NULL );
|
||||||
|
|
||||||
|
/* month name abbreviation */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Jan" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Feb" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "M\xe4r" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Apr" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Mai" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Jun" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Jul" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Aug" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Sep" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Okt" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Nov" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Dez" ) == 4 );
|
||||||
|
/* month name full */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Januar" ) == 7 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Februar" ) == 8 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "M\xe4rz" ) == 5 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "April" ) == 6 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Mai" ) == 4 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Juni" ) == 5 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Juli" ) == 5 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "August" ) == 7 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "September" ) == 10 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Oktober" ) == 8 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "November" ) == 9 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Dezember" ) == 9 );
|
||||||
|
/* day name abbreviation */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "So" ) == 3 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Mo" ) == 3 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Di" ) == 3 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Mi" ) == 3 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Do" ) == 3 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Fr" ) == 3 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Sa" ) == 3 );
|
||||||
|
/* day name full */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Sonntag" ) == 8 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Montag" ) == 7 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Dienstag" ) == 9 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Mittwoch" ) == 9 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Donnerstag" ) == 11 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Freitag" ) == 8 );
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "Samstag" ) == 8 );
|
||||||
|
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "%a %d %b %Y %T %Z" ) == 18 ); /* date time format (%c) */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "%I:%M:%S" ) == 9 ); /* 12-hour time format (%r) */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "%d.%m.%Y" ) == 9 ); /* date format (%x) */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "%H:%M:%S" ) == 9 ); /* time format (%X) */
|
||||||
|
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "" ) == 1 ); /* AM */
|
||||||
|
TESTCASE( fprintf( fh, "%s\n", "" ) == 1 ); /* PM */
|
||||||
|
fclose( fh );
|
||||||
|
TESTCASE( ( lc = _PDCLIB_load_lc_time( "./", "test" ) ) );
|
||||||
|
remove( "test_time.dat" );
|
||||||
|
|
||||||
|
TESTCASE( strcmp( lc->month_name_abbr[ 0 ], "Jan" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->month_name_abbr[ 11 ], "Dez" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->month_name_full[ 0 ], "Januar" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->month_name_full[ 11 ], "Dezember" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->day_name_abbr[ 0 ], "So" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->day_name_abbr[ 6 ], "Sa" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->day_name_full[ 0 ], "Sonntag" ) == 0 );
|
||||||
|
TESTCASE( strcmp( lc->day_name_full[ 6 ], "Samstag" ) == 0 );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
81
rocklibc/src/_PDCLIB/_PDCLIB_load_lines.c
Normal file
81
rocklibc/src/_PDCLIB/_PDCLIB_load_lines.c
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* _PDCLIB_load_lines( FILE *, size_t )
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
#ifndef REGTEST
|
||||||
|
|
||||||
|
char * _PDCLIB_load_lines( FILE * fh, size_t lines )
|
||||||
|
{
|
||||||
|
size_t required = 0;
|
||||||
|
long pos = ftell( fh );
|
||||||
|
char * rc = NULL;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* Count the number of characters */
|
||||||
|
while ( lines && ( c = fgetc( fh ) ) != EOF )
|
||||||
|
{
|
||||||
|
if ( c == '\n' )
|
||||||
|
{
|
||||||
|
--lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
++required;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! feof( fh ) )
|
||||||
|
{
|
||||||
|
if ( ( rc = (char *)malloc( required ) ) != NULL )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
fseek( fh, pos, SEEK_SET );
|
||||||
|
fread( rc, 1, required, fh );
|
||||||
|
|
||||||
|
for ( i = 0; i < required; ++i )
|
||||||
|
{
|
||||||
|
if ( rc[ i ] == '\n' )
|
||||||
|
{
|
||||||
|
rc[ i ] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
#ifndef REGTEST
|
||||||
|
FILE * fh = fopen( "test_lines.txt", "w+" );
|
||||||
|
char * rc;
|
||||||
|
|
||||||
|
TESTCASE( fh != NULL );
|
||||||
|
TESTCASE( fputs( "Foo\n\nBar\n", fh ) != EOF );
|
||||||
|
|
||||||
|
rewind( fh );
|
||||||
|
rc = _PDCLIB_load_lines( fh, 3 );
|
||||||
|
fclose( fh );
|
||||||
|
remove( "test_lines.txt" );
|
||||||
|
|
||||||
|
TESTCASE( rc != NULL );
|
||||||
|
TESTCASE( strcmp( rc, "Foo" ) == 0 );
|
||||||
|
TESTCASE( strcmp( rc + 4, "" ) == 0 );
|
||||||
|
TESTCASE( strcmp( rc + 5, "Bar" ) == 0 );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
96
rocklibc/src/_PDCLIB/_PDCLIB_naive_etod.c
Normal file
96
rocklibc/src/_PDCLIB/_PDCLIB_naive_etod.c
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/* _PDCLIB_naive_ptod( const char *, char ** endptr )
|
||||||
|
|
||||||
|
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/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
long double _PDCLIB_naive_etod( const char * s, char ** endptr )
|
||||||
|
{
|
||||||
|
/* This is nowhere good enough, just a quick approximation */
|
||||||
|
long double rc = 0.0;
|
||||||
|
|
||||||
|
while ( isdigit( (unsigned char)*s ) )
|
||||||
|
{
|
||||||
|
rc = rc * 10 + ( *s++ - '0' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *s == '.' )
|
||||||
|
{
|
||||||
|
long double fraction = 0.0;
|
||||||
|
long double scale = 1.0;
|
||||||
|
++s;
|
||||||
|
|
||||||
|
while ( isdigit( (unsigned char)*s ) )
|
||||||
|
{
|
||||||
|
fraction = fraction * 10 + ( *s++ - '0' );
|
||||||
|
scale *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc += ( fraction / scale );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( tolower( (unsigned char)*s ) == 'e' )
|
||||||
|
{
|
||||||
|
char sign = '+';
|
||||||
|
long double exp = 0.0;
|
||||||
|
long double scale = 1.0;
|
||||||
|
++s;
|
||||||
|
|
||||||
|
if ( *s == '-' )
|
||||||
|
{
|
||||||
|
sign = *s++;
|
||||||
|
}
|
||||||
|
else if ( *s == '+' )
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( isdigit( (unsigned char)*s ) )
|
||||||
|
{
|
||||||
|
exp = ( exp * 10 ) + ( *s++ - '0' );
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( exp > 0 )
|
||||||
|
{
|
||||||
|
scale *= 10;
|
||||||
|
--exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sign == '+' )
|
||||||
|
{
|
||||||
|
rc *= scale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc /= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( endptr != NULL )
|
||||||
|
{
|
||||||
|
*endptr = (char *)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* Tested by strtof / strtol / strtold */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
97
rocklibc/src/_PDCLIB/_PDCLIB_naive_ptod.c
Normal file
97
rocklibc/src/_PDCLIB/_PDCLIB_naive_ptod.c
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/* _PDCLIB_naive_ptod( const char *, char ** endptr )
|
||||||
|
|
||||||
|
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/_PDCLIB_internal.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
long double _PDCLIB_naive_ptod( const char * s, char ** endptr )
|
||||||
|
{
|
||||||
|
/* This is nowhere good enough, just a quick approximation */
|
||||||
|
long double rc = 0.0;
|
||||||
|
const char * x;
|
||||||
|
|
||||||
|
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)*s ), 16 ) ) != NULL )
|
||||||
|
{
|
||||||
|
rc = rc * 16 + ( x - _PDCLIB_digits );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *s == '.' )
|
||||||
|
{
|
||||||
|
long double fraction = 0.0;
|
||||||
|
long double scale = 1.0;
|
||||||
|
++s;
|
||||||
|
|
||||||
|
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)*s ), 16 ) ) != NULL )
|
||||||
|
{
|
||||||
|
fraction = fraction * 16 + ( x - _PDCLIB_digits );
|
||||||
|
scale *= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc += ( fraction / scale );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( tolower( (unsigned char)*s ) == 'p' )
|
||||||
|
{
|
||||||
|
char sign = '+';
|
||||||
|
long double exp = 0.0;
|
||||||
|
long double scale = 1.0;
|
||||||
|
++s;
|
||||||
|
|
||||||
|
if ( *s == '-' )
|
||||||
|
{
|
||||||
|
sign = *s++;
|
||||||
|
}
|
||||||
|
else if ( *s == '+' )
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( isdigit( (unsigned char)*s ) )
|
||||||
|
{
|
||||||
|
exp = ( exp * 10 ) + ( *s++ - '0' );
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( exp > 0 )
|
||||||
|
{
|
||||||
|
scale *= 2;
|
||||||
|
--exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sign == '+' )
|
||||||
|
{
|
||||||
|
rc *= scale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc /= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( endptr != NULL )
|
||||||
|
{
|
||||||
|
*endptr = (char *)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
#include "_PDCLIB_test.h"
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/* Tested by strtof / strtol / strtold */
|
||||||
|
return TEST_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user