Extract expand_report_argument

This commit is contained in:
Nobuyoshi Nakada 2023-08-05 19:56:29 +09:00
parent 89b3c111ff
commit be40eacc9d

49
error.c
View File

@ -721,6 +721,12 @@ finish_report(FILE *out)
if (out != stdout && out != stderr) fclose(out); if (out != stdout && out != stderr) fclose(out);
} }
struct report_expansion {
struct path_string exe, script;
rb_pid_t pid;
time_t time;
};
/* /*
* Open a bug report file to write. The `RUBY_BUGREPORT_PATH` * Open a bug report file to write. The `RUBY_BUGREPORT_PATH`
* environment variable can be set to define a template that is used * environment variable can be set to define a template that is used
@ -738,48 +744,59 @@ finish_report(FILE *out)
* %t Time of dump, expressed as seconds since the Epoch, * %t Time of dump, expressed as seconds since the Epoch,
* 1970-01-01 00:00:00 +0000 (UTC). * 1970-01-01 00:00:00 +0000 (UTC).
*/ */
static FILE * static char *
open_report_path(const char *template, char *buf, size_t size) expand_report_argument(const char **input_template, struct report_expansion *values,
char *buf, size_t size)
{ {
if (template && *template) {
char *p = buf; char *p = buf;
char *end = buf + size; char *end = buf + size;
rb_pid_t pid = 0; const char *template = *input_template;
struct path_string exe = {0};
struct path_string script = {0}; if (p >= end-1 || !*template) return NULL;
time_t t = 0; do {
while (p < end-1 && *template) {
char c = *template++; char c = *template++;
if (c == '%') { if (c == '%') {
switch (c = *template++) { switch (c = *template++) {
case 'e': case 'e':
p = append_basename(p, end, &exe, rb_argv0); p = append_basename(p, end, &values->exe, rb_argv0);
continue; continue;
case 'E': case 'E':
p = append_pathname(p, end, rb_argv0); p = append_pathname(p, end, rb_argv0);
continue; continue;
case 'f': case 'f':
p = append_basename(p, end, &script, GET_VM()->orig_progname); p = append_basename(p, end, &values->script, GET_VM()->orig_progname);
continue; continue;
case 'F': case 'F':
p = append_pathname(p, end, GET_VM()->orig_progname); p = append_pathname(p, end, GET_VM()->orig_progname);
continue; continue;
case 'p': case 'p':
if (!pid) pid = getpid(); if (!values->pid) values->pid = getpid();
snprintf(p, end-p, "%" PRI_PIDT_PREFIX "d", pid); snprintf(p, end-p, "%" PRI_PIDT_PREFIX "d", values->pid);
p += strlen(p); p += strlen(p);
continue; continue;
case 't': case 't':
if (!t) t = time(NULL); if (!values->time) values->time = time(NULL);
snprintf(p, end-p, "%" PRI_TIMET_PREFIX "d", t); snprintf(p, end-p, "%" PRI_TIMET_PREFIX "d", values->time);
p += strlen(p); p += strlen(p);
continue; continue;
} }
} }
*p++ = c; if (p < end-1) *p++ = c;
} } while (*template);
*input_template = template;
*p = '\0'; *p = '\0';
return ++p;
}
static FILE *
open_report_path(const char *template, char *buf, size_t size)
{
struct report_expansion values = {{0}};
if (!template) return NULL;
if (0) fprintf(stderr, "RUBY_BUGREPORT_PATH=%s\n", buf); if (0) fprintf(stderr, "RUBY_BUGREPORT_PATH=%s\n", buf);
if (*template) {
expand_report_argument(&template, &values, buf, size);
return fopen(buf, "w"); return fopen(buf, "w");
} }
return NULL; return NULL;