211 lines
5.8 KiB
Diff
211 lines
5.8 KiB
Diff
diff -up libical-2.0.0/src/libical/icalrecur.c.rscale libical-2.0.0/src/libical/icalrecur.c
|
|
--- libical-2.0.0/src/libical/icalrecur.c.rscale 2016-02-11 13:27:37.626579781 +0100
|
|
+++ libical-2.0.0/src/libical/icalrecur.c 2016-02-11 14:49:56.751367100 +0100
|
|
@@ -134,6 +134,7 @@
|
|
#endif
|
|
|
|
#include "icalrecur.h"
|
|
+#include "icalarray.h"
|
|
#include "icalerror.h"
|
|
#include "icalmemory.h"
|
|
#include "icaltimezone.h"
|
|
@@ -186,6 +187,139 @@
|
|
|
|
#define LEAP_MONTH 0x1000
|
|
|
|
+#if defined(HAVE_PTHREAD)
|
|
+#include <pthread.h>
|
|
+static pthread_mutex_t rscale_texts_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
+#endif
|
|
+
|
|
+static icalarray *rscale_texts = NULL;
|
|
+
|
|
+static void initialize_rscale_texts(void)
|
|
+{
|
|
+#if defined(HAVE_LIBICU)
|
|
+ UErrorCode status = U_ZERO_ERROR;
|
|
+ UEnumeration *en;
|
|
+ const char *cal;
|
|
+#endif
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_lock(&rscale_texts_mutex);
|
|
+#endif
|
|
+
|
|
+ if (rscale_texts != NULL) {
|
|
+ #if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_unlock(&rscale_texts_mutex);
|
|
+ #endif
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ rscale_texts = icalarray_new(sizeof(char **), 20);
|
|
+
|
|
+#if defined(HAVE_LIBICU)
|
|
+ en = ucal_getKeywordValuesForLocale("calendar", NULL, FALSE, &status);
|
|
+ while ((cal = uenum_next(en, NULL, &status))) {
|
|
+ char *copy = icalmemory_strdup(cal);
|
|
+ icalarray_append(rscale_texts, ©);
|
|
+ }
|
|
+ uenum_close(en);
|
|
+#endif
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_unlock(&rscale_texts_mutex);
|
|
+#endif
|
|
+}
|
|
+
|
|
+static const char *match_rscale_text(const char *text)
|
|
+{
|
|
+ size_t ii;
|
|
+ const char *res = NULL;
|
|
+
|
|
+ if(!text) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ initialize_rscale_texts();
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_lock(&rscale_texts_mutex);
|
|
+#endif
|
|
+
|
|
+ for(ii = 0; rscale_texts && ii < rscale_texts->num_elements; ii++) {
|
|
+ const char **stored, *p1, *p2;
|
|
+
|
|
+ stored = icalarray_element_at(rscale_texts, ii);
|
|
+ if(!stored || !*stored)
|
|
+ continue;
|
|
+
|
|
+ for(p1 = *stored, p2 = text; *p1 && *p2; p1++, p2++) {
|
|
+ if (tolower(*p1) != tolower(*p2))
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if(!*p1 && !*p2) {
|
|
+ res = *stored;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_unlock(&rscale_texts_mutex);
|
|
+#endif
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+static const char *match_or_add_rscale_text(const char *text)
|
|
+{
|
|
+ const char *res;
|
|
+
|
|
+ if(!text) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ res = match_rscale_text (text);
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_lock(&rscale_texts_mutex);
|
|
+#endif
|
|
+
|
|
+ if(!res && rscale_texts) {
|
|
+ res = icalmemory_strdup(text);
|
|
+ icalarray_append(rscale_texts, &res);
|
|
+ }
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_unlock(&rscale_texts_mutex);
|
|
+#endif
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+void icalrecur_free_rscale_texts(void)
|
|
+{
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_lock(&rscale_texts_mutex);
|
|
+#endif
|
|
+
|
|
+ if(rscale_texts) {
|
|
+ size_t ii;
|
|
+ for(ii = 0; rscale_texts && ii < rscale_texts->num_elements; ii++) {
|
|
+ char **stored;
|
|
+
|
|
+ stored = icalarray_element_at(rscale_texts, ii);
|
|
+ if(stored && *stored)
|
|
+ icalmemory_free_buffer(*stored);
|
|
+ }
|
|
+
|
|
+ icalarray_free(rscale_texts);
|
|
+ rscale_texts = NULL;
|
|
+ }
|
|
+
|
|
+#if defined(HAVE_PTHREAD)
|
|
+ pthread_mutex_unlock(&rscale_texts_mutex);
|
|
+#endif
|
|
+}
|
|
+
|
|
int icalrecurrencetype_rscale_is_supported(void)
|
|
{
|
|
return RSCALE_IS_SUPPORTED;
|
|
@@ -585,7 +719,7 @@ struct icalrecurrencetype icalrecurrence
|
|
if (parser.rt.freq == ICAL_NO_RECURRENCE) r = -1;
|
|
} else if (icalrecurrencetype_rscale_is_supported() &&
|
|
strcasecmp(name, "RSCALE") == 0) {
|
|
- parser.rt.rscale = icalmemory_tmp_copy(value);
|
|
+ parser.rt.rscale = match_or_add_rscale_text(value);
|
|
} else if (icalrecurrencetype_rscale_is_supported() &&
|
|
strcasecmp(name, "SKIP") == 0) {
|
|
parser.rt.skip = icalrecur_string_to_skip(value);
|
|
@@ -1359,19 +1493,16 @@ static int initialize_iterator(icalrecur
|
|
impl->greg = NULL;
|
|
} else {
|
|
UEnumeration *en;
|
|
- const char *cal;
|
|
- char *r;
|
|
+ const char *cal, *rrscale;
|
|
|
|
- /* Lowercase the specified calendar */
|
|
- for (r = rule.rscale; *r; r++) {
|
|
- *r = tolower((int)*r);
|
|
- }
|
|
+ /* This can be a user-created string, thus not a one from the pool */
|
|
+ rrscale = match_or_add_rscale_text (rule.rscale);
|
|
|
|
/* Check if specified calendar is supported */
|
|
en = ucal_getKeywordValuesForLocale("calendar", NULL, FALSE, &status);
|
|
while ((cal = uenum_next(en, NULL, &status))) {
|
|
- if (!strcmp(cal, rule.rscale)) {
|
|
- is_hebrew = !strcmp(rule.rscale, "hebrew");
|
|
+ if (rrscale == match_rscale_text(cal)) {
|
|
+ is_hebrew = rrscale == match_rscale_text("hebrew");
|
|
break;
|
|
}
|
|
}
|
|
diff -up libical-2.0.0/src/libical/icalrecur.h.rscale libical-2.0.0/src/libical/icalrecur.h
|
|
--- libical-2.0.0/src/libical/icalrecur.h.rscale 2016-02-11 14:08:38.754473804 +0100
|
|
+++ libical-2.0.0/src/libical/icalrecur.h 2016-02-11 14:51:58.542361856 +0100
|
|
@@ -181,7 +181,7 @@ struct icalrecurrencetype
|
|
short by_set_pos[ICAL_BY_SETPOS_SIZE];
|
|
|
|
/* For RSCALE extension (RFC 7529) */
|
|
- char *rscale;
|
|
+ const char *rscale;
|
|
icalrecurrencetype_skip skip;
|
|
};
|
|
|
|
@@ -191,6 +191,12 @@ LIBICAL_ICAL_EXPORT icalarray *icalrecur
|
|
|
|
LIBICAL_ICAL_EXPORT void icalrecurrencetype_clear(struct icalrecurrencetype *r);
|
|
|
|
+/* Frees pool of calendar names used by icalrecurrencetype::rscale.
|
|
+ * Do not call if anything else can use it (like components or other
|
|
+ * icalrecurrencetype structures).
|
|
+ */
|
|
+LIBICAL_ICAL_EXPORT void icalrecur_free_rscale_texts(void);
|
|
+
|
|
/**
|
|
* Array Encoding
|
|
*
|