1 /* Parse comma separated list into words. 2 Copyright (C) 1996-1997, 1999, 2004, 2007, 2009-2021 Free Software 3 Foundation, Inc. 4 This file is part of the GNU C Library. 5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. 6 7 This file is free software: you can redistribute it and/or modify 8 it under the terms of the GNU Lesser General Public License as 9 published by the Free Software Foundation; either version 3 of the 10 License, or (at your option) any later version. 11 12 This file is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 19 20 #if !_LIBC 21 # include <config.h> 22 #endif 23 24 #include <stdlib.h> 25 #include <string.h> 26 27 #if !_LIBC 28 /* This code is written for inclusion in gnu-libc, and uses names in 29 the namespace reserved for libc. If we're compiling in gnulib, 30 define those names to be the normal ones instead. */ 31 # undef __strchrnul 32 # define __strchrnul strchrnul 33 #endif 34 35 /* Parse comma separated suboption from *OPTIONP and match against 36 strings in TOKENS. If found return index and set *VALUEP to 37 optional value introduced by an equal sign. If the suboption is 38 not part of TOKENS return in *VALUEP beginning of unknown 39 suboption. On exit *OPTIONP is set to the beginning of the next 40 token or at the terminating NUL character. */ 41 int 42 getsubopt (char **optionp, char *const *tokens, char **valuep) /* */ 43 { 44 char *endp, *vstart; 45 int cnt; 46 47 if (**optionp == '\0') 48 return -1; 49 50 /* Find end of next token. */ 51 endp = __strchrnul (*optionp, ','); 52 53 /* Find start of value. */ 54 vstart = memchr (*optionp, '=', endp - *optionp); 55 if (vstart == NULL) 56 vstart = endp; 57 58 /* Try to match the characters between *OPTIONP and VSTART against 59 one of the TOKENS. */ 60 for (cnt = 0; tokens[cnt] != NULL; ++cnt) 61 if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0 62 && tokens[cnt][vstart - *optionp] == '\0') 63 { 64 /* We found the current option in TOKENS. */ 65 *valuep = vstart != endp ? vstart + 1 : NULL; 66 67 if (*endp != '\0') 68 *endp++ = '\0'; 69 *optionp = endp; 70 71 return cnt; 72 } 73 74 /* The current suboption does not match any option. */ 75 *valuep = *optionp; 76 77 if (*endp != '\0') 78 *endp++ = '\0'; 79 *optionp = endp; 80 81 return -1; 82 }