From 7ca58c594d58e4784a34824e10eab34837aaeb4a Mon Sep 17 00:00:00 2001 From: gunboy001 Date: Mon, 18 Nov 2019 23:54:59 +0100 Subject: [PATCH] code refractor --- Makefile | 16 ++-- fbuffer.c | 204 ++++++++++++++++++++++++++++++++++++++++++++ fbuffer.h | 46 ++++++++++ fbuffer.o | Bin 0 -> 6392 bytes ste.c | 251 ++---------------------------------------------------- ste.o | Bin 0 -> 12880 bytes 6 files changed, 268 insertions(+), 249 deletions(-) create mode 100644 fbuffer.c create mode 100644 fbuffer.h create mode 100644 fbuffer.o create mode 100644 ste.o diff --git a/Makefile b/Makefile index 52cccfb..cda6f76 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,19 @@ CC=gcc CFLAGS=-Wall -Wextra -pedantic -Werror -Warray-bounds OFLAGS=-O3 -#-ltcmalloc LFLAGS=-lncursesw DFLAGS=-g -O0 -v -da -Q -ste: ste.c - $(CC) $(CFLAGS) $(OFLAGS) $(LFLAGS) -o ste $^ +OBJ=ste.o fbuffer.o +DEPS=fbuffer.h + +ste: $(OBJ) + $(CC) $(CFLAGS) $(OFLAGS) $(LFLAGS) -o $@ $^ + +%.o: %.c $(DEPS) + $(CC) $(CFLAGS) $(OFLAGS) $(LFLAGS) -c -o $@ $< + -dbg: ste.c - $(CC) $(CFLAGS) $(DFLAGS) $(LFLAGS) -o dbg $^ clean: - rm ste ste.c.* dbg + rm ste $(OBJ) diff --git a/fbuffer.c b/fbuffer.c new file mode 100644 index 0000000..2325265 --- /dev/null +++ b/fbuffer.c @@ -0,0 +1,204 @@ +#include "fbuffer.h" +#include +#include +#include + +void bufInit (buf *b) +{ + b->rw = NULL; + b->rownum = 0; +} + +/* Add a row to the file buffer */ +void rowAddLast (buf *b, char *s, int len) +{ + /* Extend the block of memory containing the lines */ + row *newr = realloc(b->rw, (b->rownum + 1) * sizeof(row)); + //if (newr == NULL) termDie("realloc in rowAddLast"); + b->rw = newr; + + /* Allocate memory for the line and copy it + * at the current row number */ + b->rw[b->rownum].chars = malloc(len + 1); + //if (b->rw[b->rownum].chars == NULL) termDie("malloc in rowAddLast chars"); + memcpy(b->rw[b->rownum].chars, s, len); + b->rw[b->rownum].chars[len] = '\0'; + b->rw[b->rownum].size = len; + updateRender(&b->rw[b->rownum]); + b->rownum++; +} + +void rowAddChar (row *rw, char c, int pos) +{ + /* Check if char is valid */ + if (!c || (iscntrl(c) && c != '\t')) return; + + /* extend the string */ + rw->size++; + char *t = realloc(rw->chars, rw->size + 1); + //if (t == NULL) termDie("realloc in rowAddchar"); + rw->chars = t; + + /* make space for the new char */ + memcpy(&rw->chars[pos + 1], &rw->chars[pos], (rw->size + 1) - (pos + 1)); + + /* add the new char */ + rw->chars[pos] = c; + + updateRender(rw); +} + +int rowDeleteChar (row *rw, int select, int pos) // WIP +{ + /* Check if the character is valid */ + if (rw->chars[pos - 1] == '\0' && pos) return 0; + if (!pos && !select) return 0; + if (rw->chars[pos] == '\0' && select) return 0; + //change pos based on the command + if (!select) pos--; + + memcpy(&rw->chars[pos], &rw->chars[pos + 1], rw->size - pos); + + char *s = realloc(rw->chars, rw->size); + if (s != NULL) rw->chars = s; + rw->size--; + + updateRender(rw); + return 1; +} + +void rowAddRow (buf *b, int pos, int cur) // WIP; TO DOCUMENT +{ + /* MOVE THE ROWS AWAY */ + /* add another line to the bottom containing the previous + * (last) line, effectively making new space */ + rowAddLast(b, b->rw[b->rownum - 1].chars, b->rw[b->rownum - 1].size); + + /* copy all other lines until the specified position to the next one */ + for (int last = b->rownum - 1; last > pos; last--) + rowCpy(&b->rw[last], &b->rw[last - 1]); + + /* SPLIT THE ROW AT POS AND STORE IT */ + /* Get the row length at position after the cursor */ + int len = b->rw[pos].size - cur; + /* create a dummy row as the new row souce */ + row nex = EROW; + /* allocate a buffer */ + char *s = malloc(len + 1); + //if (s == NULL) termDie("malloc in rowAddRow s"); + /* copy the contents of the pos row after the cursor into the buffer */ + memcpy(s, &b->rw[pos].chars[cur], len); + s[len] = '\0'; + /* update the dummy row */ + nex.chars = s; + nex.size = strlen(s); + + /* MAKE THE SPLIT INTO TWO LINES */ + /* shrink the line at pos */ + char *p = realloc(b->rw[pos].chars, cur + 1); + //if (p == NULL) termDie("realloc in rowAddRow"); + b->rw[pos].chars = p; + /* and terminate it with null like a good boi */ + b->rw[pos].chars[cur] = '\0'; + /* update info and render */ + b->rw[pos].size = cur; + updateRender(&b->rw[pos]); + + /* copy the dummy to the new line and free */ + rowCpy(&b->rw[pos + 1], &nex); + rowFree(&nex); + +} + +void rowFree (row *rw) // WIP +{ + /* Free both render and memory strings */ + free(rw->render); + free(rw->chars); + /* clear sizes */ + rw->size = 0; + rw->r_size = 0; + rw->utf = 0; +} + +void rowCpy (row *to, row *from) // WIP +{ + /* Free the destination row (without destroying it) */ + rowFree(to); + /* Allocate space for the new string */ + to->chars = (char*) malloc(strlen(from->chars) + 1); + //if (to->chars == NULL) termDie("malloc in rowCpy"); + /* And update the size */ + to->size = from->size; + /* Then copy the chars from the source row to the destination row */ + memcpy(to->chars, from->chars, to->size); + to->chars[to->size] = '\0'; + /* Then update the render */ + updateRender(to); +} + +void rowAppendString (row *rw, char *s, int len) +{ + /* reallocate the row to accomodate for the added string */ + char *temp = realloc(rw->chars, rw->size + len + 1); + //if (temp == NULL) termDie("realloc in rowAppendString"); + rw->chars = temp; + + memcpy(&rw->chars[rw->size], s, len); + rw->size += len; + rw->chars[rw->size] = '\0'; + + updateRender(rw); +} + +void rowDeleteRow (buf *b, int pos) +{ + if (b->rownum == 1) return; + if (pos >= b->rownum) return; + if (pos < 0) return; + + for (; pos < b->rownum - 1; pos++) { + rowCpy(&b->rw[pos], &b->rw[pos + 1]); // rowcpy already frees the row + } + b->rownum--; + rowFree(&b->rw[b->rownum]); + row *temp = realloc(b->rw, sizeof(row) * b->rownum); + //if (temp == NULL) termDie("realloc in rowDeleteRow"); + b->rw = temp; +} + +void updateRender (row *rw) +{ + /* count the special characters + * spaces, utf-8 continuation chars */ + static int tabs, i, off, cc, ut; + for (i = 0, tabs = 0, cc = 0, ut = 0; i < rw->size; i++) { + if (rw->chars[i] == '\t') tabs++; + else if (isCont(rw->chars[i])) cc++; + else if (isUtf(rw->chars[i])) ut++; + } + rw->render = NULL; + free(rw->render); + + /* Render is long as size with the added tab spaces - 1 + * (we already count for the \t as a char) */ + rw->render = malloc(rw->size + tabs * (TABSIZE - 1) + 1); + //if (rw->render == NULL) termDie ("malloc in updateRender"); + + /* put all the characters (substituing all special chars) + * into the render buffer */ + for (i = 0, off = 0; i < rw->size; i++) { + if (rw->chars[i] == '\t') { + for (int j = 0; j < TABSIZE; j++){ + //if (!j) rw->render[off++] = '|'; + //else rw->render[off++] = ' '; + rw->render[off++] = ' '; + } + } else { + rw->render[off++] = rw->chars[i]; + } + } + rw->render[off] = '\0'; + rw->r_size = off - cc; + rw->utf = cc + ut; +} diff --git a/fbuffer.h b/fbuffer.h new file mode 100644 index 0000000..747e2ef --- /dev/null +++ b/fbuffer.h @@ -0,0 +1,46 @@ +#ifndef _FBUFFER_H_ +#define _FBUFFER_H_ + +#define TABSIZE 4 // Tab size as used in render + +/* Row structure, defines actual and + * render chars, actual and render size + * and difference between render and + * real size of the row + * Utf-8 continuation chars */ +typedef struct row { + int size; + int r_size; + int utf; + char *chars; + char *render; +} row; + +/* Empty row initializer */ +#define EROW {0, 0, 0, NULL, NULL} + +/* Rows structure (or file buffer) + * defines rows and teh number of rows */ +typedef struct buf{ + row *rw; + int rownum; +} buf; + +void bufInit (buf *b); + +void rowAddChar (row *rw, char c, int pos); +int rowDeleteChar (row *rw, int select, int pos); +void rowCpy (row *to, row *from); +void rowAddRow (buf *b, int pos, int cur); +void rowFree (row *rw); +void rowAppendString (row *rw, char *s, int len); +void rowDeleteRow (buf *b, int pos); +void rowAddLast (buf *b, char *s, int len); + +void updateRender (row *rw); + +int isUtf (int c); +int isCont (int c); +int isStart (int c); + +#endif \ No newline at end of file diff --git a/fbuffer.o b/fbuffer.o new file mode 100644 index 0000000000000000000000000000000000000000..f4d81d80ecd5840f3174bf627eb97915ff0ae4a4 GIT binary patch literal 6392 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 literal 0 HcmV?d00001 diff --git a/ste.c b/ste.c index 408e9c3..ced5c65 100644 --- a/ste.c +++ b/ste.c @@ -4,13 +4,13 @@ #include #include +#include "fbuffer.h" + /* defines */ #define CTRL(k) ((k) & 0x1f) // Control mask modifier -#define TABSIZE 4 // Tab size as used in render #define STAT_SIZE 128 #define _XOPEN_SOURCE_EXTENDED #define _GNU_SOURCE -#define EROW {0, NULL, 0, 0, NULL} /* main data structure containing: * -cursor position @@ -38,25 +38,7 @@ struct term { int pad; } t; -/* Row structure, defines actual and - * render chars, actual and render size - * and difference between render and - * real size of the row - * Utf-8 continuation chars */ -typedef struct row { - int size; - char *chars; - int r_size; - int utf; - char *render; -} row; - -/* Rows structure (or file buffer) - * defines rows and teh number of rows */ -struct { - row *rw; - int rownum; -} rows; +buf rows; const char *msg[] = { "Find: ", @@ -68,22 +50,11 @@ const char *msg[] = { static void drawBar (char *s); static void drawScreen (); static void drawLines (void); -static void updateRender (row *rw); static void curUpdateRender (void); static void cursorMove(int a); static int decimalSize (int n); static inline void lnMove (int y, int x); -/* Row operations */ -static inline void rowInit (void); -static void rowAddChar (row *rw, char c, int pos); -static int rowDeleteChar (row *rw, int select, int pos); -static void rowCpy (row *to, row *from); -static void rowAddRow (int pos); -static void rowFree (row *rw); -static void rowAppendString (row *rw, char *s, int len); -static void rowDeleteRow (int pos); - /* Terminal operations */ static void termInit (void); static void termExit (void); @@ -94,7 +65,6 @@ static void fileOpen (char *filename); void fileSave (char *filename); /* buffer operations */ -static void rowAddLast (char *s, int len); static int editorFind (const char* needle, int* y, int* x); /* garbage */ @@ -102,15 +72,12 @@ static void handleDel (int select); /* testing */ static void updateInfo (void); static int whatsThat (void); -static inline int isUtf (int c); -static inline int isCont (int c); -static inline int isStart (int c); /* --------------------------------- main ------------------------------------ */ int main (int argc, char *argv[]) { /* Initialize the first row */ - rowInit(); + bufInit(&rows); /* Try to open the file */ if (argc < 2) { @@ -159,7 +126,7 @@ int main (int argc, char *argv[]) case (KEY_ENTER): case (10): case ('\r'): - rowAddRow(t.cur.y); + rowAddRow(&rows, t.cur.y, t.cur.x); t.cur.y++; t.cur.x = 0; break; @@ -341,44 +308,6 @@ void drawBar (char *s) attroff(COLOR_PAIR(2)); } - - -void updateRender (row *rw) -{ - /* count the special characters - * spaces, utf-8 continuation chars */ - static int tabs, i, off, cc, ut; - for (i = 0, tabs = 0, cc = 0, ut = 0; i < rw->size; i++) { - if (rw->chars[i] == '\t') tabs++; - else if (isCont(rw->chars[i])) cc++; - else if (isUtf(rw->chars[i])) ut++; - } - rw->render = NULL; - free(rw->render); - - /* Render is long as size with the added tab spaces - 1 - * (we already count for the \t as a char) */ - rw->render = malloc(rw->size + tabs * (TABSIZE - 1) + 1); - if (rw->render == NULL) termDie ("malloc in updateRender"); - - /* put all the characters (substituing all special chars) - * into the render buffer */ - for (i = 0, off = 0; i < rw->size; i++) { - if (rw->chars[i] == '\t') { - for (int j = 0; j < TABSIZE; j++){ - //if (!j) rw->render[off++] = '|'; - //else rw->render[off++] = ' '; - rw->render[off++] = ' '; - } - } else { - rw->render[off++] = rw->chars[i]; - } - } - rw->render[off] = '\0'; - rw->r_size = off - cc; - rw->utf = cc + ut; -} - /* -------------------------------- draw operations -------------------------------- */ /* Open a file and put it into a buffer line by line */ @@ -398,7 +327,7 @@ void fileOpen (char *filename) while ((linelen = getline(&line, &linecap, fp)) != -1) { while (linelen > 0 && (line[linelen - 1] == '\n' || line[linelen - 1] == '\r')) linelen--; - rowAddLast(line, linelen); + rowAddLast(&rows, line, linelen); } /* free the line buffer */ free(line); @@ -408,170 +337,6 @@ void fileOpen (char *filename) /*------------------------------------- file operations ----------------------------------*/ -/* Add a row to the file buffer */ -void rowAddLast (char *s, int len) -{ - /* Extend the block of memory containing the lines */ - row *newr = realloc(rows.rw, (rows.rownum + 1) * sizeof(row)); - if (newr == NULL) termDie("realloc in rowAddLast"); - else rows.rw = newr; - - /* Allocate memory for the line and copy it - * at the current row number */ - rows.rw[rows.rownum].chars = malloc(len + 1); - if (rows.rw[rows.rownum].chars == NULL) termDie("malloc in rowAddLast chars"); - memcpy(rows.rw[rows.rownum].chars, s, len); - rows.rw[rows.rownum].chars[len] = '\0'; - rows.rw[rows.rownum].size = len; - updateRender(&rows.rw[rows.rownum]); - rows.rownum++; -} - -void rowInit (void) -{ - rows.rw = NULL; - rows.rownum = 0; -} - -void rowAddChar (row *rw, char c, int pos) -{ - /* Check if char is valid */ - if (!c || (iscntrl(c) && c != '\t')) return; - - /* extend the string */ - rw->size++; - char *t = realloc(rw->chars, rw->size + 1); - if (t == NULL) termDie("realloc in rowAddchar"); - rw->chars = t; - - /* make space for the new char */ - memcpy(&rw->chars[pos + 1], &rw->chars[pos], (rw->size + 1) - (pos + 1)); - - /* add the new char */ - rw->chars[pos] = c; - - updateRender(rw); -} - -int rowDeleteChar (row *rw, int select, int pos) // WIP -{ - /* Check if the character is valid */ - if (rw->chars[pos - 1] == '\0' && pos) return 0; - if (!pos && !select) return 0; - if (rw->chars[pos] == '\0' && select) return 0; - //change pos based on the command - if (!select) pos--; - - memcpy(&rw->chars[pos], &rw->chars[pos + 1], rw->size - pos); - - char *s = realloc(rw->chars, rw->size); - if (s != NULL) rw->chars = s; - rw->size--; - - updateRender(rw); - return 1; -} - -void rowAddRow (int pos) // WIP; TO DOCUMENT -{ - /* MOVE THE ROWS AWAY */ - /* add another line to the bottom containing the previous - * (last) line, effectively making new space */ - rowAddLast(rows.rw[rows.rownum - 1].chars, rows.rw[rows.rownum - 1].size); - - /* copy all other lines until the specified position to the next one */ - for (int last = rows.rownum - 1; last > pos; last--) - rowCpy(&rows.rw[last], &rows.rw[last - 1]); - - /* SPLIT THE ROW AT POS AND STORE IT */ - /* Get the row length at position after the cursor */ - int len = rows.rw[pos].size - t.cur.x; - /* create a dummy row as the new row souce */ - row nex = EROW; - /* allocate a buffer */ - char *s = malloc(len + 1); - if (s == NULL) termDie("malloc in rowAddRow s"); - /* copy the contents of the pos row after the cursor into the buffer */ - memcpy(s, &rows.rw[pos].chars[t.cur.x], len); - s[len] = '\0'; - /* update the dummy row */ - nex.chars = s; - nex.size = strlen(s); - - /* MAKE THE SPLIT INTO TWO LINES */ - /* shrink the line at pos */ - char *p = realloc(rows.rw[pos].chars, t.cur.x + 1); - if (p == NULL) termDie("realloc in rowAddRow"); - rows.rw[pos].chars = p; - /* and terminate it with null like a good boi */ - rows.rw[pos].chars[t.cur.x] = '\0'; - /* update info and render */ - rows.rw[pos].size = t.cur.x; - updateRender(&rows.rw[pos]); - - /* copy the dummy to the new line and free */ - rowCpy(&rows.rw[pos + 1], &nex); - rowFree(&nex); - -} - -void rowFree (row *rw) // WIP -{ - /* Free both render and memory strings */ - free(rw->render); - free(rw->chars); - /* clear sizes */ - rw->size = 0; - rw->r_size = 0; - rw->utf = 0; -} - -void rowCpy (row *to, row *from) // WIP -{ - /* Free the destination row (without destroying it) */ - rowFree(to); - /* Allocate space for the new string */ - to->chars = (char*) malloc(strlen(from->chars) + 1); - if (to->chars == NULL) termDie("malloc in rowCpy"); - /* And update the size */ - to->size = from->size; - /* Then copy the chars from the source row to the destination row */ - memcpy(to->chars, from->chars, to->size); - to->chars[to->size] = '\0'; - /* Then update the render */ - updateRender(to); -} - -void rowAppendString (row *rw, char *s, int len) -{ - /* reallocate the row to accomodate for the added string */ - char *temp = realloc(rw->chars, rw->size + len + 1); - if (temp == NULL) termDie("realloc in rowAppendString"); - rw->chars = temp; - - memcpy(&rw->chars[rw->size], s, len); - rw->size += len; - rw->chars[rw->size] = '\0'; - - updateRender(rw); -} - -void rowDeleteRow (int pos) -{ - if (rows.rownum == 1) return; - if (pos >= rows.rownum) return; - if (pos < 0) return; - - for (; pos < rows.rownum - 1; pos++) { - rowCpy(&rows.rw[pos], &rows.rw[pos + 1]); // rowcpy already frees the row - } - rows.rownum--; - rowFree(&rows.rw[rows.rownum]); - row *temp = realloc(rows.rw, sizeof(row) * rows.rownum); - if (temp == NULL) termDie("realloc in rowDeleteRow"); - rows.rw = temp; -} - /* ----------------------------- row operations --------------------------- */ /* take care of the cursor movement */ @@ -733,7 +498,7 @@ void handleDel (int select) if (t.cur.x <= 0 && t.cur.y > 0) { t.cur.x = rows.rw[t.cur.y - 1].size; rowAppendString(&rows.rw[t.cur.y - 1], rows.rw[t.cur.y].chars, rows.rw[t.cur.y].size); - rowDeleteRow(t.cur.y); + rowDeleteRow(&rows, t.cur.y); t.cur.y--; } else { if (isUtf(rows.rw[t.cur.y].chars[t.cur.x - 1])) { @@ -748,7 +513,7 @@ void handleDel (int select) } else { if (t.cur.x >= rows.rw[t.cur.y].size) { rowAppendString(&rows.rw[t.cur.y], rows.rw[t.cur.y + 1].chars, rows.rw[t.cur.y + 1].size); - rowDeleteRow(t.cur.y + 1); + rowDeleteRow(&rows, t.cur.y + 1); } else { if (isStart(rows.rw[t.cur.y].chars[t.cur.x])) { do { diff --git a/ste.o b/ste.o new file mode 100644 index 0000000000000000000000000000000000000000..75c6d5d0a90b9b65a5a45a455a4483dfa2ad336e GIT binary patch literal 12880 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