cstr_to_list.h (2374B)
1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr) 2 * 3 * The RSys library is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published 5 * by the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * The RSys library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ 15 16 /* 17 * Generate the cstr_to_list conversion function with respect to the 18 * CSTR_LIST_TYPE macro. 19 */ 20 21 #ifndef CSTR_LIST_TYPE 22 #ifndef CSTR_TO_LIST_H 23 #define CSTR_TO_LIST_H 24 25 #include "cstr.h" 26 #include "str.h" 27 28 #endif /* CSTR_TO_LIST_H */ 29 #else /* defined(CSTR_LIST_TYPE) */ 30 31 #ifndef CSTR_LIST_TYPE 32 #error "Missing the CSTR_LIST_TYPE macro defining the type of the list" 33 #endif 34 35 #ifndef CSTR_LIST_SUFFIX 36 #define CSTR_LIST_SUFFIX CSTR_LIST_TYPE 37 #endif 38 39 res_T 40 CONCAT(cstr_to_list_, CSTR_LIST_SUFFIX) 41 (const char* str, 42 const char delimiter, 43 CSTR_LIST_TYPE dst[], 44 size_t* length, 45 const size_t max_length) /* Maximum size of dst */ 46 { 47 struct str buf; 48 char delim[2] = {'\0', '\0'}; 49 size_t i; 50 char* tk; 51 char* tk_ctx; 52 res_T res = RES_OK; 53 54 str_init(NULL, &buf); 55 56 if(!str) { 57 res = RES_BAD_ARG; 58 goto error; 59 } 60 if(!dst && !length) { /* Useless invocation */ 61 goto exit; 62 } 63 64 /* Copy str in a temporary buffer to parse */ 65 res = str_set(&buf, str); 66 if(res != RES_OK) goto error; 67 68 /* Parse the string */ 69 delim[0] = delimiter; 70 tk = strtok_r(str_get(&buf), delim, &tk_ctx); 71 for(i=0; tk; tk = strtok_r(NULL, delim, &tk_ctx), ++i) { 72 if(dst) { 73 if(i >= max_length) { 74 res = RES_BAD_ARG; 75 goto error; 76 } 77 res = CONCAT(cstr_to_, CSTR_LIST_SUFFIX)(tk, dst + i); 78 } else { 79 CSTR_LIST_TYPE d; 80 res = CONCAT(cstr_to_, CSTR_LIST_SUFFIX)(tk, &d); 81 } 82 if(res != RES_OK) goto error; 83 } 84 85 if(length) 86 *length = i; 87 88 exit: 89 str_release(&buf); 90 return res; 91 error: 92 goto exit; 93 } 94 95 #undef CSTR_LIST_TYPE 96 #undef CSTR_LIST_SUFFIX 97 98 #endif /* defined(CSTR_LIST_TYPE) */