/* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen * Copyright (C) 2018 Han-Wen Nienhuys * * This file is part of Mes. * * Mes is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * Mes is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Mes. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #if __MESC__ #include #include #else // !__MESC__ #include #include #endif // !__MESC__ int dlclose (void *handle) { return 0; } void * dlopen (char const *filename, int flags) { return 0; } int execvp (char const *file, char *const argv[]) { eputs ("execvp stub\n"); return 0; } int fclose (FILE *stream) { int fd = (int)stream; return close (fd); } FILE * fdopen (int fd, char const *mode) { return (FILE*)fd; } int ferror (FILE *stream) { int fd = (int)stream; if (fd == -1) return -1; return 0; } int fflush (FILE *stream) { return 0; } int fprintf (FILE *stream, char const *format, ...) { va_list ap; va_start (ap, format); int r = vfprintf (stream, format, ap); va_end (ap); return r; } size_t fread (void *data, size_t size, size_t count, FILE *stream) { if (! size || !count) return 0; int bytes = read ((int)stream, data, size * count); if (bytes > 0) return bytes/size; return bytes; } long ftell (FILE *stream) { return lseek ((int)stream, 0, SEEK_CUR); } int fseek (FILE *stream, long offset, int whence) { int pos = lseek ((int)stream, offset, whence); if (pos >= 0) return 0; return -1; } int gettimeofday (struct timeval *tv, struct timezone *tz) { return 0; } double ldexp (double x, int exp) { eputs ("ldexp stub\n"); return 0; } struct tm * localtime (time_t const *timep) { eputs ("localtime stub\n"); return 0; } void * memmove (void *dest, void const *src, size_t n) { if (dest < src) return memcpy (dest, src, n); char *p = dest + n; char const *q = src +n; while (n--) *--p = *--q; return dest; } void * memset (void *s, int c, size_t n) { char *p = s; while (n--) *p++ = c; return s; } int memcmp (void const *s1, void const *s2, size_t n) { char *a = s1; char *b = s2; while (*a == *b && --n) {a++;b++;} return *a - *b; } int mprotect (void *addr, size_t len, int prot) { return 0; } void qswap (void *a, void *b, size_t size) { char *buf[8]; memcpy (buf, a, size); memcpy (a, b, size); memcpy (b, buf, size); } size_t qpart (void *base, size_t count, size_t size, int (*compare)(void const *, void const *)) { void* p = base + count*size; size_t i = 0; for (size_t j = 0; j < count; j++) { if (compare (base+j*size, p) < 0) { qswap (base+i*size, base+j*size, size); i++; } } if (compare (base+count*size, base+i*size) < 0) qswap (base+i*size, base+count*size, size); return i; } void qsort (void *base, size_t count, size_t size, int (*compare)(void const *, void const *)) { if (count > 1) { int p = qpart (base, count-1, size, compare); qsort (base, p, size, compare); qsort (base+p*size, count-p, size, compare); } } int remove (char const *file_name) { struct stat buf; if (stat (file_name, &buf) < 0) return -1; if (S_ISDIR (buf.st_mode)) return rmdir (file_name); return unlink (file_name); } int sigaction (int signum, struct sigaction const *act, struct sigaction *oldact) { return 0; } int sigemptyset (sigset_t *set) { return 0; } int snprintf(char *str, size_t size, char const *format, ...) { va_list ap; va_start (ap, format); int r = vsprintf (str, format, ap); va_end (ap); return r; } int sscanf (char const *str, const char *template, ...) { va_list ap; va_start (ap, template); int r = vsscanf (str, template, ap); va_end (ap); return r; return 0; } char * strcat (char *to, char const *from) { char *p = strchr (to, '\0'); while (*from) *p++ = *from++; *p = 0; return to; } char * strchr (char const *s, int c) { char const *p = s; while (*p || !c) { if (c == *p) return p; *p++; } return 0; } char * strncpy (char *dest, char const *src, size_t length) { char *p = dest; while (*src && length--) *p++ = *src++; if (*src) length++; while (length--) *p++ = 0; return dest; } char * strrchr (char const *s, int c) { int n = strlen (s); if (!n) return 0; char const *p = s + n - 1; while (*p || !c) { if (c == *p) return p; *p--; } return 0; } /** locate a substring. #memmem# finds the first occurrence of #needle# in #haystack#. This is not ANSI-C. The prototype is not in accordance with the Linux Programmer's Manual v1.15, but it is with /usr/include/string.h */ unsigned char * _memmem (unsigned char const *haystack, int haystack_len, unsigned char const *needle, int needle_len) { unsigned char const *end_haystack = haystack + haystack_len - needle_len + 1; unsigned char const *end_needle = needle + needle_len; /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation is the spice of life */ while (haystack < end_haystack) { unsigned char const *subneedle = needle; unsigned char const *subhaystack = haystack; while (subneedle < end_needle) if (*subneedle++ != *subhaystack++) goto next; /* Completed the needle. Gotcha. */ return (unsigned char *) haystack; next: haystack++; } return 0; } void * memmem (void const *haystack, int haystack_len, void const *needle, int needle_len) { unsigned char const *haystack_byte_c = (unsigned char const *)haystack; unsigned char const *needle_byte_c = (unsigned char const *)needle; return _memmem (haystack_byte_c, haystack_len, needle_byte_c, needle_len); } char * strstr (char const *haystack, char const *needle) { return memmem (haystack, strlen (haystack), needle, strlen (needle)); } double strtod (char const *nptr, char **endptr) { eputs ("strtod stub\n"); } float strtof (char const *nptr, char **endptr) { return strtod (nptr, endptr); } long double strtold (char const *nptr, char **endptr) { return strtod (nptr, endptr); } long strtol (char const *nptr, char **endptr, int base) { if (!strncmp (nptr, "0x", 2)) { char const *p = nptr + 2; return abtoi (&p, 16); } return abtoi (&nptr, base); } long long int strtoll (char const *nptr, char **endptr, int base) { eputs ("strtoll stub\n"); return 0; } unsigned long strtoul (char const *nptr, char **endptr, int base) { eputs ("strtoul stub\n"); return 0; } unsigned long long strtoull (char const *p, char **endptr, int base) { *endptr = p; return abtoi (endptr, base); } time_t time (time_t *tloc) { return 0; } int vsnprintf (char *str, size_t size, char const *format, va_list ap) { return vsprintf (str, format, ap); } void * calloc (size_t nmemb, size_t size) { size_t count = nmemb * size; void *p = malloc (count); memset (p, 0, count); return p; } int vfprintf (FILE* f, char const* format, va_list ap) { int fd = (int)f; char const *p = format; while (*p) if (*p != '%') fputc (*p++, fd); else { p++; char c = *p; switch (c) { case '%': {fputc (*p, fd); break;} case 'c': {char c; c = va_arg (ap, char); fputc (c, fd); break;} case 'd': {int d; d = va_arg (ap, int); fputs (itoa (d), fd); break;} case 's': {char *s; s = va_arg (ap, char *); fputs (s, fd); break;} default: { eputs ("vfprintf: not supported: %"); eputc (c); eputs ("\n"); p++; } } p++; } va_end (ap); return 0; } int vprintf (char const* format, va_list ap) { return vfprintf (STDOUT, format, ap); } int vsscanf (char const *s, char const *template, va_list ap) { char const *p = s; char const *t = template; while (*t && *p) if (*t != '%') { t++; p++; } else { t++; char c = *t; switch (c) { case '%': {p++; break;} case 'c': {char *c = va_arg (ap, char*); *c = *p++; break;} case 'd': case 'i': case 'u': {int *d = va_arg (ap, int*); *d = abtoi (&p, 10); break;} default: { eputs ("vsscanf: not supported: %"); eputc (c); eputs ("\n"); t++; p++; } } t++; } va_end (ap); return 0; } int vsprintf (char *str, char const* format, va_list ap) { char const *p = format; while (*p) if (*p != '%') *str++ = *p++; else { p++; char c = *p; int left_p = 0; int width = -1; if (c == '-') { left_p = 1; c = *++p; } char pad = ' '; if (c == '0') { pad = c; c = *p++; } if (c >= '0' && c <= '9') { width = abtoi (&p, 10); c = *p; } switch (c) { case '%': {*str++ = *p; break;} case 'c': {char c; c = va_arg (ap, char); *str++ = c; break;} case 'd': case 'i': case 'u': { int d = va_arg (ap, int); char const *s = itoa (d); if (width >= 0) width = width - strlen (s); if (!left_p) while (width-- > 0) *str++ = pad; while (*s) *str++ = *s++; while (width-- > 0) *str++ = pad; break; } case 's': {char *s; s = va_arg (ap, char *); while (*s) *str++ = *s++; break;} default: { eputs ("vsprintf: not supported: %"); eputc (c); eputs ("\n"); p++; } } p++; } va_end (ap); *str = 0; return strlen (str); } int sprintf (char *str, char const* format, ...) { va_list ap; va_start (ap, format); int r = vsprintf (str, format, ap); va_end (ap); return r; } int printf (char const* format, ...) { va_list ap; va_start (ap, format); int r = vprintf (format, ap); va_end (ap); return r; }