@@ -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+
6567JsonTag 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
153188JsonNode * 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