linux/tools/lib/argv_split.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Helper function for splitting a string into an argv-like array.
   4 */
   5
   6#include <stdlib.h>
   7#include <linux/kernel.h>
   8#include <linux/ctype.h>
   9#include <linux/string.h>
  10
  11static const char *skip_arg(const char *cp)
  12{
  13        while (*cp && !isspace(*cp))
  14                cp++;
  15
  16        return cp;
  17}
  18
  19static int count_argc(const char *str)
  20{
  21        int count = 0;
  22
  23        while (*str) {
  24                str = skip_spaces(str);
  25                if (*str) {
  26                        count++;
  27                        str = skip_arg(str);
  28                }
  29        }
  30
  31        return count;
  32}
  33
  34/**
  35 * argv_free - free an argv
  36 * @argv - the argument vector to be freed
  37 *
  38 * Frees an argv and the strings it points to.
  39 */
  40void argv_free(char **argv)
  41{
  42        char **p;
  43        for (p = argv; *p; p++) {
  44                free(*p);
  45                *p = NULL;
  46        }
  47
  48        free(argv);
  49}
  50
  51/**
  52 * argv_split - split a string at whitespace, returning an argv
  53 * @str: the string to be split
  54 * @argcp: returned argument count
  55 *
  56 * Returns an array of pointers to strings which are split out from
  57 * @str.  This is performed by strictly splitting on white-space; no
  58 * quote processing is performed.  Multiple whitespace characters are
  59 * considered to be a single argument separator.  The returned array
  60 * is always NULL-terminated.  Returns NULL on memory allocation
  61 * failure.
  62 */
  63char **argv_split(const char *str, int *argcp)
  64{
  65        int argc = count_argc(str);
  66        char **argv = calloc(argc + 1, sizeof(*argv));
  67        char **argvp;
  68
  69        if (argv == NULL)
  70                goto out;
  71
  72        if (argcp)
  73                *argcp = argc;
  74
  75        argvp = argv;
  76
  77        while (*str) {
  78                str = skip_spaces(str);
  79
  80                if (*str) {
  81                        const char *p = str;
  82                        char *t;
  83
  84                        str = skip_arg(str);
  85
  86                        t = strndup(p, str-p);
  87                        if (t == NULL)
  88                                goto fail;
  89                        *argvp++ = t;
  90                }
  91        }
  92        *argvp = NULL;
  93
  94out:
  95        return argv;
  96
  97fail:
  98        argv_free(argv);
  99        return NULL;
 100}
 101