/// 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; } String_t* str_lines(String_t* self, int* numlines) { char* string = self->data; String_t* lines = NULL; // find the number of lines in the file *numlines = 0; for (int i = 0; i < strlen(string); i++) { if (string[i] == '\n') { (*numlines)++; } } // add one if the last char is not a newline // in this case there is one more line than newline symbols if (self->data[strlen(self->data) - 1] != '\n') { (*numlines)++; } // allocate memory for an array of pointers to each line lines = (String_t*)malloc((*numlines + 1) * sizeof(String_t)); int i = 0; char* start = string; char* end = string; while (*end != '\0') { if (*end == '\n') { lines[i] = str_from_slice(start, end - start); end++; start = end; i++; } else { end++; } } // returns an array of String_t return lines; } /// 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; } 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\0"); // 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; // }