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.
Showing
28 changed files
with
943 additions
and
152 deletions
... | @@ -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\ | ... | ... |
... | @@ -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 | } | ... | ... |
libmailutils/property/Makefile.am
0 → 100644
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 |
libmailutils/property/assocprop.c
0 → 100644
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 | ... | ... |
libmailutils/property/propget.c
0 → 100644
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 | } |
libmailutils/property/propitr.c
0 → 100644
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 | } |
libmailutils/property/propset.c
0 → 100644
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 |
... | @@ -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\ | ... | ... |
libmailutils/tests/prop.at
0 → 100644
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 |
libmailutils/tests/prop.c
0 → 100644
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 | ... | ... |
-
Please register or sign in to post a comment