]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - string.c
Merge branch 't/flac'
[paraslash.git] / string.c
index 813999bbf1ced122ea8aa1347929ee03ce045c77..f7d70353db977d6543055c19c7bd68a17b83a3ce 100644 (file)
--- a/string.c
+++ b/string.c
@@ -521,14 +521,15 @@ __printf_2_3 int para_printf(struct para_buffer *b, const char *fmt, ...)
        }
 }
 
-/** \cond LLONG_MAX and LLONG_MIN might not be defined. */
+/** \cond llong_minmax */
+/* LLONG_MAX and LLONG_MIN might not be defined. */
 #ifndef LLONG_MAX
 #define LLONG_MAX 9223372036854775807LL
 #endif
 #ifndef LLONG_MIN
 #define LLONG_MIN (-LLONG_MAX - 1LL)
 #endif
-/** \endcond */
+/** \endcond llong_minmax */
 
 /**
  * Convert a string to a 64-bit signed integer value.
@@ -615,7 +616,7 @@ int get_loglevel_by_name(const char *txt)
        return -1;
 }
 
-static int get_next_word(const char *buf, const char *delim,  char **word)
+static int get_next_word(const char *buf, const char *delim, char **word)
 {
        enum line_state_flags {LSF_HAVE_WORD = 1, LSF_BACKSLASH = 2,
                LSF_SINGLE_QUOTE = 4, LSF_DOUBLE_QUOTE = 8};
@@ -719,6 +720,8 @@ void free_argv(char **argv)
 {
        int i;
 
+       if (!argv)
+               return;
        for (i = 0; argv[i]; i++)
                free(argv[i]);
        free(argv);
@@ -760,6 +763,7 @@ err:
        while (num_words > 0)
                free(argv[--num_words]);
        free(argv);
+       *result = NULL;
        return ret;
 }
 
@@ -789,3 +793,56 @@ int para_regcomp(regex_t *preg, const char *regex, int cflags)
        free(buf);
        return -E_REGEX;
 }
+
+/**
+ * strdup() for not necessarily zero-terminated strings.
+ *
+ * \param src The source buffer.
+ * \param len The number of bytes to be copied.
+ *
+ * \return A 0-terminated buffer of length \a len + 1.
+ *
+ * This is similar to strndup(), which is a GNU extension. However, one
+ * difference is that strndup() returns \p NULL if insufficient memory was
+ * available while this function aborts in this case.
+ *
+ * \sa strdup(), \ref para_strdup().
+ */
+char *safe_strdup(const char *src, size_t len)
+{
+       char *p;
+
+       assert(len < (size_t)-1);
+       p = para_malloc(len + 1);
+       if (len > 0)
+               memcpy(p, src, len);
+       p[len] = '\0';
+       return p;
+}
+
+/**
+ * Copy the value of a key=value pair.
+ *
+ * This checks whether the given buffer starts with "key=", ignoring case. If
+ * yes, a copy of the value is returned. The source buffer may not be
+ * zero-terminated.
+ *
+ * \param src The source buffer.
+ * \param len The number of bytes of the tag.
+ * \param key Only copy if it is the value of this key.
+ *
+ * \return A zero-terminated buffer, or \p NULL if the key was
+ * not of the given type.
+ */
+char *key_value_copy(const char *src, size_t len, const char *key)
+{
+       int keylen = strlen(key);
+
+       if (len <= keylen)
+               return NULL;
+       if (strncasecmp(src, key, keylen))
+               return NULL;
+       if (src[keylen] != '=')
+               return NULL;
+       return safe_strdup(src + keylen + 1, len - keylen - 1);
+}