#include #include #include #include "uapi/std/syscall.h" #include "uapi/std/string.h" static const char conv_tab[] = "0123456789abcdefghijklmnopqrstuvwxyz"; void __std_putc(int fd, char c) { sys_write(fd, &c, 1); } void __std_puts(int fd, const char *s) { for (; *s; s++) __std_putc(fd, *s); } static size_t __std_vprint_long_hex(char *buf, size_t blen, unsigned long num, char **ps) { char *s = &buf[blen - 2]; buf[blen - 1] = '\0'; if (num == 0) { *s = '0', s--; goto done; } while (num > 0) { *s = conv_tab[num % 16], s--; num /= 16; } done: s++; *ps = s; return blen - (s - buf); } static size_t __std_vprint_long(char *buf, size_t blen, long num, char **ps) { char *s = &buf[blen - 2]; int neg = 0; buf[blen - 1] = '\0'; if (num < 0) { neg = 1; num = -num; } else if (num == 0) { *s = '0'; s--; goto done; } while (num > 0) { *s = (num % 10) + '0'; s--; num /= 10; } if (neg) { *s = '-'; s--; } done: s++; *ps = s; return blen - (s - buf); } void __std_printk(int fd, const char *format, va_list args) { const char *s = format; for (; *s != '\0'; s++) { char buf[32], *t; int along = 0; if (*s != '%') { __std_putc(fd, *s); continue; } s++; if (*s == 'l') { along = 1; s++; if (*s == 'l') s++; } switch (*s) { case 's': __std_puts(fd, va_arg(args, char *)); break; case 'd': __std_vprint_long(buf, sizeof(buf), along ? va_arg(args, long) : (long)va_arg(args, int), &t); __std_puts(fd, t); break; case 'x': __std_vprint_long_hex(buf, sizeof(buf), along ? va_arg(args, long) : (long)va_arg(args, int), &t); __std_puts(fd, t); break; } } } void __std_printf(int fd, const char *format, ...) { va_list args; va_start(args, format); __std_printk(fd, format, args); va_end(args); } static inline bool __isspace(unsigned char c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; } static unsigned char __tolower(unsigned char c) { return (c <= 'Z' && c >= 'A') ? c - 'A' + 'a' : c; } static inline bool __isalpha(unsigned char c) { return ((c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a')); } static inline bool __isdigit(unsigned char c) { return (c <= '9' && c >= '0'); } static inline bool __isalnum(unsigned char c) { return (__isalpha(c) || __isdigit(c)); } static unsigned int __conv_val(unsigned char c) { if (__isdigit(c)) return c - '0'; else if (__isalpha(c)) return &conv_tab[__tolower(c)] - conv_tab; return -1u; } unsigned long std_strtoul(const char *nptr, char **endptr, int base) { const char *s = nptr; bool neg = false; unsigned int v; long num = 0; if (base < 0 || base == 1 || base > 36) goto fin; while (__isspace(*s)) s++; if (!*s) goto fin; if (*s == '-') neg = true, s++; if (base == 0) { if (s[0] == '0') { unsigned char p = __tolower(s[1]); switch (p) { case 'b': base = 2, s += 2; break; case 'x': base = 16, s += 2; break; default: base = 8, s += 1; break; } } else base = 10; } else if (base == 16) { if (s[0] == '0' && __tolower(s[1]) == 'x') s += 2; } for (; *s; s++) { if (__isspace(*s)) continue; if (!__isalnum(*s)) goto fin; v = __conv_val(*s); if (v == -1u || v > base) goto fin; num *= base; num += v; } fin: if (endptr) *endptr = (char *)s; return neg ? (unsigned long)-num : (unsigned long)num; } void *std_memcpy(void *to, const void *from, unsigned int n) { /* FIXME: Per-arch support */ #if 0 int d0, d1, d2; asm volatile("rep ; movsl \n" "movl %4,%%ecx \n" "andl $3,%%ecx \n" "jz 1f \n" "rep ; movsb \n" "1:" : "=&c" (d0), "=&D" (d1), "=&S" (d2) : "0" (n / 4), "g" (n), "1" ((long)to), "2" ((long)from) : "memory"); #endif return to; } int std_memcmp(const void *cs, const void *ct, size_t count) { const unsigned char *su1, *su2; int res = 0; for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) if ((res = *su1 - *su2) != 0) break; return res; } int std_strcmp(const char *cs, const char *ct) { unsigned char c1, c2; while (1) { c1 = *cs++; c2 = *ct++; if (c1 != c2) return c1 < c2 ? -1 : 1; if (!c1) break; } return 0; }