summaryrefslogtreecommitdiff
path: root/gallery-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gallery-utils.c')
-rw-r--r--gallery-utils.c149
1 files changed, 128 insertions, 21 deletions
diff --git a/gallery-utils.c b/gallery-utils.c
index 6de0224..ce80a4f 100644
--- a/gallery-utils.c
+++ b/gallery-utils.c
@@ -23,39 +23,83 @@
#include "gallery-utils.h"
+
+static char *
+strstr_exclude (const char *haystack, const char *needle, const char *exclude_when)
+{
+ const char *src;
+ char *found;
+
+ src = haystack;
+
+ while (src && strstr (src, needle)) {
+ found = strstr (src, needle);
+
+ /* skip if found 'exclude_when' at the same place as 'search' */
+ if (exclude_when && (found == strstr (haystack, exclude_when))) {
+ src += strlen (exclude_when);
+ continue;
+ }
+ else
+ return found;
+ }
+
+ return NULL;
+}
+
/*
* str_replace: replace substring 'search' with a 'replace' string
- * - only one occurence of the string is replaced
- * - reallocates the original string
+ * - multiple occurences of the string are replaced
+ * - specify 'exclude_when' if you want to skip replace when a string found at the place of 'search'
+ * - reallocates the original string
*/
void
-str_replace (char **dst, const char *search, const char *replace)
+str_replace (char **dst, const char *search, const char *replace, const char *exclude_when)
{
- char *res;
- char *tms;
- int new_str_len;
+ #define REPLACE_MAX_LENGTH 32768
+ static char d[REPLACE_MAX_LENGTH];
+ char *src;
+ char *found;
+ int i;
- /* is 'search' present in 'dst'? */
- res = strstr (*dst, search);
- if (res == NULL)
- return;
+ /* TODO: add range checking */
- new_str_len = strlen (*dst) - strlen (search) + strlen (replace) + 1;
+ if (strstr (*dst, search) == NULL || strlen (*dst) == 0 ||
+ strlen (search) == 0 || strlen (replace) == 0)
+ return;
- tms = malloc (new_str_len);
- memset (tms, 0, new_str_len);
+ i = 0;
+ src = *dst;
+ while (strstr_exclude (src, search, exclude_when)) {
+ found = strstr_exclude (src, search, exclude_when);
+
+ /* copy the data between search string */
+ if (found > src) {
+ memcpy (&d[i], src, found - src);
+ i += found - src;
+ }
+
+ /* copy replace string instead */
+ memcpy (&d[i], replace, strlen (replace));
+ i += strlen (replace);
+ src = found + strlen (search);
+ }
- memcpy (tms, *dst, res - *dst);
- memcpy ((void*) ((long int) tms + (long int) res - (long int) *dst),
- replace,
- strlen (replace));
- memcpy ((void*) ((long int) tms + (long int) res - (long int) *dst + strlen (replace)),
- (void*) ((long int) res + strlen (search)),
- strlen (res) - strlen (search));
+ /* copy the rest */
+ if (src) {
+ memcpy (&d[i], src, strlen (src));
+ i += strlen (src);
+ }
+ d[i] = 0x0;
+
+#ifdef __DEBUG_ALL__
+ printf ("str_replace('%s', '%s') = '%s' --> '%s'\n", search, replace, *dst, &d[0]);
+#endif
+
/* return fixed string */
free (*dst);
- *dst = tms;
+ *dst = g_strdup (&d[0]);
}
@@ -120,3 +164,66 @@ make_string (const char* substr, const int count)
}
+/*
+ * fix_entities: replace all invalid & entities with &
+ * - returns newly allocated string
+ */
+void
+fix_entities (char **str)
+{
+ static char d[REPLACE_MAX_LENGTH];
+ char *src;
+ char *found;
+ char *scan;
+ int i;
+
+ /* TODO: add range checking */
+
+ if (! *str || strstr (*str, "&") == NULL)
+ return;
+
+ i = 0;
+ src = *str;
+ while (strstr (src, "&")) {
+ found = strstr (src, "&");
+
+ /* copy the data between search string */
+ memcpy (&d[i], src, found - src + 1);
+ i += found - src + 1;
+
+ /* scroll to next whitespace */
+ scan = found + 1;
+ while (scan && (
+ (*scan >= 0x41 && *scan <= 0x5a) || (*scan >= 0x61 && *scan <= 0x7a) || /* A-Z, a-z */
+ (*scan >= 0x30 && *scan <= 0x39) || (*scan == 0x23) /* 0-9, # */
+ ))
+ scan++;
+
+ if (scan && (*scan == 0x3b)) {
+ /* this is semi-colon, correctly closed entity */
+ /* -- ignore */
+ }
+ else {
+ /* replace with &amp; */
+ memcpy (&d[i], "amp;", 4);
+ i += 4;
+ }
+ src = found + 1;
+ }
+
+ /* copy the rest */
+ if (src) {
+ memcpy (&d[i], src, strlen (src));
+ i += strlen (src);
+ }
+ d[i] = 0x0;
+
+
+#ifdef __DEBUG_ALL__
+ printf ("fix_entities: '%s' --> '%s'\n", *str, &d[0]);
+#endif
+
+ /* return fixed string */
+ free (*str);
+ *str = g_strdup (&d[0]);
+}