Tue May 14 19:42:04 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>

* 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 <davidm@AZStarNet.com>

	* sunrpc/getrpcent.c (interpret): Declare args.  Rewrite parsing using
	strpbrk.

Tue May 14 20:18:38 1996  Ulrich Drepper  <drepper@cygnus.com>

	* time/Makefile (routines): Add strptime.
	* time/time.h: Add prototype for strptime.
	* time/strptime.c: New file.  Implementation according to XPG4.
This commit is contained in:
Roland McGrath 1996-05-15 15:49:26 +00:00
parent 64166d9834
commit f8adc70c3f
9 changed files with 397 additions and 41 deletions

View File

@ -1,3 +1,26 @@
Tue May 14 19:42:04 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* 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 <davidm@AZStarNet.com>
* sunrpc/getrpcent.c (interpret): Declare args. Rewrite parsing using
strpbrk.
Tue May 14 20:18:38 1996 Ulrich Drepper <drepper@cygnus.com>
* 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 <roland@delasyd.gnu.ai.mit.edu> Tue May 14 14:07:10 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* libc-symbols.h (lint): Macro removed. The sunrpc code does some * libc-symbols.h (lint): Macro removed. The sunrpc code does some

View File

@ -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)/$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program)
$(slibdir)/ld-linux.so.1: $(objpfx)ld-linux.so.1; $(do-install-program) $(slibdir)/ld-linux.so.1: $(objpfx)ld-linux.so.1; $(do-install-program)
$(objpfx)ldd: ldd.sh.in $(objpfx)ldd: ldd.sh.in Makefile
sed 's%@RTLD@%$(libdir)/$(rtld-installed-name)%g' < $< > $@.new sed 's%@RTLD@%$(slibdir)/$(rtld-installed-name)%g' < $< > $@.new
chmod 555 $@.new chmod 555 $@.new
mv -f $@.new $@ mv -f $@.new $@

View File

@ -116,6 +116,7 @@ $(patsubst %,$(objpfx)%.ustamp,$(user-interfaces)): $(objpfx)%.ustamp:
touch $@ touch $@
-include $(patsubst %,$(objpfx)%.udeps,$(user-interfaces)) -include $(patsubst %,$(objpfx)%.udeps,$(user-interfaces))
$(patsubst %,$(objpfx)%.udeps,$(user-interfaces)): $(objpfx)%.udeps: $(patsubst %,$(objpfx)%.udeps,$(user-interfaces)): $(objpfx)%.udeps:
$(make-target-directory)
echo '#include <$*.defs>' | \ echo '#include <$*.defs>' | \
$(CC) $(CPPFLAGS) -M -x c - | \ $(CC) $(CPPFLAGS) -M -x c - | \
sed -e 's,- *:,$@ $(@:.udeps=.ustamp) \ sed -e 's,- *:,$@ $(@:.udeps=.ustamp) \

View File

