blob: 8ac275a84f0328f4f8f6e9721221c920046d4173 [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;
173
174 if (p->has_next)
175 {
176 *buffer = p->next;
177 p->has_next = false;
178 buffer++;
179 size--;
180 offset = 1;
181 }
182
183 return (int)fread(buffer, 1, size, p->file) + offset;
184}
185
186void fistream_showpos(struct istream *s, FILE *out)
187{
188 // TODO: implement
189}
190
swissChilid24cd202021-07-02 13:30:58 -0700191void fistream_getpos(struct istream *is, int *line, char **name)
192{
193 struct fistream_private *p = is->data;
194
195 *line = p->line;
swissChili15f1cae2021-07-05 19:08:47 -0700196 *name = p->path;
swissChilid24cd202021-07-02 13:30:58 -0700197}
198
swissChili923b5362021-05-09 20:31:43 -0700199struct istream *new_fistream(char *path, bool binary)
200{
201 struct istream *is = malloc(sizeof(struct istream));
202
203 FILE *fp = fopen(path, binary ? "rb" : "r");
204
205 if (fp == NULL)
206 {
207 free(is);
208 return NULL;
209 }
210
211 struct fistream_private *p = is->data =
212 malloc(sizeof(struct fistream_private));
213
214 p->has_next = false;
215 p->file = fp;
swissChilid24cd202021-07-02 13:30:58 -0700216 p->line = 1;
swissChili15f1cae2021-07-05 19:08:47 -0700217 p->path = path;
swissChili923b5362021-05-09 20:31:43 -0700218
219 is->data = p;
220 is->get = fistream_get;
221 is->peek = fistream_peek;
222 is->read = fistream_read;
223 is->showpos = fistream_showpos;
swissChilid24cd202021-07-02 13:30:58 -0700224 is->getpos = fistream_getpos;
swissChili923b5362021-05-09 20:31:43 -0700225
226 return is;
227}
228
229void del_fistream(struct istream *is)
230{
231 struct fistream_private *p = is->data;
232
233 fclose(p->file);
234
235 free(is->data);
236 free(is);
237}