summaryrefslogtreecommitdiff
path: root/string.c
blob: 68b01e43b8d0a54aba30e978f581b843a850aa1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "string.h"

#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

void sp_init(StringPool *sp, size_t len) {
  assert(sp != NULL);
  sp->mem = malloc(len);
  if (sp->mem == NULL) {
    printf("Malloc failed during sp_init!");
    exit(1);
  }
  sp->size = len;
  sp->offset = 0;
}

void* sp_reserve(StringPool *sp, size_t len) {
  assert(sp != NULL);
  if (sp->offset + len > sp->size) {
    printf("String pool full!");
    exit(1);
  }
  
  void *mem = sp->mem + sp->offset;
  sp->offset += len;
  return mem;
}  

StringView sv_create(StringPool *sp, char *str, size_t len) {
  assert(str != NULL);
  assert(len != 0);
  void *mem = sp_reserve(sp, len);
  memcpy(mem, str, len);
  ((char*)mem)[len] = '\0';
  return (StringView){(char*)mem, len};
}

StringView sv_concat_ss(StringPool *sp, StringView a, StringView b) {
  assert(sp != NULL);

  if (a.len == 0) return b;
  if (b.len == 0) return a; // Handle the case where both strings are empty.
  
  size_t alen = a.len;
  size_t blen = b.len;  

  if (a.buf[a.len - 1] == '\0') alen -= 1;
  if (b.buf[b.len - 1] == '\0') blen -= 1;

  size_t len = alen + blen;
  char *mem = (char *)sp_reserve(sp, len + 1);
  memcpy(mem, a.buf, alen);
  memcpy(mem + alen, b.buf, blen);
  mem[len] = '\0';
  return (StringView){.buf = mem, .len = len};
}

StringView sv_concat_ss_n(StringPool *sp, int n, ...) {
  va_list args;
  va_start(args, n);
  StringView res = {.buf = "", .len = 0};
  for (int i = 0; i < n; i++) {
    res = sv_concat_ss(sp, res, va_arg(args, StringView));
  }
  va_end(args);
  return res;
}

StringView sv_sizet_to_string(StringPool *sp, size_t s) {
  assert(sp != NULL);
  size_t size = sizeof(size_t);
  char* buf = sp_reserve(sp, size);
  snprintf(buf, size, "%d", s);
  size_t len = strlen(buf);
  return (StringView){.buf = buf, .len = len};
}  

void sv_printf_cs(char *fmt, ...) {
  va_list args;
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
}