diff options
author | Vincent Sanders <vince@kyllikki.org> | 2014-05-04 18:29:53 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2014-05-07 16:24:30 +0100 |
commit | c1e2da80dfa62793ea107cf12408c814e268a54b (patch) | |
tree | a2013312a9f24e2f1027dc343f9d9516d6945112 /utils/utils.c | |
parent | 283cd05d0112b08753cb0b0c505a370ebccc52d1 (diff) | |
download | netsurf-c1e2da80dfa62793ea107cf12408c814e268a54b.tar.gz netsurf-c1e2da80dfa62793ea107cf12408c814e268a54b.tar.bz2 |
add string utility to join strings
Diffstat (limited to 'utils/utils.c')
-rw-r--r-- | utils/utils.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/utils/utils.c b/utils/utils.c index 8cb1987d4..bb30f921e 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -160,6 +160,85 @@ bool is_dir(const char *path) return S_ISDIR(s.st_mode) ? true : false; } +/* exported interface documented in utils/utils.h */ +nserror vsnstrjoin(char **str, size_t *size, char sep, size_t nelm, va_list ap) +{ + const char *elm[16]; + size_t elm_len[16]; + size_t elm_idx; + char *fname; + size_t fname_len = 0; + char *curp; + + /* check the parameters are all sensible */ + if ((nelm == 0) || (nelm > 16)) { + return NSERROR_BAD_PARAMETER; + } + if ((*str != NULL) && (size == NULL)) { + /* if the caller is providing the buffer they must say + * how much space is available. + */ + return NSERROR_BAD_PARAMETER; + } + + /* calculate how much storage we need for the complete path + * with all the elements. + */ + for (elm_idx = 0; elm_idx < nelm; elm_idx++) { + elm[elm_idx] = va_arg(ap, const char *); + elm_len[elm_idx] = strlen(elm[elm_idx]); + fname_len += elm_len[elm_idx]; + } + fname_len += nelm; /* allow for separators and terminator */ + + /* ensure there is enough space */ + fname = *str; + if (fname != NULL) { + if (fname_len > *size) { + return NSERROR_NOSPACE; + } + } else { + fname = malloc(fname_len); + if (fname == NULL) { + return NSERROR_NOMEM; + } + } + + /* copy the elements in with apropriate separator */ + curp = fname; + for (elm_idx = 0; elm_idx < nelm; elm_idx++) { + memmove(curp, elm[elm_idx], elm_len[elm_idx]); + curp += elm_len[elm_idx]; + /* ensure string are separated */ + if (curp[-1] != sep) { + *curp = sep; + curp++; + } + } + curp[-1] = 0; /* NULL terminate */ + + assert((curp - fname) <= (int)fname_len); + + *str = fname; + if (size != NULL) { + *size = fname_len; + } + + return NSERROR_OK; +} + +/* exported interface documented in utils/utils.h */ +nserror snstrjoin(char **str, size_t *size, char sep, size_t nelm, ...) +{ + va_list ap; + nserror ret; + + va_start(ap, nelm); + ret = vsnstrjoin(str, size, sep, nelm, ap); + va_end(ap); + + return ret; +} /** * Compile a regular expression, handling errors. |