Created
January 16, 2010 00:07
-
-
Save mina86/278534 to your computer and use it in GitHub Desktop.
A simple parser converting RFC1123 date into an argument date util accepts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* RFC1123 date parser. | |
* Copyright (c) 2010 by Michal Nazarewicz (mina86/AT/mina86.com) | |
* Distributed under the terms of Academic Free License 3.0 | |
*/ | |
#include <ctype.h> | |
#include <errno.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
static const char months[] = "janfebmaraprmayjunjulaugsepoctnovdec"; | |
static const char tzs[] = "gmtutc"; | |
static void acceptWS(void); | |
static unsigned acceptStr(const char *strings); | |
static unsigned acceptInt(unsigned min, unsigned max); | |
static void ensure(int cond) { | |
if (!cond) { | |
exit(EXIT_FAILURE); | |
} | |
} | |
static char *input; | |
int main(void) { | |
unsigned day, mon, year, hour, min, sec; | |
char line[128]; | |
ensure(fgets(line, sizeof line, stdin) != 0); | |
input = line; | |
acceptStr(0); ensure(*input++ == ','); | |
day = acceptInt(1, 31); | |
mon = acceptStr(months) + 1; | |
year = acceptInt(2010, 2100); | |
hour = acceptInt(0, 23); ensure(*input++ == ':'); | |
min = acceptInt(0, 59); ensure(*input++ == ':'); | |
sec = acceptInt(0, 59); | |
acceptStr(tzs); acceptWS(); ensure(*input == 0); | |
printf("%02u%02u%02u%02u%04u.%02u\n", mon, day, hour, min, year, sec); | |
return EXIT_SUCCESS; | |
} | |
static void acceptWS(void) { | |
while (isspace(*input)) { | |
++input; | |
} | |
} | |
static unsigned acceptStr(const char *strings) { | |
char *f; | |
acceptWS(); | |
for (f = input; 1; ++input) { | |
if (isupper(*input)) { | |
*input = tolower(*input); | |
} else if (!islower(*input)) { | |
break; | |
} | |
} | |
ensure(input - f == 3); | |
if (strings) { | |
const char *s = strings; | |
while (*s && (f[0] != s[0] || f[1] != s[1] || f[2] != s[2])) { | |
s += 3; | |
} | |
ensure(*s != 0); | |
return (unsigned)(s - strings) / 3u; | |
} | |
return 0; | |
} | |
static unsigned acceptInt(unsigned min, unsigned max) { | |
unsigned long ret; | |
errno = 0; | |
ret = strtoul(input, &input, 10); | |
ensure(!errno && ret >= min && ret <= max); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment