Commit 77d2867d 77d2867d07ba9d1c5b8b0af1ba8b0543cf57f384 by Sergey Poznyakoff

Rewrite property support.

* configure.ac: Add libmailutils/property/Makefile to config files.

* include/mailutils/property.h (mu_property_create)
(mu_property_destroy): Change signature.
(mu_property_get_owner): Remove.
(mu_property_create_init)
(mu_property_set_init, mu_property_set_init_data)
(mu_property_ref, mu_property_unref)
(mu_property_save): New protos.
(mu_property_get_iterator)
(mu_assoc_property_init): New protos.
* include/mailutils/sys/property.h (property_item): Remove definition.
(MU_PROP_INIT, MU_PROP_FILL, MU_PROP_MODIFIED): New flags.
(_mu_property): Rewrite from scratch.
(_mu_property_check): New proto.

* libmailutils/property/Makefile.am: New file.
* libmailutils/property/assocprop.c: New file.
* libmailutils/property/create.c: New file.
* libmailutils/property/propget.c: New file.
* libmailutils/property/propitr.c: New file.
* libmailutils/property/propset.c: New file.

* libmailutils/Makefile.am (SUBDIRS): Add property.
(libmailutils_la_LIBADD): Add property/libproperty.la.

* libmailutils/base/property.c: Remove.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Remove property.c

* libmailutils/base/assoc.c (first): Avoid coredumping on empty
hash table.

* include/mailutils/folder.h (mu_folder_set_property)
(mu_folder_get_property): New protos.
* include/mailutils/sys/folder.h (_mu_folder) <property>
<_get_property>: New members.
* libmailutils/mailbox/folder.c (mu_folder_destroy): Destroy the
property.
(mu_folder_get_property)
(mu_folder_set_property): New functions.

* include/mailutils/mailbox.h (mu_mailbox_set_property): New proto.
* libmailutils/mailbox/mailbox.c (mu_mailbox_set_property): New function.
(mu_mailbox_get_property): Use _get_property method.

* include/mailutils/mailer.h (mu_mailer_set_property): New proto.
* include/mailutils/sys/mailer.h (_mu_mailer) <_get_property>: New member.
* libmailutils/mailer/mailer.c (mu_mailer_set_property): New function.
(mu_mailer_get_property): Use _get_property method.

* include/mailutils/iterator.h (mu_iterator_set_dataptr): New proto.
* include/mailutils/sys/iterator.h (_mu_iterator) <dataptr>: New method.
* libmailutils/base/iterator.c (mu_iterator_set_dataptr): New function.
(mu_iterator_current): Rewrite as a wrapper around mu_iterator_current_kv.
(mu_iterator_current_kv): Use dataptr method (if defined) to extract the
data pointer.

