Skip to content

Commit

Permalink
implemented --help and started on --iso-8601
Browse files Browse the repository at this point in the history
  • Loading branch information
Eike-Flath committed Apr 24, 2024
1 parent 0a5be13 commit 0ca95d7
Showing 1 changed file with 100 additions and 16 deletions.
116 changes: 100 additions & 16 deletions src/date/date.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#define INITIAL_BUF_SIZE 512

static char *operand;

static struct tm *get_time(void) {
time_t t;
if (time(&t) == -1) {
Expand Down Expand Up @@ -78,29 +80,111 @@ static int set_time(char *str) {
return EXIT_SUCCESS;
}

static void set_operand(char *o) {
if (operand) {
fprintf(stderr, "date: multiple output formats or dates specified\n");
exit(EXIT_FAILURE);
}
operand = o;
}

static void use_utc(void) {
if (setenv("TZ", "UTC", 1) == -1) {
fprintf(stderr, "date: cannot setenv TZ: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}

static void use_iso_fmt(char *iso) {
if (!strcmp(iso, "hours")) {
set_operand("+%FT%H%:z");
} else if (!strcmp(iso, "minutes")) {
set_operand("+%FT%H:%M%:z");
} else if (!strcmp(iso, "date")) {
set_operand("+%F");
} else if (!strcmp(iso, "seconds")) {
set_operand("+%FT%H:%M:%S%:z");
} else if (!strcmp(iso, "ns")) {
set_operand("+%FT%H:%M:%S,%N%:z");
} else {
fprintf(stderr, "date: invalid argument '%s' for '--iso-8601'\n", iso);
fprintf(stderr,
"must be one of 'hours', 'minutes', 'date', 'seconds', 'ns'\n");
exit(EXIT_FAILURE);
}
}

static void short_opt(char *opt) {
switch (*opt) {
case 'u':
use_utc();
break;
case 'I':
if (opt[1])
use_iso_fmt(opt + 1);
else
use_iso_fmt("date");
break;
default:
fprintf(stderr, "date: unknown option '-%c'\n", *opt);
exit(EXIT_FAILURE);
}
}

static bool strpre(const char *pre, const char *str) {
return !strncmp(pre, str, strlen(pre));
}

static void long_opt(char *opt) {
if (!strcmp(opt, "version")) {
print_version();
exit(EXIT_SUCCESS);
}
if (!strcmp(opt, "help"))
exit(system("man date"));
if (!strcmp(opt, "utc") || !strcmp(opt, "universal")) {
use_utc();
return;
}
if (strpre("iso-8601", opt)) {
char *arg = opt + strlen("iso-8601");
if (*arg) {
if (*arg != '=')
goto unknown_opt;
use_iso_fmt(arg + 1);
} else {
use_iso_fmt("date");
}
return;
}
unknown_opt:
fprintf(stderr, "date: unknown option '--%s'\n", opt);
exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
char *operand = "+%a %b %e %H:%M:%S %Z %Y";
operand = NULL;
bool parse_options = true;
for (int i = 1; i < argc; i++) {
if (parse_options) {
if (!strcmp(argv[i], "--")) {
parse_options = false;
if (parse_options && argv[i][0] == '-') {
if (argv[i][1] == '-') {
char *opt = argv[i] + 2;
if (!*opt)
parse_options = false;
else
long_opt(opt);
continue;
}
if (!strcmp(argv[i], "--version")) {
print_version();
return EXIT_SUCCESS;
}
if (!strcmp(argv[i], "-u")) {
if (setenv("TZ", "UTC", 1) == -1) {
fprintf(stderr, "date: cannot setenv TZ: %s\n", strerror(errno));
return EXIT_FAILURE;
} else {
if (argv[i][1]) {
short_opt(argv[i] + 1);
continue;
}
continue;
}
}
operand = argv[i];
set_operand(argv[i]);
}
if (!operand)
operand = "+%a %b %e %H:%M:%S %Z %Y";

if (operand[0] != '+')
return set_time(operand);
Expand All @@ -113,7 +197,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "date: malloc failed: %s\n", strerror(errno));
return EXIT_FAILURE;
}
while (!strftime(buf, cap, &operand[1], tm)) {
while (!strftime(buf, cap, operand + 1, tm)) {
cap *= 2;
char *new_buf = realloc(buf, cap);
if (!new_buf) {
Expand Down

0 comments on commit 0ca95d7

Please sign in to comment.