/// dynamic array class /// written by: Harry Irving #include #include #include #include #include typedef struct { uint32_t size, capacity; char* data; } String_t; String_t str_with_capacity(int capacity) { String_t s; /// allocate memory for 'capacity' chars s.data = (char*)calloc(capacity, sizeof(char)); s.size = 0; s.capacity = capacity; return s; } String_t str_from_chars(const char* string) { String_t s; s.data = (char*)calloc(strlen(string), sizeof(char)); strcpy(s.data, string); s.size = strlen(string); s.capacity = strlen(string); return s; } String_t str_from_slice(const char* string, int len) { String_t s; s.data = (char*)calloc(len, sizeof(char)); strncpy(s.data, string, len); s.size = len; s.capacity = len; return s; } String_t str_new() { return str_with_capacity(1); } int str_dealloc(String_t* self) { free(self->data); return 0; } int str_push(String_t* self, char c) { // check size < capacity if (self->size < self->capacity) { self->data[self->size] = c; self->size++; return 0; } // reallocate to add capacity for an extra char int newcap = self->capacity + sizeof(char); self->data = (char*)realloc(self->data, newcap); self->data[self->size] = c; self->size++; self->capacity = newcap; return 0; } char str_pop(String_t* self) { if (self->size == 0) { return '\0'; } self->size--; char c = self->data[self->size]; return c; } int str_insert(String_t* self, int index, char c) { if (index > self->size) { return -1; } self->size++; for (int i = self->size - 1; i > index; i--) { self->data[i] = self->data[i - 1]; } self->data[index] = c; return 0; } int str_remove(String_t* self, int index) { if (index >= self->size) { return -1; } self->size--; for (int i = index; i < self->size; i++) { self->data[i] = self->data[i + 1]; } return 0; } /// splits a string into an array of strings based on a delimiter String_t* str_split(String_t* self, int* res_len, char c) { char* string = self->data; String_t* elements = NULL; // find the number of lines in the file bool flag = false; *res_len = 0; for (int i = 0; i < strlen(string); i++) { if (string[i] == c) { if (flag) { (*res_len)++; flag = false; } } else { flag = true; } } if (flag) { (*res_len)++; } // allocate memory for an array of pointers to each line elements = (String_t*)malloc((*res_len) * sizeof(String_t)); int i = 0; flag = false; char* start = string; char* end = string; while (*end != '\0') { if (*end == c) { if (flag) { elements[i] = str_from_slice(start, end - start); i++; } end++; start = end; flag = false; } else { end++; flag = true; } } if (flag) { elements[i] = str_from_slice(start, end - start); } // returns an array of String_t return elements; } String_t str_merge(String_t* s1, String_t* s2) { String_t s; s.size = s1->size + s2->size; s.capacity = s.size; s.data = (char*)calloc(s.size, sizeof(char)); for (int i = 0; i < s1->size; i++) { s.data[i] = s1->data[i]; } for (int i = 0; i < s2->size; i++) { s.data[s1->size + i] = s2->data[i]; } return s; } String_t* str_lines(String_t* self, int* numlines) { return str_split(self, numlines, '\n'); } String_t str_slice(String_t* s, int start, int end) { String_t s2; s2.size = end - start; s2.capacity = s2.size; s2.data = (char*)calloc(s2.size, sizeof(char)); for (int i = 0; i < s2.size; i++) { s2.data[i] = s->data[start + i]; } return s2; } int str_len(String_t* s) { return s->size; } char* to_chars(String_t* s) { return s->data; } // int main() { // String_t s = str_from_chars("hello\nworld\neeeee\notherline\n"); // str_remove(&s, 10); // str_insert(&s, 10, 'h'); // printf("%s\n", to_chars(&s)); // int linen = 0; // String_t* lines = str_lines(&s, &linen); // for (int i=0; i < linen; i++) { // printf("%s", to_chars(&lines[i])); // } // str_dealloc(&s); // return 0; // }