+
+/**
+ * Find out if the given string is contained in the arg vector.
+ *
+ * \param arg The string to look for.
+ * \param argv The array to search.
+ *
+ * \return The first index whose value equals \a arg, or \p -E_ARG_NOT_FOUND if
+ * arg was not found in \a argv.
+ */
+int find_arg(const char *arg, char **argv)
+{
+ int i;
+
+ if (!argv)
+ return -E_ARG_NOT_FOUND;
+ for (i = 0; argv[i]; i++)
+ if (strcmp(arg, argv[i]) == 0)
+ return i;
+ return -E_ARG_NOT_FOUND;
+}
+
+/**
+ * Compile a regular expression.
+ *
+ * This simple wrapper calls regcomp() and logs a message on errors.
+ *
+ * \param preg See regcomp(3).
+ * \param regex See regcomp(3).
+ * \param cflags See regcomp(3).
+ *
+ * \return Standard.
+ */
+int para_regcomp(regex_t *preg, const char *regex, int cflags)
+{
+ char *buf;
+ size_t size;
+ int ret = regcomp(preg, regex, cflags);
+
+ if (ret == 0)
+ return 1;
+ size = regerror(ret, preg, NULL, 0);
+ buf = para_malloc(size);
+ regerror(ret, preg, buf, size);
+ PARA_ERROR_LOG("%s\n", buf);
+ 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);
+}