Skip to content

Commit a77598e

Browse files
committed
am: refactor read_author_script()
By splitting the part that reads from a file and the part that parses the variable definitions from the contents, make the latter can be more reusable in the future. Signed-off-by: Junio C Hamano <[email protected]>
1 parent d5cb9cb commit a77598e

File tree

1 file changed

+45
-58
lines changed

1 file changed

+45
-58
lines changed

builtin/am.c

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "rerere.h"
2929
#include "prompt.h"
3030
#include "mailinfo.h"
31+
#include "string-list.h"
3132

3233
/**
3334
* 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,
258259
}
259260

260261
/**
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
267264
*/
268-
static char *read_shell_var(FILE *fp, const char *key)
265+
static int parse_key_value_squoted(char *buf, struct string_list *list)
269266
{
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;
293285
}
294286

295287
/**
@@ -311,44 +303,39 @@ static char *read_shell_var(FILE *fp, const char *key)
311303
static int read_author_script(struct am_state *state)
312304
{
313305
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;
315310

316311
assert(!state->author_name);
317312
assert(!state->author_email);
318313
assert(!state->author_date);
319314

320-
fp = fopen(filename, "r");
321-
if (!fp) {
315+
fd = open(filename, O_RDONLY);
316+
if (fd < 0) {
322317
if (errno == ENOENT)
323318
return 0;
324319
die_errno(_("could not open '%s' for reading"), filename);
325320
}
321+
strbuf_read(&buf, fd, 0);
322+
close(fd);
323+
if (parse_key_value_squoted(buf.buf, &kv))
324+
goto finish;
326325

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;
352339
}
353340

354341
/**

0 commit comments

Comments
 (0)