0
 "<    /*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Derick Rethans
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "timelib.h"
#include <ctype.h>
#include <math.h>

#define TIMELIB_TIME_FREE(m) 	\
	if (m) {		\
		timelib_free(m);	\
		m = NULL;	\
	}			\

#define TIMELIB_LLABS(y) (y < 0 ? (y * -1) : y)

#define HOUR(a) (int)(a * 60)

timelib_time* timelib_time_ctor(void)
{
	timelib_time *t;
	t = timelib_calloc(1, sizeof(timelib_time));

	return t;
}

timelib_rel_time* timelib_rel_time_ctor(void)
{
	timelib_rel_time *t;
	t = timelib_calloc(1, sizeof(timelib_rel_time));

	return t;
}

timelib_time* timelib_time_clone(timelib_time *orig)
{
	timelib_time *tmp = timelib_time_ctor();
	memcpy(tmp, orig, sizeof(timelib_time));
	if (orig->tz_abbr) {
		tmp->tz_abbr = timelib_strdup(orig->tz_abbr);
	}
	if (orig->tz_info) {
		tmp->tz_info = orig->tz_info;
	}
	return tmp;
}

int timelib_time_compare(timelib_time *t1, timelib_time *t2)
{
	if (t1->sse == t2->sse) {
		if (t1->f == t2->f) {
			return 0;
		}

		if (t1->sse < 0) {
			return (t1->f < t2->f) ? 1 : -1;
		} else {
			return (t1->f < t2->f) ? -1 : 1;
		}
	}

	return (t1->sse < t2->sse) ? -1 : 1;
}

timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel)
{
	timelib_rel_time *tmp = timelib_rel_time_ctor();
	memcpy(tmp, rel, sizeof(timelib_rel_time));
	return tmp;
}

void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr)
{
	unsigned int i;
	size_t tz_abbr_len = strlen(tz_abbr);

	TIMELIB_TIME_FREE(tm->tz_abbr);
	tm->tz_abbr = timelib_strdup(tz_abbr);
	for (i = 0; i < tz_abbr_len; i++) {
		tm->tz_abbr[i] = toupper(tz_abbr[i]);
	}
}

void timelib_time_dtor(timelib_time* t)
{
	TIMELIB_TIME_FREE(t->tz_abbr);
	TIMELIB_TIME_FREE(t);
}

void timelib_rel_time_dtor(timelib_rel_time* t)
{
	TIMELIB_TIME_FREE(t);
}

timelib_time_offset* timelib_time_offset_ctor(void)
{
	timelib_time_offset *t;
	t = timelib_calloc(1, sizeof(timelib_time_offset));

	return t;
}

void timelib_time_offset_dtor(timelib_time_offset* t)
{
	TIMELIB_TIME_FREE(t->abbr);
	TIMELIB_TIME_FREE(t);
}

timelib_tzinfo* timelib_tzinfo_ctor(char *name)
{
	timelib_tzinfo *t;
	t = timelib_calloc(1, sizeof(timelib_tzinfo));
	t->name = timelib_strdup(name);

	return t;
}

timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
{
	timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
	tmp->bit32.ttisgmtcnt = tz->bit32.ttisgmtcnt;
	tmp->bit32.ttisstdcnt = tz->bit32.ttisstdcnt;
	tmp->bit32.leapcnt = tz->bit32.leapcnt;
	tmp->bit32.timecnt = tz->bit32.timecnt;
	tmp->bit32.typecnt = tz->bit32.typecnt;
	tmp->bit32.charcnt = tz->bit32.charcnt;

	tmp->trans = (int32_t *) timelib_malloc(tz->bit32.timecnt * sizeof(int32_t));
	tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit32.timecnt * sizeof(unsigned char));
	memcpy(tmp->trans, tz->trans, tz->bit32.timecnt * sizeof(int32_t));
	memcpy(tmp->trans_idx, tz->trans_idx, tz->bit32.timecnt * sizeof(unsigned char));

	tmp->type = (ttinfo*) timelib_malloc(tz->bit32.typecnt * sizeof(struct ttinfo));
	memcpy(tmp->type, tz->type, tz->bit32.typecnt *