summaryrefslogtreecommitdiff
path: root/src/web/libc.c
blob: c49fa03ea035c3a1fa88fe9783d4ec98b2c07adb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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);
}