|
|
|
@ -1,6 +1,8 @@ |
|
|
|
|
#define _XOPEN_SOURCE 600 |
|
|
|
|
#include <assert.h> |
|
|
|
|
#include <ctype.h> |
|
|
|
|
#include <errno.h> |
|
|
|
|
#include <limits.h> |
|
|
|
|
#include <stdbool.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
@ -11,6 +13,7 @@ |
|
|
|
|
#include "util.h" |
|
|
|
|
|
|
|
|
|
char *strstr(const char *haystack, const char *needle); |
|
|
|
|
char *strerror(int errnum); |
|
|
|
|
|
|
|
|
|
static int parse_section(struct parser *p) { |
|
|
|
|
str_t *section = str_create(); |
|
|
|
@ -67,23 +70,42 @@ static void parse_preamble(struct parser *p) { |
|
|
|
|
str_t *extras[2] = { NULL }; |
|
|
|
|
int section = -1; |
|
|
|
|
uint32_t ch; |
|
|
|
|
time_t date_time; |
|
|
|
|
char date[256]; |
|
|
|
|
char *source_date_epoch = getenv("SOURCE_DATE_EPOCH"); |
|
|
|
|
if (source_date_epoch != NULL) { |
|
|
|
|
struct tm source_date_epoch_tm; |
|
|
|
|
char *ret = strptime(source_date_epoch, "%s", &source_date_epoch_tm); |
|
|
|
|
if (ret == NULL || *ret != '\0') { |
|
|
|
|
fprintf(stderr, |
|
|
|
|
"Error: $SOURCE_DATE_EPOCH is set but malformed.\n"); |
|
|
|
|
exit(1); |
|
|
|
|
unsigned long long epoch; |
|
|
|
|
char *endptr; |
|
|
|
|
errno = 0; |
|
|
|
|
epoch = strtoull(source_date_epoch, &endptr, 10); |
|
|
|
|
if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) |
|
|
|
|
|| (errno != 0 && epoch == 0)) { |
|
|
|
|
fprintf(stderr, "$SOURCE_DATE_EPOCH: strtoull: %s\n", |
|
|
|
|
strerror(errno)); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
strftime(date, sizeof(date), "%F", &source_date_epoch_tm); |
|
|
|
|
if (endptr == source_date_epoch) { |
|
|
|
|
fprintf(stderr, "$SOURCE_DATE_EPOCH: No digits were found: %s\n", |
|
|
|
|
endptr); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
if (*endptr != '\0') { |
|
|
|
|
fprintf(stderr, "$SOURCE_DATE_EPOCH: Trailing garbage: %s\n", |
|
|
|
|
endptr); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
if (epoch > ULONG_MAX) { |
|
|
|
|
fprintf(stderr, "$SOURCE_DATE_EPOCH: value must be smaller than or " |
|
|
|
|
"equal to %lu but was found to be: %llu \n", |
|
|
|
|
ULONG_MAX, epoch); |
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
date_time = epoch; |
|
|
|
|
} else { |
|
|
|
|
time_t now; |
|
|
|
|
time(&now); |
|
|
|
|
struct tm *now_tm = localtime(&now); |
|
|
|
|
strftime(date, sizeof(date), "%F", now_tm); |
|
|
|
|
date_time = time(NULL); |
|
|
|
|
} |
|
|
|
|
struct tm *date_tm = localtime(&date_time); |
|
|
|
|
strftime(date, sizeof(date), "%F", date_tm); |
|
|
|
|
while ((ch = parser_getch(p)) != UTF8_INVALID) { |
|
|
|
|
if ((ch < 0x80 && isalnum(ch)) || ch == '_' || ch == '-' || ch == '.') { |
|
|
|
|
int ret = str_append_ch(name, ch); |
|
|
|
|