/src/sudo/lib/util/strsplit.c
Line | Count | Source |
1 | | /* |
2 | | * SPDX-License-Identifier: ISC |
3 | | * |
4 | | * Copyright (c) 2015 Todd C. Miller <Todd.Miller@sudo.ws> |
5 | | * |
6 | | * Permission to use, copy, modify, and distribute this software for any |
7 | | * purpose with or without fee is hereby granted, provided that the above |
8 | | * copyright notice and this permission notice appear in all copies. |
9 | | * |
10 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | | */ |
18 | | |
19 | | #include <config.h> |
20 | | |
21 | | #include <sudo_compat.h> |
22 | | #include <sudo_debug.h> |
23 | | #include <sudo_util.h> |
24 | | |
25 | | /* |
26 | | * Like strtok_r but non-destructive and works w/o a NUL terminator. |
27 | | * TODO: Optimize by storing current char in a variable ch |
28 | | */ |
29 | | const char * |
30 | | sudo_strsplit_v1(const char *str, const char *endstr, const char *sep, const char **last) |
31 | 18.5k | { |
32 | 18.5k | const char *cp, *s; |
33 | 18.5k | debug_decl(sudo_strsplit, SUDO_DEBUG_UTIL); |
34 | | |
35 | | /* If no str specified, use last ptr (if any). */ |
36 | 18.5k | if (str == NULL) |
37 | 10.1k | str = *last; |
38 | | |
39 | | /* Skip leading separator characters. */ |
40 | 26.4k | while (str < endstr) { |
41 | 51.6k | for (s = sep; *s != '\0'; s++) { |
42 | 37.8k | if (*str == *s) { |
43 | 7.95k | str++; |
44 | 7.95k | break; |
45 | 7.95k | } |
46 | 37.8k | } |
47 | 21.6k | if (*s == '\0') |
48 | 13.7k | break; |
49 | 21.6k | } |
50 | | |
51 | | /* Empty string? */ |
52 | 18.5k | if (str >= endstr) { |
53 | 4.83k | *last = endstr; |
54 | 4.83k | debug_return_ptr(NULL); |
55 | 4.83k | } |
56 | | |
57 | | /* Scan str until we hit a char from sep. */ |
58 | 9.11M | for (cp = str; cp < endstr; cp++) { |
59 | 27.3M | for (s = sep; *s != '\0'; s++) { |
60 | 18.2M | if (*cp == *s) |
61 | 8.29k | break; |
62 | 18.2M | } |
63 | 9.10M | if (*s != '\0') |
64 | 8.29k | break; |
65 | 9.10M | } |
66 | 13.7k | *last = cp; |
67 | 13.7k | debug_return_const_ptr(str); |
68 | 13.7k | } |