split_string.h 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #ifndef BADVPN_SPLIT_STRING_H
  2. #define BADVPN_SPLIT_STRING_H
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <limits.h>
  7. #include <misc/balloc.h>
  8. static char ** split_string (const char *str, char del)
  9. {
  10. size_t len = strlen(str);
  11. // count parts
  12. size_t num_parts = 0;
  13. size_t i = 0;
  14. while (1) {
  15. size_t j = i;
  16. while (j < len && str[j] != del) j++;
  17. num_parts++;
  18. if (num_parts == SIZE_MAX) { // need to allocate +1 pointer
  19. goto fail0;
  20. }
  21. if (j == len) {
  22. break;
  23. }
  24. i = j + 1;
  25. }
  26. // allocate array for part pointers
  27. char **result = BAllocArray(num_parts + 1, sizeof(*result));
  28. if (!result) {
  29. goto fail0;
  30. }
  31. num_parts = 0;
  32. i = 0;
  33. while (1) {
  34. size_t j = i;
  35. while (j < len && str[j] != del) j++;
  36. if (!(result[num_parts] = malloc(j - i + 1))) {
  37. goto fail1;
  38. }
  39. memcpy(result[num_parts], str + i, j - i);
  40. result[num_parts][j - i] = '\0';
  41. num_parts++;
  42. if (j == len) {
  43. break;
  44. }
  45. i = j + 1;
  46. }
  47. result[num_parts] = NULL;
  48. return result;
  49. fail1:
  50. while (num_parts-- > 0) {
  51. free(result[num_parts]);
  52. }
  53. BFree(result);
  54. fail0:
  55. return NULL;
  56. }
  57. #endif