From f8adc70c3f27250d5768ff922c0ac39f0e77c058 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 15 May 1996 15:49:26 +0000 Subject: [PATCH] Tue May 14 19:42:04 1996 Roland McGrath * sysdeps/generic/strrchr.c: Deansideclized. * elf/Makefile (ldd): Depend on Makefile. Find ld.so in $(slibdir) instead of $(libdir). * sysdeps/i386/strrchr.S: Use `testl $3, %esi' instead of `testb $3, %esi'; gas misassembles the latter into `testb $3, %dh'. * mach/Machrules (%.udeps rule): Do $(make-target-directory) first. Tue May 14 16:38:44 1996 David Mosberger-Tang * sunrpc/getrpcent.c (interpret): Declare args. Rewrite parsing using strpbrk. Tue May 14 20:18:38 1996 Ulrich Drepper * time/Makefile (routines): Add strptime. * time/time.h: Add prototype for strptime. * time/strptime.c: New file. Implementation according to XPG4. --- ChangeLog | 23 ++++ elf/Makefile | 4 +- mach/Machrules | 1 + sunrpc/getrpcent.c | 36 ++--- sysdeps/generic/strrchr.c | 12 +- sysdeps/i386/strrchr.S | 6 +- time/Makefile | 3 +- time/strptime.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++ time/time.h | 9 +- 9 files changed, 397 insertions(+), 41 deletions(-) create mode 100644 time/strptime.c diff --git a/ChangeLog b/ChangeLog index b48c6a5..03e3acc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +Tue May 14 19:42:04 1996 Roland McGrath + + * sysdeps/generic/strrchr.c: Deansideclized. + + * elf/Makefile (ldd): Depend on Makefile. + Find ld.so in $(slibdir) instead of $(libdir). + + * sysdeps/i386/strrchr.S: Use `testl $3, %esi' instead of `testb $3, + %esi'; gas misassembles the latter into `testb $3, %dh'. + + * mach/Machrules (%.udeps rule): Do $(make-target-directory) first. + +Tue May 14 16:38:44 1996 David Mosberger-Tang + + * sunrpc/getrpcent.c (interpret): Declare args. Rewrite parsing using + strpbrk. + +Tue May 14 20:18:38 1996 Ulrich Drepper + + * time/Makefile (routines): Add strptime. + * time/time.h: Add prototype for strptime. + * time/strptime.c: New file. Implementation according to XPG4. + Tue May 14 14:07:10 1996 Roland McGrath * libc-symbols.h (lint): Macro removed. The sunrpc code does some diff --git a/elf/Makefile b/elf/Makefile index 6569a7e..6124fa9 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -95,7 +95,7 @@ $(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so $(slibdir)/$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program) $(slibdir)/ld-linux.so.1: $(objpfx)ld-linux.so.1; $(do-install-program) -$(objpfx)ldd: ldd.sh.in - sed 's%@RTLD@%$(libdir)/$(rtld-installed-name)%g' < $< > $@.new +$(objpfx)ldd: ldd.sh.in Makefile + sed 's%@RTLD@%$(slibdir)/$(rtld-installed-name)%g' < $< > $@.new chmod 555 $@.new mv -f $@.new $@ diff --git a/mach/Machrules b/mach/Machrules index f7f6d2d..6f1c194 100644 --- a/mach/Machrules +++ b/mach/Machrules @@ -116,6 +116,7 @@ $(patsubst %,$(objpfx)%.ustamp,$(user-interfaces)): $(objpfx)%.ustamp: touch $@ -include $(patsubst %,$(objpfx)%.udeps,$(user-interfaces)) $(patsubst %,$(objpfx)%.udeps,$(user-interfaces)): $(objpfx)%.udeps: + $(make-target-directory) echo '#include <$*.defs>' | \ $(CC) $(CPPFLAGS) -M -x c - | \ sed -e 's,- *:,$@ $(@:.udeps=.ustamp) \ diff --git a/sunrpc/getrpcent.c b/sunrpc/getrpcent.c index 8ef6561..0fc7aff 100644 --- a/sunrpc/getrpcent.c +++ b/sunrpc/getrpcent.c @@ -163,13 +163,15 @@ getrpcent() return(NULL); if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) return (NULL); - if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) + if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) return (NULL); return interpret(d->line, strlen(d->line)); } static struct rpcent * interpret(val, len) + char * val; + size_t len; { register struct rpcdata *d = _rpcdata(); char *p; @@ -182,21 +184,13 @@ interpret(val, len) d->line[len] = '\n'; if (*p == '#') return (getrpcent()); - cp = index(p, '#'); + cp = strpbrk(p, "#\n"); if (cp == NULL) - { - cp = index(p, '\n'); - if (cp == NULL) - return (getrpcent()); - } + return (getrpcent()); *cp = '\0'; - cp = index(p, ' '); + cp = strpbrk(p, " \t"); if (cp == NULL) - { - cp = index(p, '\t'); - if (cp == NULL) - return (getrpcent()); - } + return (getrpcent()); *cp++ = '\0'; /* THIS STUFF IS INTERNET SPECIFIC */ d->rpc.r_name = d->line; @@ -204,15 +198,9 @@ interpret(val, len) cp++; d->rpc.r_number = atoi(cp); q = d->rpc.r_aliases = d->rpc_aliases; - cp = index(p, ' '); + cp = strpbrk(p, " \t"); if (cp != NULL) *cp++ = '\0'; - else - { - cp = index(p, '\t'); - if (cp != NULL) - *cp++ = '\0'; - } while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; @@ -220,15 +208,9 @@ interpret(val, len) } if (q < &(d->rpc_aliases[MAXALIASES - 1])) *q++ = cp; - cp = index(p, ' '); + cp = strpbrk(p, " \t"); if (cp != NULL) *cp++ = '\0'; - else - { - cp = index(p, '\t'); - if (cp != NULL) - *cp++ = '\0'; - } } *q = NULL; return (&d->rpc); diff --git a/sysdeps/generic/strrchr.c b/sysdeps/generic/strrchr.c index 29402f0..663b6aa 100644 --- a/sysdeps/generic/strrchr.c +++ b/sysdeps/generic/strrchr.c @@ -16,25 +16,23 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include - /* Find the last ocurrence of C in S. */ char * -DEFUN(strrchr, (s, c), CONST char *s AND int c) +strrchr (const char *s, int c) { - register CONST char *found, *p; + register const char *found, *p; c = (unsigned char) c; /* Since strchr is fast, we use it rather than the obvious loop. */ - + if (c == '\0') - return strchr(s, '\0'); + return strchr (s, '\0'); found = NULL; - while ((p = strchr(s, c)) != NULL) + while ((p = strchr (s, c)) != NULL) { found = p; s = p + 1; diff --git a/sysdeps/i386/strrchr.S b/sysdeps/i386/strrchr.S index 468a940..26d6a22 100644 --- a/sysdeps/i386/strrchr.S +++ b/sysdeps/i386/strrchr.S @@ -58,7 +58,7 @@ ENTRY (strrchr) implementation (this is because all processor inherant boundaries are multiples of 4. */ - testb $3, %esi /* correctly aligned ? */ + testl $3, %esi /* correctly aligned ? */ jz L19 /* yes => begin loop */ movb (%esi), %dl /* load byte in question (we need it twice) */ cmpb %dl, %cl /* compare byte */ @@ -68,7 +68,7 @@ L11: orb %dl, %dl /* is NUL? */ jz L2 /* yes => return NULL */ incl %esi /* increment pointer */ - testb $3, %esi /* correctly aligned ? */ + testl $3, %esi /* correctly aligned ? */ jz L19 /* yes => begin loop */ movb (%esi), %dl /* load byte in question (we need it twice) */ cmpb %dl, %cl /* compare byte */ @@ -78,7 +78,7 @@ L12: orb %dl, %dl /* is NUL? */ jz L2 /* yes => return NULL */ incl %esi /* increment pointer */ - testb $3, %esi /* correctly aligned ? */ + testl $3, %esi /* correctly aligned ? */ jz L19 /* yes => begin loop */ movb (%esi), %dl /* load byte in question (we need it twice) */ cmpb %dl, %cl /* compare byte */ diff --git a/time/Makefile b/time/Makefile index bb8bd20..ac422bf 100644 --- a/time/Makefile +++ b/time/Makefile @@ -29,7 +29,8 @@ routines := offtime asctime clock ctime difftime gmtime \ localtime mktime strftime time tzset tzfile \ gettimeofday settimeofday adjtime \ getitimer setitimer \ - stime dysize timegm ftime + stime dysize timegm ftime \ + strptime others := ap zdump zic tests := test_time clocktest diff --git a/time/strptime.c b/time/strptime.c new file mode 100644 index 0000000..cb3d126 --- /dev/null +++ b/time/strptime.c @@ -0,0 +1,344 @@ +/* strptime - Convert a string representation of time to a time value. +Copyright (C) 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ulrich Drepper , 1996. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include + +#include "../locale/localeinfo.h" + + +#define match_char(ch1, ch2) if (ch1 != ch2) return NULL +#define match_string(cs1, s2) \ + ({ size_t len = strlen (cs1); \ + int result = strncasecmp (cs1, s2, len) == 0; \ + if (result) s2 += len; \ + result; }) +/* We intentionally do not use isdigit() for testing because this will + lead to problems with the wide character version. */ +#define get_number(from, to) \ + do { \ + val = 0; \ + if (*rp < '0' || *rp > '9') \ + return NULL; \ + do { \ + val *= 10; \ + val += *rp++ - '0'; \ + } while (val * 10 <= to && *rp >= '0' && *rp <= '9'); \ + if (val < from || val > to) \ + return NULL; \ + } while (0) +#define get_alt_number(from, to) \ + do { \ + const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ + val = 0; \ + while (*alts != '\0') \ + { \ + size_t len = strlen (alts); \ + if (strncasecmp (alts, rp, len) == 0) \ + break; \ + alts = strchr (alts, '\0') + 1; \ + ++val; \ + } \ + if (*alts == '\0') \ + return NULL; \ + } while (0) +#define recursive(new_fmt) \ + do { \ + if (*new_fmt == '\0') \ + return NULL; \ + rp = strptime (rp, new_fmt, tm); \ + if (rp == NULL) \ + return NULL; \ + } while (0) + + +char * +strptime (const char *buf, const char *format, struct tm *tm) +{ + const char *rp; + const char *fmt; + int cnt; + size_t val; + int have_I, is_pm; + + rp = buf; + fmt = format; + have_I = is_pm = 0; + + while (*fmt != '\0') + { + /* A white space in the format string matches 0 more or white + space in the input string. */ + if (isspace (*fmt)) + { + while (isspace (*rp)) + ++rp; + ++fmt; + continue; + } + + /* Any character but `%' must be matched by the same character + in the iput string. */ + if (*fmt != '%') + { + match_char (*fmt++, *rp++); + continue; + } + + ++fmt; + switch (*fmt++) + { + case '%': + /* Match the `%' character itself. */ + match_char ('%', *rp++); + break; + case 'a': + case 'A': + /* Match day of week. */ + for (cnt = 0; cnt < 7; ++cnt) + { + if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) + break; + if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) + break; + } + if (cnt == 7) + /* Does not match a weekday name. */ + return NULL; + tm->tm_wday = cnt; + break; + case 'b': + case 'B': + case 'h': + /* Match month name. */ + for (cnt = 0; cnt < 12; ++cnt) + { + if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) + break; + if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) + break; + } + if (cnt == 12) + /* Does not match a month name. */ + return NULL; + tm->tm_mon = cnt; + break; + case 'c': + /* Match locale's date and time format. */ + recursive (_NL_CURRENT (LC_TIME, D_T_FMT)); + break; + case 'C': + /* Match century number. */ + get_number (0, 99); + /* We don't need the number. */ + break; + case 'd': + case 'e': + /* Match day of month. */ + get_number (1, 31); + tm->tm_mday = val; + break; + case 'D': + /* Match standard day format. */ + recursive ("%m/%d/%y"); + break; + case 'H': + /* Match hour in 24-hour clock. */ + get_number (0, 23); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock. */ + get_number (1, 12); + tm->tm_hour = val - 1; + have_I = 1; + break; + case 'j': + /* Match day number of year. */ + get_number (1, 366); + tm->tm_yday = val - 1; + break; + case 'm': + /* Match number of month. */ + get_number (1, 12); + tm->tm_mon = val - 1; + break; + case 'M': + /* Match minute. */ + get_number (0, 59); + tm->tm_min = val; + break; + case 'n': + case 't': + /* Match any white space. */ + while (isspace (*rp)) + ++rp; + break; + case 'p': + /* Match locale's equivalent of AM/PM. */ + if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) + break; + if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) + { + is_pm = 1; + break; + } + return NULL; + case 'r': + recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)); + break; + case 'R': + recursive ("%H:%M"); + break; + case 'S': + get_number (0, 61); + tm->tm_sec = val; + break; + case 'T': + recursive ("%H:%M:%S"); + break; + case 'U': + case 'V': + case 'W': + get_number (0, 53); + /* XXX This cannot determine any field in TM. */ + break; + case 'w': + /* Match number of weekday. */ + get_number (0, 6); + tm->tm_wday = val; + break; + case 'x': + recursive (_NL_CURRENT (LC_TIME, D_FMT)); + break; + case 'X': + recursive (_NL_CURRENT (LC_TIME, T_FMT)); + break; + case 'y': + /* Match year within century. */ + get_number (0, 99); + tm->tm_year = val; + break; + case 'Y': + /* Match year including century number. */ + get_number (0, INT_MAX); + tm->tm_year = val - (val >= 2000 ? 2000 : 1900); + break; + case 'Z': + /* XXX How to handle this? */ + break; + case 'E': + switch (*fmt++) + { + case 'c': + /* Match locale's alternate date and time format. */ + recursive (_NL_CURRENT (LC_TIME, ERA_D_T_FMT)); + break; + case 'C': + case 'y': + case 'Y': + /* Match name of base year in locale's alternate + representation. */ + /* XXX This is currently not implemented. It should + use the value _NL_CURRENT (LC_TIME, ERA) but POSIX + leaves this implementation defined and we haven't + figured out how to do it yet. */ + break; + case 'x': + recursive (_NL_CURRENT (LC_TIME, ERA_D_FMT)); + break; + case 'X': + recursive (_NL_CURRENT (LC_TIME, ERA_T_FMT)); + break; + default: + return NULL; + } + break; + case 'O': + switch (*fmt++) + { + case 'd': + case 'e': + /* Match day of month using alternate numeric symbols. */ + get_alt_number (1, 31); + tm->tm_mday = val; + break; + case 'H': + /* Match hour in 24-hour clock using alternate numeric + symbols. */ + get_alt_number (0, 23); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock using alternate numeric + symbols. */ + get_alt_number (1, 12); + tm->tm_hour = val - 1; + have_I = 1; + break; + case 'm': + /* Match month using alternate numeric symbols. */ + get_alt_number (1, 12); + tm->tm_mon = val - 1; + break; + case 'M': + /* Match minutes using alternate numeric symbols. */ + get_alt_number (0, 59); + tm->tm_min = val; + break; + case 'S': + /* Match seconds using alternate numeric symbols. */ + get_alt_number (0, 61); + tm->tm_sec = val; + break; + case 'U': + case 'V': + case 'W': + get_alt_number (0, 53); + /* XXX This cannot determine any field in TM. */ + break; + case 'w': + /* Match number of weekday using alternate numeric symbols. */ + get_alt_number (0, 6); + tm->tm_wday = val; + break; + case 'y': + /* Match year within century using alternate numeric symbols. */ + get_alt_number (0, 99); + break; + default: + return NULL; + } + break; + default: + return NULL; + } + } + + if (have_I && is_pm) + tm->tm_hour += 12; + + return (char *) rp; +} diff --git a/time/time.h b/time/time.h index fda7f20..12c3ce4 100644 --- a/time/time.h +++ b/time/time.h @@ -124,7 +124,14 @@ extern time_t __mktime_internal __P ((struct tm *__tp, Write no more than MAXSIZE characters and return the number of characters written, or 0 if it would exceed MAXSIZE. */ extern size_t strftime __P ((char *__s, size_t __maxsize, - __const char *__format, __const struct tm *__tp)); + __const char *__format, __const struct tm *__tp)); + +#ifdef __USE_MISC +/* Parse S according to FORMAT and store binary time information in TP. + The return value is a pointer to the first unparsed character in S. */ +extern char *strptime __P ((__const char *__s, __const char *__fmt, + struct tm *__tp)); +#endif /* Return the `struct tm' representation of *TIMER -- 2.7.4