blob: 9351adf446c9bc327e7f66b69d4afd0cdf733879 [file] [log] [blame]
swissChili923b5362021-05-09 20:31:43 -07001#include "istream.h"
2
3#include <stdbool.h>
4#include <stdlib.h>
5#include <string.h>
6
7struct stristream_private
8{
9 char *val;
10 int i;
11 int length;
12 int line;
13 int fromleft;
14 int linestart;
15};
16
17int stristream_peek(struct istream *is)
18{
19 struct stristream_private *p = is->data;
20
21 if (p->i < p->length)
22 return p->val[p->i];
23 else
24 return -1;
25}
26
27int stristream_get(struct istream *is)
28{
29 struct stristream_private *p = is->data;
30
31 if (p->i < p->length)
32 {
33 char c = p->val[p->i++];
34
35 p->fromleft++;
36
37 if (c == '\n')
38 {
39 p->fromleft = 1;
40 p->line++;
41 p->linestart = p->i;
42 }
43
44 return c;
45 }
46 else
47 return -1;
48}
49
50int stristream_read(struct istream *s, char *buffer, int size)
51{
52 struct stristream_private *p = s->data;
53
54 int len = MIN(size, p->length - p->i);
55 memcpy(buffer, p->val, len);
56 return len;
57}
58
59void stristream_showpos(struct istream *s, FILE *out)
60{
61 struct stristream_private *p = s->data;
62
63 fprintf(out, "line: %d, char %d\n", p->line, p->fromleft);
64
65 int end = p->length;
66
67 for (int i = p->linestart; i < p->length; i++)
68 {
69 if (p->val[i] == '\n')
70 {
71 end = i;
72 break;
73 }
74 }
75
76 fprintf(out, " | %.*s\n", end - p->linestart, p->val + p->linestart);
77 fprintf(out, " | ");
78 for (int i = 0; i < p->fromleft - 1; i++)
79 fprintf(out, " ");
80
81 fprintf(out, "\033[31m^\033[0m\n");
82}
83
84struct istream *new_stristream(char *str, int length)
85{
86 struct istream *is = malloc(sizeof(struct istream));
87 struct stristream_private *p = malloc(sizeof(struct stristream_private));
88
89 p->val = strndup(str, length);
90 p->i = 0;
91 p->length = length;
92 p->line = 1;
93 p->fromleft = 1;
94 p->linestart = 0;
95
96 is->data = p;
97 is->get = stristream_get;
98 is->peek = stristream_peek;
99 is->read = stristream_read;
100 is->showpos = stristream_showpos;
101
102 return is;
103}
104
105void del_stristream(struct istream *stristream)
106{
107 struct stristream_private *p = stristream->data;
108 free(p->val);
109 free(p);
110 free(stristream);
111}
112
113struct istream *new_stristream_nt(char *str)
114{
115 return new_stristream(str, strlen(str));
116}
117
118struct fistream_private
119{
120 FILE *file;
121 int next;
122 bool has_next;
123};
124
125int fistream_peek(struct istream *is)
126{
127 struct fistream_private *p = is->data;
128
129 if (p->has_next)
130 return p->next;
131
132 p->next = fgetc(p->file);
133 p->has_next = true;
134 return p->next;
135}
136
137int fistream_get(struct istream *is)
138{
139 struct fistream_private *p = is->data;
140
141 if (p->has_next)
142 {
143 p->has_next = false;
144 return p->next;
145 }
146
147 return fgetc(p->file);
148}
149
150int fistream_read(struct istream *is, char *buffer, int size)
151{
152 struct fistream_private *p = is->data;
153
154 int offset = 0;
155
156 if (p->has_next)
157 {
158 *buffer = p->next;
159 p->has_next = false;
160 buffer++;
161 size--;
162 offset = 1;
163 }
164
165 return (int)fread(buffer, 1, size, p->file) + offset;
166}
167
168void fistream_showpos(struct istream *s, FILE *out)
169{
170 // TODO: implement
171}
172
173struct istream *new_fistream(char *path, bool binary)
174{
175 struct istream *is = malloc(sizeof(struct istream));
176
177 FILE *fp = fopen(path, binary ? "rb" : "r");
178
179 if (fp == NULL)
180 {
181 free(is);
182 return NULL;
183 }
184
185 struct fistream_private *p = is->data =
186 malloc(sizeof(struct fistream_private));
187
188 p->has_next = false;
189 p->file = fp;
190
191 is->data = p;
192 is->get = fistream_get;
193 is->peek = fistream_peek;
194 is->read = fistream_read;
195 is->showpos = fistream_showpos;
196
197 return is;
198}
199
200void del_fistream(struct istream *is)
201{
202 struct fistream_private *p = is->data;
203
204 fclose(p->file);
205
206 free(is->data);
207 free(is);
208}