1 #include "dlogutil_line.h"
2 #include "logger_internal.h"
5 void reset_getopt_internals(void *fake)
12 bool initialize_dlogutil_line_params(struct dlogutil_line_params *params, struct buf_params buf)
16 logfile_init(¶ms->file); // TODO: add flush
17 logfile_init_buffer(¶ms->file, buf.bytes);
18 params->monitor = false;
19 params->is_dumping = false;
20 params->buf_id = LOG_ID_INVALID;
21 params->file_path = NULL;
23 params->filter = log_filter_new();
30 void free_dlogutil_line_params(struct dlogutil_line_params *params)
32 logfile_free(¶ms->file);
33 log_filter_free(params->filter);
34 free(params->file_path);
37 static int make_argc_argv_from_dlogutil_line(const char *cmdl, size_t buf_size, char buffer[buf_size], int *argc, char **argv)
43 snprintf(buffer, buf_size, "%s", cmdl); // strtok is destructive
46 char *tok = strtok_r(buffer, DELIMITER, &tok_sv);
48 /* Legacy requirement: emulate `dlogutil`
49 * invocations right up to the binary name */
50 if (!tok || strcmp(tok, "dlogutil"))
54 const int argv_size = *argc - 1; // for NULL at the end
55 while (tok && (curr_argc < argv_size)) {
56 argv[curr_argc++] = tok;
57 tok = strtok_r(NULL, DELIMITER, &tok_sv);
60 argv[curr_argc] = NULL;
66 static int get_dlogutil_params_from_argc_argv(int argc, char **argv, struct dlogutil_line_params *params)
74 static const struct option long_options[] = {
75 {"tid", required_argument, NULL, 0},
76 {"pid", required_argument, NULL, 1},
80 __attribute__((cleanup(reset_getopt_internals))) int option;
81 while ((option = getopt_long(argc, argv, "cdt:gsf:r:n:v:b:mu:", long_options, NULL)) != -1) {
86 params->is_dumping = true;
89 params->monitor = true;
92 free(params->file_path);
93 params->file_path = strdup(optarg);
94 if (!params->file_path)
98 params->buf_id = log_id_by_name(optarg);
99 if (params->buf_id == LOG_ID_INVALID)
103 if (sscanf(optarg, "%zu", ¶ms->file.rotate_size_kbytes) != 1)
107 if (sscanf(optarg, "%zu", ¶ms->file.max_rotated) != 1)
111 params->file.format.format = log_format_from_string(optarg);
115 dlogutil_filter_options_set_filterspec(params->filter, "*:s");
119 if (sscanf(optarg, "%d", &tid) != 1 || dlogutil_filter_options_set_tid(params->filter, tid))
125 if (sscanf(optarg, "%d", &pid) != 1 || dlogutil_filter_options_set_pid(params->filter, pid))
129 case '?': // invalid option or missing argument
132 // everything else gets handled in util directly
137 // dump + monitor = continuous
138 if (params->monitor && params->is_dumping) {
139 params->is_dumping = false;
140 params->monitor = false;
144 while (optind < argc)
145 dlogutil_filter_options_set_filterspec(params->filter, argv[optind++]);
147 dlogutil_filter_options_set_filterspec(params->filter, "*:D");
152 int get_dlogutil_line_params(const char *cmdl, struct dlogutil_line_params *params)
157 char *argv[64]; // size arbitrary, should reasonably fit all args
158 int argc = NELEMS(argv);
159 int ret = make_argc_argv_from_dlogutil_line(cmdl, sizeof buffer, buffer, &argc, argv);
163 return get_dlogutil_params_from_argc_argv(argc, argv, params);