@ -163,13 +163,15 @@ getrpcent()
return(NULL); return(NULL);
if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
return (NULL); return (NULL);
if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
return (NULL); return (NULL);
return interpret(d->line, strlen(d->line)); return interpret(d->line, strlen(d->line));
} }
static struct rpcent * static struct rpcent *
interpret(val, len) interpret(val, len)
char * val;
size_t len;
{ {
register struct rpcdata *d = _rpcdata(); register struct rpcdata *d = _rpcdata();
char *p; char *p;
@ -182,21 +184,13 @@ interpret(val, len)
d->line[len] = '\n'; d->line[len] = '\n';
if (*p == '#') if (*p == '#')
return (getrpcent()); return (getrpcent());
cp = index(p, '#'); cp = strpbrk(p, "#\n");
if (cp == NULL) if (cp == NULL)
{ return (getrpcent());
cp = index(p, '\n');
if (cp == NULL)
return (getrpcent());
}
*cp = '\0'; *cp = '\0';
cp = index(p, ' '); cp = strpbrk(p, " \t");
if (cp == NULL) if (cp == NULL)
{ return (getrpcent());
cp = index(p, '\t');
if (cp == NULL)
return (getrpcent());
}
*cp++ = '\0'; *cp++ = '\0';
/* THIS STUFF IS INTERNET SPECIFIC */ /* THIS STUFF IS INTERNET SPECIFIC */
d->rpc.r_name = d->line; d->rpc.r_name = d->line;
@ -204,15 +198,9 @@ interpret(val, len)
cp++; cp++;
d->rpc.r_number = atoi(cp); d->rpc.r_number = atoi(cp);
q = d->rpc.r_aliases = d->rpc_aliases; q = d->rpc.r_aliases = d->rpc_aliases;
cp = index(p, ' '); cp = strpbrk(p, " \t");
if (cp != NULL) if (cp != NULL)
*cp++ = '\0'; *cp++ = '\0';
else
{
cp = index(p, '\t');
if (cp != NULL)
*cp++ = '\0';
}
while (cp && *cp) { while (cp && *cp) {
if (*cp == ' ' || *cp == '\t') { if (*cp == ' ' || *cp == '\t') {
cp++; cp++;
@ -220,15 +208,9 @@ interpret(val, len)
} }
if (q < &(d->rpc_aliases[MAXALIASES - 1])) if (q < &(d->rpc_aliases[MAXALIASES - 1]))
*q++ = cp; *q++ = cp;
cp = index(p, ' '); cp = strpbrk(p, " \t");
if (cp != NULL) if (cp != NULL)
*cp++ = '\0'; *cp++ = '\0';
else
{
cp = index(p, '\t');
if (cp != NULL)
*cp++ = '\0';
}
} }
*q = NULL; *q = NULL;
return (&d->rpc); return (&d->rpc);

View File

@ -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, not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */ Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <string.h> #include <string.h>
/* Find the last ocurrence of C in S. */ /* Find the last ocurrence of C in S. */
char * 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; c = (unsigned char) c;
/* Since strchr is fast, we use it rather than the obvious loop. */ /* Since strchr is fast, we use it rather than the obvious loop. */
if (c == '\0') if (c == '\0')
return strchr(s, '\0'); return strchr (s, '\0');
found = NULL; found = NULL;
while ((p = strchr(s, c)) != NULL) while ((p = strchr (s, c)) != NULL)
{ {
found = p; found = p;
s = p + 1; s = p + 1;

View File

@ -58,7 +58,7 @@ ENTRY (strrchr)
implementation (this is because all processor inherant implementation (this is because all processor inherant
boundaries are multiples of 4. */ boundaries are multiples of 4. */
testb $3, %esi /* correctly aligned ? */ testl $3, %esi /* correctly aligned ? */
jz L19 /* yes => begin loop */ jz L19 /* yes => begin loop */
movb (%esi), %dl /* load byte in question (we need it twice) */ movb (%esi), %dl /* load byte in question (we need it twice) */
cmpb %dl, %cl /* compare byte */ cmpb %dl, %cl /* compare byte */
@ -68,7 +68,7 @@ L11: orb %dl, %dl /* is NUL? */
jz L2 /* yes => return NULL */ jz L2 /* yes => return NULL */
incl %esi /* increment pointer */ incl %esi /* increment pointer */
testb $3, %esi /* correctly aligned ? */ testl $3, %esi /* correctly aligned ? */
jz L19 /* yes => begin loop */ jz L19 /* yes => begin loop */
movb (%esi), %dl /* load byte in question (we need it twice) */ movb (%esi), %dl /* load byte in question (we need it twice) */
cmpb %dl, %cl /* compare byte */ cmpb %dl, %cl /* compare byte */
@ -78,7 +78,7 @@ L12: orb %dl, %dl /* is NUL? */
jz L2 /* yes => return NULL */ jz L2 /* yes => return NULL */
incl %esi /* increment pointer */ incl %esi /* increment pointer */
testb $3, %esi /* correctly aligned ? */ testl $3, %esi /* correctly aligned ? */
jz L19 /* yes => begin loop */ jz L19 /* yes => begin loop */
movb (%esi), %dl /* load byte in question (we need it twice) */ movb (%esi), %dl /* load byte in question (we need it twice) */
cmpb %dl, %cl /* compare byte */ cmpb %dl, %cl /* compare byte */

View File

@ -29,7 +29,8 @@ routines := offtime asctime clock ctime difftime gmtime \
localtime mktime strftime time tzset tzfile \ localtime mktime strftime time tzset tzfile \
gettimeofday settimeofday adjtime \ gettimeofday settimeofday adjtime \
getitimer setitimer \ getitimer setitimer \
stime dysize timegm ftime stime dysize timegm ftime \
strptime
others := ap zdump zic others := ap zdump zic
tests := test_time clocktest tests := test_time clocktest

344
time/strptime.c Normal file
View File

@ -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 <drepper@cygnus.com>, 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 <ctype.h>
#include <langinfo.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#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;
}

View File

@ -124,7 +124,14 @@ extern time_t __mktime_internal __P ((struct tm *__tp,
Write no more than MAXSIZE characters and return the number Write no more than MAXSIZE characters and return the number
of characters written, or 0 if it would exceed MAXSIZE. */ of characters written, or 0 if it would exceed MAXSIZE. */
extern size_t strftime __P ((char *__s, size_t __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 /* Return the `struct tm' representation of *TIMER