summaryrefslogtreecommitdiff
path: root/src/web/libc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/web/libc.c')
-rw-r--r--src/web/libc.c152
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);
+}