* libmailutils/tests/prop.c: New file.
* libmailutils/tests/prop.at: New file.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add prop.
(TESTSUITE_AT): Add prop.at.
* libmailutils/tests/testsuite.at: Include prop.at.
1 parent 33a277e9
...@@ -1389,6 +1389,7 @@ AC_CONFIG_FILES([ ...@@ -1389,6 +1389,7 @@ AC_CONFIG_FILES([
1389 libmailutils/mailbox/Makefile 1389 libmailutils/mailbox/Makefile
1390 libmailutils/mailer/Makefile 1390 libmailutils/mailer/Makefile
1391 libmailutils/mime/Makefile 1391 libmailutils/mime/Makefile
1392 libmailutils/property/Makefile
1392 libmailutils/server/Makefile 1393 libmailutils/server/Makefile
1393 libmailutils/string/Makefile 1394 libmailutils/string/Makefile
1394 libmailutils/stream/Makefile 1395 libmailutils/stream/Makefile
......
...@@ -89,6 +89,10 @@ extern int mu_folder_set_authority (mu_folder_t, mu_authority_t); ...@@ -89,6 +89,10 @@ extern int mu_folder_set_authority (mu_folder_t, mu_authority_t);
89 extern int mu_folder_get_url (mu_folder_t, mu_url_t *); 89 extern int mu_folder_get_url (mu_folder_t, mu_url_t *);
90 extern int mu_folder_set_url (mu_folder_t, mu_url_t); 90 extern int mu_folder_set_url (mu_folder_t, mu_url_t);
91 91
92 /* Property */
93 extern int mu_folder_set_property (mu_folder_t, mu_property_t);
94 extern int mu_folder_get_property (mu_folder_t, mu_property_t *);
95
92 /* FIXME: not implemented */ 96 /* FIXME: not implemented */
93 extern int mu_folder_decrement (mu_folder_t); 97 extern int mu_folder_decrement (mu_folder_t);
94 98
......
...@@ -72,6 +72,8 @@ extern int mu_iterator_set_itrctl (mu_iterator_t itr, ...@@ -72,6 +72,8 @@ extern int mu_iterator_set_itrctl (mu_iterator_t itr,
72 int (*itrctl) (void *, 72 int (*itrctl) (void *,
73 enum mu_itrctl_req, 73 enum mu_itrctl_req,
74 void *)); 74 void *));
75 extern int mu_iterator_set_dataptr (mu_iterator_t itr,
76 void *(*dataptr) (void *));
75 #ifdef __cplusplus 77 #ifdef __cplusplus
76 } 78 }
77 #endif 79 #endif
......
...@@ -97,6 +97,7 @@ extern int mu_mailbox_set_locker (mu_mailbox_t, mu_locker_t); ...@@ -97,6 +97,7 @@ extern int mu_mailbox_set_locker (mu_mailbox_t, mu_locker_t);
97 /* Property. */ 97 /* Property. */
98 extern int mu_mailbox_get_flags (mu_mailbox_t, int *); 98 extern int mu_mailbox_get_flags (mu_mailbox_t, int *);
99 extern int mu_mailbox_get_property (mu_mailbox_t, mu_property_t *); 99 extern int mu_mailbox_get_property (mu_mailbox_t, mu_property_t *);
100 extern int mu_mailbox_set_property (mu_mailbox_t, mu_property_t);
100 101
101 /* URL. */ 102 /* URL. */
102 extern int mu_mailbox_get_url (mu_mailbox_t, mu_url_t *); 103 extern int mu_mailbox_get_url (mu_mailbox_t, mu_url_t *);
......
...@@ -50,6 +50,8 @@ extern int mu_mailer_get_url_default (const char** url); ...@@ -50,6 +50,8 @@ extern int mu_mailer_get_url_default (const char** url);
50 50
51 /* Accessor functions. */ 51 /* Accessor functions. */
52 extern int mu_mailer_get_property (mu_mailer_t, mu_property_t *); 52 extern int mu_mailer_get_property (mu_mailer_t, mu_property_t *);
53 int mu_mailer_set_property (mu_mailer_t, mu_property_t);
54
53 extern int mu_mailer_get_stream (mu_mailer_t, mu_stream_t *) 55 extern int mu_mailer_get_stream (mu_mailer_t, mu_stream_t *)
54 __attribute__ ((deprecated)); 56 __attribute__ ((deprecated));
55 extern int mu_mailer_get_streamref (mu_mailer_t, mu_stream_t *); 57 extern int mu_mailer_get_streamref (mu_mailer_t, mu_stream_t *);
......
...@@ -27,23 +27,36 @@ ...@@ -27,23 +27,36 @@
27 extern "C" { 27 extern "C" {
28 #endif 28 #endif
29 29
30 extern int mu_property_create (mu_property_t *, void *); 30 int mu_property_create (mu_property_t *);
31 extern void mu_property_destroy (mu_property_t *, void *); 31 int mu_property_create_init (mu_property_t *pprop,
32 extern void *mu_property_get_owner (mu_property_t); 32 int (*initfun) (mu_property_t), void *initdata);
33 33 int mu_property_set_init (mu_property_t prop,
34 extern int mu_property_set_value (mu_property_t, const char *, const char *, int); 34 int (*initfun) (mu_property_t), void *initdata);
35 extern int mu_property_get_value (mu_property_t, const char *, char *, size_t, 35 int mu_property_set_init_data (mu_property_t prop, void *data,
36 size_t *); 36 void **old_data);
37 extern int mu_property_sget_value (mu_property_t prop, const char *key, 37 void mu_property_destroy (mu_property_t *pprop);
38 const char **buffer); 38
39 extern int mu_property_aget_value (mu_property_t prop, const char *key, 39 void mu_property_ref (mu_property_t prop);
40 char **buffer); 40 void mu_property_unref (mu_property_t prop);
41 int mu_property_save (mu_property_t prop);
42 int mu_property_set_value (mu_property_t, const char *, const char *, int);
43 int mu_property_get_value (mu_property_t, const char *, char *, size_t,
44 size_t *);
45 int mu_property_sget_value (mu_property_t prop, const char *key,
46 const char **buffer);
47 int mu_property_aget_value (mu_property_t prop, const char *key,
48 char **buffer);
41 49
42 /* Helper functions. */ 50 /* Helper functions. */
43 extern int mu_property_set (mu_property_t, const char *); 51 int mu_property_set (mu_property_t, const char *);
44 extern int mu_property_unset (mu_property_t, const char *); 52 int mu_property_unset (mu_property_t, const char *);
45 extern int mu_property_is_set (mu_property_t, const char *); 53 int mu_property_is_set (mu_property_t, const char *);
46 54
55 int mu_property_get_iterator (mu_property_t, mu_iterator_t *itr);
56
57 /* Implementation init functions */
58 int mu_assoc_property_init (mu_property_t);
59
47 #ifdef __cplusplus 60 #ifdef __cplusplus
48 } 61 }
49 #endif 62 #endif
......
...@@ -38,6 +38,7 @@ struct _mu_folder ...@@ -38,6 +38,7 @@ struct _mu_folder
38 mu_authority_t authority; 38 mu_authority_t authority;
39 mu_observable_t observable; 39 mu_observable_t observable;
40 mu_debug_t debug; 40 mu_debug_t debug;
41 mu_property_t property;
41 mu_stream_t stream; 42 mu_stream_t stream;
42 mu_monitor_t monitor; 43 mu_monitor_t monitor;
43 mu_url_t url; 44 mu_url_t url;
...@@ -63,6 +64,7 @@ struct _mu_folder ...@@ -63,6 +64,7 @@ struct _mu_folder
63 int (*_rename) (mu_folder_t, const char *, const char *); 64 int (*_rename) (mu_folder_t, const char *, const char *);
64 int (*_subscribe) (mu_folder_t, const char *); 65 int (*_subscribe) (mu_folder_t, const char *);
65 int (*_unsubscribe) (mu_folder_t, const char *); 66 int (*_unsubscribe) (mu_folder_t, const char *);
67 int (*_get_property)(mu_folder_t, mu_property_t *);
66 }; 68 };
67 69
68 # ifdef __cplusplus 70 # ifdef __cplusplus
......
...@@ -39,6 +39,7 @@ struct _mu_iterator ...@@ -39,6 +39,7 @@ struct _mu_iterator
39 int (*curitem_p) (void *owner, void *item); 39 int (*curitem_p) (void *owner, void *item);
40 int (*finished_p) (void *owner); 40 int (*finished_p) (void *owner);
41 int (*itrctl) (void *owner, enum mu_itrctl_req req, void *arg); 41 int (*itrctl) (void *owner, enum mu_itrctl_req req, void *arg);
42 void *(*dataptr) (void *);
42 }; 43 };
43 44
44 # ifdef __cplusplus 45 # ifdef __cplusplus
......
...@@ -51,6 +51,7 @@ struct _mu_mailer ...@@ -51,6 +51,7 @@ struct _mu_mailer
51 int (*_open) (mu_mailer_t, int flags); 51 int (*_open) (mu_mailer_t, int flags);
52 int (*_close) (mu_mailer_t); 52 int (*_close) (mu_mailer_t);
53 int (*_send_message) (mu_mailer_t, mu_message_t, mu_address_t, mu_address_t); 53 int (*_send_message) (mu_mailer_t, mu_message_t, mu_address_t, mu_address_t);
54 int (*_get_property) (mu_mailer_t, mu_property_t *);
54 }; 55 };
55 56
56 int _mu_mailer_mailbox_init (mu_mailbox_t mailbox); 57 int _mu_mailer_mailbox_init (mu_mailbox_t mailbox);
......
...@@ -31,18 +31,41 @@ ...@@ -31,18 +31,41 @@
31 extern "C" { 31 extern "C" {
32 # endif 32 # endif
33 33
34 struct property_item 34 #define MU_PROP_INIT 0x01
35 { 35 #define MU_PROP_FILL 0x02
36 char *value; 36 #define MU_PROP_MODIFIED 0x04
37 }; 37
38
39 struct _mu_property 38 struct _mu_property
40 { 39 {
41 mu_assoc_t assoc; 40 size_t _prop_ref_count; /* Reference counter */
42 void *owner; 41 int _prop_flags; /* Flags describing the state of this object */
43 mu_monitor_t lock; 42 void *_prop_data; /* Implementation-specific data */
43 void *_prop_init_data; /* Initialization data */
44
45 /* Methods */
46
47 /* Delayed initialization. This function must allocate _prop_data,
48 if needed, and initialize the rest of _prop_* methods. */
49 int (*_prop_init) (struct _mu_property *);
50 /* Free memory allocated in _prop_data */
51 void (*_prop_done) (struct _mu_property *);
52 /* Fill in the properties from an external storage */
53 int (*_prop_fill) (struct _mu_property *);
54 /* Write the properties to an external storage */
55 int (*_prop_save) (struct _mu_property *);
56 /* Get the value of the property named in the 2nd argument. If 3rd
57 arg is NULL, _prop_getval tests whether the given property is set. */
58 int (*_prop_getval) (struct _mu_property *, const char *, const char **);
59 /* Set the property */
60 int (*_prop_setval) (struct _mu_property *, const char *, const char *, int);
61 /* Unset (delete) the property */
62 int (*_prop_unset) (struct _mu_property *, const char *);
63 /* Return iterator for this property object */
64 int (*_prop_getitr) (struct _mu_property *, mu_iterator_t *);
44 }; 65 };
45 66
67 int _mu_property_check (mu_property_t prop);
68
46 # ifdef __cplusplus 69 # ifdef __cplusplus
47 } 70 }
48 # endif 71 # endif
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 # <http://www.gnu.org/licenses/>. 17 # <http://www.gnu.org/licenses/>.
18 18
19 SUBDIRS = auth base address cfg diag filter mailbox mailer mime\ 19 SUBDIRS = auth base address cfg diag filter mailbox mailer mime\
20 server string stream url . tests 20 server string stream property url . tests
21 21
22 lib_LTLIBRARIES = libmailutils.la 22 lib_LTLIBRARIES = libmailutils.la
23 23
...@@ -34,6 +34,7 @@ libmailutils_la_LIBADD = \ ...@@ -34,6 +34,7 @@ libmailutils_la_LIBADD = \
34 mailbox/libmailbox.la\ 34 mailbox/libmailbox.la\
35 mailer/libmailer.la\ 35 mailer/libmailer.la\
36 mime/libmime.la\ 36 mime/libmime.la\
37 property/libproperty.la\
37 server/libserver.la\ 38 server/libserver.la\
38 string/libstring.la\ 39 string/libstring.la\
39 stream/libstream.la\ 40 stream/libstream.la\
......
...@@ -52,7 +52,6 @@ libbase_la_SOURCES = \ ...@@ -52,7 +52,6 @@ libbase_la_SOURCES = \
52 opool.c\ 52 opool.c\
53 parsedate.c\ 53 parsedate.c\
54 permstr.c\ 54 permstr.c\
55 property.c\
56 registrar.c\ 55 registrar.c\
57 refcount.c\ 56 refcount.c\
58 rfc2047.c\ 57 rfc2047.c\
......
...@@ -391,10 +391,11 @@ first (void *owner) ...@@ -391,10 +391,11 @@ first (void *owner)
391 mu_assoc_t assoc = itr->assoc; 391 mu_assoc_t assoc = itr->assoc;
392 unsigned hash_max = hash_size[assoc->hash_num]; 392 unsigned hash_max = hash_size[assoc->hash_num];
393 unsigned i; 393 unsigned i;
394 394
395 for (i = 0; i < hash_max; i++) 395 if (assoc->tab)
396 if ((ASSOC_ELEM (assoc, i))->name) 396 for (i = 0; i < hash_max; i++)
397 break; 397 if ((ASSOC_ELEM (assoc, i))->name)
398 break;
398 itr->index = i; 399 itr->index = i;
399 return 0; 400 return 0;
400 } 401 }
......
...@@ -103,6 +103,15 @@ mu_iterator_set_itrctl (mu_iterator_t itr, ...@@ -103,6 +103,15 @@ mu_iterator_set_itrctl (mu_iterator_t itr,
103 } 103 }
104 104
105 int 105 int
106 mu_iterator_set_dataptr (mu_iterator_t itr, void *(*dataptr) (void *))
107 {
108 if (!itr)
109 return EINVAL;
110 itr->dataptr = dataptr;
111 return 0;
112 }
113
114 int
106 mu_iterator_set_destroy (mu_iterator_t itr, int (*destroy) (mu_iterator_t, void *)) 115 mu_iterator_set_destroy (mu_iterator_t itr, int (*destroy) (mu_iterator_t, void *))
107 { 116 {
108 if (!itr) 117 if (!itr)
...@@ -202,14 +211,23 @@ mu_iterator_skip (mu_iterator_t iterator, ssize_t count) ...@@ -202,14 +211,23 @@ mu_iterator_skip (mu_iterator_t iterator, ssize_t count)
202 int 211 int
203 mu_iterator_current (mu_iterator_t iterator, void **pitem) 212 mu_iterator_current (mu_iterator_t iterator, void **pitem)
204 { 213 {
205 return iterator->getitem (iterator->owner, pitem, NULL); 214 return mu_iterator_current_kv (iterator, NULL, pitem);
206 } 215 }
207 216
208 int 217 int
209 mu_iterator_current_kv (mu_iterator_t iterator, 218 mu_iterator_current_kv (mu_iterator_t iterator,
210 const void **pkey, void **pitem) 219 const void **pkey, void **pitem)
211 { 220 {
212 return iterator->getitem (iterator->owner, (void**)pitem, pkey); 221 void *ptr;
222 int rc = iterator->getitem (iterator->owner, &ptr, pkey);
223 if (rc == 0)
224 {
225 if (iterator->dataptr)
226 *pitem = iterator->dataptr (ptr);
227 else
228 *pitem = ptr;
229 }
230 return rc;
213 } 231 }
214 232
215 int 233 int
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
35 #include <mailutils/stream.h> 35 #include <mailutils/stream.h>
36 #include <mailutils/url.h> 36 #include <mailutils/url.h>
37 #include <mailutils/errno.h> 37 #include <mailutils/errno.h>
38 #include <mailutils/property.h>
38 39
39 #include <mailutils/sys/folder.h> 40 #include <mailutils/sys/folder.h>
40 41
...@@ -208,6 +209,8 @@ mu_folder_destroy (mu_folder_t *pfolder) ...@@ -208,6 +209,8 @@ mu_folder_destroy (mu_folder_t *pfolder)
208 mu_stream_destroy (&folder->stream); 209 mu_stream_destroy (&folder->stream);
209 if (folder->url) 210 if (folder->url)
210 mu_url_destroy (&folder->url); 211 mu_url_destroy (&folder->url);
212 if (folder->property)
213 mu_property_destroy (&folder->property);
211 free (folder); 214 free (folder);
212 } 215 }
213 mu_monitor_unlock (monitor); 216 mu_monitor_unlock (monitor);
...@@ -217,6 +220,31 @@ mu_folder_destroy (mu_folder_t *pfolder) ...@@ -217,6 +220,31 @@ mu_folder_destroy (mu_folder_t *pfolder)
217 } 220 }
218 } 221 }
219 222
223 int
224 mu_folder_get_property (mu_folder_t folder, mu_property_t *prop)
225 {
226 if (folder == NULL)
227 return EINVAL;
228 if (prop == NULL)
229 return MU_ERR_OUT_PTR_NULL;
230
231 if (folder->property == NULL)
232 {
233 int status;
234
235 if (folder->_get_property)
236 status = folder->_get_property (folder, &folder->property);
237 else
238 status = mu_property_create_init (&folder->property,
239 mu_assoc_property_init, NULL);
240 if (status != 0)
241 return status;
242 }
243 *prop = folder->property;
244 return 0;
245 }
246
247
220 /* Cover functions. */ 248 /* Cover functions. */
221 int 249 int
222 mu_folder_open (mu_folder_t folder, int flags) 250 mu_folder_open (mu_folder_t folder, int flags)
......
...@@ -272,7 +272,7 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox) ...@@ -272,7 +272,7 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox)
272 mu_folder_destroy (&mbox->folder); 272 mu_folder_destroy (&mbox->folder);
273 273
274 if (mbox->property) 274 if (mbox->property)
275 mu_property_destroy (&mbox->property, mbox); 275 mu_property_destroy (&mbox->property);
276 276
277 free (mbox); 277 free (mbox);
278 *pmbox = NULL; 278 *pmbox = NULL;
...@@ -648,6 +648,18 @@ mu_mailbox_get_observable (mu_mailbox_t mbox, mu_observable_t *pobservable) ...@@ -648,6 +648,18 @@ mu_mailbox_get_observable (mu_mailbox_t mbox, mu_observable_t *pobservable)
648 } 648 }
649 649
650 int 650 int
651 mu_mailbox_set_property (mu_mailbox_t mbox, mu_property_t property)
652 {
653 if (mbox == NULL)
654 return MU_ERR_MBX_NULL;
655 if (mbox->property)
656 mu_property_unref (mbox->property);
657 mbox->property = property;
658 mu_property_ref (property);
659 return 0;
660 }
661
662 int
651 mu_mailbox_get_property (mu_mailbox_t mbox, mu_property_t *pproperty) 663 mu_mailbox_get_property (mu_mailbox_t mbox, mu_property_t *pproperty)
652 { 664 {
653 if (mbox == NULL) 665 if (mbox == NULL)
...@@ -657,7 +669,13 @@ mu_mailbox_get_property (mu_mailbox_t mbox, mu_property_t *pproperty) ...@@ -657,7 +669,13 @@ mu_mailbox_get_property (mu_mailbox_t mbox, mu_property_t *pproperty)
657 669
658 if (mbox->property == NULL) 670 if (mbox->property == NULL)
659 { 671 {
660 int status = mu_property_create (&mbox->property, mbox); 672 int status;
673
674 if (mbox->_get_property)
675 status = mbox->_get_property (mbox, &mbox->property);
676 else
677 status = mu_property_create_init (&mbox->property,
678 mu_assoc_property_init, NULL);
661 if (status != 0) 679 if (status != 0)
662 return status; 680 return status;
663 } 681 }
......
...@@ -210,7 +210,7 @@ mu_mailer_destroy (mu_mailer_t * pmailer) ...@@ -210,7 +210,7 @@ mu_mailer_destroy (mu_mailer_t * pmailer)
210 mu_debug_destroy (&(mailer->debug), mailer); 210 mu_debug_destroy (&(mailer->debug), mailer);
211 211
212 if (mailer->property) 212 if (mailer->property)
213 mu_property_destroy (&(mailer->property), mailer); 213 mu_property_destroy (&mailer->property);
214 214
215 free (mailer); 215 free (mailer);
216 *pmailer = NULL; 216 *pmailer = NULL;
...@@ -706,6 +706,18 @@ mu_mailer_get_observable (mu_mailer_t mailer, mu_observable_t * pobservable) ...@@ -706,6 +706,18 @@ mu_mailer_get_observable (mu_mailer_t mailer, mu_observable_t * pobservable)
706 } 706 }
707 707
708 int 708 int
709 mu_mailer_set_property (mu_mailer_t mailer, mu_property_t property)
710 {
711 if (mailer == NULL)
712 return EINVAL;
713 if (mailer->property)
714 mu_property_unref (mailer->property);
715 mailer->property = property;
716 mu_property_ref (property);
717 return 0;
718 }
719
720 int
709 mu_mailer_get_property (mu_mailer_t mailer, mu_property_t * pproperty) 721 mu_mailer_get_property (mu_mailer_t mailer, mu_property_t * pproperty)
710 { 722 {
711 if (mailer == NULL) 723 if (mailer == NULL)
...@@ -714,7 +726,13 @@ mu_mailer_get_property (mu_mailer_t mailer, mu_property_t * pproperty) ...@@ -714,7 +726,13 @@ mu_mailer_get_property (mu_mailer_t mailer, mu_property_t * pproperty)
714 return MU_ERR_OUT_PTR_NULL; 726 return MU_ERR_OUT_PTR_NULL;
715 if (mailer->property == NULL) 727 if (mailer->property == NULL)
716 { 728 {
717 int status = mu_property_create (&(mailer->property), mailer); 729 int status;
730
731 if (mailer->_get_property)
732 status = mailer->_get_property (mailer, &mailer->property);
733 else
734 status = mu_property_create_init (&mailer->property,
735 mu_assoc_property_init, NULL);
718 if (status != 0) 736 if (status != 0)
719 return status; 737 return status;
720 } 738 }
......
1 # GNU Mailutils -- a suite of utilities for electronic mail
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 3 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General
15 # Public License along with this library. If not, see
16 # <http://www.gnu.org/licenses/>.
17
18 noinst_LTLIBRARIES = libproperty.la
19
20 libproperty_la_SOURCES = \
21 assocprop.c\
22 create.c\
23 propget.c\
24 propitr.c\
25 propset.c
26
27 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 Free
3 Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <mailutils/sys/property.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/assoc.h>
26 #include <mailutils/stream.h>
27 #include <mailutils/iterator.h>
28 #include <stdlib.h>
29
30 struct property_item
31 {
32 char *value;
33 };
34
35 static void
36 _assoc_prop_done (struct _mu_property *prop)
37 {
38 mu_assoc_t assoc = prop->_prop_data;
39 mu_stream_t str = prop->_prop_init_data;
40 mu_assoc_destroy (&assoc);
41 mu_stream_destroy (&str);
42 }
43
44 static int
45 _assoc_prop_getval (struct _mu_property *prop,
46 const char *key, const char **pval)
47 {
48 mu_assoc_t assoc = prop->_prop_data;
49 struct property_item *item;
50
51 item = mu_assoc_ref (assoc, key);
52 if (item == NULL)
53 return MU_ERR_NOENT;
54 if (pval)
55 *pval = item->value;
56 return 0;
57
58 }
59
60 static int
61 _assoc_prop_setval (struct _mu_property *prop, const char *key,
62 const char *val, int overwrite)
63 {
64 mu_assoc_t assoc = prop->_prop_data;
65 struct property_item *item;
66 int rc;
67
68 rc = mu_assoc_ref_install (assoc, key, (void **)&item);
69 if (rc == MU_ERR_NOENT)
70 {
71 item->value = strdup (val);
72 if (!item->value)
73 {
74 mu_assoc_remove (assoc, key);
75 return ENOMEM;
76 }
77 }
78 else if (overwrite)
79 {
80 char *newval = strdup (val);
81 if (!newval)
82 return ENOMEM;
83 free (item->value);
84 item->value = newval;
85 }
86 else
87 return MU_ERR_EXISTS;
88 return 0;
89 }
90
91 static int
92 _assoc_prop_unset (struct _mu_property *prop, const char *key)
93 {
94 mu_assoc_t assoc = prop->_prop_data;
95
96 return mu_assoc_remove (assoc, key);
97 }
98
99
100 static void *
101 _assoc_prop_dataptr (void *in)
102 {
103 struct property_item *item = in;
104 return item->value;
105 }
106
107 static int
108 _assoc_prop_getitr (struct _mu_property *prop, mu_iterator_t *pitr)
109 {
110 int rc;
111 mu_iterator_t itr;
112
113 rc = mu_assoc_get_iterator ((mu_assoc_t)prop->_prop_data, &itr);
114 if (rc)
115 return rc;
116 mu_iterator_set_dataptr (itr, _assoc_prop_dataptr);
117 *pitr = itr;
118 return 0;
119 }
120
121
122 static void
123 prop_free_value (void *data)
124 {
125 struct property_item *item = data;
126 free (item->value);
127 }
128
129
130 static int
131 _assoc_prop_fill (struct _mu_property *prop)
132 {
133 int rc;
134 mu_stream_t str = prop->_prop_init_data;
135 int state = 0;
136 char *buf[2] = { NULL, NULL };
137 size_t size[2] = { 0, 0 }, n;
138
139 if (!str)
140 return EINVAL;
141 mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
142 while ((rc = mu_stream_getdelim (str, &buf[state], &size[state],
143 0, &n)) == 0 &&
144 n > 0)
145 {
146 if (state == 1)
147 _assoc_prop_setval (prop, buf[0], buf[1], 1);
148 state = !state;
149 }
150 free (buf[0]);
151 free (buf[1]);
152 return rc;
153 }
154
155 static int
156 _assoc_prop_save (struct _mu_property *prop)
157 {
158 mu_stream_t str = prop->_prop_init_data;
159 mu_iterator_t itr;
160 int rc;
161 mu_off_t off;
162
163 if (!str)
164 return EINVAL;
165 rc = mu_property_get_iterator (prop, &itr);
166 if (rc)
167 return rc;
168
169 mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
170 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
171 mu_iterator_next (itr))
172 {
173 const char *name, *val;
174
175 mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
176 rc = mu_stream_write (str, name, strlen (name) + 1, NULL);
177 if (rc)
178 break;
179 rc = mu_stream_write (str, val, strlen (val) + 1, NULL);
180 if (rc)
181 break;
182 }
183 mu_iterator_destroy (&itr);
184 rc = mu_stream_seek (str, 0, MU_SEEK_CUR, &off);
185 if (rc == 0)
186 rc = mu_stream_truncate (str, off);
187 return rc;
188 }
189
190
191 int
192 mu_assoc_property_init (struct _mu_property *prop)
193 {
194 mu_assoc_t assoc;
195 int rc;
196
197 rc = mu_assoc_create (&assoc, sizeof (struct property_item), 0);
198 if (rc)
199 return rc;
200 mu_assoc_set_free (assoc, prop_free_value);
201 prop->_prop_data = assoc;
202
203 prop->_prop_done = _assoc_prop_done;
204 if (prop->_prop_init_data)
205 {
206 mu_stream_t str = prop->_prop_init_data;
207 mu_stream_ref (str);
208 prop->_prop_fill = _assoc_prop_fill;
209 prop->_prop_save = _assoc_prop_save;
210 }
211 else
212 {
213 prop->_prop_fill = NULL;
214 prop->_prop_save = NULL;
215 }
216 prop->_prop_getval = _assoc_prop_getval;
217 prop->_prop_setval = _assoc_prop_setval;
218 prop->_prop_unset = _assoc_prop_unset;
219 prop->_prop_getitr = _assoc_prop_getitr;
220 return 0;
221 }
222
...@@ -19,173 +19,148 @@ ...@@ -19,173 +19,148 @@
19 #ifdef HAVE_CONFIG_H 19 #ifdef HAVE_CONFIG_H
20 #include <config.h> 20 #include <config.h>
21 #endif 21 #endif
22 #ifdef HAVE_STRINGS_H
23 # include <strings.h>
24 #endif
25 22
26 #include <mailutils/sys/property.h> 23 #include <mailutils/types.h>
27 #include <mailutils/errno.h> 24 #include <mailutils/errno.h>
28 #include <mailutils/assoc.h> 25 #include <mailutils/sys/property.h>
29 #include <stdlib.h>
30 26
31 static void 27 int
32 prop_free_value (void *data) 28 mu_property_create (mu_property_t *pprop)
33 { 29 {
34 struct property_item *item = data; 30 mu_property_t prop = calloc (1, sizeof (prop[0]));
35 free (item->value); 31 if (!prop)
32 return ENOMEM;
33 *pprop = prop;
34 return 0;
36 } 35 }
37 36
38 int 37 int
39 mu_property_create (mu_property_t *pp, void *owner) 38 mu_property_create_init (mu_property_t *pprop,
39 int (*initfun) (mu_property_t), void *initdata)
40 { 40 {
41 int rc;
42 mu_property_t prop; 41 mu_property_t prop;
43 if (pp == NULL) 42 int rc = mu_property_create (&prop);
44 return MU_ERR_OUT_PTR_NULL; 43 if (rc == 0)
45 prop = calloc (1, sizeof *prop);
46 if (prop == NULL)
47 return ENOMEM;
48 rc = mu_assoc_create (&prop->assoc, sizeof (struct property_item), 0);
49 if (rc)
50 { 44 {
51 free (prop); 45 mu_property_set_init (prop, initfun, initdata);
52 return rc; 46 *pprop = prop;
53 } 47 }
54 mu_assoc_set_free (prop->assoc, prop_free_value); 48 return 0;
55 mu_monitor_create (&prop->lock, 0, prop); 49 }
56 prop->owner = owner; 50
57 *pp = prop; 51 int
52 mu_property_set_init (mu_property_t prop,
53 int (*initfun) (mu_property_t), void *initdata)
54 {
55 if (!prop)
56 return ENOMEM;
57 if (prop->_prop_flags & MU_PROP_INIT)
58 return MU_ERR_SEQ;
59 prop->_prop_init = initfun;
60 prop->_prop_init_data = initdata;
61 return 0;
62 }
63
64 int
65 mu_property_set_init_data (mu_property_t prop, void *data, void **old_data)
66 {
67 if (!prop)
68 return ENOMEM;
69 if (prop->_prop_flags & MU_PROP_INIT)
70 return MU_ERR_SEQ;
71 if (old_data)
72 *old_data = prop->_prop_init_data;
73 prop->_prop_init_data = data;
58 return 0; 74 return 0;
59 } 75 }
60 76
61 void 77 void
62 mu_property_destroy (mu_property_t *pp, void *owner) 78 mu_property_destroy (mu_property_t *pprop)
63 { 79 {
64 if (pp && *pp) 80 if (pprop)
65 { 81 {
66 mu_property_t prop = *pp; 82 mu_property_t prop = *pprop;
67 if (prop->owner == owner) 83 if (prop && (prop->_prop_ref_count == 0 || --prop->_prop_ref_count == 0))
68 { 84 {
69 /* Destroy the list and is properties. */ 85 mu_property_save (prop);
70 mu_monitor_wrlock (prop->lock); 86 if (prop->_prop_done)
71 mu_assoc_destroy (&prop->assoc); 87 prop->_prop_done (prop);
72 mu_monitor_unlock (prop->lock);
73 mu_monitor_destroy (&prop->lock, prop);
74 free (prop); 88 free (prop);
89 *pprop = NULL;
75 } 90 }
76 *pp = NULL;
77 } 91 }
78 } 92 }
79 93
80 void * 94 void
81 mu_property_get_owner (mu_property_t prop) 95 mu_property_ref (mu_property_t prop)
82 { 96 {
83 return (prop == NULL) ? NULL : prop->owner; 97 if (prop)
98 prop->_prop_ref_count++;
84 } 99 }
85 100
86 int 101 void
87 mu_property_set_value (mu_property_t prop, const char *key, const char *value, 102 mu_property_unref (mu_property_t prop)
88 int overwrite)
89 { 103 {
90 struct property_item *item; 104 mu_property_destroy (&prop);
91 int rc;
92
93 if (!prop)
94 return EINVAL;
95 rc = mu_assoc_ref_install (prop->assoc, key, (void **)&item);
96 if (rc == MU_ERR_NOENT)
97 {
98 item->value = strdup (value);
99 }
100 else if (overwrite)
101 {
102 free (item->value);
103 item->value = strdup (value);
104 }
105 else
106 return 0;
107
108 if (!item->value)
109 {
110 mu_assoc_remove (prop->assoc, key);
111 return ENOMEM;
112 }
113
114 return 0;
115 } 105 }
116 106
117 int 107 int
118 mu_property_sget_value (mu_property_t prop, const char *key, 108 mu_property_save (mu_property_t prop)
119 const char **buffer)
120 { 109 {
121 struct property_item *item; 110 int rc = 0;
122 111
123 if (!prop) 112 if (!prop)
124 return EINVAL; 113 return EINVAL;
125 item = mu_assoc_ref (prop->assoc, key); 114 if (prop->_prop_flags & MU_PROP_MODIFIED)
126 if (item == NULL)
127 return MU_ERR_NOENT;
128 if (buffer)
129 *buffer = item->value;
130 return 0;
131 }
132
133 int
134 mu_property_aget_value (mu_property_t prop, const char *key,
135 char **buffer)
136 {
137 const char *value;
138 int rc = mu_property_sget_value (prop, key, &value);
139 if (rc == 0)
140 { 115 {
141 if ((*buffer = strdup (value)) == NULL) 116 if (prop->_prop_save)
142 return ENOMEM; 117 rc = prop->_prop_save (prop);
118
119 if (rc == 0)
120 prop->_prop_flags &= ~MU_PROP_MODIFIED;
143 } 121 }
144 return rc; 122 return rc;
145 } 123 }
146 124
147 int 125 static int
148 mu_property_get_value (mu_property_t prop, const char *key, char *buffer, 126 _mu_property_init (mu_property_t prop)
149 size_t buflen, size_t *n)
150 { 127 {
151 size_t len = 0; 128 int rc = 0;
152 const char *value; 129 if (!(prop->_prop_flags & MU_PROP_INIT))
153 int rc = mu_property_sget_value (prop, key, &value);
154 if (rc == 0)
155 { 130 {
156 len = strlen (value) + 1; 131 if (prop->_prop_init)
157 if (buffer && buflen) 132 rc = prop->_prop_init (prop);
158 { 133 if (rc == 0)
159 if (buflen < len) 134 prop->_prop_flags |= MU_PROP_INIT;
160 len = buflen;
161 len--;
162 memcpy (buffer, value, len);
163 buffer[len] = 0;
164 }
165 } 135 }
166 if (n)
167 *n = len;
168 return rc; 136 return rc;
169 } 137 }
170 138
171 int 139 static int
172 mu_property_is_set (mu_property_t prop, const char *key) 140 _mu_property_fill (mu_property_t prop)
173 {
174 struct property_item *item = mu_assoc_ref (prop->assoc, key);
175 return (item == NULL) ? 0 : 1;
176 }
177
178 int
179 mu_property_set (mu_property_t prop, const char *key)
180 { 141 {
181 return mu_property_set_value (prop, key, "", 1); 142 int rc = 0;
143 if (!(prop->_prop_flags & MU_PROP_FILL))
144 {
145 if (prop->_prop_fill)
146 rc = prop->_prop_fill (prop);
147 if (rc == 0)
148 prop->_prop_flags |= MU_PROP_FILL;
149 }
150 return rc;
182 } 151 }
183 152
184 int 153 int
185 mu_property_unset (mu_property_t prop, const char *key) 154 _mu_property_check (mu_property_t prop)
186 { 155 {
156 int rc;
157
187 if (!prop) 158 if (!prop)
188 return EINVAL; 159 return EINVAL;
189 return mu_assoc_remove (prop->assoc, key); 160 rc = _mu_property_init (prop);
161 if (rc == 0)
162 rc = _mu_property_fill (prop);
163 return rc;
190 } 164 }
165
191 166
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 Free
3 Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <mailutils/types.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/sys/property.h>
26
27 int
28 mu_property_sget_value (mu_property_t prop, const char *key,
29 const char **pval)
30 {
31 int rc = _mu_property_check (prop);
32 if (rc)
33 return rc;
34 if (!prop->_prop_getval)
35 return MU_ERR_EMPTY_VFN;
36 return prop->_prop_getval (prop, key, pval);
37 }
38
39 int
40 mu_property_aget_value (mu_property_t prop, const char *key,
41 char **buffer)
42 {
43 const char *value;
44 int rc = mu_property_sget_value (prop, key, &value);
45 if (rc == 0)
46 {
47 if ((*buffer = strdup (value)) == NULL)
48 return ENOMEM;
49 }
50 return rc;
51 }
52
53 int
54 mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
55 size_t buflen, size_t *n)
56 {
57 size_t len = 0;
58 const char *value;
59 int rc = mu_property_sget_value (prop, key, &value);
60 if (rc == 0)
61 {
62 len = strlen (value) + 1;
63 if (buffer && buflen)
64 {
65 if (buflen < len)
66 len = buflen;
67 len--;
68 memcpy (buffer, value, len);
69 buffer[len] = 0;
70 }
71 }
72 if (n)
73 *n = len;
74 return rc;
75 }
76
77 int
78 mu_property_is_set (mu_property_t prop, const char *key)
79 {
80 if (_mu_property_check (prop))
81 return 0;
82 return mu_property_sget_value (prop, key, NULL) == 0;
83 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 Free
3 Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <mailutils/types.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/sys/property.h>
26
27 int
28 mu_property_get_iterator (mu_property_t prop, mu_iterator_t *pitr)
29 {
30 int rc = _mu_property_check (prop);
31 if (rc)
32 return rc;
33 if (!prop->_prop_getitr)
34 return MU_ERR_EMPTY_VFN;
35 return prop->_prop_getitr (prop, pitr);
36 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 Free
3 Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <mailutils/types.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/sys/property.h>
26
27 int
28 mu_property_set_value (mu_property_t prop, const char *key,
29 const char *value, int overwrite)
30 {
31 int rc = _mu_property_check (prop);
32 if (rc)
33 return rc;
34 if (!prop->_prop_setval)
35 return MU_ERR_EMPTY_VFN;
36 rc = prop->_prop_setval (prop, key, value, overwrite);
37 if (rc == 0)
38 prop->_prop_flags |= MU_PROP_MODIFIED;
39 return rc;
40 }
41
42 int
43 mu_property_unset (mu_property_t prop, const char *key)
44 {
45 int rc = _mu_property_check (prop);
46 if (rc)
47 return rc;
48 if (!prop->_prop_unset)
49 return MU_ERR_EMPTY_VFN;
50 rc = prop->_prop_unset (prop, key);
51 if (rc == 0)
52 prop->_prop_flags |= MU_PROP_MODIFIED;
53 return rc;
54 }
55
56 int
57 mu_property_set (mu_property_t prop, const char *key)
58 {
59 return mu_property_set_value (prop, key, "", 1);
60 }
61
62
63
...@@ -11,6 +11,7 @@ encode2047 ...@@ -11,6 +11,7 @@ encode2047
11 fltst 11 fltst
12 listop 12 listop
13 mailcap 13 mailcap
14 prop
14 url-parse 15 url-parse
15 wicket 16 wicket
16 wsp 17 wsp
......
...@@ -47,6 +47,7 @@ noinst_PROGRAMS = \ ...@@ -47,6 +47,7 @@ noinst_PROGRAMS = \
47 fltst\ 47 fltst\
48 listop\ 48 listop\
49 mailcap\ 49 mailcap\
50 prop\
50 url-parse\ 51 url-parse\
51 wicket\ 52 wicket\
52 wsp 53 wsp
...@@ -69,6 +70,7 @@ TESTSUITE_AT = \ ...@@ -69,6 +70,7 @@ TESTSUITE_AT = \
69 fromflt.at\ 70 fromflt.at\
70 list.at\ 71 list.at\
71 mailcap.at\ 72 mailcap.at\
73 prop.at\
72 testsuite.at\ 74 testsuite.at\
73 url.at\ 75 url.at\
74 wicket.at\ 76 wicket.at\
......
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16 # This file is part of Mailfromd testsuite.
17
18 dnl ------------------------------------------------------------------
19 dnl TESTPROP([NAME], [KW = `'], [PROG], [STDOUT = `'], [STDERR = `'])
20 dnl
21 m4_pushdef([TESTPROP],[
22 AT_SETUP([prop: $1])
23 AT_KEYWORDS([prop $2])
24 AT_CHECK([$3],[0],[$4],[$5])
25 AT_CLEANUP])
26
27 TESTPROP([set],[prop00],[
28 prop foo=bar ?foo +foo
29 ],
30 [0: foo=bar: Success
31 1: foo is set
32 2: foo=bar
33 ])
34
35 TESTPROP([overwrite],[prop01],[
36 prop foo=bar foo=baz +foo
37 ],
38 [0: foo=bar: Success
39 1: foo=baz: Success
40 2: foo=baz
41 ])
42
43 TESTPROP([set without overwrite],[prop03],[
44 prop foo=bar foo:=baz +foo
45 ],
46 [0: foo=bar: Success
47 1: foo=baz: Item already exists
48 2: foo=bar
49 ])
50
51 TESTPROP([set/unset],[prop04],[
52 prop foo=bar ?foo +foo -foo ?foo
53 ],
54 [0: foo=bar: Success
55 1: foo is set
56 2: foo=bar
57 3: unset foo: Success
58 4: foo is not set
59 ])
60
61 TESTPROP([read/save],[prop06],[
62 prop --file=db user=gray package=mailutils org=GNU test=6.a
63 if test -f db; then
64 prop --file=db | sort
65 else
66 echo 2>&1 "failed to create file"
67 exit 1
68 fi
69
70 prop --file=db -test
71 prop --file=db | sort
72
73 prop --file=db test=6.b descr="New test"
74 prop --file=db | sort
75 ],
76 [0: user=gray: Success
77 1: package=mailutils: Success
78 2: org=GNU: Success
79 3: test=6.a: Success
80 Property dump:
81 org=GNU
82 package=mailutils
83 test=6.a
84 user=gray
85 0: unset test: Success
86 Property dump:
87 org=GNU
88 package=mailutils
89 user=gray
90 0: test=6.b: Success
91 1: descr=New test: Success
92 Property dump:
93 descr=New test
94 org=GNU
95 package=mailutils
96 test=6.b
97 user=gray
98 ])
99
100 m4_popdef([TESTPROP])
101
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <mailutils/mailutils.h>
21
22 void
23 help (char *progname)
24 {
25 printf ("usage: %s [--file=NAME] [--dump] [COMMAND...]\n", progname);
26 printf ("Valid COMMANDs are:\n");
27 printf (" X=Y set property X to value Y\n");
28 printf (" X:=Y same, but fail if X has already been set\n");
29 printf (" ?X query whether X is set\n");
30 printf (" +X query the value of the property X\n");
31 printf (" -X unset property X\n");
32 exit (0);
33 }
34
35 int
36 main (int argc, char **argv)
37 {
38 mu_property_t prop;
39 mu_iterator_t itr;
40 int i, j, rc;
41 char *filename = NULL;
42 int dumpit = 0;
43 mu_stream_t str = NULL;
44
45 if (argc == 1)
46 help (argv[0]);
47
48 for (i = 1; i < argc; i++)
49 {
50 if (!(argv[i][0] == '-' && argv[i][1] == '-'))
51 break;
52 if (strcmp (argv[i], "--help") == 0)
53 help (argv[0]);
54 else if (strncmp (argv[i], "--file=", 7) == 0)
55 filename = argv[i] + 7;
56 else if (strcmp (argv[i], "--dump") == 0)
57 dumpit = 1;
58 else
59 {
60 mu_error ("unknown switch: %s", argv[i]);
61 return 1;
62 }
63 }
64
65 if (filename)
66 {
67 MU_ASSERT (mu_file_stream_create (&str, filename,
68 MU_STREAM_RDWR|MU_STREAM_CREAT));
69 mu_stream_unref (str);
70 if (i == argc)
71 dumpit = 1;
72 }
73
74 MU_ASSERT (mu_property_create_init (&prop, mu_assoc_property_init, str));
75
76 for (j = 0; i < argc; i++, j++)
77 {
78 char *key = argv[i];
79 char *p = strchr (key, '=');
80
81 if (p)
82 {
83 int override;
84 if (p > key && p[-1] == ':')
85 {
86 override = 0;
87 p[-1] = 0;
88 }
89 else
90 {
91 override = 1;
92 *p = 0;
93 }
94 p++;
95 rc = mu_property_set_value (prop, key, p, override);
96 printf ("%d: %s=%s: %s\n",
97 j, key, p, mu_strerror (rc));
98 }
99 else if (key[0] == '?')
100 {
101 key++;
102 rc = mu_property_is_set (prop, key);
103 printf ("%d: %s is %s\n", j, key, rc ? "set" : "not set");
104 }
105 else if (key[0] == '-')
106 {
107 key++;
108 rc = mu_property_unset (prop, key);
109 printf ("%d: unset %s: %s\n", j, key, mu_strerror (rc));
110 }
111 else if (key[0] == '+')
112 {
113 const char *val;
114
115 key++;
116 rc = mu_property_sget_value (prop, key, &val);
117 if (rc)
118 printf ("%d: cannot get %s: %s\n", j, key, mu_strerror (rc));
119 else
120 printf ("%d: %s=%s\n", j, key, val);
121 }
122 else
123 {
124 mu_error ("%d: unrecognized command", i);
125 }
126 }
127
128 if (dumpit)
129 {
130 if (mu_property_get_iterator (prop, &itr) == 0)
131 {
132 printf ("Property dump:\n");
133 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
134 mu_iterator_next (itr))
135 {
136 const char *name, *val;
137
138 mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
139 printf ("%s=%s\n", name, val);
140 }
141 mu_iterator_destroy (&itr);
142 }
143 }
144
145 mu_property_destroy (&prop);
146 return 0;
147 }
...@@ -65,4 +65,5 @@ m4_include([decode2047.at]) ...@@ -65,4 +65,5 @@ m4_include([decode2047.at])
65 m4_include([encode2047.at]) 65 m4_include([encode2047.at])
66 m4_include([fromflt.at]) 66 m4_include([fromflt.at])
67 m4_include([wicket.at]) 67 m4_include([wicket.at])
68 m4_include([prop.at])
68 69
......