mailinfo: simplify parsing of header values
Our code to parse header values first checks to see if a line starts with a header, and then manually skips past the matched string to find the value. We can do this all in one step by modeling after skip_prefix(), which returns a pointer into the string after the parsing. This lets us remove some repeated strings, and will also enable us to parse more flexibly in a future patch. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Feb 11, 2020 at 12:19 UTC
f447d0293e803d9acf390bbdf373ed98bdc125f4
1 file changed
+22
-18
mailinfo.c
+22
-18
@@ -346,11 +346,16 @@ static const char *header[MAX_HDR_PARSED] = {
346
"From","Subject","Date",
347
};
348
349
-static inline int cmp_header(const struct strbuf *line, const char *hdr)
349
+static inline int skip_header(const struct strbuf *line, const char *hdr,
350
+ const char **outval)
351
{
351
- int len = strlen(hdr);
352
- return !strncasecmp(line->buf, hdr, len) && line->len > len &&
353
- line->buf[len] == ':' && isspace(line->buf[len + 1]);
352
+ const char *val;
353
+ if (!skip_iprefix(line->buf, hdr, &val) ||
354
+ *val++ != ':' ||
355
+ !isspace(*val++))
356
+ return 0;
357
+ *outval = val;
358
+ return 1;
359
}
360
361
static int is_format_patch_separator(const char *line, int len)
@@ -547,17 +552,18 @@ static int check_header(struct mailinfo *mi,
552
const struct strbuf *line,
553
struct strbuf *hdr_data[], int overwrite)
554
{
550
- int i, ret = 0, len;
555
+ int i, ret = 0;
556
struct strbuf sb = STRBUF_INIT;
557
+ const char *val;
558
559
/* search for the interesting parts */
560
for (i = 0; header[i]; i++) {
555
- int len = strlen(header[i]);
556
- if ((!hdr_data[i] || overwrite) && cmp_header(line, header[i])) {
561
+ if ((!hdr_data[i] || overwrite) &&
562
+ skip_header(line, header[i], &val)) {
563
/* Unwrap inline B and Q encoding, and optionally
564
* normalize the meta information to utf8.
565
*/
560
- strbuf_addstr(&sb, line->buf + len + 2);
566
+ strbuf_addstr(&sb, val);
567
decode_header(mi, &sb);
568
handle_header(&hdr_data[i], &sb);
569
ret = 1;
@@ -566,25 +572,22 @@ static int check_header(struct mailinfo *mi,
572
}
573
574
/* Content stuff */
569
- if (cmp_header(line, "Content-Type")) {
570
- len = strlen("Content-Type: ");
571
- strbuf_addstr(&sb, line->buf + len);
575
+ if (skip_header(line, "Content-Type", &val)) {
576
+ strbuf_addstr(&sb, val);
577
decode_header(mi, &sb);
578
handle_content_type(mi, &sb);
579
ret = 1;
580
goto check_header_out;
581
}
577
- if (cmp_header(line, "Content-Transfer-Encoding")) {
578
- len = strlen("Content-Transfer-Encoding: ");
579
- strbuf_addstr(&sb, line->buf + len);
582
+ if (skip_header(line, "Content-Transfer-Encoding", &val)) {
583
+ strbuf_addstr(&sb, val);
584
decode_header(mi, &sb);
585
handle_content_transfer_encoding(mi, &sb);
586
ret = 1;
587
goto check_header_out;
588
}
585
- if (cmp_header(line, "Message-Id")) {
586
- len = strlen("Message-Id: ");
587
- strbuf_addstr(&sb, line->buf + len);
589
+ if (skip_header(line, "Message-Id", &val)) {
590
+ strbuf_addstr(&sb, val);
591
decode_header(mi, &sb);
592
if (mi->add_message_id)
593
mi->message_id = strbuf_detach(&sb, NULL);
@@ -606,8 +609,9 @@ static int is_inbody_header(const struct mailinfo *mi,
609
const struct strbuf *line)
610
{
611
int i;
612
+ const char *val;
613
for (i = 0; header[i]; i++)
610
- if (!mi->s_hdr_data[i] && cmp_header(line, header[i]))
614
+ if (!mi->s_hdr_data[i] && skip_header(line, header[i], &val))
615
return 1;
616
return 0;
617
}