parent
31afd8b2bc
commit
7ca58c594d
@ -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)
|
||||
|
@ -0,0 +1,204 @@ |
||||
#include "fbuffer.h" |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <ctype.h> |
||||
|
||||
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; |
||||
} |
@ -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 |
Loading…
Reference in new issue