diff options
Diffstat (limited to 'src/garray.c')
-rw-r--r-- | src/garray.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/garray.c b/src/garray.c new file mode 100644 index 0000000000..ebd6748e78 --- /dev/null +++ b/src/garray.c @@ -0,0 +1,144 @@ +/* + * Functions for handling growing arrays. + */ + +#include "vim.h" +#include "ascii.h" +#include "misc2.h" +#include "garray.h" +//#include "globals.h" +#include "memline.h" + +/* + * Clear an allocated growing array. + */ +void ga_clear(garray_T *gap) +{ + vim_free(gap->ga_data); + ga_init(gap); +} + +/* + * Clear a growing array that contains a list of strings. + */ +void ga_clear_strings(garray_T *gap) +{ + int i; + + for (i = 0; i < gap->ga_len; ++i) + vim_free(((char_u **)(gap->ga_data))[i]); + ga_clear(gap); +} + +/* + * Initialize a growing array. Don't forget to set ga_itemsize and + * ga_growsize! Or use ga_init2(). + */ +void ga_init(garray_T *gap) +{ + gap->ga_data = NULL; + gap->ga_maxlen = 0; + gap->ga_len = 0; +} + +void ga_init2(garray_T *gap, int itemsize, int growsize) +{ + ga_init(gap); + gap->ga_itemsize = itemsize; + gap->ga_growsize = growsize; +} + +/* + * Make room in growing array "gap" for at least "n" items. + * Return FAIL for failure, OK otherwise. + */ +int ga_grow(garray_T *gap, int n) +{ + size_t old_len; + size_t new_len; + char_u *pp; + + if (gap->ga_maxlen - gap->ga_len < n) { + if (n < gap->ga_growsize) + n = gap->ga_growsize; + new_len = gap->ga_itemsize * (gap->ga_len + n); + pp = (gap->ga_data == NULL) + ? alloc((unsigned)new_len) : vim_realloc(gap->ga_data, new_len); + if (pp == NULL) + return FAIL; + old_len = gap->ga_itemsize * gap->ga_maxlen; + vim_memset(pp + old_len, 0, new_len - old_len); + gap->ga_maxlen = gap->ga_len + n; + gap->ga_data = pp; + } + return OK; +} + +/* + * For a growing array that contains a list of strings: concatenate all the + * strings with a separating comma. + * Returns NULL when out of memory. + */ +char_u *ga_concat_strings(garray_T *gap) +{ + int i; + int len = 0; + char_u *s; + + for (i = 0; i < gap->ga_len; ++i) + len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + 1; + + s = alloc(len + 1); + if (s != NULL) { + *s = NUL; + for (i = 0; i < gap->ga_len; ++i) { + if (*s != NUL) + STRCAT(s, ","); + STRCAT(s, ((char_u **)(gap->ga_data))[i]); + } + } + return s; +} + +/* + * Concatenate a string to a growarray which contains characters. + * Note: Does NOT copy the NUL at the end! + */ +void ga_concat(garray_T *gap, char_u *s) +{ + int len = (int)STRLEN(s); + + if (ga_grow(gap, len) == OK) { + mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len); + gap->ga_len += len; + } +} + +/* + * Append one byte to a growarray which contains bytes. + */ +void ga_append(garray_T *gap, int c) +{ + if (ga_grow(gap, 1) == OK) { + *((char *)gap->ga_data + gap->ga_len) = c; + ++gap->ga_len; + } +} + +#if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264) +/* + * Append the text in "gap" below the cursor line and clear "gap". + */ +void append_ga_line(garray_T *gap) +{ + /* Remove trailing CR. */ + if (gap->ga_len > 0 + && !curbuf->b_p_bin + && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR) + --gap->ga_len; + ga_append(gap, NUL); + ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE); + gap->ga_len = 0; +} +#endif + |