浏览器

This commit is contained in:
2026-04-25 14:24:07 +08:00
parent b84e4ad56e
commit 7d50586a4e
8 changed files with 2726 additions and 6 deletions

View File

@@ -187,6 +187,23 @@ set(USER_CFLAGS_DOOM
"${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/doom_shim.h" "${CMAKE_SOURCE_DIR}/cleonos/c/apps/doom/doom_shim.h"
) )
set(USER_CFLAGS_BROWSER
-std=c11
-ffreestanding
-fno-stack-protector
-fno-builtin
-Wall
-Wextra
-Wno-error
-Wno-unused-parameter
-Wno-sign-compare
-Wno-missing-field-initializers
-DNDEBUG
"-I${CMAKE_SOURCE_DIR}/cleonos/c/include"
"-I${CMAKE_SOURCE_DIR}/cleonos/third-party/litehtml/src/gumbo/include"
"-I${CMAKE_SOURCE_DIR}/cleonos/third-party/litehtml/src/gumbo/include/gumbo"
)
set(USER_LDFLAGS set(USER_LDFLAGS
-nostdlib -nostdlib
-z -z

View File

@@ -71,6 +71,23 @@ function(add_user_c_object_doom SRC OUTPUT_VAR)
set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE) set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE)
endfunction() endfunction()
function(add_user_c_object_browser SRC OUTPUT_VAR)
string(REGEX REPLACE "\\.c$" ".o" OBJ_REL "${SRC}")
set(OBJ_PATH "${USER_OBJ_ROOT}/${OBJ_REL}")
get_filename_component(OBJ_DIR "${OBJ_PATH}" DIRECTORY)
set(_deps "${CMAKE_SOURCE_DIR}/${SRC}" ${USER_INC_SOURCES_ABS} ${BROWSER_GUMBO_DEP_SOURCES_ABS})
add_custom_command(
OUTPUT "${OBJ_PATH}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${OBJ_DIR}"
COMMAND ${USER_CC} ${USER_CFLAGS_BROWSER} -c "${CMAKE_SOURCE_DIR}/${SRC}" -o "${OBJ_PATH}"
DEPENDS ${_deps}
VERBATIM
)
set(${OUTPUT_VAR} "${OBJ_PATH}" PARENT_SCOPE)
endfunction()
set(USER_COMMON_OBJECTS) set(USER_COMMON_OBJECTS)
foreach(SRC IN LISTS USER_COMMON_SOURCES) foreach(SRC IN LISTS USER_COMMON_SOURCES)
add_user_c_object("${SRC}" OBJ_OUT) add_user_c_object("${SRC}" OBJ_OUT)
@@ -126,6 +143,26 @@ file(GLOB_RECURSE DOOMGENERIC_DEP_SOURCES_ABS CONFIGURE_DEPENDS
) )
list(SORT DOOMGENERIC_DEP_SOURCES_ABS) list(SORT DOOMGENERIC_DEP_SOURCES_ABS)
set(BROWSER_GUMBO_DIR "${CMAKE_SOURCE_DIR}/cleonos/third-party/litehtml/src/gumbo")
set(BROWSER_GUMBO_SRC_BASENAMES
attribute char_ref error parser string_buffer string_piece tag tokenizer utf8 util vector
)
set(BROWSER_GUMBO_APP_SOURCES)
foreach(_base IN LISTS BROWSER_GUMBO_SRC_BASENAMES)
list(APPEND BROWSER_GUMBO_APP_SOURCES "cleonos/third-party/litehtml/src/gumbo/${_base}.c")
endforeach()
set(BROWSER_GUMBO_REQUIRED_SOURCE "${CMAKE_SOURCE_DIR}/cleonos/third-party/litehtml/src/gumbo/parser.c")
if(EXISTS "${BROWSER_GUMBO_REQUIRED_SOURCE}")
set(BROWSER_GUMBO_AVAILABLE ON)
else()
set(BROWSER_GUMBO_AVAILABLE OFF)
cl_log_warn("litehtml gumbo sources missing, browser app will be skipped: ${BROWSER_GUMBO_REQUIRED_SOURCE}")
endif()
file(GLOB_RECURSE BROWSER_GUMBO_DEP_SOURCES_ABS CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/cleonos/third-party/litehtml/src/gumbo/include/*.h"
)
list(SORT BROWSER_GUMBO_DEP_SOURCES_ABS)
set(USER_SHELL_COMMAND_APPS set(USER_SHELL_COMMAND_APPS
help args ls cat grep head tail wc cut uniq sort pwd cd exec pid spawn wait sleep yield help args ls cat grep head tail wc cut uniq sort pwd cd exec pid spawn wait sleep yield
ping ifconfig nslookup httpget ping ifconfig nslookup httpget
@@ -133,7 +170,7 @@ set(USER_SHELL_COMMAND_APPS
procstat sysstat procstat sysstat
diskinfo mkfsfat32 mount partctl diskinfo mkfsfat32 mount partctl
shutdown restart exit clear ansi ansitest wavplay fastfetch memstat fsstat taskstat userstat shutdown restart exit clear ansi ansitest wavplay fastfetch memstat fsstat taskstat userstat
shstat stats tty dmesg kbdstat mkdir touch write append cp mv rm kdbg bmpview qrcode shstat stats tty dmesg kbdstat mkdir touch write append cp mv rm kdbg bmpview qrcode browser
) )
foreach(SRC IN LISTS USER_APP_MAIN_SOURCES) foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
@@ -164,6 +201,10 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
cl_log_warn("skip user app doom because doomgeneric sources are unavailable") cl_log_warn("skip user app doom because doomgeneric sources are unavailable")
continue() continue()
endif() endif()
if(_app_name STREQUAL "browser" AND NOT BROWSER_GUMBO_AVAILABLE)
cl_log_warn("skip user app browser because litehtml gumbo sources are unavailable")
continue()
endif()
list(FIND USER_APP_NAMES "${_app_name}" _dup_name_idx) list(FIND USER_APP_NAMES "${_app_name}" _dup_name_idx)
if(NOT _dup_name_idx EQUAL -1) if(NOT _dup_name_idx EQUAL -1)
@@ -171,7 +212,11 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
endif() endif()
list(APPEND USER_APP_NAMES "${_app_name}") list(APPEND USER_APP_NAMES "${_app_name}")
add_user_c_object("${SRC}" _user_obj) if(_app_name STREQUAL "browser")
add_user_c_object_browser("${SRC}" _user_obj)
else()
add_user_c_object("${SRC}" _user_obj)
endif()
set(_app_specific_objs) set(_app_specific_objs)
file(GLOB _app_specific_abs CONFIGURE_DEPENDS file(GLOB _app_specific_abs CONFIGURE_DEPENDS
@@ -185,6 +230,11 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
list(APPEND _app_specific_abs "${CMAKE_SOURCE_DIR}/${_doom_src}") list(APPEND _app_specific_abs "${CMAKE_SOURCE_DIR}/${_doom_src}")
endforeach() endforeach()
endif() endif()
if(_app_name STREQUAL "browser")
foreach(_gumbo_src IN LISTS BROWSER_GUMBO_APP_SOURCES)
list(APPEND _app_specific_abs "${CMAKE_SOURCE_DIR}/${_gumbo_src}")
endforeach()
endif()
list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx) list(FIND USER_SHELL_COMMAND_APPS "${_app_name}" _shell_cmd_idx)
if(NOT _shell_cmd_idx EQUAL -1) if(NOT _shell_cmd_idx EQUAL -1)
@@ -201,8 +251,12 @@ foreach(SRC IN LISTS USER_APP_MAIN_SOURCES)
continue() continue()
endif() endif()
if(_app_name STREQUAL "doom") if(_extra_rel STREQUAL "cleonos/c/apps/cmd_runtime.c")
add_user_c_object("${_extra_rel}" _extra_obj)
elseif(_app_name STREQUAL "doom")
add_user_c_object_doom("${_extra_rel}" _extra_obj) add_user_c_object_doom("${_extra_rel}" _extra_obj)
elseif(_app_name STREQUAL "browser")
add_user_c_object_browser("${_extra_rel}" _extra_obj)
else() else()
add_user_c_object("${_extra_rel}" _extra_obj) add_user_c_object("${_extra_rel}" _extra_obj)
endif() endif()

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,11 @@ unsigned long strtoul(const char *text, char **out_end, int base);
long long strtoll(const char *text, char **out_end, int base); long long strtoll(const char *text, char **out_end, int base);
unsigned long long strtoull(const char *text, char **out_end, int base); unsigned long long strtoull(const char *text, char **out_end, int base);
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t count, size_t size);
void *realloc(void *ptr, size_t size);
void srand(unsigned int seed); void srand(unsigned int seed);
int rand(void); int rand(void);

View File

@@ -0,0 +1,9 @@
#ifndef CLEONOS_LIBC_STRINGS_H
#define CLEONOS_LIBC_STRINGS_H
#include <stddef.h>
int strcasecmp(const char *left, const char *right);
int strncasecmp(const char *left, const char *right, size_t size);
#endif

View File

@@ -2,6 +2,7 @@
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <string.h>
#include <cleonos_syscall.h> #include <cleonos_syscall.h>
@@ -239,6 +240,109 @@ unsigned long long strtoull(const char *text, char **out_end, int base) {
return (unsigned long long)strtoul(text, out_end, base); return (unsigned long long)strtoul(text, out_end, base);
} }
#define CLIB_HEAP_CAPACITY (4U * 1024U * 1024U)
#define CLIB_HEAP_ALIGN 8U
typedef union clib_heap_storage {
unsigned long long align;
unsigned char bytes[CLIB_HEAP_CAPACITY];
} clib_heap_storage;
static clib_heap_storage clib_heap;
static size_t clib_heap_used = 0U;
static size_t clib_align_up(size_t value, size_t align) {
size_t mask;
if (align == 0U) {
return value;
}
mask = align - 1U;
return (value + mask) & ~mask;
}
__attribute__((weak)) void *malloc(size_t size) {
size_t need;
size_t begin;
size_t end;
size_t *hdr;
if (size == 0U) {
return (void *)0;
}
size = clib_align_up(size, CLIB_HEAP_ALIGN);
need = sizeof(size_t) + size;
begin = clib_align_up(clib_heap_used, CLIB_HEAP_ALIGN);
if (begin > (size_t)CLIB_HEAP_CAPACITY || need > (size_t)CLIB_HEAP_CAPACITY - begin) {
return (void *)0;
}
end = begin + need;
hdr = (size_t *)(void *)(clib_heap.bytes + begin);
*hdr = size;
clib_heap_used = end;
return (void *)(hdr + 1);
}
__attribute__((weak)) void free(void *ptr) {
(void)ptr;
/* monotonic allocator: memory is reclaimed when process exits */
}
__attribute__((weak)) void *calloc(size_t count, size_t size) {
size_t total;
void *ptr;
if (count == 0U || size == 0U) {
return (void *)0;
}
if (count > ((size_t)-1) / size) {
return (void *)0;
}
total = count * size;
ptr = malloc(total);
if (ptr == (void *)0) {
return (void *)0;
}
(void)memset(ptr, 0, total);
return ptr;
}
__attribute__((weak)) void *realloc(void *ptr, size_t size) {
void *out;
size_t old_size;
if (ptr == (void *)0) {
return malloc(size);
}
if (size == 0U) {
free(ptr);
return (void *)0;
}
old_size = *((size_t *)ptr - 1U);
out = malloc(size);
if (out == (void *)0) {
return (void *)0;
}
if (old_size < size) {
(void)memcpy(out, ptr, old_size);
} else {
(void)memcpy(out, ptr, size);
}
free(ptr);
return out;
}
static unsigned long clib_rand_state = 1UL; static unsigned long clib_rand_state = 1UL;
void srand(unsigned int seed) { void srand(unsigned int seed) {

View File

@@ -0,0 +1,81 @@
#include <strings.h>
#include <ctype.h>
static int clib_strings_lower(int ch) {
if (ch >= 'A' && ch <= 'Z') {
return ch - 'A' + 'a';
}
return ch;
}
__attribute__((weak)) int strcasecmp(const char *left, const char *right) {
size_t i = 0U;
if (left == right) {
return 0;
}
if (left == (const char *)0) {
return -1;
}
if (right == (const char *)0) {
return 1;
}
while (left[i] != '\0' && right[i] != '\0') {
int lc = clib_strings_lower((unsigned char)left[i]);
int rc = clib_strings_lower((unsigned char)right[i]);
if (lc != rc) {
return (lc < rc) ? -1 : 1;
}
i++;
}
if (left[i] == right[i]) {
return 0;
}
return (left[i] < right[i]) ? -1 : 1;
}
__attribute__((weak)) int strncasecmp(const char *left, const char *right, size_t size) {
size_t i = 0U;
if (size == 0U || left == right) {
return 0;
}
if (left == (const char *)0) {
return -1;
}
if (right == (const char *)0) {
return 1;
}
while (i < size && left[i] != '\0' && right[i] != '\0') {
int lc = clib_strings_lower((unsigned char)left[i]);
int rc = clib_strings_lower((unsigned char)right[i]);
if (lc != rc) {
return (lc < rc) ? -1 : 1;
}
i++;
}
if (i == size) {
return 0;
}
if (left[i] == right[i]) {
return 0;
}
return (left[i] < right[i]) ? -1 : 1;
}

1
cleonos/third-party/litehtml vendored Submodule

Submodule cleonos/third-party/litehtml added at 8836bc1bc3