aboutsummaryrefslogtreecommitdiffstats
path: root/buffer.c
blob: b863a1699b5b0607138a5a7152d978290c5b139f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* Copyright (c) 2021 nytpu <alex@nytpu.com>
 * SPDX-License-Identifier: GPL-3.0-only
 * For more license details, see LICENSE or <https://www.gnu.org/licenses/gpl-3.0.html>.
 */

#include "buffer.h"
#include "common.h"

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

bool
in_bounds(RowNum at, RowNum top)
{
	if (at < 1 || at > top) return false;
	return true;
}

void
insert_row(RowNum at, char *r, size_t len)
{
	if (!in_bounds(at, E.numrows+1)) return;
	--at;

	E.rows = realloc(E.rows, (E.numrows+1) * sizeof(struct Row));
	if (at != E.numrows) {
		memmove(&E.rows[at+1], &E.rows[at], (E.numrows-at) * sizeof(struct Row));
		for (RowNum i = at+1; i <= E.numrows; ++i) ++E.rows[i].idx;
	}

	E.rows[at].size = len;
	E.rows[at].chars = malloc(len + 1);
	memcpy(E.rows[at].chars, r, len);
	E.rows[at].chars[len] = '\0';
	++E.numrows;
	E.dirty = true;
}

void
delete_row(RowNum at)
{
	if (!in_bounds(at, E.numrows)) return;
	--at;

	free(E.rows[at].chars);
	memmove(&E.rows[at], &E.rows[at+1], (E.numrows-at-1) * sizeof(struct Row));
	for (RowNum i = at; i < E.numrows; ++i) --E.rows[i].idx;
	--E.numrows;
	E.dirty = true;
}

void
delete_rows(RowNum from, RowNum to)
{
	if (!in_bounds(from, E.numrows)) return;
	if (!in_bounds(to, E.numrows)) return;
	for (; from <= to; ++from) delete_row(from);
}