extern FILE* stdout;
extern FILE* stderr;
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
FILE* fopen(const char* path, const char* mode);
int fclose(FILE* fp);
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp);
size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* fp);
+int fseek(FILE* fp, long offset, int whence);
+long ftell(FILE* fp);
+void rewind(FILE* fp);
int fflush(FILE* fp);
int fgetc(FILE* fp);
char* fgets(char* s, int size, FILE* fp);
int puts(const char* s);
int printf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
int vprintf(const char* fmt, va_list ap);
+int sprintf(char* buf, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
int snprintf(char* buf, size_t size, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
int vsnprintf(char* buf, size_t size, const char* fmt, va_list ap);
+int sscanf(const char* str, const char* fmt, ...);
+int remove(const char* path);
+int rename(const char* oldpath, const char* newpath);
#endif
int atoi(const char* s);
char* realpath(const char* path, char* resolved);
+char* getenv(const char* name);
+int abs(int x);
+long labs(long x);
+
void exit(int status) __attribute__((noreturn));
#ifndef NULL
char* strchr(const char* s, int c);
char* strrchr(const char* s, int c);
char* strcat(char* dst, const char* src);
+char* strncat(char* dst, const char* src, size_t n);
+char* strdup(const char* s);
+int strcasecmp(const char* a, const char* b);
+int strncasecmp(const char* a, const char* b, size_t n);
+char* strstr(const char* haystack, const char* needle);
+void* memchr(const void* s, int c, size_t n);
+char* strtok(char* str, const char* delim);
#endif
int feof(FILE* fp) { return fp ? (fp->flags & _STDIO_EOF) : 0; }
int ferror(FILE* fp) { return fp ? (fp->flags & _STDIO_ERR) : 0; }
+int fseek(FILE* fp, long offset, int whence) {
+ if (!fp) return -1;
+ fflush(fp);
+ fp->buf_pos = 0;
+ fp->buf_len = 0;
+ fp->flags &= ~_STDIO_EOF;
+ int rc = lseek(fp->fd, (int)offset, whence);
+ return (rc < 0) ? -1 : 0;
+}
+
+long ftell(FILE* fp) {
+ if (!fp) return -1;
+ long pos = (long)lseek(fp->fd, 0, 1 /* SEEK_CUR */);
+ if (pos < 0) return -1;
+ if (fp->flags & _STDIO_READ) {
+ pos -= (long)(fp->buf_len - fp->buf_pos);
+ }
+ return pos;
+}
+
+void rewind(FILE* fp) {
+ if (fp) fseek(fp, 0, 0 /* SEEK_SET */);
+}
+
+int remove(const char* path) {
+ return unlink(path);
+}
+
+int rename(const char* oldpath, const char* newpath) {
+ (void)oldpath; (void)newpath;
+ return -1;
+}
+
int vfprintf(FILE* fp, const char* fmt, va_list ap) {
char buf[1024];
int n = vsnprintf(buf, sizeof(buf), fmt, ap);
#undef PUTC
}
+int sprintf(char* buf, const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ int r = vsnprintf(buf, (size_t)0x7FFFFFFF, fmt, ap);
+ va_end(ap);
+ return r;
+}
+
int snprintf(char* buf, size_t size, const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
return r;
}
+int sscanf(const char* str, const char* fmt, ...) {
+ /* Minimal sscanf: only supports %d and %s */
+ va_list ap;
+ va_start(ap, fmt);
+ int count = 0;
+ const char* s = str;
+ const char* f = fmt;
+ while (*f && *s) {
+ if (*f == '%') {
+ f++;
+ if (*f == 'd' || *f == 'i') {
+ f++;
+ int* out = va_arg(ap, int*);
+ int neg = 0;
+ while (*s == ' ') s++;
+ if (*s == '-') { neg = 1; s++; }
+ else if (*s == '+') { s++; }
+ if (*s < '0' || *s > '9') break;
+ int val = 0;
+ while (*s >= '0' && *s <= '9') { val = val * 10 + (*s - '0'); s++; }
+ *out = neg ? -val : val;
+ count++;
+ } else if (*f == 's') {
+ f++;
+ char* out = va_arg(ap, char*);
+ while (*s == ' ') s++;
+ int i = 0;
+ while (*s && *s != ' ' && *s != '\n' && *s != '\t') out[i++] = *s++;
+ out[i] = '\0';
+ count++;
+ } else {
+ break;
+ }
+ } else if (*f == ' ') {
+ f++;
+ while (*s == ' ') s++;
+ } else {
+ if (*f != *s) break;
+ f++; s++;
+ }
+ }
+ va_end(ap);
+ return count;
+}
+
int vprintf(const char* fmt, va_list ap) {
char buf[1024];
int n = vsnprintf(buf, sizeof(buf), fmt, ap);
return resolved;
}
+char* getenv(const char* name) {
+ (void)name;
+ return (char*)0;
+}
+
+int abs(int x) {
+ return x < 0 ? -x : x;
+}
+
+long labs(long x) {
+ return x < 0 ? -x : x;
+}
+
void exit(int status) {
_exit(status);
}
*p = 0;
return dst;
}
+
+char* strncat(char* dst, const char* src, size_t n) {
+ char* p = dst;
+ while (*p) p++;
+ size_t i = 0;
+ while (i < n && src[i]) { *p++ = src[i++]; }
+ *p = 0;
+ return dst;
+}
+
+char* strdup(const char* s) {
+ if (!s) return (void*)0;
+ size_t len = strlen(s) + 1;
+ extern void* malloc(size_t);
+ char* d = (char*)malloc(len);
+ if (d) memcpy(d, s, len);
+ return d;
+}
+
+static int tolower_impl(int c) {
+ return (c >= 'A' && c <= 'Z') ? c + 32 : c;
+}
+
+int strcasecmp(const char* a, const char* b) {
+ while (*a && tolower_impl((unsigned char)*a) == tolower_impl((unsigned char)*b)) { a++; b++; }
+ return tolower_impl((unsigned char)*a) - tolower_impl((unsigned char)*b);
+}
+
+int strncasecmp(const char* a, const char* b, size_t n) {
+ for (size_t i = 0; i < n; i++) {
+ int ca = tolower_impl((unsigned char)a[i]);
+ int cb = tolower_impl((unsigned char)b[i]);
+ if (ca != cb) return ca - cb;
+ if (a[i] == 0) break;
+ }
+ return 0;
+}
+
+char* strstr(const char* haystack, const char* needle) {
+ if (!*needle) return (char*)haystack;
+ size_t nlen = strlen(needle);
+ while (*haystack) {
+ if (strncmp(haystack, needle, nlen) == 0) return (char*)haystack;
+ haystack++;
+ }
+ return (void*)0;
+}
+
+void* memchr(const void* s, int c, size_t n) {
+ const uint8_t* p = (const uint8_t*)s;
+ for (size_t i = 0; i < n; i++) {
+ if (p[i] == (uint8_t)c) return (void*)(p + i);
+ }
+ return (void*)0;
+}
+
+static char* strtok_state = (void*)0;
+
+char* strtok(char* str, const char* delim) {
+ if (str) strtok_state = str;
+ if (!strtok_state) return (void*)0;
+ /* skip leading delimiters */
+ while (*strtok_state && strchr(delim, *strtok_state)) strtok_state++;
+ if (!*strtok_state) return (void*)0;
+ char* start = strtok_state;
+ while (*strtok_state && !strchr(delim, *strtok_state)) strtok_state++;
+ if (*strtok_state) *strtok_state++ = 0;
+ return start;
+}