strv.c revision fe382237cad0ade50d38075e0bf948ce07618461
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2010 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringchar *strv_find(char **l, const char *name) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar *strv_find_prefix(char **l, const char *name) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar *strv_find_startswith(char **l, const char *name) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Like strv_find_prefix, but actually returns only the
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering * suffix, not the whole item */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringvoid strv_clear(char **l) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering for (k = l; *k; k++)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar **strv_free(char **l) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar **strv_copy(char * const *l) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering char **r, **k;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering for (; *l; k++, l++) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringunsigned strv_length(char * const *l) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering unsigned n = 0;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering for (; *l; l++)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar **strv_new_ap(const char *x, va_list ap) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering const char *s;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering unsigned n = 0, i = 0;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* As a special trick we ignore all listed strings that equal
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering * (const char*) -1. This is supposed to be used with the
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering * STRV_IFNOTNULL() macro to include possibly NULL strings in
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering * the string list. */
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (s == (const char*) -1)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (x != (const char*) -1) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (s == (const char*) -1)
d23a27a964748967e1ad20e86de869a753af555bTom Gundersenchar **strv_new(const char *x, ...) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringint strv_extend_strv(char ***a, char **b) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringchar **strv_split(const char *s, const char *separator) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned n, i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar **strv_split_newlines(const char *s) {
2e276efc7b0398a3086629a52970bdd4ab7252f9Zbigniew Jędrzejewski-Szmek /* Special version of strv_split() that splits on newlines and
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek * suppresses an empty string at the end */
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poetteringint strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *word = NULL;
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek r = extract_first_word(&s, &word, separators, flags);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringchar *strv_join(char **l, const char *separator) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering /* assuming here that escaped string cannot be more
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering * than twice as long, and reserving space for the
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering * separator and quotes.
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering /* Increase and check for overflow */
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering c = realloc_multiply(*l, sizeof(char*), m);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poetteringint strv_push_pair(char ***l, char *a, char *b) {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek /* increase and check for overflow */
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek m = n + !!a + !!b + 1;
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek c = realloc_multiply(*l, sizeof(char*), m);
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poetteringint strv_push_prepend(char ***l, char *value) {
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek unsigned n, m, i;
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek /* increase and check for overflow */
03664a62914782dbd8f069bbcf8a0c8ca1df7010Lukas Nykryn c = new(char*, m);
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek for (i = 0; i < n; i++)
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek c[i+1] = (*l)[i];
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringint strv_consume_pair(char ***l, char *a, char *b) {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmekint strv_consume_prepend(char ***l, char *value) {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek r = strv_push_prepend(l, value);
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmekint strv_extend(char ***l, const char *value) {
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersenchar **strv_uniq(char **l) {
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersen /* Drops duplicate entries. The first identical string will be
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersen * kept, the others dropped */
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersenbool strv_is_uniq(char **l) {
cb57dd41595adddb08095298bb1ed258c8ea4877Tom Gundersen return false;
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersenchar **strv_remove(char **l, const char *s) {
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen char **f, **t;
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen /* Drops every occurrence of s in the string list, edits
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen * in-place. */
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen for (f = t = l; *f; f++)
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersenchar **strv_parse_nulstr(const char *s, size_t l) {
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen const char *p;
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen unsigned c = 0, i = 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering for (p = s; p < s + l; p++)
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek if (s[l-1] != 0)
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering while (p < s + l) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering const char *e;
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering e = memchr(p, 0, s + l - p);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering v[i] = strndup(p, e ? e - p : s + l - p);
2e276efc7b0398a3086629a52970bdd4ab7252f9Zbigniew Jędrzejewski-Szmekchar **strv_split_nulstr(const char *s) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringbool strv_overlap(char **a, char **b) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poetteringstatic int str_compare(const void *_a, const void *_b) {
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek const char **a = (const char**) _a, **b = (const char**) _b;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return strcmp(*a, *b);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringchar **strv_sort(char **l) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering qsort(l, strv_length(l), sizeof(char*), str_compare);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringbool strv_equal(char **a, char **b) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return a == b;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering for ( ; *a || *b; ++a, ++b)
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmekint strv_extendf(char ***l, const char *format, ...) {
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersenchar **strv_reverse(char **l) {
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen unsigned n, i;
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen for (i = 0; i < n / 2; i++) {
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen l[i] = l[n-1-i];
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen l[n-1-i] = t;
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poetteringchar **strv_shell_escape(char **l, const char *bad) {
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering /* Escapes every character in every string in l that is in bad,
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek * edits in-place, does not roll-back on error. */
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmekbool strv_fnmatch(char* const* patterns, const char *s, int flags) {
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek if (fnmatch(*p, s, 0) == 0)
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmekchar ***strv_free_free(char ***l) {
1bf968f36393666f2c57953b1748e6219c027deeTom Gundersen for (i = l; *i; i++)