blob: 423c23112654b1d4d5873ec048ab8750cf0199d3 [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
swissChilid24cd202021-07-02 13:30:58 -070084void stristream_getpos(struct istream *is, int *line, char **name)
85{
86 struct stristream_private *p = is->data;
87
88 *name = "<input literal>";
89 *line = p->line;
90}
91
swissChili923b5362021-05-09 20:31:43 -070092struct istream *new_stristream(char *str, int length)
93{
94 struct istream *is = malloc(sizeof(struct istream));
95 struct stristream_private *p = malloc(sizeof(struct stristream_private));
96
97 p->val = strndup(str, length);
98 p->i = 0;
99 p->length = length;
100 p->line = 1;
101 p->fromleft = 1;
102 p->linestart = 0;
103
104 is->data = p;
105 is->get = stristream_get;
106 is->peek = stristream_peek;
107 is->read = stristream_read;
108 is->showpos = stristream_showpos;
swissChilid24cd202021-07-02 13:30:58 -0700109 is->getpos = stristream_getpos;
swissChili923b5362021-05-09 20:31:43 -0700110
111 return is;
112}
113
114void del_stristream(struct istream *stristream)
115{
116 struct stristream_private *p = stristream->data;
117 free(p->val);
118 free(p);
119 free(stristream);
120}
121
122struct istream *new_stristream_nt(char *str)
123{
124 return new_stristream(str, strlen(str));
125}
126
127struct fistream_private
128{
129 FILE *file;
130 int next;
131 bool has_next;
swissChilid24cd202021-07-02 13:30:58 -0700132 int line;
swissChili15f1cae2021-07-05 19:08:47 -0700133 char *path;
swissChili923b5362021-05-09 20:31:43 -0700134};
135
136int fistream_peek(struct istream *is)
137{
138 struct fistream_private *p = is->data;
139
140 if (p->has_next)
141 return p->next;
142
143 p->next = fgetc(p->file);
144 p->has_next = true;
145 return p->next;
146}
147
148int fistream_get(struct istream *is)
149{
150 struct fistream_private *p = is->data;
151
swissChilid24cd202021-07-02 13:30:58 -0700152 char c;
153
swissChili923b5362021-05-09 20:31:43 -0700154 if (p->has_next)
155 {
156 p->has_next = false;
swissChilid24cd202021-07-02 13:30:58 -0700157 c = p->next;
swissChili923b5362021-05-09 20:31:43 -0700158 }
swissChilid24cd202021-07-02 13:30:58 -0700159 else
160 c = fgetc(p->file);
swissChili923b5362021-05-09 20:31:43 -0700161
swissChilid24cd202021-07-02 13:30:58 -0700162 if (c == '\n')
163 p->line++;
164
165 return c;
swissChili923b5362021-05-09 20:31:43 -0700166}
167
168int fistream_read(struct istream *is, char *buffer, int size)
169{
170 struct fistream_private *p = is->data;
171
172 int offset = 0;
swissChili53e7cd12021-08-02 21:55:53 -0700173 char *buffer_o = buffer;
swissChili923b5362021-05-09 20:31:43 -0700174
175 if (p->has_next)
176 {
177 *buffer = p->next;
178 p->has_next = false;
179 buffer++;
180 size--;
181 offset = 1;
182 }
183
swissChili53e7cd12021-08-02 21:55:53 -0700184 int read = (int)fread(buffer, 1, size, p->file) + offset;
185
186 for (int i = 0; i < read; i++)
187 {
188 if (buffer_o[i] == '\n')
189 p->line++;
190 }
191
192 return read;
swissChili923b5362021-05-09 20:31:43 -0700193}
194
195void fistream_showpos(struct istream *s, FILE *out)
196{
swissChili53e7cd12021-08-02 21:55:53 -0700197 struct fistream_private *p = s->data;
198
199 fprintf(out, "At %s:%d\n", p->path, p->line);
swissChili923b5362021-05-09 20:31:43 -0700200}
201
swissChilid24cd202021-07-02 13:30:58 -0700202void fistream_getpos(struct istream *is, int *line, char **name)
203{
204 struct fistream_private *p = is->data;
205
206 *line = p->line;
swissChili15f1cae2021-07-05 19:08:47 -0700207 *name = p->path;
swissChilid24cd202021-07-02 13:30:58 -0700208}
209
swissChili923b5362021-05-09 20:31:43 -0700210struct istream *new_fistream(char *path, bool binary)
211{
212 struct istream *is = malloc(sizeof(struct istream));
213
214 FILE *fp = fopen(path, binary ? "rb" : "r");
215
216 if (fp == NULL)
217 {
218 free(is);
219 return NULL;
220 }
221
222 struct fistream_private *p = is->data =
223 malloc(sizeof(struct fistream_private));
224
225 p->has_next = false;
226 p->file = fp;
swissChilid24cd202021-07-02 13:30:58 -0700227 p->line = 1;
swissChili15f1cae2021-07-05 19:08:47 -0700228 p->path = path;
swissChili923b5362021-05-09 20:31:43 -0700229
230 is->data = p;
231 is->get = fistream_get;
232 is->peek = fistream_peek;
233 is->read = fistream_read;
234 is->showpos = fistream_showpos;
swissChilid24cd202021-07-02 13:30:58 -0700235 is->getpos = fistream_getpos;
swissChili923b5362021-05-09 20:31:43 -0700236
237 return is;
238}
239
240void del_fistream(struct istream *is)
241{
242 struct fistream_private *p = is->data;
243
244 fclose(p->file);
245
246 free(is->data);
247 free(is);
248}