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