Commit c51fa40b c51fa40b04c2b6cc8c0ef0693b8b2df89ac3119c by Sergey Poznyakoff

* include/mailutils/property.h: Update

* libproto/include/property0.h (struct property_item): Remove
key, set and next.
(struct _mu_property): Use mu_assoc_t to keep the items.
* mailbox/property.c: Rewrite using mu_assoc_t for storage.

* mailbox/parsedate.y (DATE_SET): Take an additional argument
specifying upper limit for the value. Bail out if val is out of
range. All callers updated.
(SET_.*): Rewrite via __SET_.*
1 parent dbd734c2
2008-01-02 Sergey Poznyakoff <gray@gnu.org.ua>
* include/mailutils/property.h: Update
* libproto/include/property0.h (struct property_item): Remove
key, set and next.
(struct _mu_property): Use mu_assoc_t to keep the items.
* mailbox/property.c: Rewrite using mu_assoc_t for storage.
* mailbox/parsedate.y (DATE_SET): Take an additional argument
specifying upper limit for the value. Bail out if val is out of
range. All callers updated.
(SET_.*): Rewrite via __SET_.*
2007-12-30 Sergey Poznyakoff <gray@gnu.org.ua>
* comsat/comsat.c: New config statement require-tty.
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2005, 2007, 2008
Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2007, 2008 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -29,6 +29,7 @@
#include <mailutils/property.h>
#include <mailutils/monitor.h>
#include <mailutils/assoc.h>
#ifdef __cplusplus
extern "C" {
......@@ -36,15 +37,12 @@ extern "C" {
struct property_item
{
char *key;
char *value;
int set;
struct property_item *next;
};
struct _mu_property
{
struct property_item *items;
mu_assoc_t assoc;
void *owner;
mu_monitor_t lock;
};
......
%{
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2003, 2007 Free Software Foundation, Inc.
Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
......@@ -14,8 +14,7 @@
You should have received a copy of the GNU General Public License
along with GNU Mailutils; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA */
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* A heavily modified version of the well-known public domain getdate.y.
It was originally written by Steven M. Bellovin <smb@research.att.com>
......@@ -127,19 +126,35 @@ struct pd_date
};
#define DATE_INIT(date) memset(&(date), 0, sizeof(date))
#define DATE_SET(date, memb, m, val) \
do { date . memb = val; date.mask |= m; } while (0)
#define SET_SECOND(d,v) DATE_SET(d,second,PD_MASK_SECOND,v)
#define SET_MINUTE(d,v) DATE_SET(d,minute,PD_MASK_MINUTE,v)
#define SET_HOUR(d,v) DATE_SET(d,hour,PD_MASK_HOUR,v)
#define SET_DAY(d,v) DATE_SET(d,day,PD_MASK_DAY,v)
#define SET_MONTH(d,v) DATE_SET(d,month,PD_MASK_MONTH,v)
#define SET_YEAR(d,v) DATE_SET(d,year,PD_MASK_YEAR,v)
#define SET_TZ(d,v) DATE_SET(d,tz,PD_MASK_TZ,v)
#define SET_MERIDIAN(d,v) DATE_SET(d,meridian,PD_MASK_MERIDIAN,v)
#define SET_ORDINAL(d,v) DATE_SET(d,ordinal,PD_MASK_ORDINAL,v)
#define SET_NUMBER(d,v) DATE_SET(d,number,PD_MASK_NUMBER,v)
#define DATE_SET(date, memb, m, val, lim, onerror) \
do \
{ \
if (val < 0 || (lim && val >= lim)) onerror; \
date . memb = val; date.mask |= m; \
} \
while (0)
#define __SET_SECOND(d,v,a) DATE_SET(d,second,PD_MASK_SECOND,v,60,a)
#define __SET_MINUTE(d,v,a) DATE_SET(d,minute,PD_MASK_MINUTE,v,60,a)
#define __SET_HOUR(d,v,a) DATE_SET(d,hour,PD_MASK_HOUR,v,24,a)
#define __SET_DAY(d,v,a) DATE_SET(d,day,PD_MASK_DAY,v,31,a)
#define __SET_MONTH(d,v,a) DATE_SET(d,month,PD_MASK_MONTH,v,12,a)
#define __SET_YEAR(d,v,a) DATE_SET(d,year,PD_MASK_YEAR,v,0,a)
#define __SET_TZ(d,v,a) DATE_SET(d,tz,PD_MASK_TZ,v,0,a)
#define __SET_MERIDIAN(d,v,a) DATE_SET(d,meridian,PD_MASK_MERIDIAN,v,MER24+1,a)
#define __SET_ORDINAL(d,v,a) DATE_SET(d,ordinal,PD_MASK_ORDINAL,v,0,a)
#define __SET_NUMBER(d,v,a) DATE_SET(d,number,PD_MASK_NUMBER,v,0,a)
#define SET_SECOND(d,v) __SET_SECOND(d,v,YYERROR)
#define SET_MINUTE(d,v) __SET_MINUTE(d,v,YYERROR)
#define SET_HOUR(d,v) __SET_HOUR(d,v,YYERROR)
#define SET_DAY(d,v) __SET_DAY(d,v,YYERROR)
#define SET_MONTH(d,v) __SET_MONTH(d,v,YYERROR)
#define SET_YEAR(d,v) __SET_YEAR(d,v,YYERROR)
#define SET_TZ(d,v) __SET_TZ(d,v,YYERROR)
#define SET_MERIDIAN(d,v) __SET_MERIDIAN(d,v,YYERROR)
#define SET_ORDINAL(d,v) __SET_ORDINAL(d,v,YYERROR)
#define SET_NUMBER(d,v) __SET_NUMBER(d,v,YYERROR)
int
pd_date_union (struct pd_date *a, struct pd_date *b)
......@@ -1057,19 +1072,19 @@ mu_parse_date (const char *p, time_t *rettime, const time_t *now)
return -1;
if (!MASK_IS_SET (pd.date.mask, PD_MASK_YEAR))
SET_YEAR (pd.date, tmp->tm_year + TM_YEAR_ORIGIN);
__SET_YEAR (pd.date, tmp->tm_year + TM_YEAR_ORIGIN, return -1);
if (!MASK_IS_SET (pd.date.mask, PD_MASK_MONTH))
SET_MONTH (pd.date, tmp->tm_mon + 1);
__SET_MONTH (pd.date, tmp->tm_mon + 1, return -1);
if (!MASK_IS_SET (pd.date.mask, PD_MASK_DAY))
SET_DAY (pd.date, tmp->tm_mday);
__SET_DAY (pd.date, tmp->tm_mday, return -1);
if (!MASK_IS_SET (pd.date.mask, PD_MASK_HOUR))
SET_HOUR (pd.date, tmp->tm_hour);
__SET_HOUR (pd.date, tmp->tm_hour, return -1);
if (!MASK_IS_SET (pd.date.mask, PD_MASK_MERIDIAN))
SET_MERIDIAN (pd.date, MER24);
__SET_MERIDIAN (pd.date, MER24, return -1);
if (!MASK_IS_SET (pd.date.mask, PD_MASK_MINUTE))
SET_MINUTE (pd.date, tmp->tm_min);
__SET_MINUTE (pd.date, tmp->tm_min, return -1);
if (!MASK_IS_SET (pd.date.mask, PD_MASK_SECOND))
SET_SECOND (pd.date, tmp->tm_sec);
__SET_SECOND (pd.date, tmp->tm_sec, return -1);
tm.tm_year = norm_year (pd.date.year) - TM_YEAR_ORIGIN + pd.rel.year;
tm.tm_mon = pd.date.month - 1 + pd.rel.month;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
......@@ -24,23 +24,35 @@
# include <strings.h>
#endif
#include <mailutils/errno.h>
#include <property0.h>
#include <mailutils/errno.h>
#include <mailutils/assoc.h>
#include <stdlib.h>
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
static int property_find (mu_property_t, const char *, struct property_item **);
static void
prop_free_value (void *data)
{
struct property_item *item = data;
free (item->value);
}
int
mu_property_create (mu_property_t *pp, void *owner)
{
int rc;
mu_property_t prop;
if (pp == NULL)
return MU_ERR_OUT_PTR_NULL;
prop = calloc (1, sizeof *prop);
if (prop == NULL)
return ENOMEM;
rc = mu_assoc_create (&prop->assoc, sizeof (struct property_item), 0);
if (rc)
{
free (prop);
return rc;
}
mu_assoc_set_free (prop->assoc, prop_free_value);
mu_monitor_create (&prop->lock, 0, prop);
prop->owner = owner;
*pp = prop;
......@@ -55,18 +67,9 @@ mu_property_destroy (mu_property_t *pp, void *owner)
mu_property_t prop = *pp;
if (prop->owner == owner)
{
struct property_item *item, *cur;
/* Destroy the list and is properties. */
mu_monitor_wrlock (prop->lock);
for (item = prop->items; item; item = cur)
{
if (item->key)
free (item->key);
if (item->value)
free (item->value);
cur = item->next;
free (item);
}
mu_assoc_destroy (&prop->assoc);
mu_monitor_unlock (prop->lock);
mu_monitor_destroy (&prop->lock, prop);
free (prop);
......@@ -82,167 +85,108 @@ mu_property_get_owner (mu_property_t prop)
}
int
mu_property_set_value (mu_property_t prop, const char *key, const char *value,
mu_property_set_value (mu_property_t prop, const char *key, const char *value,
int overwrite)
{
struct property_item *item;
int status = property_find (prop, key, &item);
if (status != 0)
return status;
int rc;
if (item->set)
if (!prop)
return EINVAL;
rc = mu_assoc_ref_install (prop->assoc, key, (void **)&item);
if (rc == MU_ERR_NOENT)
{
if (overwrite)
{
item->set = 0;
if (item->value)
free (item->value);
item->value = NULL;
if (value)
{
item->set = 1;
item->value = strdup (value);
if (item->value == NULL)
status = ENOMEM;
}
}
item->value = strdup (value);
}
else
else if (overwrite)
{
item->set = 1;
if (item->value)
free (item->value);
if (value)
{
item->value = strdup (value);
if (item->value == NULL)
status = ENOMEM;
}
free (item->value);
item->value = strdup (value);
}
return status;
}
int
mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
size_t buflen, size_t *n)
{
struct property_item *item = NULL;
int status;
size_t len;
status = property_find (prop, key, &item);
if (status != 0)
return status;
len = (item->value) ? strlen (item->value) : 0;
if (buffer && buflen != 0)
else
return 0;
if (!item->value)
{
buflen--;
len = min (buflen, len);
strncpy (buffer, item->value, len)[len] = '\0';
mu_assoc_remove (prop->assoc, key);
return ENOMEM;
}
if (n)
*n = len;
return 0;
}
int
mu_property_sget_value (mu_property_t prop, const char *key,
const char **buffer)
{
struct property_item *item = NULL;
int status;
struct property_item *item;
status = property_find (prop, key, &item);
if (status == 0)
if (!prop)
return EINVAL;
item = mu_assoc_ref (prop->assoc, key);
if (item == NULL)
return MU_ERR_NOENT;
if (buffer)
*buffer = item->value;
return status;
return 0;
}
int
mu_property_aget_value (mu_property_t prop, const char *key,
char **buffer)
{
struct property_item *item = NULL;
int status;
status = property_find (prop, key, &item);
if (status == 0)
const char *value;
int rc = mu_property_sget_value (prop, key, &value);
if (rc == 0)
{
*buffer = strdup (item->value);
if (!*buffer)
status = ENOMEM;
if ((*buffer = strdup (value)) == NULL)
return ENOMEM;
}
return status;
return rc;
}
int
mu_property_set (mu_property_t prop, const char *k)
mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
size_t buflen, size_t *n)
{
struct property_item *item = NULL;
int status = property_find (prop, k, &item);
if (status != 0)
return status;
item->set = 1;
return 0;
size_t len = 0;
const char *value;
int rc = mu_property_sget_value (prop, key, &value);
if (rc == 0)
{
len = strlen (value) + 1;
if (buffer && buflen)
{
if (buflen < len)
len = buflen;
len--;
memcpy (buffer, value, len);
buffer[len] = 0;
}
}
if (n)
*n = len;
return rc;
}
int
mu_property_unset (mu_property_t prop, const char *k)
mu_property_is_set (mu_property_t prop, const char *key)
{
struct property_item *item = NULL;
int status = property_find (prop, k, &item);
if (status != 0)
return status;
item->set = 0;
return 0;
struct property_item *item = mu_assoc_ref (prop->assoc, key);
return (item == NULL) ? 0 : 1;
}
int
mu_property_is_set (mu_property_t prop, const char *k)
mu_property_set (mu_property_t prop, const char *key)
{
struct property_item *item = NULL;
int status = property_find (prop, k, &item);
if (status != 0)
return 0;
return item->set;
return mu_property_set_value (prop, key, "", 1);
}
static int
property_find (mu_property_t prop, const char *key, struct property_item **item)
int
mu_property_unset (mu_property_t prop, const char *key)
{
size_t len = 0;
struct property_item *cur = NULL;
if (prop == NULL || key == NULL)
if (!prop)
return EINVAL;
mu_monitor_wrlock (prop->lock);
for (len = strlen (key), cur = prop->items; cur; cur = cur->next)
{
if (strlen (cur->key) == len && !strcmp (key, cur->key))
break;
}
if (cur == NULL)
{
cur = calloc (1, sizeof *cur);
if (cur == NULL)
{
mu_monitor_unlock (prop->lock);
return ENOMEM;
}
cur->key = strdup (key);
if (cur->key == NULL)
{
mu_monitor_unlock (prop->lock);
free (cur);
return ENOMEM;
}
cur->next = prop->items;
prop->items = cur;
}
*item = cur;
mu_monitor_unlock (prop->lock);
return 0;
return mu_assoc_remove (prop->assoc, key);
}
......