mirror of
https://github.com/michaeldv/pit.git
synced 2025-12-10 08:25:34 +00:00
Finished with time parsing
This commit is contained in:
142
src/args.c
142
src/args.c
@@ -1,6 +1,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
|
|
||||||
int pit_arg_is_option(char **arg)
|
int pit_arg_is_option(char **arg)
|
||||||
@@ -44,57 +45,116 @@ ulong pit_arg_number(char **arg, char *required)
|
|||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm);
|
static char *adjust_alpha_date(char **arg, char *format)
|
||||||
// time_t mktime ( struct tm * timeptr );
|
{
|
||||||
|
char *pch = strstr(*arg, ", ");
|
||||||
|
|
||||||
|
if (pch) {
|
||||||
|
pch += 2;
|
||||||
|
if (isdigit(*pch) && isdigit(*(pch + 1)) && !isdigit(*(pch + 2))) {
|
||||||
|
inline_replace(format, "%Y", "%y"); /* Two digit year as in Oct 10, 92 19:30 */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inline_replace(format, ", %Y", ""); /* No year as in Oct 10 19:30 */
|
||||||
|
}
|
||||||
|
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *adjust_slash_date(char **arg, char *format)
|
||||||
|
{
|
||||||
|
char *first = strchr(*arg, '/');
|
||||||
|
char *last = strrchr(*arg, '/');
|
||||||
|
if (first == last++) {
|
||||||
|
inline_replace(format, "/%Y", ""); /* Single slash, i.e. no year as in 1/10 19:30 */
|
||||||
|
} else {
|
||||||
|
if (isdigit(*last) && isdigit(*(last + 1)) && !isdigit(*(last + 2))) {
|
||||||
|
inline_replace(format, "%Y", "%y"); /* Two digit year as in 1/10/92 19:30 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *adjust_time(char **arg, char *format)
|
||||||
|
{
|
||||||
|
if (strstr(*arg, "am") || strstr(*arg, "pm")) {
|
||||||
|
inline_replace(format, "%H", "%I");
|
||||||
|
strcat(format, "%p");
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
time_t pit_arg_date(char **arg, char *required)
|
time_t pit_arg_date(char **arg, char *required)
|
||||||
{
|
{
|
||||||
time_t seconds = (time_t)-1;
|
char format[32];
|
||||||
|
time_t now = time(NULL);
|
||||||
|
time_t seconds = (time_t)0;
|
||||||
|
struct tm *ptm = localtime(&now);
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
|
|
||||||
if (required && (!*arg || pit_arg_is_option(arg))) {
|
if (required && (!*arg || pit_arg_is_option(arg))) {
|
||||||
die("missing %s", required);
|
die("missing %s", required);
|
||||||
} else {
|
} else {
|
||||||
|
bool alpha_date = isalpha(**arg);
|
||||||
|
bool slash_date = (strchr(*arg, '/') != NULL);
|
||||||
|
|
||||||
|
if (alpha_date && islower(**arg)) {
|
||||||
|
**arg = toupper(**arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alpha_date || slash_date) { /* Date is present */
|
||||||
|
if (strchr(*arg, ':')) {
|
||||||
|
if (alpha_date) {
|
||||||
|
strcpy(format, "%b %d, %Y %H:%M"); /* Oct 10, 1992 19:30 */
|
||||||
|
} else {
|
||||||
|
strcpy(format, "%m/%d/%Y %H:%M"); /* 10/10/1992 19:30 */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strlen(*arg) > 12) {
|
||||||
|
if (alpha_date) {
|
||||||
|
strcpy(format, "%b %d, %Y %H"); /* Oct 10, 1992 19 */
|
||||||
|
} else {
|
||||||
|
strcpy(format, "%m/%d/%Y %H"); /* 10/10/1992 19 */
|
||||||
|
}
|
||||||
|
} else { /* Date with no time */
|
||||||
|
if (alpha_date) {
|
||||||
|
strcpy(format, "%b %d, %Y"); /* Oct 10, 1992 */
|
||||||
|
} else {
|
||||||
|
strcpy(format, "%m/%d/%Y"); /* 10/10/1992 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (alpha_date) { /* Replace %Y with %y for two-digit year... */
|
||||||
|
adjust_alpha_date(arg, format); /* or remove %Y if no year was specified */
|
||||||
|
} else {
|
||||||
|
adjust_slash_date(arg, format);
|
||||||
|
}
|
||||||
|
} else { /* No date, time only */
|
||||||
|
if (strchr(*arg, ':')) {
|
||||||
|
strcpy(format, "%H:%M"); /* 19:30 */
|
||||||
|
} else {
|
||||||
|
strcpy(format, "%H"); /* 19 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adjust_time(arg, format); /* Replace %H with %I%p for am/pm time */
|
||||||
|
|
||||||
|
/* Ready to roll :-) */
|
||||||
memset(&tm, 0, sizeof(tm));
|
memset(&tm, 0, sizeof(tm));
|
||||||
if (strptime(*arg, "%m/%d/%Y", &tm)) {
|
// printf("format: %s\n", format);
|
||||||
|
if (strptime(*arg, format, &tm)) {
|
||||||
|
printf("then: %s\n", asctime(&tm));
|
||||||
|
if (!tm.tm_mday) tm.tm_mday = ptm->tm_mday;
|
||||||
|
if (!tm.tm_mon) tm.tm_mon = ptm->tm_mon;
|
||||||
|
if (!tm.tm_year) tm.tm_year = ptm->tm_year;
|
||||||
|
|
||||||
|
// printf(" now: %s\n", asctime(ptm));
|
||||||
|
// printf(" adj: %s\n", asctime(&tm));
|
||||||
seconds = mktime(&tm);
|
seconds = mktime(&tm);
|
||||||
}
|
|
||||||
|
|
||||||
if (strchr(*arg, ',')) { /* Date present. */
|
|
||||||
if (strchr(*arg, ':')) { /* Date and HH:MM. */
|
|
||||||
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* Date and HH:MM am/pm. */
|
|
||||||
/* Oct 10, 1992 7:30pm */
|
|
||||||
} else {
|
|
||||||
/* Oct 10, 1992 19:30 */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (strlen(*arg) > 12) { /* Date and HH. */
|
|
||||||
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* Date and HH am/pm. */
|
|
||||||
/* Oct 10, 1992 7pm */
|
|
||||||
} else {
|
|
||||||
/* Oct 10, 1992 19 */ /* HH */
|
|
||||||
}
|
|
||||||
} else { /* Date with no time. */
|
|
||||||
/* Oct 10, 1992 19 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { /* No date, time only. */
|
|
||||||
if (strchr(*arg, ':')) { /* HH:MM. */
|
|
||||||
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* HH:MM am/pm. */
|
|
||||||
/* 7:30pm */
|
|
||||||
} else {
|
|
||||||
/* 19:30 */
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!strstr(*arg, "am") || !strstr(*arg, "pm")) { /* HH am/pm. */
|
|
||||||
/* 7pm */
|
|
||||||
} else {
|
|
||||||
/* 19 */ /* HH */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seconds == (time_t)-1) {
|
if (seconds == (time_t)-1) {
|
||||||
|
perish("invalid date");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
die("invalid %s: %s", required, *arg);
|
die("invalid %s: %s", required, *arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,5 +69,6 @@ char *home_dir(char *username, int len);
|
|||||||
char *expand_path(char *path, char *expanded);
|
char *expand_path(char *path, char *expanded);
|
||||||
char *format_date(time_t date);
|
char *format_date(time_t date);
|
||||||
char *format_time(time_t time);
|
char *format_time(time_t time);
|
||||||
|
char *inline_replace(char *this, char *old, char *new);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
22
src/util.c
22
src/util.c
@@ -86,6 +86,28 @@ char *format_time(time_t time)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *inline_replace(char *this, char *old, char *new)
|
||||||
|
{
|
||||||
|
char *start = this;
|
||||||
|
char *next = this;
|
||||||
|
int new_length = strlen(new);
|
||||||
|
int old_length = strlen(old);
|
||||||
|
|
||||||
|
if (this && old && new && (old_length > 0) && (old_length >= new_length)) {
|
||||||
|
while (*this) {
|
||||||
|
if (strncmp(this, old, old_length)) {
|
||||||
|
*next++ = *this++; /* Not a start of old thising, copy character unchanged. */
|
||||||
|
} else {
|
||||||
|
strncpy(next, new, new_length); /* Found the old string, replace it with the new one. */
|
||||||
|
next += new_length; /* Adjust pointers to move beyond replaced string. */
|
||||||
|
this += old_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*next = '\0';
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
printf("your username: %s\n", current_user());
|
printf("your username: %s\n", current_user());
|
||||||
|
|||||||
58
test/should.rb
Normal file
58
test/should.rb
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
class Hand < RuntimeError
|
||||||
|
def oops(msg)
|
||||||
|
puts "\n#{msg} in #{self.backtrace[-1].sub(':', ' line ')}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class String
|
||||||
|
def should
|
||||||
|
def self.equal(expected)
|
||||||
|
raise Hand unless self == expected
|
||||||
|
print '.'
|
||||||
|
rescue => e
|
||||||
|
e.oops "equal failed: #{self} != #{expected}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.match(expected)
|
||||||
|
raise Hand unless self =~ expected
|
||||||
|
print '.'
|
||||||
|
rescue => e
|
||||||
|
e.oops "match failed: #{self} !~ /#{expected.source}/"
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def should_not
|
||||||
|
def self.equal(expected)
|
||||||
|
raise Hand unless self != expected
|
||||||
|
print '.'
|
||||||
|
rescue => e
|
||||||
|
e.oops "not equal failed: #{self} == #{expected}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.match(expected)
|
||||||
|
raise Hand unless self !~ expected
|
||||||
|
print '.'
|
||||||
|
rescue => e
|
||||||
|
e.oops "not match failed: #{self} =~ /#{expected.source}/"
|
||||||
|
end
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
"123".should.equal "123"
|
||||||
|
"123".should.equal "321"
|
||||||
|
|
||||||
|
"123".should_not.equal "321"
|
||||||
|
"123".should_not.equal "123"
|
||||||
|
|
||||||
|
"abc".should.match /B/i
|
||||||
|
"abc".should.match /xyz/
|
||||||
|
|
||||||
|
"abc".should_not.match /xyz/
|
||||||
|
"abc".should_not.match /abc/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user