28
28
#include "rerere.h"
29
29
#include "prompt.h"
30
30
#include "mailinfo.h"
31
+ #include "string-list.h"
31
32
32
33
/**
33
34
* Returns 1 if the file is empty or does not exist, 0 otherwise.
@@ -258,38 +259,29 @@ static int read_state_file(struct strbuf *sb, const struct am_state *state,
258
259
}
259
260
260
261
/**
261
- * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE
262
- * as a newly-allocated string. VALUE must be a quoted string, and the KEY must
263
- * match `key`. Returns NULL on failure.
264
- *
265
- * This is used by read_author_script() to read the GIT_AUTHOR_* variables from
266
- * the author-script.
262
+ * Take a series of KEY='VALUE' lines where VALUE part is
263
+ * sq-quoted, and append <KEY, VALUE> at the end of the string list
267
264
*/
268
- static char * read_shell_var ( FILE * fp , const char * key )
265
+ static int parse_key_value_squoted ( char * buf , struct string_list * list )
269
266
{
270
- struct strbuf sb = STRBUF_INIT ;
271
- const char * str ;
272
-
273
- if (strbuf_getline_lf (& sb , fp ))
274
- goto fail ;
275
-
276
- if (!skip_prefix (sb .buf , key , & str ))
277
- goto fail ;
278
-
279
- if (!skip_prefix (str , "=" , & str ))
280
- goto fail ;
281
-
282
- strbuf_remove (& sb , 0 , str - sb .buf );
283
-
284
- str = sq_dequote (sb .buf );
285
- if (!str )
286
- goto fail ;
287
-
288
- return strbuf_detach (& sb , NULL );
289
-
290
- fail :
291
- strbuf_release (& sb );
292
- return NULL ;
267
+ while (* buf ) {
268
+ struct string_list_item * item ;
269
+ char * np ;
270
+ char * cp = strchr (buf , '=' );
271
+ if (!cp )
272
+ return -1 ;
273
+ np = strchrnul (cp , '\n' );
274
+ * cp ++ = '\0' ;
275
+ item = string_list_append (list , buf );
276
+
277
+ buf = np + (* np == '\n' );
278
+ * np = '\0' ;
279
+ cp = sq_dequote (cp );
280
+ if (!cp )
281
+ return -1 ;
282
+ item -> util = xstrdup (cp );
283
+ }
284
+ return 0 ;
293
285
}
294
286
295
287
/**
@@ -311,44 +303,39 @@ static char *read_shell_var(FILE *fp, const char *key)
311
303
static int read_author_script (struct am_state * state )
312
304
{
313
305
const char * filename = am_path (state , "author-script" );
314
- FILE * fp ;
306
+ struct strbuf buf = STRBUF_INIT ;
307
+ struct string_list kv = STRING_LIST_INIT_DUP ;
308
+ int retval = -1 ; /* assume failure */
309
+ int fd ;
315
310
316
311
assert (!state -> author_name );
317
312
assert (!state -> author_email );
318
313
assert (!state -> author_date );
319
314
320
- fp = fopen (filename , "r" );
321
- if (! fp ) {
315
+ fd = open (filename , O_RDONLY );
316
+ if (fd < 0 ) {
322
317
if (errno == ENOENT )
323
318
return 0 ;
324
319
die_errno (_ ("could not open '%s' for reading" ), filename );
325
320
}
321
+ strbuf_read (& buf , fd , 0 );
322
+ close (fd );
323
+ if (parse_key_value_squoted (buf .buf , & kv ))
324
+ goto finish ;
326
325
327
- state -> author_name = read_shell_var (fp , "GIT_AUTHOR_NAME" );
328
- if (!state -> author_name ) {
329
- fclose (fp );
330
- return -1 ;
331
- }
332
-
333
- state -> author_email = read_shell_var (fp , "GIT_AUTHOR_EMAIL" );
334
- if (!state -> author_email ) {
335
- fclose (fp );
336
- return -1 ;
337
- }
338
-
339
- state -> author_date = read_shell_var (fp , "GIT_AUTHOR_DATE" );
340
- if (!state -> author_date ) {
341
- fclose (fp );
342
- return -1 ;
343
- }
344
-
345
- if (fgetc (fp ) != EOF ) {
346
- fclose (fp );
347
- return -1 ;
348
- }
349
-
350
- fclose (fp );
351
- return 0 ;
326
+ if (kv .nr != 3 ||
327
+ strcmp (kv .items [0 ].string , "GIT_AUTHOR_NAME" ) ||
328
+ strcmp (kv .items [1 ].string , "GIT_AUTHOR_EMAIL" ) ||
329
+ strcmp (kv .items [2 ].string , "GIT_AUTHOR_DATE" ))
330
+ goto finish ;
331
+ state -> author_name = kv .items [0 ].util ;
332
+ state -> author_email = kv .items [1 ].util ;
333
+ state -> author_date = kv .items [2 ].util ;
334
+ retval = 0 ;
335
+ finish :
336
+ string_list_clear (& kv , !!retval );
337
+ strbuf_release (& buf );
338
+ return retval ;
352
339
}
353
340
354
341
/**
0 commit comments