9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit d8f11964ad3523f4510fc77a36befc6e4626bd81
parent 91007a9244e60b1c2690a60ac3d0b7eaecd94266
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Thu, 25 Oct 2018 15:17:44 +0100

[libc] Synchronize with scc libc

Diffstat:
Ainclude/bits/amd64/arch/time.h | 8++++++++
Ainclude/bits/arm64/arch/time.h | 8++++++++
Ainclude/locale.h | 39+++++++++++++++++++++++++++++++++++++++
Ainclude/time.h | 43+++++++++++++++++++++++++++++++++++++++++++
Msrc/libc/Makefile | 31+++++++++++++++++++++++++++++++
Asrc/libc/__abs.c | 4++++
Asrc/libc/__labs.c | 4++++
Asrc/libc/__llabs.c | 4++++
Asrc/libc/_daysyear.c | 30++++++++++++++++++++++++++++++
Asrc/libc/abs.c | 8++++++++
Asrc/libc/asctime.c | 12++++++++++++
Asrc/libc/atoi.c | 25+++++++++++++++++++++++++
Asrc/libc/atol.c | 26++++++++++++++++++++++++++
Asrc/libc/atoll.c | 26++++++++++++++++++++++++++
Asrc/libc/bsearch.c | 26++++++++++++++++++++++++++
Asrc/libc/ctime.c | 8++++++++
Asrc/libc/difftime.c | 8++++++++
Asrc/libc/fgetc.c | 8++++++++
Asrc/libc/fgets.c | 19+++++++++++++++++++
Asrc/libc/freopen.c | 14++++++++++++++
Asrc/libc/getc.c | 8++++++++
Asrc/libc/getchar.c | 8++++++++
Asrc/libc/gets.c | 17+++++++++++++++++
Asrc/libc/gmtime.c | 35+++++++++++++++++++++++++++++++++++
Asrc/libc/labs.c | 8++++++++
Asrc/libc/llabs.c | 8++++++++
Asrc/libc/localeconv.c | 29+++++++++++++++++++++++++++++
Asrc/libc/localtime.c | 21+++++++++++++++++++++
Asrc/libc/mktime.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/perror.c | 16++++++++++++++++
Asrc/libc/qsort.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/realloc.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/rewind.c | 10++++++++++
Asrc/libc/setlocale.c | 16++++++++++++++++
Asrc/libc/strftime.c | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libc/tmpnam.c | 31+++++++++++++++++++++++++++++++
Asrc/libc/tolower.c | 9+++++++++
37 files changed, 1061 insertions(+), 0 deletions(-)

