diff options
Diffstat (limited to 'src/web/libc.c')
| -rw-r--r-- | src/web/libc.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/web/libc.c b/src/web/libc.c new file mode 100644 index 00000000..c49fa03e --- /dev/null +++ b/src/web/libc.c @@ -0,0 +1,152 @@ +/* Minimal libc-shaped surface used by Tree-sitter inside the freestanding + * browser module. Allocation lives in web.zig so it shares Zig's wasm heap; + * these routines neither import browser functions nor perform IO. */ +#include <ctype.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <wctype.h> + +_Noreturn void abort(void) { + __builtin_trap(); +} + +size_t strlen(const char *str) { + const char *end = str; + while (*end) end++; + return (size_t)(end - str); +} + +char *strchr(const char *str, int character) { + const unsigned char needle = (unsigned char)character; + do { + if ((unsigned char)*str == needle) return (char *)str; + } while (*str++); + return (char *)0; +} + +void *memchr(const void *ptr, int value, size_t count) { + const unsigned char *bytes = (const unsigned char *)ptr; + const unsigned char needle = (unsigned char)value; + for (size_t index = 0; index < count; index++) { + if (bytes[index] == needle) return (void *)(bytes + index); + } + return (void *)0; +} + +int strcmp(const char *lhs, const char *rhs) { + while (*lhs && (unsigned char)*lhs == (unsigned char)*rhs) { + lhs++; + rhs++; + } + return (int)(unsigned char)*lhs - (int)(unsigned char)*rhs; +} + +int strncmp(const char *lhs, const char *rhs, size_t count) { + while (count && *lhs && (unsigned char)*lhs == (unsigned char)*rhs) { + lhs++; + rhs++; + count--; + } + return count ? (int)(unsigned char)*lhs - (int)(unsigned char)*rhs : 0; +} + +char *strncpy(char *restrict dest, const char *restrict src, size_t count) { + char *result = dest; + while (count && *src) { + *dest++ = *src++; + count--; + } + while (count--) *dest++ = '\0'; + return result; +} + +int isprint(int character) { + return character >= 0x20 && character <= 0x7e; +} + +int isdigit(int character) { + return character >= '0' && character <= '9'; +} + +int iswspace(wint_t character) { + return character == ' ' || (character >= '\t' && character <= '\r'); +} + +int iswalnum(wint_t character) { + return iswdigit(character) || iswalpha(character); +} + +int iswalpha(wint_t character) { + return (character >= 'A' && character <= 'Z') || + (character >= 'a' && character <= 'z') || character >= 0x80; +} + +int iswblank(wint_t character) { + return character == ' ' || character == '\t'; +} + +int iswdigit(wint_t character) { + return character >= '0' && character <= '9'; +} + +int iswlower(wint_t character) { + return character >= 'a' && character <= 'z'; +} + +int iswupper(wint_t character) { + return character >= 'A' && character <= 'Z'; +} + +int iswxdigit(wint_t character) { + return iswdigit(character) || (character >= 'A' && character <= 'F') || + (character >= 'a' && character <= 'f'); +} + +wint_t towupper(wint_t character) { + return iswlower(character) ? character - ('a' - 'A') : character; +} + +int vsnprintf(char *restrict buffer, size_t size, const char *restrict format, va_list args) { + (void)format; + (void)args; + if (size) buffer[0] = '\0'; + return 0; +} + +int snprintf(char *restrict buffer, size_t size, const char *restrict format, ...) { + va_list args; + va_start(args, format); + int result = vsnprintf(buffer, size, format, args); + va_end(args); + return result; +} + +int fprintf(FILE *stream, const char *format, ...) { + (void)stream; + (void)format; + return 0; +} + +int fclose(FILE *stream) { + (void)stream; + return 0; +} + +FILE *fdopen(int descriptor, const char *mode) { + (void)descriptor; + (void)mode; + return (FILE *)0; +} + +int fputc(int character, FILE *stream) { + (void)stream; + return character; +} + +int fputs(const char *string, FILE *stream) { + (void)stream; + return (int)strlen(string); +} |
