From e4d6a971c15b0326166ae1511af471534dd3bdce Mon Sep 17 00:00:00 2001 From: FantasyPvP <80643031+FantasyPvP@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:36:52 +0000 Subject: [PATCH] started working on scrolling, enter key works now --- .vscode/settings.json | 4 +- final/binary | Bin 21920 -> 22336 bytes final/dynstr.c | 25 +++++ final/dynstr.h | 4 + final/editor.c | 196 +++++++++++++++++++++++++++----------- final/editor.h | 9 +- final/log.txt | 20 +--- final/main.c | 39 ++++++-- final/somecode.c | 213 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 427 insertions(+), 83 deletions(-) create mode 100644 final/somecode.c diff --git a/.vscode/settings.json b/.vscode/settings.json index a8195b9..ea95eb7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,8 @@ "format": "c", "initializer_list": "c", "vector": "c", - "__bit_reference": "c" + "__bit_reference": "c", + "source_location": "c", + "stdbool.h": "c" } } \ No newline at end of file diff --git a/final/binary b/final/binary index 72a77337f1c1236f9790a8a4c27feec797d2856e..71919e902a76e6ff6095bf02b4cab27eb6d275d5 100755 GIT binary patch literal 22336 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 F@ZWmjdHVnW delta 5803 zcmaJ_3v^UPn*Qo`chZT3PQoJ{A*2xy#z#nqjKnn|AXf@77#;z|0Ynmp2m>rM!t6}8 zbsA^9bEnr}ot;(3*$H!;!C60m>fmHCA_RXe^uQO z(6e<;SM~p>?|;-^b?>d@%dF`|))>xh%YkZ@dO&31?wfv}fhiq&afoNF&qjW{Yy9k&8YX@*Bj@_BHitJn z5UFflC7$z5$&UbF0F(^|hDTu$Z@l=(H-W7X%%8`Ecq}lLb*ldtRo_CrX!M6gak^jl z{Ug~?#owa(->SYx=_LJO(HaP|okTsA9u`leg+(eY%x)HI{CR97^&&ehEZWk-?5vvD zFPML-SRV+pX-aw^EzIs!)BWMVSO(l6{@ofe{zU*e$VX?j4mD^Z&SIJmu_%3+csYH8 zC=8a0`+^JoJGRzG#lHl9E=n`&G{BElhTeXCeFoq|J!MZN(T6f4qvoqx4j>)d4e$0xCZ_=b>^3xi=GHX8!V6}8 zvI@i1L@$n{$jQvh-;%4CXul@Pb}=jSuKZD2s9O8IdZd*cD}J4sS5i1c>SZYafYx`g zEzDF@E3 zD+(3vQUE+r{y_!66M=VVC>w~5;%?yOa)3XcjAqErP~oGb_?j7cqWlj^fBJ95hTO5N zK|GN=?xsWqfbFFEZGISaB_P z{gb9BN9}=t+EM@AQOHy(-u%R3{Oe;)o{sV!zf#sAGrzI7-ETv-~=Wf6@ zoRx~x&J%VgPmEfwjJ`*z`RM?60|n*4L0YN9lu90RT2epKcKin6PHp0=JGF_+m&im% z=oPzvS2DDVYW1;(j^zvp?fNsW5KmI&KGx7d8z8jnSuIh-lZ6b3H*}1NE~h^9i;&h# zXFx3Uq@^huLcjP5fNOW$N>qFx5c=6k08Wx8Mn10mO$6R409?PtpXP~C$7lgqo9sMh z_oJ6!Dei-$d00v*DehAgH)Vq&%>a5+6t`hK93#&AhNCBXseU;f=so0#2u`QWX-NqZ z?eRo3VNkS_L_hUJS9!8B9q8M1#Y37GBRHD`%Uru7bhwSgdci6(fWFFjL&uJ2DfKbx z>!ai24IO{GeR68XB`FW6oVYauwfyFhs)(ZbeYwZ%e%6=X*n9KWQa1KZqIw#0QOY+| z&8aD=_+>M>V6YM+PD8(I_w%O*6EOFpxa)?JS2HDXx93yg+4X zrzo1}1uB@+9$9xm{KpNq6z(Mr#~yI)lYDKPo?eyW&RaC)&GS!9sI+#T7qch)*vh=n zoSaZ-S!L(MiAlFuFP;;j8$S}wlMDO{zLrufnKCikY@P?X)9?a!wl|4!Ve2( zW*-Rs}V+dDedeU#dNBJy&sBK z#zta)(kUi{L^YXccdGp~aJTwfp-Tw*s8$U2#gvKaplcsbjJ5v1dFL-lS=PR7nwmhy z82t;lC~Mm)mKV$t@%-G_foXuw>9{YYY~=3B0ljH>yg!>e4XWzh${;NgmA`UvU}*Gu z_6W5b0`=4Mdgq*xvhkZhSD!X#FUy#xwS>p}XK<&X)j9oy{rb=cM5-joUAxs)NosXb zb~N<(Gj!|`v(m4s=S&Hpu(dNwzffyOVqM4Gs*LX+acvp@DW)_7`%6?AcMq+=En4(U z$&fPs-j^P5FrEykMH%#AONp1s_fC^mAV#3hk%PnNtW+m#BJgpp&X3Ok#a!rhX?1Ar zTV2GH%oLV}=Wb=T*}uP09@VsRXSPx{tD!v5wU`)d>HV4fU)oqc?koxN7Q3Aeh`t$Q zK*7=G(3>#kW^*_2eldlgwMaQf8%%?M?8WVNs+(4q9!X_(`__Zp4g8)aI7bfBJGB>D zfeG!VFQg0|u6doifz`!;-c7&zoS63O+^uPK7YCj9=nr@2-lqU-Co zMe4Ujwr&1FT_jq!Ga89*j?~rGM>9Q1bbVc9Tix2tn`$E)>o?V9uGv%@87hmeuisi5 z*|>QlUg?tZS6x!R-6dsjmz1nqO5P>qq+6%gA`^IM`?_^?TO;eXZ`_!PZS{W_tGgpI zsWuavH;f0^7~kK}w?;mI#*d^7GNAHfDNh3^>y)yX0S7vztY*OEZYj4g;LdI-8yOJo zmU15h+PkG}W56vZr94gYlTv0|!0MAy7F$4GkCfFGu&PJOEf!YeOpla}7O?S@l>02; z{3lW#w}1&LDbHF!X-dkGKEO^%Il~A1SFe=!`GDZ3QttEtf9R9)IUn$4pOlAuKwiI; z9X{ZJ&!mK3JY0Gs<6?JdUf|IVDffw&N+&QT-YzYSJ@~Pdn=JsdhG+lOx+^Qq_pmiA zJ&3UYo&)f2C!|#G8t8+rbOlryM?J^8jP@(uupPDoihRBo+S3WR?Nhyh(v zF1dyA)-Njc!vkSguS+l^sNvED5pc(&lTpc zsn0)PF!vg}D&+u@O6Of=_l(ggGdgNr0bDfvcvyq0>ZcnQ>)Y=yz9Wvz$zxpg8&vO7 zU-HiuT~2&6GcQ^?-u0t3zB(QN9Hd#(-!jrZ6P+pq0PTkVS)QJy_AG#I%0Jz&urFzT zEY}C*SmD9@2d@|X_dZHgKC;c#hSz9Qk_+Aq+>J&MH;8*pD%9~t zFT5UN;5XjCs>24`yH4@in+D@)+PMJK#s~18;s2)z&%3bs&_i5v-e^>rnd(RZ;P-29 zKR0ozHyHp~hX01CYjq|9$TfUEf+#>erT~l+Y;ImbiC-_{wSJfTz2#m`dimQ8O0&tj zm)!=1@+%{K*GSd*2w<<@T*|FFN*dNMeT_DxwUT{$Nib{TU2=VB5dUhTRL>@AKUh=0 zsc0=~f4FH|bZgOC(7VlMQ8BMcoSOHR_@DWU{5!s17kz5s_2T;ro)$UxOl+Qc&;3j! zt48OpqkF!(%DMNWVniDpsl{daB_AHv3 z({4QT#yR4|qNy1Xb9zNY{^Hv+n+(;IAyzE@ZjN{QdE*wbXK{?}6XTam9lY%wthtbQ zXh~6~ch(F<#IsB8W>1O}OQz<0;|f>osV)?iOS5y=m+Dk{<2}CShn7|_mJ)lG7K&s| zc7}IcwuujFZqM*mxl`mXo5?!G{mW)%glB1tpxCqQ_RI*^)F*z?wd}hY=~bE>E%q!b F{6A6|vrzy5 diff --git a/final/dynstr.c b/final/dynstr.c index 1823e5c..2ffb31b 100644 --- a/final/dynstr.c +++ b/final/dynstr.c @@ -156,10 +156,35 @@ String_t* str_split(String_t* self, int* res_len, char c) { 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; } diff --git a/final/dynstr.h b/final/dynstr.h index 6f86e5b..a4f4018 100644 --- a/final/dynstr.h +++ b/final/dynstr.h @@ -13,10 +13,14 @@ String_t str_from_chars(char* string); String_t str_from_slice(char* string, int len); +String_t str_merge(String_t* s1, String_t* s2); + String_t str_new(); String_t* str_lines(String_t* self, int* numlines); +String_t str_slice(String_t* s, int start, int end); + // String_t* str_split(String_t* self, int* res_len, char c); void str_push(String_t* s, char c); diff --git a/final/editor.c b/final/editor.c index 5f782d7..d1d5ea2 100644 --- a/final/editor.c +++ b/final/editor.c @@ -5,104 +5,196 @@ typedef struct { uint32_t lines; - uint32_t screen_line; - uint32_t screen_col; + uint32_t buffer_line; + uint32_t buffer_col; + uint32_t y_offset; + uint32_t x_offset; bool editmode; String_t* buffer; } Editor; -Editor editor_from(char* input_string) { - Editor e; - e.lines = 0; - e.screen_line = 0; - e.screen_col = 0; - e.editmode = false; +void add_toolbar(Editor* self) { + int max_x, max_y; + getmaxyx(stdscr, max_y, max_x); - int linenum = 0; - String_t lines = str_from_chars(input_string); - e.buffer = str_lines(&lines, &linenum); - e.lines = (size_t)linenum; - str_dealloc(&lines); - - for (size_t i = 0; i < e.lines; i++) { + move(max_y - 1, 0); + char mode[8]; + snprintf(mode, 9, "[%6s]", self->editmode ? "Insert" : "Normal"); + addstr(mode); +} + +void refresh_buffer(Editor* self) { + + move(0, 0); + + clear(); + + // get the screen size so we can figure out where to place characters + int max_x, max_y; + getmaxyx(stdscr, max_y, max_x); + + for (size_t i = self->y_offset; i < self->lines && i < self->y_offset + max_y; i++) { + // for (size_t i = 0; i < self->lines; i++) { // adding the line number char line_no[5]; snprintf(line_no, 5, "%-5d", i + 1); // adding the line of text to the buffer addstr(line_no); addch(' '); - addstr(to_chars(&e.buffer[i])); + addstr(to_chars(&self->buffer[i])); addstr("\n"); } + + add_toolbar(self); + + move(self->buffer_line, self->buffer_col + 5); +} + +void move_cursor_on_screen(Editor* editor, int x, int y) { + int newx = x + 5; // account for the line number + + move(y, newx); +} + +void switch_mode(Editor* self) { + self->editmode = !self->editmode; + refresh_buffer(self); +} + +void newline(Editor* self) { + move(self->buffer_line, 0); + char line_no[5]; + snprintf(line_no, 5, "%-5d", self->buffer_line + 1); + // adding the line of text to the buffer + addstr(line_no); + addch(' '); + move(self->buffer_line, self->buffer_col + 5); +} + +Editor editor_from(String_t input_string) { + Editor e; + e.lines = 0; + e.buffer_line = 0; + e.buffer_col = 0; + e.y_offset = 0; + e.x_offset = 0; + e.editmode = false; + + int linenum = 0; + e.buffer = str_lines(&input_string, &linenum); + e.lines = (size_t)linenum; + str_dealloc(&input_string); + + refresh_buffer(&e); return e; } Editor new_editor() { - return editor_from(""); + return editor_from(str_new()); } void move_cursor(Editor* self, int x, int y) { if (y != 0 - && (int)(self->screen_line) + y >= 0 - && self->screen_line + y <= self->lines) + && (int)(self->buffer_line) + y >= 0 + && self->buffer_line + y <= self->lines) { - self->screen_line += y; - int line_width = str_len(&self->buffer[self->screen_line]); - if (self->screen_col > line_width) { - self->screen_col = line_width; + // move the cursor up or down + self->buffer_line += y; + int line_width = str_len(&self->buffer[self->buffer_line]); + if (self->buffer_col > line_width) { + self->buffer_col = line_width; } - } else if ((int)(self->screen_col) + x < 0) { - if ((int)self->screen_line - 1 >= 0) { - self->screen_line -= 1; - self->screen_col = str_len(&self->buffer[self->screen_line]); + } else if ((int)(self->buffer_col) + x < 0) { + // moving the cursor off the left hand side of the line + if ((int)self->buffer_line > 0) { + self->buffer_line -= 1; + self->buffer_col = str_len(&self->buffer[self->buffer_line]); } - } else if (self->screen_col + x > str_len(&self->buffer[self->screen_line])) { - if (self->screen_line + 1 <= self->lines) { - self->screen_col = 0; - self->screen_line += 1; + } else if (self->buffer_col + x > str_len(&self->buffer[self->buffer_line])) { + // moving the cursor off the right hand side of the line + if (self->buffer_line < self->lines) { + self->buffer_col = 0; + self->buffer_line += 1; } } else if (x != 0) { - self->screen_col += x; + // moving the cursor left or right in any other case + self->buffer_col += x; } - move(self->screen_line, self->screen_col + 5); + move_cursor_on_screen(self, self->buffer_col, self->buffer_line); } void delchar(Editor* self) { - str_remove(&self->buffer[self->screen_line], self->screen_col); - delch(); + if (self->buffer_col == str_len(&self->buffer[self->buffer_line])) { + + if (self->buffer_line +1 == self->lines) { + return; + } + + self->buffer[self->buffer_line] = str_merge(&self->buffer[self->buffer_line], &self->buffer[self->buffer_line + 1]); + + for (size_t i = self->buffer_line + 2; i < self->lines; i++) { + self->buffer[i - 1] = self->buffer[i]; + } + + self->buffer[self->lines - 1] = str_new(); + self->lines--; + refresh_buffer(self); + } else { + // removes the character from the current line + str_remove(&self->buffer[self->buffer_line], self->buffer_col); + delch(); + } + } void pressed_enter(Editor* self) { + // allocate memory immediately since we know a new line is being added + self->lines++; + self->buffer = realloc(self->buffer, sizeof(String_t) * (self->lines)); + + if (self->buffer_line == self->lines -1) { + // if at end of file add an empty line + self->buffer[self->lines - 1] = str_new(); + } else { + // else shift each line downwards including everything past the cursor on the current line + for (size_t i = self->lines - 1; i > self->buffer_line + 1; i--) { + self->buffer[i] = self->buffer[i - 1]; + } + + self->buffer[self->buffer_line + 1] = str_slice( + &self->buffer[self->buffer_line], + self->buffer_col, + str_len(&self->buffer[self->buffer_line]) + ); + + self->buffer[self->buffer_line] = str_slice( + &self->buffer[self->buffer_line], + 0, + self->buffer_col + ); + } + // refresh the screen with the new data + refresh_buffer(self); move_cursor(self, 1, 0); } +// inserts a character at the cursor void addchar(Editor* self, char c) { - if (self->screen_line == self->lines) { - move(self->screen_line, 0); - char line_no[5]; - snprintf(line_no, 5, "%-5d", self->screen_line + 1); - // adding the line of text to the buffer - addstr(line_no); - addch(' '); - move(self->screen_line, self->screen_col + 5); + if (self->buffer_line == self->lines) { + // if we are at the end of the file then we need to add a new line + newline(self); - fprintf(stderr, "buffer full\n"); // reallocate self->buffer to be 1 larger self->lines++; - self->buffer = realloc(self->buffer, sizeof(String_t) * (self->lines + 1)); + self->buffer = realloc(self->buffer, sizeof(String_t) * (self->lines)); // allocate the memory space for the new line and add it to the buffer - self->buffer[self->screen_line] = str_new(); - for (size_t i = 0; i < self->lines; i++) { - fprintf(stderr, "size: %d\n", (&self->buffer[i])->size); - } - - fprintf(stderr, "ok!"); + self->buffer[self->buffer_line] = str_new(); } insch(c); // insert the character into the string at the given index - str_insert(&self->buffer[self->screen_line], self->screen_col, c); + str_insert(&self->buffer[self->buffer_line], self->buffer_col, c); move_cursor(self, 1, 0); } diff --git a/final/editor.h b/final/editor.h index fadee90..5eb7ed1 100644 --- a/final/editor.h +++ b/final/editor.h @@ -3,19 +3,22 @@ typedef struct { uint32_t lines; - uint32_t screen_line; - uint32_t screen_col; + uint32_t buffer_line; + uint32_t buffer_col; + uint32_t y_offset; + uint32_t x_offset; bool editmode; String_t* buffer; } Editor; Editor new_editor(); -Editor editor_from(char* input_string); +Editor editor_from(String_t input_string); void move_cursor(Editor* self, int x, int y); void delchar(Editor* self); void addchar(Editor* self, char c); void pressed_enter(Editor* self); +void switch_mode(Editor* self); String_t* to_string(Editor* self); diff --git a/final/log.txt b/final/log.txt index ca0ed9d..50edf5f 100644 --- a/final/log.txt +++ b/final/log.txt @@ -1,19 +1 @@ -buffer full -size: 25 -size: 23 -size: 25 -size: 0 -ok!buffer full -size: 25 -size: 23 -size: 30 -size: 4 -size: 0 -ok!buffer full -size: 25 -size: 23 -size: 30 -size: 4 -size: 1 -size: 0 -ok! \ No newline at end of file +Fatal glibc error: malloc.c:2599 (sysmalloc): assertion failed: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0) diff --git a/final/main.c b/final/main.c index 2894162..c4d5dd3 100644 --- a/final/main.c +++ b/final/main.c @@ -22,16 +22,40 @@ int open_editor() { int max_y, max_x; getmaxyx(stdscr, max_y, max_x); - Editor editor = editor_from("this is some text to edit\nthis is the second line\nand this is the third lol"); - move(0, 5); + FILE* file = fopen("somecode.c", "r"); + if (file == NULL) { + endwin(); + printf("Failed to open file\n"); + return 1; + } + + String_t text = str_new(); + + // read from file char by char + + while (true) { + char line[1024]; + if (fgets(line, 1024, file) == NULL) { + break; + } + String_t new_text = str_from_chars(line); + text = str_merge(&text, &new_text); + str_dealloc(&new_text); + } + + fclose(file); + + Editor editor = editor_from(text); + move(0, 5); + while (true) { refresh(); int c = getch(); if (editor.editmode == true) { switch (c) { case 27: - editor.editmode = false; + switch_mode(&editor); break; case KEY_BACKSPACE: move_cursor(&editor, -1, 0); @@ -40,10 +64,8 @@ int open_editor() { case KEY_DC: delchar(&editor); break; - case KEY_ENTER: - //pressed_enter(&editor); - move_cursor(&editor, 1, 0); - //TODO: next line + case '\n': + pressed_enter(&editor); break; case KEY_UP: move_cursor(&editor, 0, -1); @@ -58,6 +80,7 @@ int open_editor() { move_cursor(&editor, 1, 0); break; default: + fprintf(stderr, "%d\n", c); addchar(&editor, c); break; } @@ -67,7 +90,7 @@ int open_editor() { endwin(); return 0; case 'i': - editor.editmode = true; + switch_mode(&editor); break; case 'w': // TODO: write function to save the data to a file diff --git a/final/somecode.c b/final/somecode.c new file mode 100644 index 0000000..2ffb31b --- /dev/null +++ b/final/somecode.c @@ -0,0 +1,213 @@ +/// 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; +// }