Home | History | Annotate | Line # | Download | only in time
strptime.c revision 1.1
      1 /*	$NetBSD: strptime.c,v 1.1 1997/04/23 01:18:06 mrg Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1994 Powerdog Industries.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer
     13  *    in the documentation and/or other materials provided with the
     14  *    distribution.
     15  * 3. All advertising materials mentioning features or use of this
     16  *    software must display the following acknowledgement:
     17  *      This product includes software developed by Powerdog Industries.
     18  * 4. The name of Powerdog Industries may not be used to endorse or
     19  *    promote products derived from this software without specific prior
     20  *    written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY
     23  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE
     26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     29  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     31  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     32  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 #ifndef lint
     36 #if 0
     37 static char copyright[] =
     38 "@(#) Copyright (c) 1994 Powerdog Industries.  All rights reserved.";
     39 static char sccsid[] = "@(#)strptime.c  0.1 (Powerdog) 94/03/27";
     40 #else
     41 static char rcsid[] = "$NetBSD: strptime.c,v 1.1 1997/04/23 01:18:06 mrg Exp $";
     42 #endif
     43 #endif /* not lint */
     44 
     45 #include <sys/localedef.h>
     46 #include <locale.h>
     47 #include <time.h>
     48 #include <ctype.h>
     49 #include <string.h>
     50 
     51 char    *
     52 strptime(const char *buf, const char *fmt, struct tm *tm)
     53 {
     54 	const char *ptr;
     55         char    c;
     56 	int     i, len;
     57 
     58         ptr = fmt;
     59         while (*ptr != 0) {
     60                 if (*buf == 0)
     61                         break;
     62 
     63                 c = *ptr++;
     64 
     65                 if (c != '%') {
     66                         if (isspace(c))
     67                                 while (*buf != 0 && isspace(*buf))
     68                                         buf++;
     69                         else if (c != *buf++)
     70                                 return 0;
     71                         continue;
     72                 }
     73 
     74                 c = *ptr++;
     75                 switch (c) {
     76                 case 0:
     77                 case '%':
     78                         if (*buf++ != '%')
     79                                 return 0;
     80                         break;
     81 
     82                 case 'c':
     83                         buf = strptime(buf, _CurrentTimeLocale->d_t_fmt, tm);
     84                         if (buf == 0)
     85                                 return 0;
     86                         break;
     87 
     88                 case 'D':
     89                         buf = strptime(buf, "%m/%d/%y", tm);
     90                         if (buf == 0)
     91                                 return 0;
     92                         break;
     93 
     94                 case 'R':
     95                         buf = strptime(buf, "%H:%M", tm);
     96                         if (buf == 0)
     97                                 return 0;
     98                         break;
     99 
    100                 case 'r':
    101                         buf = strptime(buf, _CurrentTimeLocale->t_fmt_ampm,tm);
    102                         if (buf == 0)
    103                                 return 0;
    104                         break;
    105 
    106                 case 'T':
    107                         buf = strptime(buf, "%H:%M:%S", tm);
    108                         if (buf == 0)
    109                                 return 0;
    110                         break;
    111 
    112                 case 'X':
    113                         buf = strptime(buf, _CurrentTimeLocale->t_fmt, tm);
    114                         if (buf == 0)
    115                                 return 0;
    116                         break;
    117 
    118                 case 'x':
    119                         buf = strptime(buf, _CurrentTimeLocale->d_fmt, tm);
    120                         if (buf == 0)
    121                                 return 0;
    122                         break;
    123 
    124                 case 'j':
    125                         if (!isdigit(*buf))
    126                                 return 0;
    127 
    128                         for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
    129                                 i *= 10;
    130                                 i += *buf - '0';
    131                         }
    132                         if (i > 366)
    133                                 return 0;
    134 
    135                         tm->tm_yday = i;
    136                         break;
    137 
    138                 case 'M':
    139                 case 'S':
    140                         if (*buf == 0 || isspace(*buf))
    141                                 break;
    142 
    143                         if (!isdigit(*buf))
    144                                 return 0;
    145 
    146                         for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
    147                                 i *= 10;
    148                                 i += *buf - '0';
    149                         }
    150                         if (i > 59)
    151                                 return 0;
    152 
    153                         if (c == 'M')
    154                                 tm->tm_min = i;
    155                         else
    156                                 tm->tm_sec = i;
    157 
    158                         if (*buf != 0 && isspace(*buf))
    159                                 while (*ptr != 0 && !isspace(*ptr))
    160                                         ptr++;
    161                         break;
    162 
    163                 case 'H':
    164                 case 'I':
    165                 case 'k':
    166                 case 'l':
    167                         if (!isdigit(*buf))
    168                                 return 0;
    169 
    170                         for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
    171                                 i *= 10;
    172                                 i += *buf - '0';
    173                         }
    174                         if (c == 'H' || c == 'k') {
    175                                 if (i > 23)
    176                                         return 0;
    177                         } else if (i > 11)
    178                                 return 0;
    179 
    180                         tm->tm_hour = i;
    181 
    182                         if (*buf != 0 && isspace(*buf))
    183                                 while (*ptr != 0 && !isspace(*ptr))
    184                                         ptr++;
    185                         break;
    186 
    187                 case 'p':
    188                         len = strlen(_CurrentTimeLocale->am_pm[0]);
    189                         if (strncasecmp(buf, _CurrentTimeLocale->am_pm[0],
    190 					len) == 0) {
    191                                 if (tm->tm_hour > 12)
    192                                         return 0;
    193                                 if (tm->tm_hour == 12)
    194                                         tm->tm_hour = 0;
    195                                 buf += len;
    196                                 break;
    197                         }
    198 
    199                         len = strlen(_CurrentTimeLocale->am_pm[1]);
    200                         if (strncasecmp(buf, _CurrentTimeLocale->am_pm[1],
    201 					len) == 0) {
    202                                 if (tm->tm_hour > 12)
    203                                         return 0;
    204                                 if (tm->tm_hour != 12)
    205                                         tm->tm_hour += 12;
    206                                 buf += len;
    207                                 break;
    208                         }
    209 
    210                         return 0;
    211 
    212                 case 'A':
    213                 case 'a':
    214                         for (i = 0; i < 7; i++) {
    215                                 len = strlen(_CurrentTimeLocale->day[i]);
    216                                 if (strncasecmp(buf,
    217 						_CurrentTimeLocale->day[i],
    218 						len) == 0)
    219 					break;
    220 
    221                                 len = strlen(_CurrentTimeLocale->abday[i]);
    222                                 if (strncasecmp(buf,
    223 						_CurrentTimeLocale->abday[i],
    224 						len) == 0)
    225 					break;
    226                         }
    227                         if (i == 7)
    228                                 return 0;
    229 
    230                         tm->tm_wday = i;
    231                         buf += len;
    232                         break;
    233 
    234                 case 'd':
    235                 case 'e':
    236                         if (!isdigit(*buf))
    237                                 return 0;
    238 
    239                         for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
    240                                 i *= 10;
    241                                 i += *buf - '0';
    242                         }
    243                         if (i > 31)
    244                                 return 0;
    245 
    246                         tm->tm_mday = i;
    247 
    248                         if (*buf != 0 && isspace(*buf))
    249                                 while (*ptr != 0 && !isspace(*ptr))
    250                                         ptr++;
    251                         break;
    252 
    253                 case 'B':
    254                 case 'b':
    255                 case 'h':
    256                         for (i = 0; i < 12; i++) {
    257 				len = strlen(_CurrentTimeLocale->mon[i]);
    258                                 if (strncasecmp(buf,
    259 						_CurrentTimeLocale->mon[i],
    260                                                 len) == 0)
    261                                         break;
    262 
    263 				len = strlen(_CurrentTimeLocale->abmon[i]);
    264                                 if (strncasecmp(buf,
    265 						_CurrentTimeLocale->abmon[i],
    266                                                 len) == 0)
    267                                         break;
    268                         }
    269                         if (i == 12)
    270                                 return 0;
    271 
    272                         tm->tm_mon = i;
    273                         buf += len;
    274                         break;
    275 
    276                 case 'm':
    277                         if (!isdigit(*buf))
    278                                 return 0;
    279 
    280                         for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
    281                                 i *= 10;
    282                                 i += *buf - '0';
    283                         }
    284                         if (i < 1 || i > 12)
    285                                 return 0;
    286 
    287                         tm->tm_mon = i - 1;
    288 
    289                         if (*buf != 0 && isspace(*buf))
    290                                 while (*ptr != 0 && !isspace(*ptr))
    291                                         ptr++;
    292                         break;
    293 
    294                 case 'Y':
    295                 case 'y':
    296                         if (*buf == 0 || isspace(*buf))
    297                                 break;
    298 
    299                         if (!isdigit(*buf))
    300                                 return 0;
    301 
    302                         for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
    303                                 i *= 10;
    304                                 i += *buf - '0';
    305                         }
    306                         if (c == 'Y')
    307                                 i -= 1900;
    308                         if (i < 0)
    309                                 return 0;
    310 
    311                         tm->tm_year = i;
    312 
    313                         if (*buf != 0 && isspace(*buf))
    314                                 while (*ptr != 0 && !isspace(*ptr))
    315                                         ptr++;
    316                         break;
    317                 }
    318         }
    319 
    320         return (char *) buf;
    321 }
    322 
    323 
    324