Skip to content

Commit a641454

Browse files
committed
Merge branch 'gromgit-fix-long-lines'
2 parents d972f29 + 669f3fe commit a641454

File tree

1 file changed

+55
-21
lines changed

1 file changed

+55
-21
lines changed

jo.c

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ static JsonNode *pile; /* pile of nested objects/arrays */
6262
#define TAG_FLAG_NUMBER (TAG_TO_FLAGS(JSON_NUMBER))
6363
#define COERCE_MASK (TAG_FLAG_BOOL | TAG_FLAG_STRING | TAG_FLAG_NUMBER)
6464

65+
#define debug(format, args...) fprintf (stderr, format, args)
66+
6567
JsonTag flags_to_tag(int flags) {
6668
return flags / (FLAG_MASK + 1);
6769
}
@@ -106,11 +108,45 @@ void json_copy_to_object(JsonNode * obj, JsonNode * object_or_array, int clobber
106108
}
107109
}
108110

109-
char *slurp_file(const char* filename, size_t *out_len, bool fold_newlines)
111+
char *slurp(FILE *fp, off_t bufblk_sz, int eos_char, size_t *out_len, bool fold_newlines)
110112
{
111113
char *buf;
112114
int i = 0;
113-
int ch;
115+
int ch = EOF;
116+
off_t buffer_len = bufblk_sz;
117+
118+
if ((buf = malloc(buffer_len)) == NULL) {
119+
i = -1;
120+
} else {
121+
while ((ch = fgetc(fp)) != eos_char && ch != EOF) {
122+
if (i == (buffer_len - 1)) {
123+
buffer_len += bufblk_sz;
124+
if ((buf = realloc(buf, buffer_len)) == NULL) {
125+
i = -1;
126+
break;
127+
}
128+
}
129+
if (ch != '\n' || !fold_newlines) {
130+
buf[i++] = ch;
131+
}
132+
}
133+
}
134+
if (ch == EOF && i <= 0) {
135+
/* EOF at first read */
136+
if (buf) {
137+
free(buf);
138+
buf = NULL;
139+
}
140+
} else if (buf) {
141+
buf[i] = 0;
142+
}
143+
*out_len = i;
144+
return buf;
145+
}
146+
147+
char *slurp_file(const char* filename, size_t *out_len, bool fold_newlines)
148+
{
149+
char *buf;
114150
off_t buffer_len;
115151
FILE *fp;
116152
bool use_stdin = strcmp(filename, "-") == 0;
@@ -130,24 +166,23 @@ char *slurp_file(const char* filename, size_t *out_len, bool fold_newlines)
130166
fseeko(fp, 0, SEEK_SET);
131167
}
132168

133-
if ((buf = malloc(buffer_len)) == NULL) {
169+
buf = slurp(fp, buffer_len, EOF, out_len, fold_newlines);
170+
if (*out_len < 0) {
134171
errx(1, "File %s is too large to be read into memory", filename);
135172
}
136-
while ((ch = fgetc(fp)) != EOF) {
137-
if (i == (buffer_len - 1)) {
138-
buffer_len += SLURP_BLOCK_SIZE;
139-
if ((buf = realloc(buf, buffer_len)) == NULL) {
140-
errx(1, "File %s is too large to be read into memory", filename);
141-
}
142-
}
143-
if (ch != '\n' || !fold_newlines) {
144-
buf[i++] = ch;
145-
}
146-
}
147173
if (!use_stdin) fclose(fp);
148-
buf[i] = 0;
149-
*out_len = i;
150-
return (buf);
174+
return buf;
175+
}
176+
177+
char *slurp_line(FILE *fp, size_t *out_len)
178+
{
179+
char *buf;
180+
181+
buf = slurp(fp, SLURP_BLOCK_SIZE, '\n', out_len, false);
182+
if (*out_len < 0) {
183+
errx(1, "Line too large to be read into memory");
184+
}
185+
return buf;
151186
}
152187

153188
JsonNode *jo_mknull(JsonTag type) {
@@ -601,7 +636,7 @@ int main(int argc, char **argv)
601636
{
602637
int c, key_delim = 0;
603638
bool showversion = false;
604-
char *kv, *js_string, *progname, buf[BUFSIZ], *p;
639+
char *kv, *js_string, *progname, *buf, *p;
605640
char *in_file = NULL, *in_str;
606641
char *out_file = NULL;
607642
FILE *out = stdout;
@@ -695,12 +730,11 @@ int main(int argc, char **argv)
695730
if (flags & FLAG_NOSTDIN) {
696731
return(0);
697732
}
698-
while (fgets(buf, sizeof(buf), stdin) != NULL) {
699-
if (buf[strlen(buf) - 1] == '\n')
700-
buf[strlen(buf) - 1] = 0;
733+
while ((buf = slurp_line(stdin, &in_len)) != NULL && in_len > 0) {
701734
p = ttyin ? utf8_from_locale(buf, -1) : buf;
702735
append_kv(json, flags, key_delim, p);
703736
if (ttyin) utf8_free(p);
737+
if (buf) free(buf);
704738
}
705739
} else {
706740
while ((kv = *argv++)) {

0 commit comments

Comments
 (0)