1 /* 2 * Another stupid program, this one parsing the headers of an 3 * email to figure out authorship and subject 4 */ 5 #include "cache.h" 6 #include "builtin.h" 7 #include "utf8.h" 8 #include "strbuf.h" 9 #include "mailinfo.h" 10 #include "parse-options.h" 11 12 static const char * const mailinfo_usage[] = { 13 /* TRANSLATORS: keep <> in "<" mail ">" info. */ 14 N_("git mailinfo [<options>] <msg> <patch> < mail >info"), 15 NULL, 16 }; 17 18 struct metainfo_charset 19 { 20 enum { 21 CHARSET_DEFAULT, 22 CHARSET_NO_REENCODE, 23 CHARSET_EXPLICIT, 24 } policy; 25 const char *charset; 26 }; 27 28 static int parse_opt_explicit_encoding(const struct option *opt, 29 const char *arg, int unset) 30 { 31 struct metainfo_charset *meta_charset = opt->value; 32 33 BUG_ON_OPT_NEG(unset); 34 35 meta_charset->policy = CHARSET_EXPLICIT; 36 meta_charset->charset = arg; 37 38 return 0; 39 } 40 41 static int parse_opt_quoted_cr(const struct option *opt, const char *arg, int unset) 42 { 43 BUG_ON_OPT_NEG(unset); 44 45 if (mailinfo_parse_quoted_cr_action(arg, opt->value) != 0) 46 return error(_("bad action '%s' for '%s'"), arg, "--quoted-cr"); 47 return 0; 48 } 49 50 int cmd_mailinfo(int argc, const char **argv, const char *prefix) 51 { 52 struct metainfo_charset meta_charset; 53 struct mailinfo mi; 54 int status; 55 char *msgfile, *patchfile; 56 57 struct option options[] = { 58 OPT_BOOL('k', NULL, &mi.keep_subject, N_("keep subject")), 59 OPT_BOOL('b', NULL, &mi.keep_non_patch_brackets_in_subject, 60 N_("keep non patch brackets in subject")), 61 OPT_BOOL('m', "message-id", &mi.add_message_id, 62 N_("copy Message-ID to the end of commit message")), 63 OPT_SET_INT_F('u', NULL, &meta_charset.policy, 64 N_("re-code metadata to i18n.commitEncoding"), 65 CHARSET_DEFAULT, PARSE_OPT_NONEG), 66 OPT_SET_INT_F('n', NULL, &meta_charset.policy, 67 N_("disable charset re-coding of metadata"), 68 CHARSET_NO_REENCODE, PARSE_OPT_NONEG), 69 OPT_CALLBACK_F(0, "encoding", &meta_charset, N_("encoding"), 70 N_("re-code metadata to this encoding"), 71 PARSE_OPT_NONEG, parse_opt_explicit_encoding), 72 OPT_BOOL(0, "scissors", &mi.use_scissors, N_("use scissors")), 73 OPT_CALLBACK_F(0, "quoted-cr", &mi.quoted_cr, N_("<action>"), 74 N_("action when quoted CR is found"), 75 PARSE_OPT_NONEG, parse_opt_quoted_cr), 76 OPT_HIDDEN_BOOL(0, "inbody-headers", &mi.use_inbody_headers, 77 N_("use headers in message's body")), 78 OPT_END() 79 }; 80 81 setup_mailinfo(&mi); 82 meta_charset.policy = CHARSET_DEFAULT; 83 84 argc = parse_options(argc, argv, prefix, options, mailinfo_usage, 0); 85 86 if (argc != 2) 87 usage_with_options(mailinfo_usage, options); 88 89 switch (meta_charset.policy) { 90 case CHARSET_DEFAULT: 91 mi.metainfo_charset = get_commit_output_encoding(); 92 break; 93 case CHARSET_NO_REENCODE: 94 mi.metainfo_charset = NULL; 95 break; 96 case CHARSET_EXPLICIT: 97 break; 98 default: 99 BUG("invalid meta_charset.policy"); 100 } 101 102 mi.input = stdin; 103 mi.output = stdout; 104 105 msgfile = prefix_filename(prefix, argv[0]); 106 patchfile = prefix_filename(prefix, argv[1]); 107 108 status = !!mailinfo(&mi, msgfile, patchfile); 109 clear_mailinfo(&mi); 110 111 free(msgfile); 112 free(patchfile); 113 return status; 114 } 115