cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

string.c (2399B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#include "config.h"
     21
     22#include "common/string.h"
     23
     24#include <guacamole/mem.h>
     25
     26#include <stdlib.h>
     27#include <string.h>
     28
     29size_t guac_count_occurrences(const char* string, char c) {
     30
     31    size_t count = 0;
     32
     33    while (*string != 0) {
     34
     35        /* Count each occurrence */
     36        if (*string == c)
     37            count = guac_mem_ckd_add_or_die(count, 1);
     38
     39        /* Next character */
     40        string++;
     41
     42    }
     43
     44    return count;
     45
     46}
     47
     48char** guac_split(const char* string, char delim) {
     49
     50    size_t i = 0;
     51
     52    /* Calculate number of tokens present based on number of delimiters */
     53    size_t token_count = guac_mem_ckd_add_or_die(guac_count_occurrences(string, delim), 1);
     54    const char* token_start = string;
     55
     56    /* Allocate space for tokens, including NULL terminator */
     57    char** tokens = guac_mem_alloc(sizeof(char*), guac_mem_ckd_add_or_die(token_count, 1));
     58
     59    do {
     60
     61        size_t length;
     62        char* token;
     63
     64        /* Find end of token */
     65        while (*string != 0 && *string != delim)
     66            string++;
     67
     68        /* Calculate token length */
     69        length = string - token_start;
     70
     71        /* Allocate space for token and NULL terminator */
     72        tokens[i++] = token = guac_mem_alloc(guac_mem_ckd_add_or_die(length, 1));
     73
     74        /* Copy token, store null */
     75        memcpy(token, token_start, length);
     76        token[length] = 0;
     77
     78        /* Stop at end of string */
     79        if (*string == 0)
     80            break;
     81
     82        /* Next token */
     83        token_start = ++string;
     84
     85    } while (i < token_count);
     86
     87    /* NULL terminator */
     88    tokens[i] = NULL;
     89
     90    return tokens;
     91
     92}
     93