-
Notifications
You must be signed in to change notification settings - Fork 0
/
buffer.c
119 lines (103 loc) · 2.07 KB
/
buffer.c
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "utils.h"
//#define N 4096
#define N 4096
#define BUFFER_INPUT_FILENO script_fileno
static char A[N+1];
static char B[N+1];
static char* front;
static char* back;
static char* mark;
static size_t count;
extern unsigned int script_fileno;
static void buff_eof() {
error("Reached end of file!");
}
static void buff_update() {
unsigned int n = read(BUFFER_INPUT_FILENO, back, N);
while (n < N) {
*(back+n) = '\0';
n++;
}
swap(&front, &back);
}
static int buff_check(char* p) {
if (back <= p && p <= back+N) return 0;
if (front <= p && p <= front+N) return 1;
return -1;
}
char* buff_next() {
++count;
++mark;
if (*mark == '\0') {
if (mark == back+N) mark = front;
else if (mark == front+N) {
buff_update();
mark = front;
}
}
return mark;
}
char* buff_back() {
--count;
--mark;
if (mark == front-1) mark = back+N-1;
return mark;
}
char* buff_rewind(unsigned int n) {
char * f = mark; while(n) {
f = buff_back(); n--;
} return f;
}
char* buff_copy(char* begin, char* end) {
char* dest = (char*) malloc(sizeof(char)*buff_distance(begin, end)+1);
char* adv = dest;
if (begin == end) {
adv[0] = '\0'; return dest;
}
char* t = mark;
size_t c = count;
mark = begin;
do {
*adv = *begin;
begin = buff_next();
adv++;
} while (begin!=end && *begin != '\0');
*adv = '\0';
mark = t;
count = c;
return dest;
}
void buff_print(char* begin, char* end) {
if (begin == end) return;
char* t = mark;
size_t c = count;
mark = begin;
do {
write(STDOUT_FILENO, begin, 1);
begin = buff_next();
} while (begin!=end && *begin != '\0');
mark = t;
count = c;
}
unsigned int buff_distance(char* begin, char* end) {
if (begin == end) return 0;
if (buff_check(begin) == buff_check(end)) return end - begin;
if (back == (char*) &A) return end - begin - 1 ;
return begin - end - 1;
}
void buff_print_all() {
write(STDOUT_FILENO, back, N);
write(STDOUT_FILENO, front, N);
printf("\n");
}
size_t buff_get_count() { return count; }
char* buff_init() {
front = A;
back = B;
mark = A;
count = 0;
buff_update();
buff_update();
mark = back;
return mark;
}