mirror of
https://git.proxmox.com/git/libgit2
synced 2025-10-15 20:18:26 +00:00
Approxidate: use libgit2 naming/calling conventions.
Also use git_time_t (64-bit integer) for time values, although the 2038 problem is still present on 32-bit machines.
This commit is contained in:
parent
1ce4cc0164
commit
dd9e4abc1b
30
src/date.c
30
src/date.c
@ -30,7 +30,7 @@ typedef enum {
|
|||||||
/*
|
/*
|
||||||
* This is like mktime, but without normalization of tm_wday and tm_yday.
|
* This is like mktime, but without normalization of tm_wday and tm_yday.
|
||||||
*/
|
*/
|
||||||
static time_t tm_to_time_t(const struct tm *tm)
|
static git_time_t tm_to_time_t(const struct tm *tm)
|
||||||
{
|
{
|
||||||
static const int mdays[] = {
|
static const int mdays[] = {
|
||||||
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
||||||
@ -454,7 +454,7 @@ static int match_tz(const char *date, int *offp)
|
|||||||
* Parse a string like "0 +0000" as ancient timestamp near epoch, but
|
* Parse a string like "0 +0000" as ancient timestamp near epoch, but
|
||||||
* only when it appears not as part of any other string.
|
* only when it appears not as part of any other string.
|
||||||
*/
|
*/
|
||||||
static int match_object_header_date(const char *date, unsigned long *timestamp, int *offset)
|
static int match_object_header_date(const char *date, git_time_t *timestamp, int *offset)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
unsigned long stamp;
|
unsigned long stamp;
|
||||||
@ -479,11 +479,11 @@ static int match_object_header_date(const char *date, unsigned long *timestamp,
|
|||||||
|
|
||||||
/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
|
/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
|
||||||
(i.e. English) day/month names, and it doesn't work correctly with %z. */
|
(i.e. English) day/month names, and it doesn't work correctly with %z. */
|
||||||
static int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
|
static int parse_date_basic(const char *date, git_time_t *timestamp, int *offset)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
int tm_gmt;
|
int tm_gmt;
|
||||||
unsigned long dummy_timestamp;
|
git_time_t dummy_timestamp;
|
||||||
int dummy_offset;
|
int dummy_offset;
|
||||||
|
|
||||||
if (!timestamp)
|
if (!timestamp)
|
||||||
@ -533,7 +533,7 @@ static int parse_date_basic(const char *date, unsigned long *timestamp, int *off
|
|||||||
if (*offset == -1)
|
if (*offset == -1)
|
||||||
*offset = ((time_t)*timestamp - mktime(&tm)) / 60;
|
*offset = ((time_t)*timestamp - mktime(&tm)) / 60;
|
||||||
|
|
||||||
if (*timestamp == (unsigned long)-1)
|
if (*timestamp == (git_time_t)-1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!tm_gmt)
|
if (!tm_gmt)
|
||||||
@ -546,7 +546,7 @@ static int parse_date_basic(const char *date, unsigned long *timestamp, int *off
|
|||||||
* Relative time update (eg "2 days ago"). If we haven't set the time
|
* Relative time update (eg "2 days ago"). If we haven't set the time
|
||||||
* yet, we need to set it from current time.
|
* yet, we need to set it from current time.
|
||||||
*/
|
*/
|
||||||
static unsigned long update_tm(struct tm *tm, struct tm *now, unsigned long sec)
|
static git_time_t update_tm(struct tm *tm, struct tm *now, unsigned long sec)
|
||||||
{
|
{
|
||||||
time_t n;
|
time_t n;
|
||||||
|
|
||||||
@ -822,7 +822,7 @@ static void pending_number(struct tm *tm, int *num)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long approxidate_str(const char *date,
|
static git_time_t approxidate_str(const char *date,
|
||||||
const struct timeval *tv,
|
const struct timeval *tv,
|
||||||
int *error_ret)
|
int *error_ret)
|
||||||
{
|
{
|
||||||
@ -859,20 +859,18 @@ static unsigned long approxidate_str(const char *date,
|
|||||||
return update_tm(&tm, &now, 0);
|
return update_tm(&tm, &now, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long approxidate_careful(const char *date, int *error_ret)
|
int git__date_parse(git_time_t *out, const char *date)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
unsigned long timestamp;
|
git_time_t timestamp;
|
||||||
int offset;
|
int offset, error_ret=0;
|
||||||
int dummy = 0;
|
|
||||||
if (!error_ret)
|
|
||||||
error_ret = &dummy;
|
|
||||||
|
|
||||||
if (!parse_date_basic(date, ×tamp, &offset)) {
|
if (!parse_date_basic(date, ×tamp, &offset)) {
|
||||||
*error_ret = 0;
|
*out = timestamp;
|
||||||
return timestamp;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
return approxidate_str(date, &tv, error_ret);
|
*out = approxidate_str(date, &tv, &error_ret);
|
||||||
|
return error_ret;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef INCLUDE_date_h__
|
#ifndef INCLUDE_date_h__
|
||||||
#define INCLUDE_date_h__
|
#define INCLUDE_date_h__
|
||||||
|
|
||||||
unsigned long approxidate_careful(const char *date, int *error_ret);
|
#include "git2/types.h"
|
||||||
|
|
||||||
|
int git__date_parse(git_time_t *out, const char *date);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -200,11 +200,11 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char *
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int date_error = 0;
|
int date_error = 0;
|
||||||
time_t timestamp;
|
git_time_t timestamp;
|
||||||
git_buf datebuf = GIT_BUF_INIT;
|
git_buf datebuf = GIT_BUF_INIT;
|
||||||
|
|
||||||
git_buf_put(&datebuf, reflogspec+2, reflogspeclen-3);
|
git_buf_put(&datebuf, reflogspec+2, reflogspeclen-3);
|
||||||
timestamp = approxidate_careful(git_buf_cstr(&datebuf), &date_error);
|
date_error = git__date_parse(×tamp, git_buf_cstr(&datebuf));
|
||||||
|
|
||||||
/* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */
|
/* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */
|
||||||
if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) {
|
if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) {
|
||||||
|
13
tests-clar/date/date.c
Normal file
13
tests-clar/date/date.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "clar_libgit2.h"
|
||||||
|
|
||||||
|
#include "date.h"
|
||||||
|
|
||||||
|
void test_date_date__overflow(void)
|
||||||
|
{
|
||||||
|
git_time_t d2038, d2039;
|
||||||
|
|
||||||
|
/* This fails on a 32-bit machine. */
|
||||||
|
cl_git_pass(git__date_parse(&d2038, "2038-1-1"));
|
||||||
|
cl_git_pass(git__date_parse(&d2039, "2039-1-1"));
|
||||||
|
cl_assert(d2038 < d2039);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user