Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:20:42

0001 #ifndef __STRPTIME_C__
0002 #define __STRPTIME_C__
0003 /*
0004  * Copyright (c) 1999 Kungliga Tekniska Högskolan
0005  * (Royal Institute of Technology, Stockholm, Sweden). 
0006  * All rights reserved. 
0007  *
0008  * Redistribution and use in source and binary forms, with or without 
0009  * modification, are permitted provided that the following conditions 
0010  * are met: 
0011  *
0012  * 1. Redistributions of source code must retain the above copyright 
0013  *    notice, this list of conditions and the following disclaimer. 
0014  *
0015  * 2. Redistributions in binary form must reproduce the above copyright 
0016  *    notice, this list of conditions and the following disclaimer in the 
0017  *    documentation and/or other materials provided with the distribution. 
0018  *
0019  * 3. Neither the name of KTH nor the names of its contributors may be
0020  *    used to endorse or promote products derived from this software without
0021  *    specific prior written permission.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
0024  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0026  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0030  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0031  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
0032  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
0033  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
0034 
0035 extern "C"
0036 {
0037 
0038 #ifndef HAVE_STRPTIME_PROTOTYPE 
0039 #ifdef HAVE_CONFIG_H
0040 #include <config.h>
0041 #endif
0042 #include <ctype.h>
0043 //#include "roken.h"
0044 #include <stdio.h>
0045 #include <stdlib.h>
0046 #include <stdarg.h>
0047 #include <string.h>
0048 #include <signal.h>
0049 #include <time.h>
0050 
0051 
0052 static const char *abb_weekdays[] = {
0053     "Sun",
0054     "Mon",
0055     "Tue",
0056     "Wed",
0057     "Thu",
0058     "Fri",
0059     "Sat",
0060     NULL
0061 };
0062 
0063 static const char *full_weekdays[] = {
0064     "Sunday",
0065     "Monday",
0066     "Tuesday",
0067     "Wednesday",
0068     "Thursday",
0069     "Friday",
0070     "Saturday",
0071     NULL
0072 };
0073 
0074 static const char *abb_month[] = {
0075     "Jan",
0076     "Feb",
0077     "Mar",
0078     "Apr",
0079     "May",
0080     "Jun",
0081     "Jul",
0082     "Aug",
0083     "Sep",
0084     "Oct",
0085     "Nov",
0086     "Dec",
0087     NULL
0088 };
0089 
0090 static const char *full_month[] = {
0091     "January",
0092     "February",
0093     "Mars",
0094     "April",
0095     "May",
0096     "June",
0097     "July",
0098     "August",
0099     "September",
0100     "October",
0101     "November",
0102     "December",
0103     NULL,
0104 };
0105 
0106 static const char *ampm[] = {
0107     "am",
0108     "pm",
0109     NULL
0110 };
0111 
0112 /*
0113  * Try to match `*buf' to one of the strings in `strs'.  Return the
0114  * index of the matching string (or -1 if none).  Also advance buf.
0115  */
0116 
0117 static int
0118 match_string (const char **buf, const char **strs)
0119 {
0120     int i = 0;
0121 
0122     for (i = 0; strs[i] != NULL; ++i) {
0123     int len = strlen (strs[i]);
0124 
0125     if (strncasecmp (*buf, strs[i], len) == 0) {
0126         *buf += len;
0127         return i;
0128     }
0129     }
0130     return -1;
0131 }
0132 
0133 /*
0134  * tm_year is relative this year */
0135 
0136 const int tm_year_base = 1900;
0137 
0138 /*
0139  * Return TRUE iff `year' was a leap year.
0140  */
0141 
0142 static int
0143 is_leap_year (int year)
0144 {
0145     return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
0146 }
0147 
0148 /*
0149  * Return the weekday [0,6] (0 = Sunday) of the first day of `year'
0150  */
0151 
0152 static int
0153 first_day (int year)
0154 {
0155     int ret = 4;
0156 
0157     for (; year > 1970; --year)
0158     ret = (ret + 365 + is_leap_year (year) ? 1 : 0) % 7;
0159     return ret;
0160 }
0161 
0162 /*
0163  * Set `timeptr' given `wnum' (week number [0, 53])
0164  */
0165 
0166 static void
0167 set_week_number_sun (struct tm *timeptr, int wnum)
0168 {
0169     int fday = first_day (timeptr->tm_year + tm_year_base);
0170 
0171     timeptr->tm_yday = wnum * 7 + timeptr->tm_wday - fday;
0172     if (timeptr->tm_yday < 0) {
0173     timeptr->tm_wday = fday;
0174     timeptr->tm_yday = 0;
0175     }
0176 }
0177 
0178 /*
0179  * Set `timeptr' given `wnum' (week number [0, 53])
0180  */
0181 
0182 static void
0183 set_week_number_mon (struct tm *timeptr, int wnum)
0184 {
0185     int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
0186 
0187     timeptr->tm_yday = wnum * 7 + (timeptr->tm_wday + 6) % 7 - fday;
0188     if (timeptr->tm_yday < 0) {
0189     timeptr->tm_wday = (fday + 1) % 7;
0190     timeptr->tm_yday = 0;
0191     }
0192 }
0193 
0194 /*
0195  * Set `timeptr' given `wnum' (week number [0, 53])
0196  */
0197 
0198 static void
0199 set_week_number_mon4 (struct tm *timeptr, int wnum)
0200 {
0201     int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
0202     int offset = 0;
0203 
0204     if (fday < 4)
0205     offset += 7;
0206 
0207     timeptr->tm_yday = offset + (wnum - 1) * 7 + timeptr->tm_wday - fday;
0208     if (timeptr->tm_yday < 0) {
0209     timeptr->tm_wday = fday;
0210     timeptr->tm_yday = 0;
0211     }
0212 }
0213 
0214 /*
0215  *
0216  */
0217 
0218 char *
0219 strptime (const char *buf, const char *format, struct tm *timeptr)
0220 {
0221     char c;
0222 
0223     for (; (c = *format) != '\0'; ++format) {
0224     char *s;
0225     int ret;
0226 
0227     if (isspace (c)) {
0228         while (isspace (*buf))
0229         ++buf;
0230     } else if (c == '%' && format[1] != '\0') {
0231         c = *++format;
0232         if (c == 'E' || c == 'O')
0233         c = *++format;
0234         switch (c) {
0235         case 'A' :
0236         ret = match_string (&buf, full_weekdays);
0237         if (ret < 0)
0238             return NULL;
0239         timeptr->tm_wday = ret;
0240         break;
0241         case 'a' :
0242         ret = match_string (&buf, abb_weekdays);
0243         if (ret < 0)
0244             return NULL;
0245         timeptr->tm_wday = ret;
0246         break;
0247         case 'B' :
0248         ret = match_string (&buf, full_month);
0249         if (ret < 0)
0250             return NULL;
0251         timeptr->tm_mon = ret;
0252         break;
0253         case 'b' :
0254         case 'h' :
0255         ret = match_string (&buf, abb_month);
0256         if (ret < 0)
0257             return NULL;
0258         timeptr->tm_mon = ret;
0259         break;
0260         case 'C' :
0261         ret = strtol (buf, &s, 10);
0262         if (s == buf)
0263             return NULL;
0264         timeptr->tm_year = (ret * 100) - tm_year_base;
0265         buf = s;
0266         break;
0267         case 'c' :
0268         abort ();
0269         case 'D' :      /* %m/%d/%y */
0270         s = strptime (buf, "%m/%d/%y", timeptr);
0271         if (s == NULL)
0272             return NULL;
0273         buf = s;
0274         break;
0275         case 'd' :
0276         case 'e' :
0277         ret = strtol (buf, &s, 10);
0278         if (s == buf)
0279             return NULL;
0280         timeptr->tm_mday = ret;
0281         buf = s;
0282         break;
0283         case 'H' :
0284         case 'k' :
0285         ret = strtol (buf, &s, 10);
0286         if (s == buf)
0287             return NULL;
0288         timeptr->tm_hour = ret;
0289         buf = s;
0290         break;
0291         case 'I' :
0292         case 'l' :
0293         ret = strtol (buf, &s, 10);
0294         if (s == buf)
0295             return NULL;
0296         if (ret == 12)
0297             timeptr->tm_hour = 0;
0298         else
0299             timeptr->tm_hour = ret;
0300         buf = s;
0301         break;
0302         case 'j' :
0303         ret = strtol (buf, &s, 10);
0304         if (s == buf)
0305             return NULL;
0306         timeptr->tm_yday = ret - 1;
0307         buf = s;
0308         break;
0309         case 'm' :
0310         ret = strtol (buf, &s, 10);
0311         if (s == buf)
0312             return NULL;
0313         timeptr->tm_mon = ret - 1;
0314         buf = s;
0315         break;
0316         case 'M' :
0317         ret = strtol (buf, &s, 10);
0318         if (s == buf)
0319             return NULL;
0320         timeptr->tm_min = ret;
0321         buf = s;
0322         break;
0323         case 'n' :
0324         if (*buf == '\n')
0325             ++buf;
0326         else
0327             return NULL;
0328         break;
0329         case 'p' :
0330         ret = match_string (&buf, ampm);
0331         if (ret < 0)
0332             return NULL;
0333         if (timeptr->tm_hour == 0) {
0334             if (ret == 1)
0335             timeptr->tm_hour = 12;
0336         } else
0337             timeptr->tm_hour += 12;
0338         break;
0339         case 'r' :      /* %I:%M:%S %p */
0340         s = strptime (buf, "%I:%M:%S %p", timeptr);
0341         if (s == NULL)
0342             return NULL;
0343         buf = s;
0344         break;
0345         case 'R' :      /* %H:%M */
0346         s = strptime (buf, "%H:%M", timeptr);
0347         if (s == NULL)
0348             return NULL;
0349         buf = s;
0350         break;
0351         case 'S' :
0352         ret = strtol (buf, &s, 10);
0353         if (s == buf)
0354             return NULL;
0355         timeptr->tm_sec = ret;
0356         buf = s;
0357         break;
0358         case 't' :
0359         if (*buf == '\t')
0360             ++buf;
0361         else
0362             return NULL;
0363         break;
0364         case 'T' :      /* %H:%M:%S */
0365         case 'X' :
0366         s = strptime (buf, "%H:%M:%S", timeptr);
0367         if (s == NULL)
0368             return NULL;
0369         buf = s;
0370         break;
0371         case 'u' :
0372         ret = strtol (buf, &s, 10);
0373         if (s == buf)
0374             return NULL;
0375         timeptr->tm_wday = ret - 1;
0376         buf = s;
0377         break;
0378         case 'w' :
0379         ret = strtol (buf, &s, 10);
0380         if (s == buf)
0381             return NULL;
0382         timeptr->tm_wday = ret;
0383         buf = s;
0384         break;
0385         case 'U' :
0386         ret = strtol (buf, &s, 10);
0387         if (s == buf)
0388             return NULL;
0389         set_week_number_sun (timeptr, ret);
0390         buf = s;
0391         break;
0392         case 'V' :
0393         ret = strtol (buf, &s, 10);
0394         if (s == buf)
0395             return NULL;
0396         set_week_number_mon4 (timeptr, ret);
0397         buf = s;
0398         break;
0399         case 'W' :
0400         ret = strtol (buf, &s, 10);
0401         if (s == buf)
0402             return NULL;
0403         set_week_number_mon (timeptr, ret);
0404         buf = s;
0405         break;
0406         case 'x' :
0407         s = strptime (buf, "%Y:%m:%d", timeptr);
0408         if (s == NULL)
0409             return NULL;
0410         buf = s;
0411         break;
0412         case 'y' :
0413         ret = strtol (buf, &s, 10);
0414         if (s == buf)
0415             return NULL;
0416         if (ret < 70)
0417             timeptr->tm_year = 100 + ret;
0418         else
0419             timeptr->tm_year = ret;
0420         buf = s;
0421         break;
0422         case 'Y' :
0423         ret = strtol (buf, &s, 10);
0424         if (s == buf)
0425             return NULL;
0426         timeptr->tm_year = ret - tm_year_base;
0427         buf = s;
0428         break;
0429         case 'Z' :
0430         abort ();
0431         case '\0' :
0432         --format;
0433         /* FALLTHROUGH */
0434         case '%' :
0435         if (*buf == '%')
0436             ++buf;
0437         else
0438             return NULL;
0439         break;
0440         default :
0441         if (*buf == '%' || *++buf == c)
0442             ++buf;
0443         else
0444             return NULL;
0445         break;
0446         }
0447     } else {
0448         if (*buf == c)
0449         ++buf;
0450         else
0451         return NULL;
0452     }
0453     }
0454     return (char *)buf;
0455 }
0456 
0457 #endif
0458 }
0459 
0460 #endif /* __STRPTIME_C__ */