Revision bab748371a104c58058c0eff9f4073b710ce0355 authored by Jeff King on 20 June 2016, 21:14:14 UTC, committed by Junio C Hamano on 20 June 2016, 22:08:07 UTC
When we want to know the local timezone offset at a given
timestamp, we compute it by asking for localtime() at the
given time, and comparing the offset to GMT at that time.
However, there's some juggling between time_t and "struct
tm" which happens, which involves calling our own
tm_to_time_t().

If that function returns an error (e.g., because it only
handles dates up to the year 2099), it returns "-1", which
we treat as a time_t, and is clearly bogus, leading to
bizarre timestamps (that seem to always adjust the time back
to (time_t)(uint32_t)-1, in the year 2106).

It's not a good idea for local_tzoffset() to simply die
here; it would make it hard to run "git log" on a repository
with funny timestamps. Instead, let's just treat such cases
as "zero offset".

Reported-by: Norbert Kiesel <nkiesel@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 36d6792
Raw File
hashmap.h
#ifndef HASHMAP_H
#define HASHMAP_H

/*
 * Generic implementation of hash-based key-value mappings.
 * See Documentation/technical/api-hashmap.txt.
 */

/* FNV-1 functions */

extern unsigned int strhash(const char *buf);
extern unsigned int strihash(const char *buf);
extern unsigned int memhash(const void *buf, size_t len);
extern unsigned int memihash(const void *buf, size_t len);

static inline unsigned int sha1hash(const unsigned char *sha1)
{
	/*
	 * Equivalent to 'return *(unsigned int *)sha1;', but safe on
	 * platforms that don't support unaligned reads.
	 */
	unsigned int hash;
	memcpy(&hash, sha1, sizeof(hash));
	return hash;
}

/* data structures */

struct hashmap_entry {
	struct hashmap_entry *next;
	unsigned int hash;
};

typedef int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key,
		const void *keydata);

struct hashmap {
	struct hashmap_entry **table;
	hashmap_cmp_fn cmpfn;
	unsigned int size, tablesize, grow_at, shrink_at;
};

struct hashmap_iter {
	struct hashmap *map;
	struct hashmap_entry *next;
	unsigned int tablepos;
};

/* hashmap functions */

extern void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
		size_t initial_size);
extern void hashmap_free(struct hashmap *map, int free_entries);

/* hashmap_entry functions */

static inline void hashmap_entry_init(void *entry, unsigned int hash)
{
	struct hashmap_entry *e = entry;
	e->hash = hash;
	e->next = NULL;
}
extern void *hashmap_get(const struct hashmap *map, const void *key,
		const void *keydata);
extern void *hashmap_get_next(const struct hashmap *map, const void *entry);
extern void hashmap_add(struct hashmap *map, void *entry);
extern void *hashmap_put(struct hashmap *map, void *entry);
extern void *hashmap_remove(struct hashmap *map, const void *key,
		const void *keydata);

static inline void *hashmap_get_from_hash(const struct hashmap *map,
		unsigned int hash, const void *keydata)
{
	struct hashmap_entry key;
	hashmap_entry_init(&key, hash);
	return hashmap_get(map, &key, keydata);
}

/* hashmap_iter functions */

extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);
extern void *hashmap_iter_next(struct hashmap_iter *iter);
static inline void *hashmap_iter_first(struct hashmap *map,
		struct hashmap_iter *iter)
{
	hashmap_iter_init(map, iter);
	return hashmap_iter_next(iter);
}

/* string interning */

extern const void *memintern(const void *data, size_t len);
static inline const char *strintern(const char *string)
{
	return memintern(string, strlen(string));
}

#endif
back to top