aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-07-19 12:37:52 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-07-19 12:37:52 +0200
commit0d6dbfe292c61b935edd3e367c9032b27c850efc (patch)
treeac26fdd1abd9bf7f7d555053cc356668b1c1c4d4
parentbb6cfc65c9e86d85c74d5bcce6c32a8937e611f8 (diff)
downloadvis-0d6dbfe292c61b935edd3e367c9032b27c850efc.tar.gz
vis-0d6dbfe292c61b935edd3e367c9032b27c850efc.tar.xz
text: slight cleanup, add a few comments
-rw-r--r--text.c39
-rw-r--r--text.h40
2 files changed, 56 insertions, 23 deletions
diff --git a/text.c b/text.c
index 520211e..fee7aef 100644
--- a/text.c
+++ b/text.c
@@ -34,6 +34,7 @@
#include "text.h"
#include "util.h"
+/* Allocate buffers holding the actual file content in junks of size: */
#define BUFFER_SIZE (1 << 20)
/* Files smaller than this value are copied on load, larger ones are mmap(2)-ed
* directely. Hence the former can be truncated, while doing so on the latter
@@ -50,18 +51,19 @@ struct Regex {
*/
typedef struct Buffer Buffer;
struct Buffer {
- size_t size; /* maximal capacity */
- size_t len; /* current used length / insertion position */
- char *data; /* actual data */
+ size_t size; /* maximal capacity */
+ size_t len; /* current used length / insertion position */
+ char *data; /* actual data */
enum { MMAP, MALLOC} type; /* type of allocation */
- Buffer *next; /* next junk */
+ Buffer *next; /* next junk */
};
/* A piece holds a reference (but doesn't itself store) a certain amount of data.
* All active pieces chained together form the whole content of the document.
* At the beginning there exists only one piece, spanning the whole document.
- * Upon insertion/delition new pieces will be created to represent the changes.
- * Generally pieces are never destroytxt, but kept around to peform undo/redo operations.
+ * Upon insertion/deletion new pieces will be created to represent the changes.
+ * Generally pieces are never destroyed, but kept around to peform undo/redo
+ * operations.
*/
struct Piece {
Text *text; /* text to which this piece belongs */
@@ -69,11 +71,11 @@ struct Piece {
Piece *global_prev; /* double linked list in order of allocation, */
Piece *global_next; /* used to free individual pieces */
const char *data; /* pointer into a Buffer holding the data */
- size_t len; /* the lenght in number of bytes starting from content */
+ size_t len; /* the length in number of bytes of the data */
};
-/* used to transform a global position (byte offset starting from the begining
- * of the text) into an offset relative to piece.
+/* used to transform a global position (byte offset starting from the beginning
+ * of the text) into an offset relative to a piece.
*/
typedef struct {
Piece *piece; /* piece holding the location */
@@ -129,7 +131,7 @@ struct Text {
Action *last_action; /* the last action added to the tree, chronologically */
Action *saved_action; /* the last action at the time of the save operation */
size_t size; /* current file content size in bytes */
- struct stat info; /* stat as proped on load time */
+ struct stat info; /* stat as probed at load time */
LineCache lines; /* mapping between absolute pos in bytes and logical line breaks */
enum TextNewLine newlines; /* which type of new lines does the file use */
};
@@ -1081,13 +1083,15 @@ bool text_delete(Text *txt, size_t pos, size_t len) {
size_t off = loc.off;
if (cache_delete(txt, p, off, len))
return true;
- size_t cur; // how much has already been deleted
- bool midway_start = false, midway_end = false;
Change *c = change_alloc(txt, pos);
if (!c)
return false;
- Piece *before, *after; // unmodified pieces before / after deletion point
- Piece *start, *end; // span which is removed
+
+ bool midway_start = false, midway_end = false; /* split pieces? */
+ Piece *before, *after; /* unmodified pieces before/after deletion point */
+ Piece *start, *end; /* span which is removed */
+ size_t cur; /* how much has already been deleted */
+
if (off == p->len) {
/* deletion starts at a piece boundry */
cur = 0;
@@ -1102,6 +1106,7 @@ bool text_delete(Text *txt, size_t pos, size_t len) {
if (!before)
return false;
}
+
/* skip all pieces which fall into deletion range */
while (cur < len) {
p = p->next;
@@ -1112,8 +1117,8 @@ bool text_delete(Text *txt, size_t pos, size_t len) {
/* deletion stops at a piece boundry */
end = p;
after = p->next;
- } else { // cur > len
- /* deletion stops midway through a piece */
+ } else {
+ /* cur > len: deletion stops midway through a piece */
midway_end = true;
end = p;
after = piece_alloc(txt);
@@ -1527,7 +1532,7 @@ bool text_range_valid(Filerange *r) {
}
size_t text_range_size(Filerange *r) {
- return text_range_valid(r) ? r-> end - r->start : 0;
+ return text_range_valid(r) ? r->end - r->start : 0;
}
Filerange text_range_empty(void) {
diff --git a/text.h b/text.h
index 16b4a45..3b6344b 100644
--- a/text.h
+++ b/text.h
@@ -15,9 +15,13 @@ typedef struct {
size_t start, end; /* range in bytes from start of the file */
} Filerange;
+/* test whether the given range is valid (start <= end) */
bool text_range_valid(Filerange*);
+/* get the size of the range (end-start) or zero if invalid */
size_t text_range_size(Filerange*);
+/* create an empty / invalid range of size zero */
Filerange text_range_empty(void);
+/* merge two ranges into a new one which contains both of them */
Filerange text_range_union(Filerange*, Filerange*);
typedef struct Text Text;
@@ -36,17 +40,23 @@ typedef struct {
text_iterator_valid(&it); \
text_iterator_next(&it))
-Text *text_load(const char *file);
+/* create a text instance populated with the given file content, if `filename'
+ * is NULL the text starts out empty */
+Text *text_load(const char *filename);
/* file information at time of load or last save */
struct stat text_stat(Text*);
+/* insert `len' bytes starting from `data' at `pos' which has to be
+ * in the interval [0, text_size(txt)] */
bool text_insert(Text*, size_t pos, const char *data, size_t len);
+/* delete `len' bytes starting from `pos' */
bool text_delete(Text*, size_t pos, size_t len);
+/* mark the current text state, such that it can be {un,re}done */
void text_snapshot(Text*);
-/* undo/redos to the last snapshoted state. returns the position where
- * the change occured or EPOS if nothing could be undo/redo. */
+/* undo/redo to the last snapshotted state. returns the position where
+ * the change occured or EPOS if nothing could be {un,re}done. */
size_t text_undo(Text*);
size_t text_redo(Text*);
-/* move chronlogically to the count earlier/later revision */
+/* move chronlogically to the `count' earlier/later revision */
size_t text_earlier(Text*, int count);
size_t text_later(Text*, int count);
/* restore the text to the state closest to the time given */
@@ -57,7 +67,12 @@ time_t text_state(Text*);
size_t text_pos_by_lineno(Text*, size_t lineno);
size_t text_lineno_by_pos(Text*, size_t pos);
+/* set `buf' to the byte found at `pos' and return true, if `pos' is invalid
+ * false is returned and `buf' is left unmodified */
bool text_byte_get(Text*, size_t pos, char *buf);
+/* store at most `len' bytes starting from `pos' into `buf', the return value
+ * indicates how many bytes were copied into `buf'. WARNING buf will not be
+ * NUL terminated. */
size_t text_bytes_get(Text*, size_t pos, size_t len, char *buf);
Iterator text_iterator_get(Text*, size_t pos);
@@ -78,13 +93,20 @@ bool text_iterator_char_next(Iterator*, char *c);
bool text_iterator_char_prev(Iterator*, char *c);
typedef const char* Mark;
+/* mark position `pos', the returned mark can be used to later retrieve
+ * the same text segment */
Mark text_mark_set(Text*, size_t pos);
+/* get position of mark in bytes from start of the file or EPOS if
+ * the mark is not/no longer valid e.g. if the corresponding text was
+ * deleted. If the change is later restored the mark will once again be
+ * valid. */
size_t text_mark_get(Text*, Mark);
/* get position of change denoted by index, where 0 indicates the most recent */
size_t text_history_get(Text*, size_t index);
-
+/* return the size in bytes of the whole text */
size_t text_size(Text*);
+/* query whether the text contains any unsaved modifications */
bool text_modified(Text*);
/* which type of new lines does the text use? */
@@ -95,10 +117,16 @@ enum TextNewLine {
enum TextNewLine text_newline_type(Text*);
-bool text_save(Text*, const char *file);
+/* save the whole text to the given `filename'. Return true if succesful.
+ * In which case an implicit snapshot is taken. The save might associate a
+ * new inode to file. */
+bool text_save(Text*, const char *filename);
bool text_range_save(Text*, Filerange*, const char *file);
+/* write the text content to the given file descriptor `fd'. Return the
+ * number of bytes written or -1 in case there was an error. */
ssize_t text_write(Text*, int fd);
ssize_t text_range_write(Text*, Filerange*, int fd);
+/* release all ressources associated with this text instance */
void text_free(Text*);
typedef struct Regex Regex;