You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
capi4yaps/util.c

596 lines
10 KiB

/* -*- mode: c; mode: fold -*- */
# include "config.h"
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <ctype.h>
# include <string.h>
# include <time.h>
# include "pager.h"
/*{{{ utility functions */
char *
skip (char *str)
{
while (*str && (! isspace (*str)))
++str;
if (*str) {
*str++ = '\0';
while (isspace (*str))
++str;
}
return str;
}
char *
skipch (char *str, char ch)
{
while (*str && (*str != ch))
++str;
if (*str) {
*str++ = '\0';
while (isspace (*str))
++str;
}
return str;
}
char *
getline (FILE *fp, Bool cont)
{
char *buf;
int size;
char *ret;
int len;
char *ptr;
size = 256;
if (! (buf = malloc (size + 2)))
return NULL;
len = 0;
while (ret = fgets (buf + len, size - len - 2, fp)) {
if (ptr = strchr (buf + len, '\n')) {
*ptr = '\0';
len += strlen (buf + len);
if (! cont)
break;
if (len && (buf[len - 1] == '\\')) {
--len;
buf[len] = '\0';
} else
break;
} else
len += strlen (buf + len);
if (len + 64 >= size) {
size += size;
if (! (buf = Realloc (buf, size + 2)))
break;
}
}
if ((! ret) && buf) {
free (buf);
buf = NULL;
}
return len || ret ? buf : NULL;
}
int
verbose_out (char *fmt, ...)
{
va_list par;
va_start (par, fmt);
vfprintf (stdout, fmt, par);
va_end (par);
return 0;
}
/*}}}*/
/*{{{ string_t handling */
string_t *
snewc (char *str)
{
string_t *s;
if (s = (string_t *) malloc (sizeof (string_t))) {
s -> str = NULL;
if (str) {
s -> len = strlen (str);
s -> size = s -> len + 1;
if (s -> str = (char_t *) malloc (sizeof (char_t) * s -> size))
memcpy (s -> str, str, s -> len);
else {
free (s);
s = NULL;
}
} else {
s -> len = 0;
s -> size = 0;
}
}
return s;
}
string_t *
snew (char_t *str, int len)
{
string_t *s;
if (s = (string_t *) malloc (sizeof (string_t))) {
s -> str = NULL;
s -> len = 0;
s -> size = 0;
if (len > 0)
if (s -> str = (char_t *) malloc (sizeof (char_t) * (len + 1))) {
s -> size = len + 1;
if (str) {
s -> len = len;
memcpy (s -> str, str, len);
} else
s -> len = 0;
} else {
free (s);
s = NULL;
}
}
return s;
}
Bool
sexpand (string_t *s, int nsize)
{
if (s && (nsize + 2 > s -> size)) {
s -> size = nsize + 2;
if (! (s -> str = (char_t *) Realloc (s -> str, sizeof (char_t) * s -> size))) {
s -> size = 0;
s -> len = 0;
return False;
}
}
return True;
}
Bool
scopy (string_t *dst, string_t *src)
{
if (dst && src && sexpand (dst, src -> len + 1)) {
if (src -> str) {
memcpy (dst -> str, src -> str, src -> len);
dst -> len = src -> len;
} else
dst -> len = 0;
return True;
}
return False;
}
Bool
scat (string_t *dst, string_t *src)
{
if (dst && src && sexpand (dst, dst -> len + src -> len + 1)) {
if (src -> str) {
memcpy (dst -> str + dst -> len, src -> str, src -> len);
dst -> len += src -> len;
}
return True;
}
return False;
}
static Bool
dostr (string_t *dst, char *src, Bool (*func) (string_t *, string_t *))
{
Bool ret;
string_t *rsrc;
ret = False;
if (dst)
if (src) {
if (rsrc = snewc (src)) {
ret = (*func) (dst, rsrc);
sfree (rsrc);
}
} else
ret = True;
return ret;
}
Bool
scopyc (string_t *dst, char *src)
{
return dostr (dst, src, scopy);
}
Bool
scatc (string_t *dst, char *src)
{
return dostr (dst, src, scat);
}
string_t *
scut (string_t *str, int start, int len)
{
string_t *res;
if (len < 0)
len = str ? str -> len - start : 0;
if (res = snew (NULL, len + 1)) {
if (str -> len > start) {
if (str -> len - start < len)
len = str -> len - start;
} else
len = 0;
if (len > 0)
memcpy (res -> str, str -> str + start, len);
res -> len = len;
}
return res;
}
void
sdel (string_t *str, int start, int len)
{
int size;
if (str -> len > start) {
if (str -> len - start < len)
len = str -> len - start;
} else
len = 0;
if (len > 0) {
size = str -> len - (start + len);
if (size > 0)
memcpy (str -> str + start, str -> str + start + len, str -> len - (start + len));
str -> len -= len;
}
}
Bool
sput (string_t *str, string_t *ins, int pos, int len)
{
if ((len < 0) || (len > ins -> len))
len = ins -> len;
if (len + pos >= str -> size)
if (! sexpand (str, len + pos + 1))
return False;
memcpy (str -> str + pos, ins -> str, len);
if (str -> len < len + pos)
str -> len = len + pos;
return True;
}
Bool
sputc (string_t *str, char *ins, int pos, int len)
{
Bool ret;
string_t *rins;
ret = False;
if (str && ins && (rins = snewc (ins))) {
ret = sput (str, rins, pos, len);
sfree (rins);
}
return ret;
}
char *
sextract (string_t *s)
{
char *ret;
ret = NULL;
if (s)
if (ret = malloc (s -> len + 1))
if (s -> str) {
memcpy (ret, s -> str, s -> len);
ret[s -> len] = '\0';
} else
ret[0] = '\0';
return ret;
}
char *
schar (string_t *s)
{
if (s) {
if (s -> len + 1>= s -> size)
sexpand (s, s -> len + 2);
if (s -> len + 1 < s -> size) {
s -> str[s -> len] = '\0';
return (char *) s -> str;
}
}
return NULL;
}
void *
sfree (string_t *s)
{
if (s) {
if (s -> str)
free (s -> str);
free (s);
}
return NULL;
}
void
srelease (string_t *s)
{
if (s -> size + 1 > s -> len) {
s -> size = s -> len + 1;
if (! (s -> str = (char_t *) Realloc (s -> str, sizeof (char_t) * (s -> size + 2)))) {
s -> size = 0;
s -> len = 0;
}
}
}
Bool
siscntrl (string_t *s, int pos)
{
return (s && (pos >= 0) && (pos < s -> len) && iscntrl (s -> str[pos])) ? True : False;
}
Bool
sisspace (string_t *s, int pos)
{
return (s && (pos >= 0) && (pos < s -> len) && isspace (s -> str[pos])) ? True : False;
}
Bool
sisdigit (string_t *s, int pos)
{
return (s && (pos >= 0) && (pos < s -> len) && isdigit (s -> str[pos])) ? True : False;
}
int
stoi (string_t *s)
{
int ret;
ret = 0;
if (s && s -> str) {
s -> str[s -> len] = '\0';
ret = atoi ((char *) s -> str);
}
return ret;
}
/*}}}*/
/*{{{ date_t handling */
# if ! HAVE_MEMSET && ! HAVE_BZERO
static void
dozero (void *p, int len)
{
unsigned char *ptr = (char *) p;
while (len-- > 0)
*ptr++ = 0;
}
# endif /* ! HAVE_MEMSET && ! HAVE_BZERO */
date_t *
dat_free (date_t *d)
{
if (d)
free (d);
return NULL;
}
date_t *
dat_parse (char *str)
{
date_t *d;
time_t tim;
struct tm *tt;
struct tm tm;
Bool add;
char *ptr, *sav;
char *p1, *p2;
int mode;
int n, val;
char sep;
date_t tmp;
d = NULL;
if ((! str) || (str = strdup (str))) {
if (d = (date_t *) malloc (sizeof (date_t))) {
time (& tim);
if (tt = localtime (& tim)) {
d -> day = tt -> tm_mday;
d -> mon = tt -> tm_mon + 1;
d -> year = tt -> tm_year + 1900;
d -> hour = tt -> tm_hour;
d -> min = tt -> tm_min;
d -> sec = tt -> tm_sec;
} else {
d -> day = 1;
d -> mon = 1;
d -> year = 1970;
d -> hour = 0;
d -> min = 0;
d -> sec = 0;
}
if (str && strcmp (str, "now")) {
if (*str == '+') {
add = True;
ptr = str + 1;
} else {
add = False;
ptr = str;
}
tmp.day = -1;
tmp.mon = -1;
tmp.year = -1;
tmp.hour = -1;
tmp.min = -1;
tmp.sec = -1;
while (*ptr) {
sav = ptr;
ptr = skip (ptr);
if (strchr (sav, '.')) {
sep = '.';
mode = 1;
} else if (strchr (sav, '/')) {
sep = '/';
mode = 2;
} else if (strchr (sav, ':')) {
sep = ':';
mode = 3;
} else {
sep = '\0';
mode = 0;
}
for (p1 = sav, n = 0; *p1; ++n) {
p2 = p1;
p1 = skipch (p1, sep);
val = atoi (p2);
switch (mode) {
case 0:
tmp.sec = 0;
if (val < 30) {
tmp.hour = val;
tmp.min = 0;
} else {
tmp.hour = val / 60;
tmp.min = val % 60;
}
break;
case 1:
if (n == 0)
tmp.day = val;
else if (n == 1)
tmp.mon = val;
else if (n == 2) {
if ((! add) && (val < 1900))
val += 1900;
tmp.year = val;
}
break;
case 2:
if (n == 0)
tmp.mon = val;
else if (n == 1)
tmp.day = val;
else if (n == 2) {
if ((! add) && (val < 1900))
val += 1900;
tmp.year = val;
}
break;
case 3:
if (n == 0) {
tmp.hour = val;
tmp.min = 0;
tmp.sec = 0;
} else if (n == 1)
tmp.min = val;
else if (n == 2)
tmp.sec = val;
break;
}
}
}
if (add) {
if (tmp.day != -1)
d -> day += tmp.day;
if (tmp.mon != -1)
d -> mon += tmp.mon;
if (tmp.year != -1)
d -> year += tmp.year;
if (tmp.hour != -1)
d -> hour += tmp.hour;
if (tmp.min != -1)
d -> min += tmp.min;
if (tmp.sec != -1)
d -> sec += tmp.sec;
} else {
if (tmp.day != -1)
d -> day = tmp.day;
if (tmp.mon != -1)
d -> mon = tmp.mon;
if (tmp.year != -1)
d -> year = tmp.year;
if (tmp.hour != -1)
d -> hour = tmp.hour;
if (tmp.min != -1)
d -> min = tmp.min;
if (tmp.sec != -1)
d -> sec = tmp.sec;
}
# if HAVE_MEMSET
memset (& tm, 0, sizeof (tm));
# elif HAVE_BZERO
bzero (& tm, sizeof (tm));
# else
dozero (& tm, sizeof (tm));
# endif /* ! HAVE_MEMSET && ! HAVE_BZERO */
tm.tm_mday = d -> day;
tm.tm_mon = d -> mon - 1;
tm.tm_year = d -> year - 1900;
tm.tm_hour = d -> hour;
tm.tm_min = d -> min;
tm.tm_sec = d -> sec;
tm.tm_isdst = tt -> tm_isdst;
if (mktime (& tm) == (time_t) -1)
d = dat_free (d);
else {
d -> day = tm.tm_mday;
d -> mon = tm.tm_mon + 1;
d -> year = tm.tm_year + 1900;
d -> hour = tm.tm_hour;
d -> min = tm.tm_min;
d -> sec = tm.tm_sec;
}
}
}
if (str)
free (str);
}
return d;
}
int
dat_diff (date_t *d1, date_t *d2)
{
int v1, v2;
if (d1)
v1 = (((((d1 -> year * 12 + d1 -> mon) * 31 + d1 -> day) * 24 + d1 -> hour) * 60 + d1 -> min) * 60 + d1 -> sec);
else
v1 = 0;
if (d2)
v2 = (((((d2 -> year * 12 + d2 -> mon) * 31 + d2 -> day) * 24 + d2 -> hour) * 60 + d2 -> min) * 60 + d2 -> sec);
else
v2 = 0;
return v2 - v1;
}
void
dat_clear (date_t *d)
{
d -> day = 0;
d -> mon = 0;
d -> year = 0;
d -> hour = 0;
d -> min = 0;
d -> sec = 0;
}
void
dat_localtime (date_t *d)
{
time_t tim;
struct tm *tt;
time (& tim);
if (tt = localtime (& tim)) {
d -> day = tt -> tm_mday;
d -> mon = tt -> tm_mon + 1;
d -> year = tt -> tm_year + 1900;
d -> hour = tt -> tm_hour;
d -> min = tt -> tm_min;
d -> sec = tt -> tm_sec;
} else
dat_clear (d);
}
/*}}}*/