mirror of
https://github.com/Fennix-Project/Userspace.git
synced 2025-05-28 15:34:26 +00:00
Update userspace
This commit is contained in:
parent
e5c3c55e17
commit
a945423ef9
7
.gitmodules
vendored
7
.gitmodules
vendored
@ -1,12 +1,13 @@
|
|||||||
[submodule "apps/user/games/doomgeneric"]
|
[submodule "apps/user/games/doomgeneric"]
|
||||||
path = apps/user/games/doomgeneric
|
path = apps/user/games/doomgeneric
|
||||||
url = https://github.com/Fennix-Project/doomgeneric.git
|
url = https://github.com/Fennix-Project/doomgeneric.git
|
||||||
[submodule "mlibc"]
|
|
||||||
path = mlibc
|
|
||||||
url = https://github.com/Fennix-Project/mlibc.git
|
|
||||||
[submodule "apps/base/bash"]
|
[submodule "apps/base/bash"]
|
||||||
path = apps/base/bash
|
path = apps/base/bash
|
||||||
url = https://github.com/Fennix-Project/bash.git
|
url = https://github.com/Fennix-Project/bash.git
|
||||||
[submodule "musl"]
|
[submodule "musl"]
|
||||||
path = musl
|
path = musl
|
||||||
url = https://github.com/Fennix-Project/musl.git
|
url = https://github.com/Fennix-Project/musl.git
|
||||||
|
[submodule "apps/base/busybox"]
|
||||||
|
path = apps/base/busybox
|
||||||
|
url = git://busybox.net/busybox.git
|
||||||
|
branch = 1_36_stable
|
13
Makefile
13
Makefile
@ -22,10 +22,8 @@ endif
|
|||||||
|
|
||||||
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
MUSL_CONFIGURE_FLAGS := --enable-static --disable-shared
|
MUSL_CONFIGURE_FLAGS := --enable-static --disable-shared
|
||||||
MLIBC_CONFIGURE_FLAGS := -Ddefault_library=static
|
|
||||||
else
|
else
|
||||||
MUSL_CONFIGURE_FLAGS := --enable-shared --enable-static
|
MUSL_CONFIGURE_FLAGS := --enable-shared --enable-static
|
||||||
MLIBC_CONFIGURE_FLAGS := -Ddefault_library=both
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build_musl:
|
build_musl:
|
||||||
@ -42,15 +40,6 @@ build_musl:
|
|||||||
mkdir -p out/include/fennix
|
mkdir -p out/include/fennix
|
||||||
cp ../Kernel/syscalls.h out/include/fennix/syscall.h
|
cp ../Kernel/syscalls.h out/include/fennix/syscall.h
|
||||||
|
|
||||||
build_mlibc:
|
|
||||||
cp ../Kernel/syscalls.h ./mlibc/sysdeps/fennix/include/fennix/syscall.h
|
|
||||||
ifeq ($(wildcard cache/mlibc),)
|
|
||||||
cd mlibc && meson $(MLIBC_CONFIGURE_FLAGS) --cross-file ci/fennix.cross-file ../cache/mlibc
|
|
||||||
endif
|
|
||||||
cd cache/mlibc && DESTDIR=../../out ninja install
|
|
||||||
mv out/usr/local/include/* out/include/
|
|
||||||
mv out/usr/local/lib/* out/lib/
|
|
||||||
|
|
||||||
create_out:
|
create_out:
|
||||||
rm -rf out
|
rm -rf out
|
||||||
mkdir -p out
|
mkdir -p out
|
||||||
@ -68,8 +57,6 @@ ifeq ($(USE_LIBC), internal)
|
|||||||
make -C libc build
|
make -C libc build
|
||||||
else ifeq ($(USE_LIBC), musl)
|
else ifeq ($(USE_LIBC), musl)
|
||||||
$(MAKE) build_musl
|
$(MAKE) build_musl
|
||||||
else ifeq ($(USE_LIBC), mlibc)
|
|
||||||
$(MAKE) build_mlibc
|
|
||||||
endif
|
endif
|
||||||
make -C libs build
|
make -C libs build
|
||||||
make -C apps build
|
make -C apps build
|
||||||
|
@ -25,12 +25,32 @@ ifeq ($(wildcard $(CACHE_DIR)/bash),)
|
|||||||
--host=$(TARGET) \
|
--host=$(TARGET) \
|
||||||
--enable-minimal-config
|
--enable-minimal-config
|
||||||
endif
|
endif
|
||||||
make -C $(CACHE_DIR)/bash -j$(shell nproc)
|
LDFLAGS="--static" make -C $(CACHE_DIR)/bash -j$(shell nproc)
|
||||||
make -C $(CACHE_DIR)/bash install
|
make -C $(CACHE_DIR)/bash install
|
||||||
|
|
||||||
|
BUSYBOX_CROSS_PATH := $(cwd)/../../../tools/cross/bin/$(TARGET)-
|
||||||
|
|
||||||
|
build_busybox:
|
||||||
|
ifeq ($(wildcard $(CACHE_DIR)/busybox),)
|
||||||
|
mkdir -p $(CACHE_DIR)/busybox
|
||||||
|
cd $(CACHE_DIR)/busybox && \
|
||||||
|
make KBUILD_SRC=../../apps/base/busybox \
|
||||||
|
CROSS_COMPILE=$(BUSYBOX_CROSS_PATH) \
|
||||||
|
-f ../../apps/base/busybox/Makefile \
|
||||||
|
allnoconfig
|
||||||
|
endif
|
||||||
|
cd $(CACHE_DIR)/busybox && \
|
||||||
|
make -C $(CACHE_DIR)/busybox \
|
||||||
|
CROSS_COMPILE=$(BUSYBOX_CROSS_PATH) -j$(shell nproc)
|
||||||
|
cd $(CACHE_DIR)/busybox && \
|
||||||
|
make -C $(CACHE_DIR)/busybox \
|
||||||
|
CONFIG_PREFIX=$(PREFIX) \
|
||||||
|
CROSS_COMPILE=$(BUSYBOX_CROSS_PATH) install
|
||||||
|
|
||||||
build:
|
build:
|
||||||
make -C echo build
|
make -C echo build
|
||||||
make -C fsh build
|
make -C fsh build
|
||||||
|
# $(MAKE) build_busybox
|
||||||
# $(MAKE) build_bash
|
# $(MAKE) build_bash
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
1
apps/base/busybox
Submodule
1
apps/base/busybox
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 1a64f6a20aaf6ea4dbba68bbfa8cc1ab7e5c57c4
|
@ -52,7 +52,7 @@ build: $(FILENAME)
|
|||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(SYSROOT) $(OBJ) -lssp -linit -o $@
|
$(CC) $(LDFLAGS) $(SYSROOT) $(OBJ) -lssp -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
%.o: %.c $(HEADERS)
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
|
#include <sys/wait.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include "aux.h"
|
#include "aux.h"
|
||||||
|
|
||||||
#include <libinit/init.h>
|
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#define print(m, ...) init_log(m, ##__VA_ARGS__)
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
void test_args(int argc, char *argv[], char *envp[])
|
void test_args(int argc, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
print("%p %p %p\n", (void *)(uint64_t)&argc, (void *)&argv, (void *)&envp);
|
printf("%p %p %p\n", (void *)(uint64_t)&argc, (void *)&argv, (void *)&envp);
|
||||||
print("I have %d arguments\n", argc);
|
printf("I have %d arguments\n", argc);
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
print("argv[%d] = (%p) %s\n", i, argv[i], argv[i]);
|
printf("argv[%d] = (%p) %s\n", i, argv[i], argv[i]);
|
||||||
|
|
||||||
int envc = 0;
|
int envc = 0;
|
||||||
while (envp[envc] != NULL)
|
while (envp[envc] != NULL)
|
||||||
envc++;
|
envc++;
|
||||||
|
|
||||||
print("I have %d environment variables\n", envc);
|
printf("I have %d environment variables\n", envc);
|
||||||
for (int i = 0; i < envc; i++)
|
for (int i = 0; i < envc; i++)
|
||||||
print("envp[%d] = (%p) %s\n", i, envp[i], envp[i]);
|
printf("envp[%d] = (%p) %s\n", i, envp[i], envp[i]);
|
||||||
|
|
||||||
Elf64_auxv_t *auxv;
|
Elf64_auxv_t *auxv;
|
||||||
char **e = envp;
|
char **e = envp;
|
||||||
@ -30,22 +30,30 @@ void test_args(int argc, char *argv[], char *envp[])
|
|||||||
;
|
;
|
||||||
|
|
||||||
for (auxv = (Elf64_auxv_t *)e; auxv->a_type != AT_NULL; auxv++)
|
for (auxv = (Elf64_auxv_t *)e; auxv->a_type != AT_NULL; auxv++)
|
||||||
print("auxv: %ld %#lx\n", auxv->a_type, auxv->a_un.a_val);
|
printf("auxv: %ld %#lx\n", auxv->a_type, auxv->a_un.a_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[], char *envp[])
|
int main(int argc, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
// test_args(argc, argv, envp);
|
freopen("/dev/tty", "w", stdout);
|
||||||
|
freopen("/dev/tty", "w", stderr);
|
||||||
|
|
||||||
|
test_args(argc, argv, envp);
|
||||||
FILE *test = fopen("/Test.txt", "r");
|
FILE *test = fopen("/Test.txt", "r");
|
||||||
if (test == NULL)
|
if (test == NULL)
|
||||||
{
|
{
|
||||||
print("Failed to open file\n");
|
printf("Failed to open file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[1024];
|
printf("Test.txt contents: ");
|
||||||
int read = fread(buf, 1024, 1, test);
|
char ch;
|
||||||
print("/Test.txt (%ld): %s\n", read, buf);
|
do
|
||||||
|
{
|
||||||
|
ch = fgetc(test);
|
||||||
|
putchar(ch);
|
||||||
|
} while (ch != EOF);
|
||||||
|
|
||||||
fclose(test);
|
fclose(test);
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -55,7 +63,7 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
|
|
||||||
if (pid == 0) // Child process
|
if (pid == 0) // Child process
|
||||||
{
|
{
|
||||||
print("Creating shell process\n");
|
printf("Creating shell process\n");
|
||||||
char *args[] = {"/bin/sh", NULL};
|
char *args[] = {"/bin/sh", NULL};
|
||||||
execv(args[0], args);
|
execv(args[0], args);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@ -65,18 +73,18 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
wait(&status);
|
wait(&status);
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status))
|
||||||
{
|
{
|
||||||
print("Child process exited with code: %d\n", WEXITSTATUS(status));
|
printf("Child process exited with code: %d\n", WEXITSTATUS(status));
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print("Execution failed.\n");
|
printf("Execution failed.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print("\eFF0000Failed to create the process.\n");
|
printf("\eFF0000Failed to create the process.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ extern "C"
|
|||||||
#define stdout stdout
|
#define stdout stdout
|
||||||
#define stderr stderr
|
#define stderr stderr
|
||||||
|
|
||||||
|
FILE *freopen(const char *filename, const char *mode, FILE *stream);
|
||||||
FILE *fopen(const char *filename, const char *mode);
|
FILE *fopen(const char *filename, const char *mode);
|
||||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||||
@ -77,6 +78,8 @@ extern "C"
|
|||||||
int puts(const char *s);
|
int puts(const char *s);
|
||||||
int putchar(int c);
|
int putchar(int c);
|
||||||
|
|
||||||
|
int fgetc(FILE *stream);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,6 +10,12 @@ PUBLIC FILE *stdin = NULL;
|
|||||||
PUBLIC FILE *stdout = NULL;
|
PUBLIC FILE *stdout = NULL;
|
||||||
PUBLIC FILE *stderr = NULL;
|
PUBLIC FILE *stderr = NULL;
|
||||||
|
|
||||||
|
PUBLIC FILE *freopen(const char *filename, const char *mode, FILE *stream)
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PUBLIC FILE *fopen(const char *filename, const char *mode)
|
PUBLIC FILE *fopen(const char *filename, const char *mode)
|
||||||
{
|
{
|
||||||
int fd = syscall2(sys_FileOpen, (uint64_t)filename, (uint64_t)mode);
|
int fd = syscall2(sys_FileOpen, (uint64_t)filename, (uint64_t)mode);
|
||||||
|
9
libc/src/std/io/get.c
Normal file
9
libc/src/std/io/get.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <fennix/syscall.h>
|
||||||
|
|
||||||
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
|
PUBLIC int fgetc(FILE *stream)
|
||||||
|
{
|
||||||
|
}
|
@ -1,10 +1,8 @@
|
|||||||
build:
|
build:
|
||||||
cp -r include/* ../out/include
|
# cp -r include/* ../out/include
|
||||||
make -C libgcc build
|
make -C libgcc build
|
||||||
make -C libinit build
|
|
||||||
make -C libssp build
|
make -C libssp build
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C libgcc clean
|
make -C libgcc clean
|
||||||
make -C libinit clean
|
|
||||||
make -C libssp clean
|
make -C libssp clean
|
||||||
|
0
libs/include/.gitkeep
Normal file
0
libs/include/.gitkeep
Normal file
@ -1,8 +0,0 @@
|
|||||||
#ifndef __FENNIX_LIB_DRAW_H__
|
|
||||||
#define __FENNIX_LIB_DRAW_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
void DrawRect(int x, int y, int w, int h, int color);
|
|
||||||
|
|
||||||
#endif // !__FENNIX_LIB_DRAW_H__
|
|
@ -1,16 +0,0 @@
|
|||||||
#ifndef __FENNIX_LIBS_INIT_H__
|
|
||||||
#define __FENNIX_LIBS_INIT_H__
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
int printf_libinit(const char *format, ...);
|
|
||||||
int vprintf_libinit(const char *format, va_list arg);
|
|
||||||
int sprintf_libinit(char *s, const char *format, ...);
|
|
||||||
int vsprintf_libinit(char *s, const char *format, va_list arg);
|
|
||||||
int snprintf_libinit(char *s, size_t count, const char *format, ...);
|
|
||||||
int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg);
|
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void init_log(const char *fmt, ...);
|
|
||||||
|
|
||||||
#endif // !__FENNIX_LIBS_INIT_H__
|
|
@ -1,60 +0,0 @@
|
|||||||
# Config file
|
|
||||||
include ../../../Makefile.conf
|
|
||||||
|
|
||||||
NAME=init
|
|
||||||
|
|
||||||
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
|
||||||
OBJECT_NAME := lib$(NAME).a
|
|
||||||
else
|
|
||||||
OBJECT_NAME := lib$(NAME).so
|
|
||||||
endif
|
|
||||||
|
|
||||||
OUTPUT_DIR=../../out/lib/
|
|
||||||
SYSROOT = --sysroot=../../out/
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
|
||||||
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
ASM_ARCH := elf64
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
ASM_ARCH := elf32
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS := -fvisibility=hidden -fPIC -fPIE -I../include -I../../out/include
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(OBJECT_NAME)
|
|
||||||
|
|
||||||
$(OBJECT_NAME): $(OBJ)
|
|
||||||
$(info Linking $@)
|
|
||||||
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
|
||||||
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
|
||||||
else
|
|
||||||
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
|
||||||
endif
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -c $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ)
|
|
@ -1,31 +0,0 @@
|
|||||||
#include <libinit/init.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <features.h>
|
|
||||||
#include "printf.h"
|
|
||||||
|
|
||||||
#ifdef __FENNIX_LIBC__
|
|
||||||
#define cprintf printf_libinit
|
|
||||||
#define cvprintf vprintf_libinit
|
|
||||||
#else
|
|
||||||
#define cprintf printf
|
|
||||||
#define cvprintf vprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void init_log(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
static short log_lock = 0;
|
|
||||||
while (log_lock)
|
|
||||||
usleep(1);
|
|
||||||
__sync_synchronize();
|
|
||||||
log_lock = 1;
|
|
||||||
|
|
||||||
cprintf("\eCCCCCC[\e0088FFinit\eCCCCCC] \eAAAAAA");
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
cvprintf(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
cprintf("\eCCCCCC");
|
|
||||||
|
|
||||||
log_lock = 0;
|
|
||||||
__sync_synchronize();
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,174 +0,0 @@
|
|||||||
/**
|
|
||||||
* @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
|
|
||||||
* 2021-2022, Haifa, Palestine/Israel
|
|
||||||
* @author (c) Marco Paland (info@paland.com)
|
|
||||||
* 2014-2019, PALANDesign Hannover, Germany
|
|
||||||
*
|
|
||||||
* @note Others have made smaller contributions to this file: see the
|
|
||||||
* contributors page at https://github.com/eyalroz/printf/graphs/contributors
|
|
||||||
* or ask one of the authors.
|
|
||||||
*
|
|
||||||
* @brief Small stand-alone implementation of the printf family of functions
|
|
||||||
* (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with
|
|
||||||
* a very limited resources.
|
|
||||||
*
|
|
||||||
* @note the implementations are thread-safe; re-entrant; use no functions from
|
|
||||||
* the standard library; and do not dynamically allocate any memory.
|
|
||||||
*
|
|
||||||
* @license The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PRINTF_H_
|
|
||||||
#define PRINTF_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include <cstdarg>
|
|
||||||
#include <cstddef>
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#else
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define ATTR_PRINTF(one_based_format_index, first_arg) \
|
|
||||||
__attribute__((format(__printf__, (one_based_format_index), (first_arg))))
|
|
||||||
#define ATTR_VPRINTF(one_based_format_index) ATTR_PRINTF((one_based_format_index), 0)
|
|
||||||
#else
|
|
||||||
#define ATTR_PRINTF((one_based_format_index), (first_arg))
|
|
||||||
#define ATTR_VPRINTF(one_based_format_index)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
|
|
||||||
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
|
|
||||||
#define printf_ printf
|
|
||||||
#define sprintf_ sprintf
|
|
||||||
#define vsprintf_ vsprintf
|
|
||||||
#define snprintf_ snprintf
|
|
||||||
#define vsnprintf_ vsnprintf
|
|
||||||
#define vprintf_ vprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If you want to include this implementation file directly rather than
|
|
||||||
// link against, this will let you control the functions' visibility,
|
|
||||||
// e.g. make them static so as not to clash with other objects also
|
|
||||||
// using them.
|
|
||||||
#ifndef PRINTF_VISIBILITY
|
|
||||||
#define PRINTF_VISIBILITY
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* An implementation of the C standard's printf/vprintf
|
|
||||||
*
|
|
||||||
* @note you must implement a @ref putchar_ function for using this function - it invokes @ref putchar_
|
|
||||||
* rather than directly performing any I/O (which insulates it from any dependence on the operating system
|
|
||||||
* and external libraries).
|
|
||||||
*
|
|
||||||
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
|
|
||||||
* additional arguments.
|
|
||||||
* @param arg Additional arguments to the function, one for each %-specifier in @p format string
|
|
||||||
* @return The number of characters written into @p s, not counting the terminating null character
|
|
||||||
*/
|
|
||||||
///@{
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int printf_libinit(const char *format, ...) ATTR_PRINTF(1, 2);
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int vprintf_libinit(const char *format, va_list arg) ATTR_VPRINTF(1);
|
|
||||||
///@}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An implementation of the C standard's sprintf/vsprintf
|
|
||||||
*
|
|
||||||
* @note For security considerations (the potential for exceeding the buffer bounds), please consider using
|
|
||||||
* the size-constrained variant, @ref snprintf / @ref vsnprintf , instead.
|
|
||||||
*
|
|
||||||
* @param s An array in which to store the formatted string. It must be large enough to fit the formatted
|
|
||||||
* output!
|
|
||||||
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
|
|
||||||
* additional arguments.
|
|
||||||
* @param arg Additional arguments to the function, one for each specifier in @p format
|
|
||||||
* @return The number of characters written into @p s, not counting the terminating null character
|
|
||||||
*/
|
|
||||||
///@{
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int sprintf_libinit(char *s, const char *format, ...) ATTR_PRINTF(2, 3);
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int vsprintf_libinit(char *s, const char *format, va_list arg) ATTR_VPRINTF(2);
|
|
||||||
///@}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An implementation of the C standard's snprintf/vsnprintf
|
|
||||||
*
|
|
||||||
* @param s An array in which to store the formatted string. It must be large enough to fit either the
|
|
||||||
* entire formatted output, or at least @p n characters. Alternatively, it can be NULL, in which case
|
|
||||||
* nothing will be printed, and only the number of characters which _could_ have been printed is
|
|
||||||
* tallied and returned.
|
|
||||||
* @param n The maximum number of characters to write to the array, including a terminating null character
|
|
||||||
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
|
|
||||||
* additional arguments.
|
|
||||||
* @param arg Additional arguments to the function, one for each specifier in @p format
|
|
||||||
* @return The number of characters that COULD have been written into @p s, not counting the terminating
|
|
||||||
* null character. A value equal or larger than @p n indicates truncation. Only when the returned value
|
|
||||||
* is non-negative and less than @p n, the null-terminated string has been fully and successfully printed.
|
|
||||||
*/
|
|
||||||
///@{
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int snprintf_libinit(char *s, size_t count, const char *format, ...) ATTR_PRINTF(3, 4);
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg) ATTR_VPRINTF(3);
|
|
||||||
///@}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* printf/vprintf with user-specified output function
|
|
||||||
*
|
|
||||||
* An alternative to @ref printf_, in which the output function is specified dynamically
|
|
||||||
* (rather than @ref putchar_ being used)
|
|
||||||
*
|
|
||||||
* @param out An output function which takes one character and a type-erased additional parameters
|
|
||||||
* @param extra_arg The type-erased argument to pass to the output function @p out with each call
|
|
||||||
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
|
|
||||||
* additional arguments.
|
|
||||||
* @param arg Additional arguments to the function, one for each specifier in @p format
|
|
||||||
* @return The number of characters for which the output f unction was invoked, not counting the terminating null character
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int fctprintf_libinit(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...) ATTR_PRINTF(3, 4);
|
|
||||||
PRINTF_VISIBILITY
|
|
||||||
int vfctprintf_libinit(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) ATTR_VPRINTF(3);
|
|
||||||
|
|
||||||
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
|
|
||||||
#undef printf_
|
|
||||||
#undef sprintf_
|
|
||||||
#undef vsprintf_
|
|
||||||
#undef snprintf_
|
|
||||||
#undef vsnprintf_
|
|
||||||
#undef vprintf_
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // PRINTF_H_
|
|
1
mlibc
1
mlibc
@ -1 +0,0 @@
|
|||||||
Subproject commit 77f7b4d310c05c82d64899f2186558f5abbcdded
|
|
Loading…
x
Reference in New Issue
Block a user