]> git.lizzy.rs Git - nothing.git/blob - src/system/line_stream.c
Remove `lt == NULL` checks
[nothing.git] / src / system / line_stream.c
1 #include "system/stacktrace.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <stdbool.h>
7
8 #include "line_stream.h"
9 #include "lt.h"
10 #include "lt/lt_adapters.h"
11 #include "system/nth_alloc.h"
12 #include "system/log.h"
13
14 struct LineStream
15 {
16     Lt lt;
17     FILE *stream;
18     char *buffer;
19     size_t capacity;
20     bool unfinished;
21 };
22
23 static void fclose_lt(void* file)
24 {
25     fclose(file);
26 }
27
28 LineStream *create_line_stream(const char *filename,
29                                const char *mode,
30                                size_t capacity)
31 {
32     trace_assert(filename);
33     trace_assert(mode);
34
35     Lt lt = {0};
36
37     LineStream *line_stream = PUSH_LT(
38         lt,
39         nth_calloc(1, sizeof(LineStream)),
40         free);
41     if (line_stream == NULL) {
42         RETURN_LT(lt, NULL);
43     }
44     line_stream->lt = lt;
45
46     line_stream->stream = PUSH_LT(
47         lt,
48         fopen(filename, mode),
49         fclose_lt);
50     if (line_stream->stream == NULL) {
51         log_fail("Could not open file '%s': %s\n", filename, strerror(errno));
52         RETURN_LT(lt, NULL);
53     }
54
55     line_stream->buffer = PUSH_LT(
56         lt,
57         nth_calloc(1, sizeof(char) * capacity),
58         free);
59     if (line_stream->buffer == NULL) {
60         RETURN_LT(lt, NULL);
61     }
62
63     line_stream->capacity = capacity;
64     line_stream->unfinished = false;
65
66     return line_stream;
67 }
68
69 void destroy_line_stream(LineStream *line_stream)
70 {
71     trace_assert(line_stream);
72
73     RETURN_LT0(line_stream->lt);
74 }
75
76
77 const char *line_stream_next_chunk(LineStream *line_stream)
78 {
79     trace_assert(line_stream);
80
81     const char *s = fgets(line_stream->buffer,
82                           (int) line_stream->capacity,
83                           line_stream->stream);
84     if (s == NULL) {
85         return NULL;
86     }
87     size_t n = strlen(s);
88     line_stream->unfinished = s[n - 1] != '\n';
89
90     return s;
91 }
92
93 const char *line_stream_next(LineStream *line_stream)
94 {
95     trace_assert(line_stream);
96
97     while (line_stream->unfinished) {
98         line_stream_next_chunk(line_stream);
99     }
100
101     return line_stream_next_chunk(line_stream);
102 }