diff options
| author | Jakob Kaivo <jkk@ung.org> | 2019-01-26 22:41:05 -0500 |
|---|---|---|
| committer | Jakob Kaivo <jkk@ung.org> | 2019-01-26 22:41:05 -0500 |
| commit | 8c6d4505329f94446084ca93eae10cd796d79a8d (patch) | |
| tree | c00c6a990c81bd771ebcac72b38fd3ce2382c42e /nonstd/static | |
new framework for building sources after gitlab migration
Diffstat (limited to 'nonstd/static')
| -rw-r--r-- | nonstd/static/fopen.h | 12 | ||||
| -rw-r--r-- | nonstd/static/locale.h | 75 | ||||
| -rw-r--r-- | nonstd/static/printf.h | 318 | ||||
| -rw-r--r-- | nonstd/static/scanf.h | 7 | ||||
| -rw-r--r-- | nonstd/static/thread.h | 5 | ||||
| -rw-r--r-- | nonstd/static/wctrans.h | 5 | ||||
| -rw-r--r-- | nonstd/static/wctype.h | 15 |
7 files changed, 437 insertions, 0 deletions
diff --git a/nonstd/static/fopen.h b/nonstd/static/fopen.h new file mode 100644 index 00000000..64d30f1e --- /dev/null +++ b/nonstd/static/fopen.h @@ -0,0 +1,12 @@ +#include "nonstd/FILE.h" + +static FILE *__common_fopen(struct __fopen_options *opt) +{ + FILE *f = NULL; + if (__libc.stdio.nopen < FOPEN_MAX) { + f = __libc.stdio.files + __libc.stdio.nopen; + __libc.stdio.nopen++; + } + f->fd = opt->fd; + return f; +} diff --git a/nonstd/static/locale.h b/nonstd/static/locale.h new file mode 100644 index 00000000..e96b0376 --- /dev/null +++ b/nonstd/static/locale.h @@ -0,0 +1,75 @@ +#include <limits.h> +#include "nonstd/types.h" + +#ifndef LC_GLOBAL_LOCALE +typedef void * locale_t; +#define LC_GLOBAL_LOCALE ((locale_t)(-1)) +#endif + +static unsigned char *__getmap(int map) +{ + static unsigned char c_attr[UCHAR_MAX + 1] = {0}; + static unsigned char c_lower[UCHAR_MAX + 1] = {0}; + static unsigned char c_upper[UCHAR_MAX + 1] = {0}; + struct __locale_t c; + struct __locale_t *locale = __libc.per_thread()->locale; + + if (!locale || locale == LC_GLOBAL_LOCALE || !locale->ctype) { + locale = __libc.locale.global; + } + + if (!locale || !locale->ctype) { + unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; + unsigned char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + /* $@` are in ASCII but not 9899 */ + unsigned char punct[] = "!\"#%&'()*+,-./:;<=>?[\\]^_{|}~$@`"; + unsigned char space[] = " \f\n\r\t\v"; + unsigned char xdigit[] = "0123456789abcdefABCDEF"; + + locale = &c; + c.ctattr = c_attr; + c.ctolower = c_lower; + c.ctoupper = c_upper; + + if (c_attr['a'] == 0) { + unsigned int i; + for (i = 0; i <= UCHAR_MAX; i++) { + c_attr[i] = 0; + c_lower[i] = i; + c_upper[i] = i; + } + + for (i = 0; i < sizeof(lower); i++) { + c_attr[lower[i]] = __libc.ctype.lower; + c_upper[lower[i]] = upper[i]; + } + + for (i = 0; i < sizeof(upper); i++) { + c_attr[upper[i]] = __libc.ctype.upper; + c_lower[upper[i]] = lower[i]; + } + + for (i = 0; i < sizeof(xdigit); i++) { + c_attr[xdigit[i]] |= __libc.ctype.xdigit; + } + + for (i = 0; i < sizeof(punct); i++) { + c_attr[punct[i]] = __libc.ctype.punct; + } + + for (i = 0; i < sizeof(space); i++) { + c_attr[space[i]] = __libc.ctype.space; + } + + c_attr[0] = 0; + } + } + + if (map == __libc.ctype.ctolower) { + return locale->ctolower; + } else if (map == __libc.ctype.ctoupper) { + return locale->ctoupper; + } + + return locale->ctattr; +} diff --git a/nonstd/static/printf.h b/nonstd/static/printf.h new file mode 100644 index 00000000..9ad3a76d --- /dev/null +++ b/nonstd/static/printf.h @@ -0,0 +1,318 @@ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stddef.h> +#include "nonstd/types.h" + +#include <unistd.h> + +#define NUMBUFLEN 64 + +#define LEFT (1 << 0) +#define SIGN (1 << 1) +#define SPACE (1 << 2) +#define ALT (1 << 3) +#define ZERO (1 << 4) +#define UPPER (1 << 5) +#define UNSIGNED (1 << 6) + +/* TODO: remove this */ +uintmax_t strtoumax(const char *s, char **n, int base) +{ + (void)base; + *n = (char*)s; + return 0; +} + +static int __append(char *s, char *argstring, int nout, size_t n) +{ + s += nout; + while (*argstring) { + if (nout < (int)n) { + *s++ = *argstring; + } + nout++; + argstring++; + } + return nout; +} + +static void __itos(char *s, intmax_t n, int flags, int precision, int base) +{ + char digits[] = "0123456789abcdef"; + char sign = n < 0 ? '-' : '+'; + char buf[NUMBUFLEN]; + char *out = buf + NUMBUFLEN; + if (flags & UPPER && base > 10) { + size_t i; + for (i = 0; i < sizeof(digits); i++) { + digits[i] = (char)toupper(digits[i]); + } + } + *out = '\0'; + out--; + while (n > 0) { + precision--; + *out = digits[n % base]; + n /= base; + out--; + } + if (flags & SIGN || sign == '-') { + *out = sign; + out--; + } + out++; + while ((*s++ = *out++) != 0) { + continue; + } +} + +static int __common_printf(struct priscn_options *opt, + const char * restrict format, va_list arg) +{ + char buf[BUFSIZ]; + int nout = 0; + int fd = -1; + FILE *f = NULL; + + intmax_t argint = 0; + void *argptr = NULL; + char numbuf[NUMBUFLEN]; + + size_t i; + size_t n = 0; + char *s = NULL; + + if (opt->stream) { + /* file based */ + f = opt->stream; + s = buf; + n = BUFSIZ; + flockfile(f); + } else if (opt->string) { + /* memory buffer */ + s = opt->string; + n = opt->maxlen; + } else { + /* file descriptor */ + s = buf; + n = BUFSIZ; + fd = opt->fd; + } + + for (i = 0; format[i] != 0; i++) { + if (format[i] != '%') { + if (nout < (int)n) { + s[nout] = format[i]; + } + nout++; + continue; + } + + /* + // zero of more flags "-+ #0" + // optional width "*" or decimal integer + // optional precision ".*" or ".[decimal]" + // optional length modifier "hh", "h", "l", "ll", "j", + // "z", "t", "L" + // conversion specifier "diouxXfFeEgGaAcspn%" + */ + int flags = 0; + /* uintmax_t width = 0; */ + int step = 0; + int precision = 0; + int base = 10; + enum { def, hh, h, l, ll, j, z, t, L } length = def; + + while (step == 0) { + i++; + switch (format[i]) { + case '-': flags |= LEFT; break; + case '+': flags |= SIGN; break; + case ' ': flags |= SPACE; break; + case '#': flags |= ALT; break; + case '0': flags |= ZERO; break; + default: step = 1; break; + } + } + + if (format[i] == '*') { + i++; + } else if (isdigit(format[i])) { + /* + char *end; + width = strtoumax(format + i, &end, 10); + i = end - format; + */ + } + + if (format[i] == '.') { + i++; + if (format[i] == '*') { + i++; + } else if (isdigit(format[i])) { + char *end; + precision = (int)strtoumax(format + i, &end, 10); + i = end - format; + } else { + /* invalid precision */ + nout = -nout; + goto end; + } + } + + if (format[i] == 'h') { + i++; + if (format[i] == 'h') { + i++; + length = hh; + } else { + length = h; + } + } else if (format[i] == 'l') { + i++; + if (format[i] == 'l') { + i++; + length = ll; + } else { + length = l; + } + } else if (format[i] == 'j') { + i++; + length = j; + } else if (format[i] == 'z') { + i++; + length = z; + } else if (format[i] == 't') { + i++; + length = t; + } else if (format[i] == 'L') { + i++; + length = L; + } + + if (isupper(format[i])) { + flags |= UPPER; + } + + switch (format[i]) { + case 'o': /* unsigned int */ + case 'u': + case 'x': + case 'X': + flags |= UNSIGNED; + + case 'd': /* int */ + case 'i': + switch (length) { + case hh: argint = (signed char)va_arg(arg, int); break; + case h: argint = (short int)va_arg(arg, int); break; + case l: argint = va_arg(arg, long int); break; + case ll: argint = va_arg(arg, long long int); break; + case j: argint = va_arg(arg, intmax_t); break; + case z: argint = va_arg(arg, size_t); break; + case t: argint = va_arg(arg, ptrdiff_t); break; + case L: nout = -nout; goto end; + default: argint = va_arg(arg, int); break; + } + if (format[i] == 'o') { + base = 8; + } else if (format[i] == 'x') { + base = 16; + } else if (format[i] == 'X') { + base = 16; + flags |= UPPER; + } else { + base = 10; + } + __itos(numbuf, (long int)argint, flags, precision, base); + nout = __append(s, numbuf, nout, n); + break; + + + case 'f': /* double [-]ddd.ddd */ + case 'F': + break; + + case 'e': /* double [-]d.ddde+/-dd */ + case 'E': + break; + + case 'g': /* double f or e see docs */ + case 'G': + break; + + case 'a': /* double as hex */ + case 'A': + break; + + case 'c': /* char */ + if (length == def) { + char c = va_arg(arg, int); + if (nout < (int)n) { + s[nout] = c; + } + nout++; + } else if (length == l) { + /* wint_t wc = va_arg(arg, wint_t); */ + /* char mb[MB_CUR_MAX + 1] = "WC"; */ + /* wctomb(mb, wc); */ + /* nout = __append(s, mb, nout, n); */ + } else { + nout = -nout; + goto end; + } + break; + + case 's': /* string */ + if (length == def) { + char *string = va_arg(arg, char *); + nout = __append(s, string, nout, n); + } else if (length == l) { + /*wchar_t *ws = va_arg(arg, wchar_t *); */ + /*char *mbs = malloc(wcslen(ws) * MB_CUR_MAX + 1); */ + /*wcstombs(mbs, ws, wcslen(ws) * MB_CUR_MAX + 1); */ + /*nout = __append(s, mbs, nout, n); */ + /*free(mbs); */ + nout = __append(s, "WIDE STRING", nout, n); + } else { + nout = -nout; + goto end; + } + + break; + + case 'p': /* pointer */ + argptr = va_arg(arg, void *); + nout = __append(s, "0x", nout, n); + __itos(numbuf, (intptr_t)argptr, ZERO, sizeof(argptr) * 2, 16); + nout = __append(s, numbuf, nout, n); + break; + + case 'n': /* write-back */ + break; + + case '%': /* literal '%' */ + if (nout < (int)n) { + s[nout] = '%'; + } + nout++; + break; + + default: /* undefined */ + return -nout; + } + } + + end: + if (f) { + fwrite(buf, 1, nout % BUFSIZ, f); + funlockfile(f); + } else if (fd != -1) { + write(fd, buf, nout % BUFSIZ); + } + + return nout; +} diff --git a/nonstd/static/scanf.h b/nonstd/static/scanf.h new file mode 100644 index 00000000..89622951 --- /dev/null +++ b/nonstd/static/scanf.h @@ -0,0 +1,7 @@ +#include "nonstd/types.h" + +static int __common_scanf(struct priscn_options *opt, const char *format, va_list arg) +{ + (void)opt; (void)format; (void)arg; + return 0; +} diff --git a/nonstd/static/thread.h b/nonstd/static/thread.h new file mode 100644 index 00000000..00b40861 --- /dev/null +++ b/nonstd/static/thread.h @@ -0,0 +1,5 @@ +static struct per_thread *per_thread(void) +{ + static struct per_thread pt = {0}; + return &pt; +} diff --git a/nonstd/static/wctrans.h b/nonstd/static/wctrans.h new file mode 100644 index 00000000..5dcb7608 --- /dev/null +++ b/nonstd/static/wctrans.h @@ -0,0 +1,5 @@ +static const char *__wctrans[] = { + NULL, /* 0 is an invalid wctrans_t */ + "tolower", + "toupper", +}; diff --git a/nonstd/static/wctype.h b/nonstd/static/wctype.h new file mode 100644 index 00000000..e0615096 --- /dev/null +++ b/nonstd/static/wctype.h @@ -0,0 +1,15 @@ +static const char *__wctype[] = { + 0, /* 0 is an invalid wctype_t */ + "alnum", + "alpha", + "blank", + "cntrl", + "digit", + "graph", + "lower", + "print", + "punct", + "space", + "upper", + "xdigit", +}; |
