1edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project/*  $OpenBSD: strptime.c,v 1.11 2005/08/08 08:05:38 espie Exp $ */
2edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project/*  $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $    */
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*-
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved.
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code was contributed to The NetBSD Foundation by Klaus Klein.
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    documentation and/or other materials provided with the distribution.
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. All advertising materials mentioning features or use of this software
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    must display the following acknowledgement:
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *        This product includes software developed by the NetBSD
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *        Foundation, Inc. and its contributors.
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 4. Neither the name of The NetBSD Foundation nor the names of its
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    contributors may be used to endorse or promote products derived
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    from this software without specific prior written permission.
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * POSSIBILITY OF SUCH DAMAGE.
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project//#include <sys/localedef.h>
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h>
4181baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes#include <errno.h>
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <locale.h>
4381baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes#include <stdlib.h>
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <time.h>
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "tzfile.h"
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const struct {
49edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *abday[7];
50edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *day[7];
51edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *abmon[12];
52edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *mon[12];
53edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *am_pm[2];
54edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *d_t_fmt;
55edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *d_fmt;
56edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *t_fmt;
57edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *t_fmt_ampm;
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} _DefaultTimeLocale = {
59edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    {
60edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
61edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    },
62edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    {
63edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
64edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Friday", "Saturday"
65edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    },
66edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    {
67edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
68edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
69edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    },
70edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    {
71edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "January", "February", "March", "April", "May", "June", "July",
72edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "August", "September", "October", "November", "December"
73edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    },
74edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    {
75edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "AM", "PM"
76edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    },
77edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%a %b %d %H:%M:%S %Y",
78edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%m/%d/%y",
79edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%H:%M:%S",
80edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%I:%M:%S %p"
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
83edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define _ctloc(x) (_DefaultTimeLocale.x)
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * We do not implement alternate representations. However, we always
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * check whether a given modifier is allowed for a certain conversion.
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
89edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define _ALT_E          0x01
90edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define _ALT_O          0x02
91edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define _LEGAL_ALT(x)       { if (alt_format & ~(x)) return (0); }
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
94b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kastenstruct century_relyear {
95b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    int century;
96b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    int relyear;
97b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten};
98edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Projectstatic  int _conv_num(const unsigned char **, int *, int, int);
99b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kastenstatic  unsigned char *_strptime(const unsigned char *, const char *, struct tm *,
100b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten        struct century_relyear *);
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectchar *
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstrptime(const char *buf, const char *fmt, struct tm *tm)
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
106b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    struct century_relyear cr;
107b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    cr.century = TM_YEAR_BASE;
108b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    cr.relyear = -1;
109b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    return (char*)(_strptime((const unsigned char*)buf, fmt, tm, &cr));
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
112edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Projectstatic unsigned char *
113b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten_strptime(const unsigned char *buf, const char *fmt, struct tm *tm, struct century_relyear *cr)
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
115edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    unsigned char c;
116edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const unsigned char *bp;
117edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    size_t len = 0;
118edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    int alt_format, i;
119edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
120edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    bp = (unsigned char *)buf;
121edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    while ((c = *fmt) != '\0') {
122edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        /* Clear `alternate' modifier prior to new conversion. */
123edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        alt_format = 0;
124edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
125edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        /* Eat up white-space. */
126edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (isspace(c)) {
127edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            while (isspace(*bp))
128edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                bp++;
129edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
130edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            fmt++;
131edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            continue;
132edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        }
13381baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes
134edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if ((c = *fmt++) != '%')
135edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            goto literal;
136edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
137edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
138edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Projectagain:      switch (c = *fmt++) {
139edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case '%':   /* "%%" is converted to "%". */
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectliteral:
141edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (c != *bp++)
142edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            return (NULL);
143edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
144edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        break;
145edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
146edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        /*
147edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         * "Alternative" modifiers. Just set the appropriate flag
148edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         * and start over again.
149edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         */
150edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'E':   /* "%E?" alternative conversion modifier. */
151edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
152edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            alt_format |= _ALT_E;
153edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            goto again;
154edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
155edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'O':   /* "%O?" alternative conversion modifier. */
156edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
157edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            alt_format |= _ALT_O;
158edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            goto again;
15981baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes
160edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        /*
161edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         * "Complex" conversion rules, implemented through recursion.
162edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         */
163edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'c':   /* Date and time, using the locale's format. */
164edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_E);
165b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, cr)))
166edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
167edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
168edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
169edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'D':   /* The date as "%m/%d/%y". */
170edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
171b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, "%m/%d/%y", tm, cr)))
172edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
173edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
17481baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes
175edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'R':   /* The time as "%H:%M". */
176edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
177b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, "%H:%M", tm, cr)))
178edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
179edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
180edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
181edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'r':   /* The time as "%I:%M:%S %p". */
182edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
183b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, cr)))
184edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
185edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
186edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
187edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'T':   /* The time as "%H:%M:%S". */
188edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
189b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, "%H:%M:%S", tm, cr)))
190edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
191edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
192edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
193edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'X':   /* The time, using the locale's format. */
194edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_E);
195b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, cr)))
196edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
197edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
198edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
199edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'x':   /* The date, using the locale's format. */
200edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_E);
201b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, cr)))
202edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
203edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
204edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
205edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        /*
206edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         * "Elementary" conversion rules.
207edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         */
208edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'A':   /* The day of week, using the locale's form. */
209edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'a':
210edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
211edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            for (i = 0; i < 7; i++) {
212edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /* Full name. */
213edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                len = strlen(_ctloc(day[i]));
214edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (strncasecmp(_ctloc(day[i]), (const char*)bp, len) == 0)
215edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    break;
216edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
217edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /* Abbreviated name. */
218edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                len = strlen(_ctloc(abday[i]));
219edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (strncasecmp(_ctloc(abday[i]), (const char*)bp, len) == 0)
220edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    break;
221edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            }
222edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
223edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* Nothing matched. */
224edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (i == 7)
225edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
226edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
227edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            tm->tm_wday = i;
228edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            bp += len;
229edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
230edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
231edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'B':   /* The month, using the locale's form. */
232edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'b':
233edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'h':
234edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
235edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            for (i = 0; i < 12; i++) {
236edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /* Full name. */
237edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                len = strlen(_ctloc(mon[i]));
238edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (strncasecmp(_ctloc(mon[i]), (const char*)bp, len) == 0)
239edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    break;
240edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
241edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /* Abbreviated name. */
242edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                len = strlen(_ctloc(abmon[i]));
243edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (strncasecmp(_ctloc(abmon[i]), (const char*)bp, len) == 0)
244edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    break;
245edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            }
246edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
247edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* Nothing matched. */
248edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (i == 12)
249edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
250edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
251edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            tm->tm_mon = i;
252edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            bp += len;
253edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
254edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
255edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'C':   /* The century number. */
256edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_E);
257edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &i, 0, 99)))
258edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
259edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
260b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            cr->century = i * 100;
261edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
262edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
263edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'd':   /* The day of month. */
264edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'e':
265edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
266edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_mday, 1, 31)))
267edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
268edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
269edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
270edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'k':   /* The hour (24-hour clock representation). */
271edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
272edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* FALLTHROUGH */
273edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'H':
274edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
275edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_hour, 0, 23)))
276edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
277edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
278edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
279edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'l':   /* The hour (12-hour clock representation). */
280edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
281edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* FALLTHROUGH */
282edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'I':
283edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
284edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_hour, 1, 12)))
285edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
286edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
287edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
288edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'j':   /* The day of year. */
289edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
290edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_yday, 1, 366)))
291edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
292edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            tm->tm_yday--;
293edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
294edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
295edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'M':   /* The minute. */
296edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
297edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_min, 0, 59)))
298edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
299edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
300edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
301edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'm':   /* The month. */
302edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
303edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_mon, 1, 12)))
304edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
305edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            tm->tm_mon--;
306edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
307edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
308edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'p':   /* The locale's equivalent of AM/PM. */
309edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
310edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* AM? */
311edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            len = strlen(_ctloc(am_pm[0]));
312edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (strncasecmp(_ctloc(am_pm[0]), (const char*)bp, len) == 0) {
313edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (tm->tm_hour > 12)   /* i.e., 13:00 AM ?! */
314edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    return (NULL);
315edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                else if (tm->tm_hour == 12)
316edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    tm->tm_hour = 0;
317edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
318edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                bp += len;
319edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                break;
320edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            }
321edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* PM? */
322edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            len = strlen(_ctloc(am_pm[1]));
323edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (strncasecmp(_ctloc(am_pm[1]), (const char*)bp, len) == 0) {
324edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (tm->tm_hour > 12)   /* i.e., 13:00 PM ?! */
325edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    return (NULL);
326edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                else if (tm->tm_hour < 12)
327edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    tm->tm_hour += 12;
328edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
329edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                bp += len;
330edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                break;
331edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            }
332edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
333edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /* Nothing matched. */
334edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            return (NULL);
335edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
336edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'S':   /* The seconds. */
337edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
338edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_sec, 0, 61)))
339edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
340edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
341edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
34281baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes        case 's':
34381baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes            {
34481baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                // Android addition, based on FreeBSD's implementation.
34581baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                int saved_errno = errno;
34681baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                errno = 0;
34781baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                const unsigned char* old_bp = bp;
34881baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                long n = strtol((const char*) bp, (char**) &bp, 10);
34981baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                time_t t = n;
35081baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                if (bp == old_bp || errno == ERANGE || ((long) t) != n) {
35181baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                    errno = saved_errno;
35281baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                    return NULL;
35381baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                }
35481baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                errno = saved_errno;
35581baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes
35681baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes                if (localtime_r(&t, tm) == NULL) return NULL;
35781baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes            }
35881baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes            break;
35981baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes
36081baaf272cb79c69ca9b0969466f5f946c923a2bElliott Hughes
361edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'U':   /* The week of year, beginning on sunday. */
362edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'W':   /* The week of year, beginning on monday. */
363edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
364edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /*
365edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             * XXX This is bogus, as we can not assume any valid
366edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             * information present in the tm structure at this
367edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             * point to calculate a real value, so just check the
368edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             * range for now.
369edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             */
370edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             if (!(_conv_num(&bp, &i, 0, 53)))
371edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
372edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project             break;
373edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
374edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'w':   /* The day of week, beginning on sunday. */
375edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_O);
376edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &tm->tm_wday, 0, 6)))
377edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
378edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
379edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
380edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'Y':   /* The year. */
381edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_E);
382edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            if (!(_conv_num(&bp, &i, 0, 9999)))
383edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
384edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
385b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            cr->relyear = -1;
386edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            tm->tm_year = i - TM_YEAR_BASE;
387edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
388edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
389edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'y':   /* The year within the century (2 digits). */
390edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(_ALT_E | _ALT_O);
391b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (!(_conv_num(&bp, &cr->relyear, 0, 99)))
392edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                return (NULL);
393edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
394edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
395edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        /*
396edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         * Miscellaneous conversions.
397edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project         */
398edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 'n':   /* Any kind of white-space. */
399edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        case 't':
400edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            _LEGAL_ALT(0);
401edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            while (isspace(*bp))
402edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                bp++;
403edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
404edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
405edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
406edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        default:    /* Unknown/unsupported conversion. */
407edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            return (NULL);
408edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        }
409edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
410edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
411edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }
412edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
413edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /*
414edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project     * We need to evaluate the two digit year spec (%y)
415edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project     * last as we can get a century spec (%C) at any time.
416edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project     */
417b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten    if (cr->relyear != -1) {
418b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten        if (cr->century == TM_YEAR_BASE) {
419b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            if (cr->relyear <= 68)
420b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten                tm->tm_year = cr->relyear + 2000 - TM_YEAR_BASE;
421edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            else
422b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten                tm->tm_year = cr->relyear + 1900 - TM_YEAR_BASE;
423edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        } else {
424b138e4f90ffec34b4cc903cffbe18f9ea2d903d4Glenn Kasten            tm->tm_year = cr->relyear + cr->century - TM_YEAR_BASE;
425edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        }
426edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }
427edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
428edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    return (unsigned char*)bp;
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_conv_num(const unsigned char **buf, int *dest, int llim, int ulim)
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
435edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    int result = 0;
436edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    int rulim = ulim;
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
438edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (**buf < '0' || **buf > '9')
439edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        return (0);
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
441edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /* we use rulim to break out of the loop when we run out of digits */
442edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    do {
443edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        result *= 10;
444edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        result += *(*buf)++ - '0';
445edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        rulim /= 10;
446edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
448edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (result < llim || result > ulim)
449edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        return (0);
4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
451edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    *dest = result;
452edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    return (1);
4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4543376c23daceddd603478347c00163f39e7c9e1eeElliott Hughes
4553376c23daceddd603478347c00163f39e7c9e1eeElliott Hugheschar* strptime_l(const char* buf, const char* fmt, struct tm* tm, locale_t l) {
4563376c23daceddd603478347c00163f39e7c9e1eeElliott Hughes  return strptime(buf, fmt, tm);
4573376c23daceddd603478347c00163f39e7c9e1eeElliott Hughes}
458