/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 | | /* |
20 | | * This is an open source non-commercial project. Dear PVS-Studio, please check it. |
21 | | * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com |
22 | | */ |
23 | | |
24 | | #include <config.h> |
25 | | |
26 | | #include "sudo_compat.h" |
27 | | #include "sudo_debug.h" |
28 | | #include "sudo_util.h" |
29 | | |
30 | | /* |
31 | | * Like strtok_r but non-destructive and works w/o a NUL terminator. |
32 | | * TODO: Optimize by storing current char in a variable ch |
33 | | */ |
34 | | const char * |
35 | | sudo_strsplit_v1(const char *str, const char *endstr, const char *sep, const char **last) |
36 | 17.2k | { |
37 | 17.2k | const char *cp, *s; |
38 | 17.2k | debug_decl(sudo_strsplit, SUDO_DEBUG_UTIL); |
39 | | |
40 | | /* If no str specified, use last ptr (if any). */ |
41 | 17.2k | if (str == NULL) |
42 | 9.33k | str = *last; |
43 | | |
44 | | /* Skip leading separator characters. */ |
45 | 24.7k | while (str < endstr) { |
46 | 47.1k | for (s = sep; *s != '\0'; s++) { |
47 | 34.4k | if (*str == *s) { |
48 | 7.47k | str++; |
49 | 7.47k | break; |
50 | 7.47k | } |
51 | 34.4k | } |
52 | 20.1k | if (*s == '\0') |
53 | 12.7k | break; |
54 | 20.1k | } |
55 | | |
56 | | /* Empty string? */ |
57 | 17.2k | if (str >= endstr) { |
58 | 4.58k | *last = endstr; |
59 | 4.58k | debug_return_ptr(NULL); |
60 | 4.58k | } |
61 | | |
62 | | /* Scan str until we hit a char from sep. */ |
63 | 6.22M | for (cp = str; cp < endstr; cp++) { |
64 | 18.6M | for (s = sep; *s != '\0'; s++) { |
65 | 12.4M | if (*cp == *s) |
66 | 7.55k | break; |
67 | 12.4M | } |
68 | 6.22M | if (*s != '\0') |
69 | 7.55k | break; |
70 | 6.22M | } |
71 | 12.7k | *last = cp; |
72 | 12.7k | debug_return_const_ptr(str); |
73 | 12.7k | } |