git.haldean.org expel / b1079ad
put line in stream in a helper thing Haldean Brown 6 years ago
5 changed file(s) with 126 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
0 nobase_include_HEADERS = expel/bdagc.h expel/stream.h expel/timer.h expel/ast.h expel/const.h expel/assert.h expel/env.h expel/token.h expel/gen.h expel/natives.h expel/expel.h expel/dagc.h expel/uri.h expel/def-native.h expel/value.h expel/string.h expel/util.h expel/gc.h expel/compile.h expel/pointerset.h expel/schedule.h expel/parse.h expel/types.h expel/vector.h expel/resolve.h expel/closure.h
0 nobase_include_HEADERS = expel/bdagc.h expel/stream.h expel/timer.h expel/ast.h expel/const.h expel/assert.h expel/env.h expel/token.h expel/gen.h expel/natives.h expel/expel.h expel/dagc.h expel/uri.h expel/def-native.h expel/value.h expel/string.h expel/util.h expel/gc.h expel/compile.h expel/pointerset.h expel/schedule.h expel/parse.h expel/types.h expel/vector.h expel/resolve.h expel/closure.h expel/streamutil.h
11
22 expel/const.h: ../res/const.txt
33 $(AWK) -f ../res/compile-const.awk $< > $@
0 /*
1 * streamutil.h: generally useful stream helpers
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/stream.h"
20
21 /* Takes the line with index i from stream and copies it into the n-length
22 * buffer res. */
23 no_ignore xl_error
24 xl_streamutil_get_line(
25 char *res,
26 struct xl_stream *stream,
27 size_t i,
28 size_t n);
00 lib_LIBRARIES = libexpel.a
1 libexpel_a_SOURCES = store.c error.c uri.c gen.c timer.c eval.c load.c gc.c pointerset.c compile.c string.c schedule.c natives.c types.c print-ast.c value.c bdagc.c assert.c explain.c ast.c dagc.c parse.c util.c rt.c stream.c env.c token.l grammar.y uri-value.tree humanize-poly.tree vector.c resolve.c closure.c
1 libexpel_a_SOURCES = store.c error.c uri.c gen.c timer.c eval.c load.c gc.c pointerset.c compile.c string.c schedule.c natives.c types.c print-ast.c value.c bdagc.c assert.c explain.c ast.c dagc.c parse.c util.c rt.c stream.c env.c token.l grammar.y uri-value.tree humanize-poly.tree vector.c resolve.c closure.c streamutil.c
22 BUILT_SOURCES = grammar.h uri-value.h humanize-poly.h
33
44 libexpel_a_CFLAGS = -std=c11 -Werror -Wall -Wextra -fno-strict-aliasing -rdynamic -Wswitch-enum -fPIC
1818
1919 #include <stdlib.h>
2020 #include "expel/parse.h"
21 #include "expel/streamutil.h"
2122 #include "grammar.h"
2223
2324 /* autotools doesn't yet support flex headers, so we have to declare these
3233 xl_vector_free(&ctx->allocs);
3334 }
3435
35 #define lis_buf_size 1024
3636 void
3737 _print_line_in_stream(struct xl_stream *stream, size_t line)
3838 {
39 char buf[lis_buf_size];
40 size_t i;
41 size_t n_lines_seen;
42 size_t read;
39 #define lis_buf_len 512
40 char buf[lis_buf_len];
41 char *explain;
42 xl_error err;
4343
44 xl_stream_reset(stream);
45 n_lines_seen = 0;
46
47 for (;;)
44 err = xl_streamutil_get_line(buf, stream, line, lis_buf_len);
45 if (err != OK)
4846 {
49 read = xl_stream_read(buf, stream, lis_buf_size - 1);
50 if (read == 0)
51 return;
52 buf[read] = '\0';
53
54 for (i = 0; i < lis_buf_size - 1; i++)
55 {
56 if (buf[i] == '\n')
57 {
58 n_lines_seen++;
59 if (n_lines_seen == line)
60 goto line_found;
61 }
62 }
47 explain = xl_error_explain(err);
48 printf("couldn't print line in file: %s\n", explain);
49 return;
6350 }
64
65 line_found:
66 for (;;)
67 {
68 for (i++; i < lis_buf_size - 1; i++)
69 {
70 putchar(buf[i]);
71 if (buf[i] == '\n')
72 return;
73 }
74 read = xl_stream_read(buf, stream, lis_buf_size - 1);
75 if (read == 0)
76 {
77 printf("\n");
78 return;
79 }
80 i = 0;
81 }
51 printf("%s\n", buf);
8252 }
8353
8454 void
0 /*
1 * streamutil.c: generally useful stream helpers
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <strings.h>
20 #include "expel/streamutil.h"
21
22 #define GET_LINE_BUF_SIZE 1024
23
24 no_ignore xl_error
25 xl_streamutil_get_line(
26 char *res,
27 struct xl_stream *stream,
28 size_t line_i,
29 size_t n)
30 {
31 char buf[GET_LINE_BUF_SIZE];
32 size_t i;
33 size_t res_i;
34 size_t n_lines_seen;
35 size_t read;
36
37 xl_stream_reset(stream);
38 n_lines_seen = 0;
39
40 if (n <= 1)
41 return xl_raise(ERR_BAD_VALUE, "buffer too short");
42 bzero(res, n);
43
44 for (;;)
45 {
46 read = xl_stream_read(buf, stream, GET_LINE_BUF_SIZE - 1);
47 if (read == 0)
48 return xl_raise(ERR_NO_DATA, "line does not exist");
49 buf[read] = '\0';
50
51 for (i = 0; i < GET_LINE_BUF_SIZE - 1; i++)
52 {
53 if (buf[i] == '\n')
54 {
55 n_lines_seen++;
56 if (n_lines_seen == line_i)
57 goto line_found;
58 }
59 }
60 }
61
62 line_found:
63 res_i = 0;
64 for (;;)
65 {
66 for (i++; i < GET_LINE_BUF_SIZE - 1; i++)
67 {
68 if (buf[i] == '\n')
69 return OK;
70 res[res_i++] = buf[i];
71 if (res_i - 1 == n)
72 return xl_raise(
73 ERR_FULL, "not enough space in buffer");
74 }
75 read = xl_stream_read(buf, stream, GET_LINE_BUF_SIZE - 1);
76 if (read == 0)
77 {
78 return OK;
79 }
80 i = 0;
81 }
82 }
83