Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2/* Copyright (C) 2020 Facebook, Inc. */
3#include <stdlib.h>
4#include <errno.h>
5#include "testing_helpers.h"
6
7int parse_num_list(const char *s, bool **num_set, int *num_set_len)
8{
9 int i, set_len = 0, new_len, num, start = 0, end = -1;
10 bool *set = NULL, *tmp, parsing_end = false;
11 char *next;
12
13 while (s[0]) {
14 errno = 0;
15 num = strtol(s, &next, 10);
16 if (errno)
17 return -errno;
18
19 if (parsing_end)
20 end = num;
21 else
22 start = num;
23
24 if (!parsing_end && *next == '-') {
25 s = next + 1;
26 parsing_end = true;
27 continue;
28 } else if (*next == ',') {
29 parsing_end = false;
30 s = next + 1;
31 end = num;
32 } else if (*next == '\0') {
33 parsing_end = false;
34 s = next;
35 end = num;
36 } else {
37 return -EINVAL;
38 }
39
40 if (start > end)
41 return -EINVAL;
42
43 if (end + 1 > set_len) {
44 new_len = end + 1;
45 tmp = realloc(set, new_len);
46 if (!tmp) {
47 free(set);
48 return -ENOMEM;
49 }
50 for (i = set_len; i < start; i++)
51 tmp[i] = false;
52 set = tmp;
53 set_len = new_len;
54 }
55 for (i = start; i <= end; i++)
56 set[i] = true;
57 }
58
59 if (!set)
60 return -EINVAL;
61
62 *num_set = set;
63 *num_set_len = set_len;
64
65 return 0;
66}