rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

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) */