blob: 957b2b56f924feaab70cbbc01cbdbb777edfa5cd [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;
swissChili923b5362021-05-09 20:31:43 -0700133};
134
135int fistream_peek(struct istream *is)
136{
137 struct fistream_private *p = is->data;
138
139 if (p->has_next)
140 return p->next;
141
142 p->next = fgetc(p->file);
143 p->has_next = true;
144 return p->next;
145}
146
147int fistream_get(struct istream *is)
148{
149 struct fistream_private *p = is->data;
150
swissChilid24cd202021-07-02 13:30:58 -0700151 char c;
152
swissChili923b5362021-05-09 20:31:43 -0700153 if (p->has_next)
154 {
155 p->has_next = false;
swissChilid24cd202021-07-02 13:30:58 -0700156 c = p->next;
swissChili923b5362021-05-09 20:31:43 -0700157 }
swissChilid24cd202021-07-02 13:30:58 -0700158 else
159 c = fgetc(p->file);
swissChili923b5362021-05-09 20:31:43 -0700160
swissChilid24cd202021-07-02 13:30:58 -0700161 if (c == '\n')
162 p->line++;
163
164 return c;
swissChili923b5362021-05-09 20:31:43 -0700165}
166
167int fistream_read(struct istream *is, char *buffer, int size)
168{
169 struct fistream_private *p = is->data;
170
171 int offset = 0;
172
173 if (p->has_next)
174 {
175 *buffer = p->next;
176 p->has_next = false;
177 buffer++;
178 size--;
179 offset = 1;
180 }
181
182 return (int)fread(buffer, 1, size, p->file) + offset;
183}
184
185void fistream_showpos(struct istream *s, FILE *out)
186{
187 // TODO: implement
188}
189
swissChilid24cd202021-07-02 13:30:58 -0700190void fistream_getpos(struct istream *is, int *line, char **name)
191{
192 struct fistream_private *p = is->data;
193
194 *line = p->line;
195 *name = "<FILE *>";
196}
197
swissChili923b5362021-05-09 20:31:43 -0700198struct istream *new_fistream(char *path, bool binary)
199{
200 struct istream *is = malloc(sizeof(struct istream));
201
202 FILE *fp = fopen(path, binary ? "rb" : "r");
203
204 if (fp == NULL)
205 {
206 free(is);
207 return NULL;
208 }
209
210 struct fistream_private *p = is->data =
211 malloc(sizeof(struct fistream_private));
212
213 p->has_next = false;
214 p->file = fp;
swissChilid24cd202021-07-02 13:30:58 -0700215 p->line = 1;
swissChili923b5362021-05-09 20:31:43 -0700216
217 is->data = p;
218 is->get = fistream_get;
219 is->peek = fistream_peek;
220 is->read = fistream_read;
221 is->showpos = fistream_showpos;
swissChilid24cd202021-07-02 13:30:58 -0700222 is->getpos = fistream_getpos;
swissChili923b5362021-05-09 20:31:43 -0700223
224 return is;
225}
226
227void del_fistream(struct istream *is)
228{
229 struct fistream_private *p = is->data;
230
231 fclose(p->file);
232
233 free(is->data);
234 free(is);
235}