diff --git a/include/bits/amd64/arch/time.h b/include/bits/amd64/arch/time.h @@ -0,0 +1,8 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#define _SIZET +#endif + +#define _MAXYEAR 9999 + +typedef long int time_t; diff --git a/include/bits/arm64/arch/time.h b/include/bits/arm64/arch/time.h @@ -0,0 +1,8 @@ +#ifndef _SIZET +typedef unsigned long size_t; +#define _SIZET +#endif + +#define _MAXYEAR 9999 + +typedef long int time_t; diff --git a/include/locale.h b/include/locale.h @@ -0,0 +1,39 @@ +#ifndef _LOCALE_H +#define _LOCALE_H + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MONETARY 3 +#define LC_NUMERIC 4 +#define LC_TIME 5 + +struct lconv { + char *decimal_point; + char *thousands_sep; + char *grouping; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char *currency_symbol; + char *int_curr_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_frac_digits; +}; + +extern char *setlocale(int category, const char *locale); +extern struct lconv *localeconv(void); + +#endif diff --git a/include/time.h b/include/time.h @@ -0,0 +1,43 @@ +#ifndef _TIME_H +#define _TIME_H + +#include <arch/time.h> + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define CLOCKS_PER_SEC 1000000 + +typedef long int clock_t; + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + + /* fields used internally */ + + char *tm_zone; + long tm_gmtoff; +}; + +extern clock_t clock(void); +extern double difftime(time_t time1, time_t time0); +extern time_t mktime(struct tm *timeptr); +extern time_t time(time_t *timer); +extern char *asctime(const struct tm *timeptr); +extern char *ctime(const time_t *timer); +extern struct tm *gmtime(const time_t *timer); +extern struct tm *localtime(const time_t *timer); +extern size_t strftime(char * restrict s, size_t maxsize, + const char * restrict format, + const struct tm * restrict timeptr); + +#endif diff --git a/src/libc/Makefile b/src/libc/Makefile @@ -82,6 +82,37 @@ COBJ = __assert.o \ vfprintf.o \ vsnprintf.o \ vsprintf.o \ + __abs.o\ + __labs.o\ + __llabs.o\ + _daysyear.o\ + abs.o\ + asctime.o\ + atoi.o\ + atol.o\ + atoll.o\ + bsearch.o\ + ctime.o\ + fgetc.o\ + fgets.o\ + freopen.o\ + getc.o\ + getchar.o\ + gets.o\ + gmtime.o\ + labs.o\ + llabs.o\ + localeconv.o\ + localtime.o\ + mktime.o\ + perror.o\ + qsort.o\ + realloc.o\ + rewind.o\ + setlocale.o\ + strftime.o\ + tmpnam.o\ + tolower.o\ OBJS = $(COBJ) $(SYSOBJ) TARGET = $(PROJECTDIR)/lib/libc.a diff --git a/src/libc/__abs.c b/src/libc/__abs.c @@ -0,0 +1,4 @@ +#define __USE_MACROS +#include <stdlib.h> + +int __abs; diff --git a/src/libc/__labs.c b/src/libc/__labs.c @@ -0,0 +1,4 @@ +#define __USE_MACROS +#include <stdlib.h> + +long __labs; diff --git a/src/libc/__llabs.c b/src/libc/__llabs.c @@ -0,0 +1,4 @@ +#define __USE_MACROS +#include <stdlib.h> + +long long __llabs; diff --git a/src/libc/_daysyear.c b/src/libc/_daysyear.c @@ -0,0 +1,30 @@ +#include <time.h> +#include "libc.h" + +int _daysmon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +int +_daysyear(int year) +{ + if (year%4 != 0) + return 365; + if (year%100 == 0 && year%400 != 0) + return 365; + return 366; +} + +/* + * Happy New Year!!!! + */ +int +_newyear(int year) +{ + int day; + + year += 1900 - 1; + day = 1 + year + year/4; + day -= year/100; + day += year/400; + + return day % 7; +} diff --git a/src/libc/abs.c b/src/libc/abs.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#undef abs + +int +abs(int n) +{ + return (n < 0) ? -n : n; +} diff --git a/src/libc/asctime.c b/src/libc/asctime.c @@ -0,0 +1,12 @@ +#include <time.h> +#undef asctime + +#include <stdio.h> // TODO: remove me! +char * +asctime(const struct tm *tm) +{ + static char buf[30]; + + strftime(buf, sizeof(buf), "%c\n", tm); + return buf; +} diff --git a/src/libc/atoi.c b/src/libc/atoi.c @@ -0,0 +1,25 @@ +#include <ctype.h> +#include <stdlib.h> +#undef atoi + +int +atoi(const char *s) +{ + int n, sign = -1; + + while (isspace(*s)) + ++s; + + switch (*s) { + case '-': + sign = 1; + case '+': + ++s; + } + + /* Compute n as a negative number to avoid overflow on INT_MIN */ + for (n = 0; isdigit(*s); ++s) + n = 10*n - (*s - '0'); + + return sign * n; +} diff --git a/src/libc/atol.c b/src/libc/atol.c @@ -0,0 +1,26 @@ +#include <ctype.h> +#include <stdlib.h> +#undef atol + +long +atol(const char *s) +{ + int sign = -1; + long n; + + while (isspace(*s)) + ++s; + + switch (*s) { + case '-': + sign = 1; + case '+': + ++s; + } + + /* Compute n as a negative number to avoid overflow on LONG_MIN */ + for (n = 0; isdigit(*s); ++s) + n = 10*n - (*s - '0'); + + return sign * n; +} diff --git a/src/libc/atoll.c b/src/libc/atoll.c @@ -0,0 +1,26 @@ +#include <ctype.h> +#include <stdlib.h> +#undef atoll + +long long +atoll(const char *s) +{ + int sign = -1; + long long n; + + while (isspace(*s)) + ++s; + + switch (*s) { + case '-': + sign = 1; + case '+': + ++s; + } + + /* Compute n as a negative number to avoid overflow on LLONG_MIN */ + for (n = 0; isdigit(*s); ++s) + n = 10*n - (*s - '0'); + + return sign * n; +} diff --git a/src/libc/bsearch.c b/src/libc/bsearch.c @@ -0,0 +1,26 @@ +#include <stdlib.h> + +void * +bsearch(const void *key, const void *ary, size_t n, size_t size, + int (*cmp)(const void *, const void *)) +{ + int t; + size_t mid, low, high; + char *cur, *base = ary; + + low = 0; + high = n - 1; + while (low <= high) { + mid = low + (high - low) / 2; + cur = base + mid*size; + + if ((t = (*cmp)(key, cur)) == 0) + return cur; + else if (t > 0) + low = mid + 1; + else + high = mid - 1; + } + + return NULL; +} diff --git a/src/libc/ctime.c b/src/libc/ctime.c @@ -0,0 +1,8 @@ +#include <time.h> +#undef ctime + +char * +ctime(const time_t *t) +{ + return asctime(localtime(t)); +} diff --git a/src/libc/difftime.c b/src/libc/difftime.c @@ -0,0 +1,8 @@ +#include <time.h> +#undef difftime + +double +difftime(time_t t1, time_t t2) +{ + return (double) (t1 - t2); +} diff --git a/src/libc/fgetc.c b/src/libc/fgetc.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef fgetc + +int +fgetc(FILE *fp) +{ + return getc(fp); +} diff --git a/src/libc/fgets.c b/src/libc/fgets.c @@ -0,0 +1,19 @@ +#include <stdio.h> +#undef fgets + +char * +fgets(char *s, int n, FILE *fp) +{ + int ch; + char *t = s; + + while (--n > 0 && (ch = getc(fp)) != EOF) { + if ((*t++ = ch) == '\n') + break; + } + if (ch == EOF && s == t) + return NULL; + *t = '\0'; + + return s; +} diff --git a/src/libc/freopen.c b/src/libc/freopen.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#include "syscall.h" +#include "libc.h" +#undef freopen + +FILE * +freopen(const char * restrict name, const char * restrict mode, + FILE * restrict fp) +{ + if (fclose(fp) == EOF) + return NULL; + return _fpopen(name, mode, fp); +} diff --git a/src/libc/getc.c b/src/libc/getc.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef getc + +int +getc(FILE *fp) +{ + return (fp->rp >= fp->wp) ? __getc(fp) : *fp->rp++; +} diff --git a/src/libc/getchar.c b/src/libc/getchar.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#undef getchar + +int +getchar(void) +{ + return getc(stdin); +} diff --git a/src/libc/gets.c b/src/libc/gets.c @@ -0,0 +1,17 @@ +#include <stdio.h> +#undef gets + +char * +gets(char *s) +{ + int ch; + char *t = s; + + while ((ch = getc(stdin)) != EOF && ch != '\n') + *t++ = ch; + if (ch == EOF && s == t) + return NULL; + *t = '\0'; + + return s; +} diff --git a/src/libc/gmtime.c b/src/libc/gmtime.c @@ -0,0 +1,35 @@ +#include <time.h> +#include "libc.h" +#undef gmtime + +struct tm * +gmtime(const time_t *t) +{ + static struct tm tm; + time_t sec, min, hour, year, day; + int i; + + tm.tm_sec = *t % SECDAY; + tm.tm_min = tm.tm_sec / 60; + tm.tm_sec %= 60; + tm.tm_hour = tm.tm_min / 60; + tm.tm_min %= 60; + day = *t / SECDAY; + + tm.tm_wday = (day + THU) % 7; /* 1/1/1970 was Thursday */ + + for (i = EPOCH; day >= _daysyear(i); ++i) + day -= _daysyear(i); + tm.tm_year = i - 1900; + tm.tm_yday = day; + + _daysmon[FEB] = FEBDAYS(tm.tm_year); + for (i = JAN; day > _daysmon[i]; i++) + day -= _daysmon[i]; + tm.tm_mon = i; + tm.tm_mday = day + 1; + + tm.tm_isdst = 0; + + return &tm; +} diff --git a/src/libc/labs.c b/src/libc/labs.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#undef labs + +long +labs(long n) +{ + return (n < 0) ? -n : n; +} diff --git a/src/libc/llabs.c b/src/libc/llabs.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#undef llabs + +long long +llabs(long long n) +{ + return (n < 0) ? -n : n; +} diff --git a/src/libc/localeconv.c b/src/libc/localeconv.c @@ -0,0 +1,29 @@ +#include <locale.h> +#include <limits.h> +#undef localeconv + +struct lconv * +localeconv(void) +{ + static struct lconv lc = { + .decimal_point = ".", + .thousands_sep = "", + .grouping = "", + .mon_decimal_point = "", + .mon_thousands_sep = "", + .mon_grouping = "", + .positive_sign = "", + .negative_sign = "", + .currency_symbol = "", + .int_curr_symbol = "", + .frac_digits = CHAR_MAX, + .p_cs_precedes = CHAR_MAX, + .n_cs_precedes = CHAR_MAX, + .p_sep_by_space = CHAR_MAX, + .p_sign_posn = CHAR_MAX, + .n_sep_by_space = CHAR_MAX, + .n_sign_posn = CHAR_MAX, + .int_frac_digits = CHAR_MAX, + }; + return &lc; +} diff --git a/src/libc/localtime.c b/src/libc/localtime.c @@ -0,0 +1,21 @@ +#include <time.h> +#include "libc.h" +#undef localtime + +struct tm * +localtime(const time_t *timep) +{ + struct tzone *tz; + struct tm *tm; + time_t t = *timep; + + t += tz->gmtoff * 60; + t += tz->isdst * 60; + tm = gmtime(&t); + tz = _tzone(tm); + tm->tm_zone = tz->name; + tm->tm_isdst = tz->isdst; + tm->tm_gmtoff = tz->gmtoff; + + return tm; +} diff --git a/src/libc/mktime.c b/src/libc/mktime.c @@ -0,0 +1,112 @@ +#include <limits.h> +#include <time.h> +#include "libc.h" +#undef mktime + +static int +norm(int *val, int *next, int qty) +{ + int v = *val, n = *next, d; + + if (v < 0) { + d = -v / qty + 1; + v += d * qty; + if (n > INT_MAX - d) + return 0; + n += d; + } + if (v >= qty) { + d = v / qty; + v -= d * qty; + if (n < INT_MIN + d) + return 0; + n -= d; + } + + *val = v; + *next = n; + return 1; +} + +static int +normalize(struct tm *tm) +{ + int mon, day, year; + struct tm aux = *tm; + + if (!norm(&tm->tm_sec, &tm->tm_min, 60) || + !norm(&tm->tm_min, &tm->tm_hour, 60) || + !norm(&tm->tm_hour, &tm->tm_mday, 24) || + !norm(&tm->tm_mon, &tm->tm_year, 12)) { + return 0; + } + + day = tm->tm_mday; + year = EPOCH + tm->tm_year; + _daysmon[FEB] = FEBDAYS(year); + + for (mon = tm->tm_mon; day < 1; --mon) { + day += _daysmon[mon]; + if (mon == JAN) { + if (year == EPOCH) + return -1; + year--; + _daysmon[FEB] = FEBDAYS(year); + mon = DEC+1; + } + } + + for (; day > _daysmon[mon]; ++mon) { + day -= _daysmon[mon]; + if (mon == DEC) { + if (year == _MAXYEAR) + return -1; + year++; + _daysmon[FEB] = FEBDAYS(year); + mon = JAN-1; + } + } + + tm->tm_mon = mon; + tm->tm_year = year - EPOCH; + tm->tm_mday = day; + tm->tm_wday = (_newyear(tm->tm_year) + tm->tm_yday) % 7; + + return 1; +} + +time_t +mktime(struct tm *tm) +{ + int i, year, dst; + time_t t; + struct tm *aux; + + if (!normalize(tm)) + return -1; + + t = 0; + year = tm->tm_year + 1900; + for (i = EPOCH; i < year; i++) + t += _daysyear(i) * SECDAY; + + for (i = 0; i < tm->tm_mon; i++) + t += _daysmon[i] * SECDAY; + + t += tm->tm_sec; + t += tm->tm_min * SECMIN; + t += tm->tm_hour * SECHOUR; + t += (tm->tm_mday-1) * SECDAY; + + aux = localtime(&t); + + dst = 0; + if (tm->tm_isdst == 0 && aux->tm_isdst == 1) + dst = -SECHOUR; + else if (tm->tm_isdst == 1 && aux->tm_isdst == 0) + dst = +SECHOUR; + + t += aux->tm_gmtoff + dst; + + return t; +} diff --git a/src/libc/perror.c b/src/libc/perror.c @@ -0,0 +1,16 @@ +#include <errno.h> +#include <stdio.h> +#include <string.h> +#undef perror + +void +perror(const char *msg) +{ + if (msg && *msg) { + fputs(msg, stderr); + putc(':', stderr); + putc(' ', stderr); + } + fputs(strerror(errno), stderr); + putc('\n', stderr); +} diff --git a/src/libc/qsort.c b/src/libc/qsort.c @@ -0,0 +1,68 @@ +#include <stdlib.h> +#include <string.h> +#undef qsort + +/* + * This implementation of qsort is based in the paper + * "Engineering a Sort Function", by Jon L.Bentley and M. Douglas McIlroy. + * A lot of different optimizations were removed to make the code simpler. + */ + +struct qsort { + size_t es; + int (*cmp)(const void *, const void *); +}; + +static void +swap(char *i, char *j, size_t n) +{ + do { + char c = *i; + *i++ = *j; + *j++ = c; + } while (--n > 0); +} + +static void +xqsort(char *a, size_t n, struct qsort *qs) +{ + size_t j, es = qs->es; + char *pi, *pj, *pn; + + if (n <= 1) + return; + + pi = a; + pn = pj = a + n*es; + + swap(a, a + n/2 * es, es); + for (;;) { + do { + pi += es; + } while (pi < pn && qs->cmp(pi, a) < 0); + + do { + pj -= es; + } while (pj > a && qs->cmp(pj, a) > 0); + + if (pj < pi) + break; + swap(pi, pj, es); + } + swap(a, pj, es); + + j = (pj - a) / es; + xqsort(a, j, qs); + xqsort(a + (j+1)*es, n-j-1, qs); +} + +void +qsort(void *base, size_t nmemb, size_t size, + int (*f)(const void *, const void *)) +{ + struct qsort qs; + + qs.cmp = f; + qs.es = size; + xqsort(base, nmemb, &qs); +} diff --git a/src/libc/realloc.c b/src/libc/realloc.c @@ -0,0 +1,68 @@ +#include <stdlib.h> +#include <string.h> + +#include "malloc.h" +#undef realloc + +void * +realloc(void *ptr, size_t nbytes) +{ + Header *oh, *prev, *next, *new; + size_t nunits, avail, onbytes, n; + + if (!nbytes) + return NULL; + + if (!ptr) + return malloc(nbytes); + + nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; + oh = (Header*)ptr - 1; + + if (oh->h.size == nunits) + return ptr; + + new = oh + nunits; + + if (nunits < oh->h.size - 1) { + new->h.size = oh->h.size - nunits; + oh->h.size = nunits; + free(new + 1); + return oh; + } + + prev = _prevchunk(oh); + + if (oh + oh->h.size == prev->h.next) { + /* + * if there is free space adjacent + * to the current memory + */ + next = prev->h.next; + avail = oh->h.size + next->h.size; + + if (avail == nunits) { + oh->h.size = nunits; + prev->h.next = next->h.next; + return oh; + } + + if (avail > nunits) { + oh->h.size = nunits; + prev->h.next = new; + new->h.next = next; + new->h.size = avail - nunits; + return oh; + } + } + + onbytes = (oh->h.size - 1) * sizeof(Header); + if ((new = malloc(nbytes)) == NULL) + return NULL; + + n = (onbytes > nbytes) ? nbytes : onbytes; + memcpy(new, ptr, n); + free(ptr); + + return new; +} diff --git a/src/libc/rewind.c b/src/libc/rewind.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#undef rewind + +void +rewind(FILE *fp) +{ + fp->flags &= ~_IOERR; + fseek(fp, 0, SEEK_SET); + clearerr(fp); +} diff --git a/src/libc/setlocale.c b/src/libc/setlocale.c @@ -0,0 +1,16 @@ +#include <locale.h> +#include <stddef.h> +#undef setlocale + +char * +setlocale(int category, const char *locale) +{ + if (category > LC_TIME || category < LC_ALL) + return NULL; + if (!locale || + locale[0] == '\0' || + locale[0] == 'C' && locale[1] == '\0') { + return "C"; + } + return NULL; +} diff --git a/src/libc/strftime.c b/src/libc/strftime.c @@ -0,0 +1,246 @@ +#include <time.h> +#include <string.h> +#include "libc.h" +#undef strftime + +static char *days[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", +}; + +static char *months[] = { + "January", "February", "March", "April", + "May", "June", "July", "August", + "September", "October", "November", "December" +}; + +static char *am_pm[] = {"AM", "PM"}; + +static size_t +sval(char *s, size_t siz, char **strs, int abrev, int idx, int max) +{ + char *str; + size_t len; + + if (idx < 0 && idx >= max) + goto wrong; + + str = strs[idx]; + len = (!abrev) ? strlen(str) : 3; + if (len > siz) + goto wrong; + + memcpy(s, str, len); + return len; + +wrong: + *s = '?'; + return 1; +} + +static size_t +dval(char *s, size_t siz, int prec, int fill, int val) +{ + char *t; + int n; + static char digits[] = "0123456789"; + + if (prec > siz || val < 0) { + *s = '?'; + return 1; + } + + n = prec; + do { + s[--n] = digits[val % 10]; + val /= 10; + } while (n > 0 && val > 0); + + while (n > 0) + s[--n] = fill; + + return prec; +} + +static size_t +timezone(char *s, size_t prec, const struct tm * restrict tm) +{ + long off = tm->tm_gmtoff; + + if (prec < 5) { + *s = '?'; + return 1; + } + + if (off >= 0) { + *s++ = '+'; + } else { + *s++ = '-'; + off = -off; + } + + dval(s, 2, 2, '0', off / 3600); + dval(s, 2, 2, '0', (off % 3600) / 60); + + return 5; +} + +size_t +strftime(char * restrict s, size_t siz, + const char * restrict fmt, + const struct tm * restrict tm) +{ + int ch, abrev, val, fill, width; + size_t n, inc; + char *tfmt; + + for (n = siz-1; (ch = *fmt++) && n > 0; s += inc, n -= inc) { + if (ch != '%') { + *s = ch; + inc = 1; + continue; + } + + abrev = 0; + fill = '0'; + width = 2; + + switch (*fmt++) { + case 'Z': + if (!tm->tm_zone) + break; + inc = sval(s, n, &tm->tm_zone, 0, 0, 1); + break; + case 'a': + abrev = 1; + case 'A': + inc = sval(s, n, days, abrev, tm->tm_wday, 7); + break; + case 'h': + case 'b': + abrev = 1; + case 'B': + inc = sval(s, n, months, abrev, tm->tm_mon, 12); + break; + case 'p': + inc = sval(s, n, am_pm, 0, tm->tm_hour > 12, 2); + break; + case 'c': + tfmt = "%a %b %e %T %Y"; + goto recursive; + case 'D': + tfmt = "%m/%d/%y"; + goto recursive; + case 'F': + tfmt = "%Y-%m-%d"; + goto recursive; + case 'R': + tfmt = "%H:%M"; + goto recursive; + case 'X': + case 'T': + tfmt = "%H:%M:%S"; + goto recursive; + case 'r': + tfmt = "%I:%M:%S %p"; + goto recursive; + case 'x': + tfmt = "%m/%d/%y"; + goto recursive; + recursive: + inc = strftime(s, n+1, tfmt, tm) - 1; + break; + case 'n': + val = '\n'; + goto character; + case 't': + val = '\t'; + goto character; + case '%': + val = '%'; + character: + *s = val; + inc = 1; + break; + case 'e': + fill = ' '; + val = tm->tm_mday; + goto number; + case 'd': + val = tm->tm_mday; + goto number; + case 'V': + case 'g': + case 'G': + /* TODO */ + break; + case 'C': + val = tm->tm_year / 100; + goto number; + case 'H': + val = tm->tm_hour; + goto number; + case 'I': + val = tm->tm_hour; + if (val == 0) + val = 12; + if (val > 12) + val -= 12; + goto number; + case 'j': + width = 3; + val = tm->tm_yday+1; + goto number; + case 'm': + val = tm->tm_mon+1; + goto number; + case 'M': + val = tm->tm_min; + goto number; + case 'S': + val = tm->tm_sec; + goto number; + case 'u': + width = 1; + val = tm->tm_wday+1; + goto number; + case 'U': + val = tm->tm_yday / 7; + if (_newyear(tm->tm_year) == SAT) + val++; + goto number; + case 'W': + val = tm->tm_yday / 7; + if (_newyear(tm->tm_year) == MON) + val++; + goto number; + case 'w': + width = 1; + val = tm->tm_wday; + goto number; + case 'y': + val = tm->tm_year%100; + goto number; + case 'Y': + width = 4; + val = 1900 + tm->tm_year; + number: + inc = dval(s, n, width, fill, val); + break; + case 'z': + inc = timezone(s, n, tm); + break; + case 'E': + case 'O': + if (*fmt != '\0') + fmt += 2;; + case '\0': + inc = 0; + --fmt; + break; + } + } + *s = '\0'; + + return siz - n; +} diff --git a/src/libc/tmpnam.c b/src/libc/tmpnam.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <string.h> +#include "syscall.h" +#undef tmpnam + +char * +tmpnam(char *s) +{ + static char *tmpl, buf[L_tmpnam]; + char *p; + + if (*buf == '\0') { + for (tmpl = buf, p = _TMPNAME; *tmpl++ = *p++; ) + ; + for (p = tmpl; p < &buf[L_tmpnam-1]; ++p) + *p = '0'; + *p = '\0'; + } + for (;;) { + for (p = tmpl; *p && *p != '9'; ++p) + ; + if (*p == '\0') + return NULL; + ++*p; + if (_access(buf, 0) != 0) + break; + } + if (s) + strcpy(s, buf); + return buf; +} diff --git a/src/libc/tolower.c b/src/libc/tolower.c @@ -0,0 +1,9 @@ +#define __USE_MACROS +#include <ctype.h> +#undef tolower + +int +tolower(int c) +{ + return (isupper(c)) ? c | 0x20 : c; +}