X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=string.c;h=8c8c50ac6ef30e51ec86751837e44e0e2a4ef95f;hp=bbb7c7dd2e2ef671d2b89d5a5cebd89e535066d5;hb=d4b040af5e31260dbf71f4547484179f32be4746;hpb=94a8bedb95f6df273c1f6bab502b4bae0c3b75e5 diff --git a/string.c b/string.c index bbb7c7dd..8c8c50ac 100644 --- a/string.c +++ b/string.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2011 Andre Noll + * Copyright (C) 2004-2012 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -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. @@ -710,6 +711,32 @@ out: return ret; } +/** + * Get the number of the word the cursor is on. + * + * \param buf The zero-terminated line buffer. + * \param delim Characters that separate words. + * \param point The cursor position. + * + * \return Zero-based word number. + */ +int compute_word_num(const char *buf, const char *delim, int point) +{ + int ret, num_words; + const char *p; + char *word; + + for (p = buf, num_words = 0; ; p += ret, num_words++) { + ret = get_next_word(p, delim, &word); + if (ret <= 0) + break; + free(word); + if (p + ret >= buf + point) + break; + } + return num_words; +} + /** * Free an array of words created by create_argv(). * @@ -719,6 +746,8 @@ void free_argv(char **argv) { int i; + if (!argv) + return; for (i = 0; argv[i]; i++) free(argv[i]); free(argv); @@ -760,6 +789,7 @@ err: while (num_words > 0) free(argv[--num_words]); free(argv); + *result = NULL; return ret; } @@ -789,3 +819,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); +}