13 #define MAX_BUF ((512 * 1024) - 1)
15 int lparse_fd(int fd
, uint size
, int (*parse
)(char *, uint
))
19 if (!buf
&& !(buf
= calloc(1, MAX_BUF
+ 1)))
22 while (tot_rd
< size
) {
27 bytes_rd
= read(fd
, buf
, MAX_BUF
< size
? MAX_BUF
: size
);
31 if (tot_rd
+ bytes_rd
< size
) {
32 /* rewind the file to the last found newline */
33 while (buf
[bytes_rd
- 1] != '\n')
35 lseek(fd
, tot_rd
+ bytes_rd
, SEEK_SET
);
39 /* set a sentinel for memchr() */
43 for (blkparsed
= 0; blkparsed
< bytes_rd
; cur
= next
+ 1) {
45 next
= memchr(cur
, '\n', bytes_rd
+ 1 - blkparsed
);
57 int lparse_rev_fd(int fd
, uint size
, int (*parse
)(char *, uint
))
59 uint tot_rd
= 0, parsed
= 0, reads
= 0, expected_reads
= 0;
61 if (!buf
&& !(buf
= calloc(1, MAX_BUF
+ 1)))
64 expected_reads
= size
/ MAX_BUF
+ 1;
65 while (tot_rd
< size
) {
66 char *cur
, *first
, *eol
, *last
;
73 * First we figure out where to start reading
74 * and how much to read. Then we lseek() to that
75 * position and actually read it in (works)
77 if (tot_rd
+ MAX_BUF
< size
) {
80 to_read
= size
- tot_rd
;
82 pos
= lseek(fd
, size
- tot_rd
- to_read
, SEEK_SET
);
84 bytes_rd
= read(fd
, buf
, to_read
);
88 if (tot_rd
+ bytes_rd
< size
) {
91 * set 'first' to just after first newline or,
92 * failing that, to the start of the buffer itself
94 first
= memchr(buf
, '\n', bytes_rd
);
100 /* remember the position of the first found newline */
101 bytes_rd
-= first
- buf
;
108 * if the buffer we just read ends with a newline, we must
109 * discard it from the first round of parsing, or we'll add
110 * one line for each time we read.
112 if (first
[bytes_rd
- 1] == '\n')
115 eol
= last
= first
+ bytes_rd
;
116 for (blkparsed
= 0; blkparsed
< bytes_rd
; cur
= eol
- 1) {
121 * set 'cur' to first newline befor 'eol', and set
122 * 'line' to first char after it
124 cur
= memrchr(first
, '\n', bytes_rd
- blkparsed
);
132 blkparsed
+= len
+ 1;
144 int lparse_path_real(int rev
, const char *path
, uint size
, int (*parse
)(char *, uint
))
148 /* zero size files are never interesting */
152 if ((fd
= open(path
, O_RDONLY
)) < 0)
156 result
= lparse_rev_fd(fd
, size
, parse
);
158 result
= lparse_fd(fd
, size
, parse
);