Move the util parser outside of util so we can reuse it 93/244893/4
authorMateusz Majewski <m.majewski2@samsung.com>
Fri, 25 Sep 2020 11:03:31 +0000 (13:03 +0200)
committerMichal Bloch <m.bloch@partner.samsung.com>
Mon, 28 Sep 2020 14:38:36 +0000 (14:38 +0000)
Change-Id: Icec52e46925923e549850ad9f10f221f7e363dfc

Makefile.am
include/util_parser.h [new file with mode: 0644]
src/logutil/logutil.c
src/logutil/logutil_doc.h
src/shared/util_parser.c [new file with mode: 0644]

index d0c3c4e..f38f03f 100644 (file)
@@ -93,7 +93,8 @@ dlogutil_SOURCES = \
        src/shared/logcommon.c \
        src/shared/logprint.c \
        src/shared/log_file.c \
-       src/shared/ptrs_list.c
+       src/shared/ptrs_list.c \
+       src/shared/util_parser.c
 
 libexec_PROGRAMS = dlog-log-critical
 
diff --git a/include/util_parser.h b/include/util_parser.h
new file mode 100644 (file)
index 0000000..d595ee3
--- /dev/null
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <dlog-internal.h>
+#include <dlogutil-internal.h>
+
+typedef enum action_e {
+       ACTION_PRINT = 0,
+       ACTION_GET_CAPACITY,
+       ACTION_CLEAR,
+} action_e;
+
+struct parse_result {
+       enum {
+               PARSE_OK,
+               PARSE_OOM,
+               PARSE_BAD_COLOR,
+               PARSE_BAD_SORT_BY,
+               PARSE_BAD_BUFFER,
+               PARSE_BAD_FORMAT,
+               PARSE_OPTION_REPEATED,
+               PARSE_OPTION_NUMERICAL_ARGUMENT,
+               PARSE_VERSION_REQUESTED,
+               PARSE_HELP_REQUESTED,
+               PARSE_NO_PARSE,
+       } status;
+       union {
+               struct {
+                       bool colors_auto;
+                       bool colors_force;
+                       log_print_format format;
+                       size_t rotate_size_kbytes;
+                       size_t max_rotated;
+                       const char *file_path;
+                       size_t write_buffer_size;
+                       int enabled_buffers;
+                       action_e action;
+                       list_head filterspecs;
+                       list_head pid_filters;
+                       list_head tid_filters;
+                       int sorting_settings;
+                       dlogutil_mode_e mode;
+                       unsigned dump_size;
+                       dlogutil_sorting_order_e sort_by;
+               };
+               const char *which_option;
+               const char *bad_contents;
+       };
+};
+
+struct parse_result parse_options(int argc, char **argv);
+void parse_result_cleanup(struct parse_result *pr);
index 079642e..a3862c7 100644 (file)
 #include <stdlib.h>
 
 #include <fcntl.h>
-#include <getopt.h>
 #include <sys/epoll.h>
 
 #include <log_file.h>
-#include <sort_vector.h>
-#include <dlog-internal.h>
+#include <util_parser.h>
 
 #include "logutil_doc.h"
 
 // buffers to use by default, when nothing specified
 static const int default_buffers = (1 << LOG_ID_MAIN) | (1 << LOG_ID_SYSTEM) | (1 << LOG_ID_APPS);
 
-typedef enum action_e {
-       ACTION_PRINT = 0,
-       ACTION_GET_CAPACITY,
-       ACTION_CLEAR,
-} action_e;
-
 static void show_version(const char *name)
 {
        printf("%s version: %s-%s\n", name, __DLOG_VERSION, __DLOG_RELEASE);
 }
 
-struct parse_result {
-       enum {
-               PARSE_OK,
-               PARSE_OOM,
-               PARSE_BAD_COLOR,
-               PARSE_BAD_SORT_BY,
-               PARSE_BAD_BUFFER,
-               PARSE_BAD_FORMAT,
-               PARSE_OPTION_REPEATED,
-               PARSE_OPTION_NUMERICAL_ARGUMENT,
-               PARSE_VERSION_REQUESTED,
-               PARSE_HELP_REQUESTED,
-               PARSE_NO_PARSE,
-       } status;
-       union {
-               struct {
-                       bool colors_auto;
-                       bool colors_force;
-                       log_print_format format;
-                       size_t rotate_size_kbytes;
-                       size_t max_rotated;
-                       const char *file_path;
-                       size_t write_buffer_size;
-                       int enabled_buffers;
-                       action_e action;
-                       list_head filterspecs;
-                       list_head pid_filters;
-                       list_head tid_filters;
-                       int sorting_settings;
-                       dlogutil_mode_e mode;
-                       unsigned dump_size;
-                       dlogutil_sorting_order_e sort_by;
-               };
-               const char *which_option;
-               const char *bad_contents;
-       };
-};
-
-void parse_result_cleanup(struct parse_result *pr)
-{
-       if (pr && pr->status == PARSE_OK) {
-               list_clear(&pr->filterspecs);
-               list_clear_free_contents(&pr->pid_filters);
-               list_clear_free_contents(&pr->tid_filters);
-       }
-}
-
-static struct parse_result parse_options(int argc, char **argv)
-{
-       bool colors_auto = true;
-       bool colors_force = false;
-       log_print_format format = FORMAT_BRIEF;
-       size_t rotate_size_kbytes = DEFAULT_ROTATE_SIZE_KB;
-       size_t max_rotated = DEFAULT_ROTATE_NUM_FILES;
-       const char *file_path = NULL;
-       size_t write_buffer_size = 0;
-       int enabled_buffers = 0;
-       action_e action = ACTION_PRINT;
-       __attribute__((cleanup(list_clear))) list_head filterspecs = NULL;
-       __attribute__((cleanup(list_clear_free_contents))) list_head pid_filters = NULL;
-       __attribute__((cleanup(list_clear_free_contents))) list_head tid_filters = NULL;
-       int sorting_settings = DEFAULT_SORT_BUFFER_SIZE;
-       dlogutil_mode_e mode = DLOGUTIL_MODE_CONTINUOUS;
-       unsigned dump_size = DLOGUTIL_MAX_DUMP_SIZE;
-       dlogutil_sorting_order_e sort_by = DLOGUTIL_SORT_DEFAULT;
-
-       bool buffer_made = false;
-
-       while (1) {
-               static const struct option long_options[] = {
-                       {"tid"    , required_argument, NULL,   0},
-                       {"pid"    , required_argument, NULL,   1},
-                       {"version",       no_argument, NULL,   2},
-                       {"color"  , required_argument, NULL,   3},
-                       {"sort-by", required_argument, NULL,   4},
-                       {"help"   ,       no_argument, NULL, 'h'},
-                       {0}
-               };
-               int option = getopt_long(argc, argv, "cdmt:gsf:r:n:v:b:u:e:h", long_options, NULL);
-
-               if (option < 0)
-                       break;
-
-               switch (option) {
-               case 0: { /* tid filter */
-                       int tid;
-                       if (sscanf(optarg, "%d", &tid) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "--tid", };
-                       else {
-                               pid_t *insert = calloc(1, sizeof(pid_t));
-                               if (insert == NULL)
-                                       return (struct parse_result) { .status = PARSE_OOM, };
-                               *insert = tid;
-                               if (!list_add(&tid_filters, insert)) {
-                                       free(insert);
-                                       return (struct parse_result) { .status = PARSE_OOM, };
-                               }
-                       }
-                       break;
-               }
-               case 1: { /* pid filter */
-                       int pid;
-                       if (sscanf(optarg, "%d", &pid) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "--pid", };
-                       else {
-                               pid_t *insert = calloc(1, sizeof(pid_t));
-                               if (insert == NULL)
-                                       return (struct parse_result) { .status = PARSE_OOM, };
-                               *insert = pid;
-                               if (!list_add(&tid_filters, insert)) {
-                                       free(insert);
-                                       return (struct parse_result) { .status = PARSE_OOM, };
-                               }
-                       }
-                       break;
-               }
-               case 2: { /* version */
-                       return (struct parse_result) { .status = PARSE_VERSION_REQUESTED, };
-               }
-               case 3: /* colored headers */
-                       colors_auto = false;
-                       if (!strcmp(optarg, "always"))
-                               colors_force = true;
-                       else if (!strcmp(optarg, "auto"))
-                               colors_auto = true;
-                       else if (!strcmp(optarg, "never"))
-                               colors_force = false;
-                       else
-                               return (struct parse_result) { .status = PARSE_BAD_COLOR, .bad_contents = optarg, };
-                       break;
-               case 4: /* timestamp */
-                       if (!strcmp(optarg, "default"))
-                               sort_by = DLOGUTIL_SORT_DEFAULT;
-                       else {
-                               sort_by = get_order_from_string(optarg);
-                               if (sort_by == DLOGUTIL_SORT_DEFAULT)
-                                       return (struct parse_result) { .status = PARSE_BAD_SORT_BY, .bad_contents = optarg, };
-                       }
-                       break;
-               case 'd':
-                       mode = DLOGUTIL_MODE_DUMP;
-                       break;
-               case 'm':
-                       mode = DLOGUTIL_MODE_MONITOR;
-                       break;
-               case 't':
-                       mode = DLOGUTIL_MODE_DUMP;
-                       if (sscanf(optarg, "%u", &dump_size) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-t", };
-                       break;
-               case 'c':
-                       action = ACTION_CLEAR;
-                       break;
-               case 'g':
-                       action = ACTION_GET_CAPACITY;
-                       break;
-               case 'b': {
-                       log_id_t id = log_id_by_name(optarg);
-                       if (id == LOG_ID_INVALID)
-                               return (struct parse_result) { .status = PARSE_BAD_BUFFER, .bad_contents = optarg, };
-                       bit_set(&enabled_buffers, id);
-                       break;
-               }
-               case 'u': {
-                       unsigned size;
-                       if (sscanf(optarg, "%u", &size) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-u", };
-                       if (size == 0)
-                               sorting_settings = 0;
-                       else
-                               sorting_settings = size;
-                       break;
-               }
-               case 'f':
-                       file_path = optarg;
-                       break;
-               case 'v': {
-                       format = log_format_from_string(optarg);
-                       if (format == FORMAT_OFF)
-                               return (struct parse_result) { .status = PARSE_BAD_FORMAT, .bad_contents = optarg, };
-                       break;
-               }
-               case 's':
-                       if (!list_add(&filterspecs, "*:S"))
-                               return (struct parse_result) { .status = PARSE_OOM, };
-                       break;
-               case 'r':
-                       if (sscanf(optarg, "%zu", &rotate_size_kbytes) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-r", };
-                       break;
-               case 'n':
-                       if (sscanf(optarg, "%zu", &max_rotated) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-n", };
-                       break;
-               case 'e': {
-                       if (buffer_made)
-                               return (struct parse_result) { .status = PARSE_OPTION_REPEATED, .which_option = "-e", };
-                       if (sscanf(optarg, "%zu", &write_buffer_size) != 1)
-                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-e", };
-                       buffer_made = true;
-                       break;
-               }
-               case 'h':
-                       return (struct parse_result) { .status = PARSE_HELP_REQUESTED, };
-               default: // invalid option or missing mandatory parameter
-                       return (struct parse_result) { .status = PARSE_NO_PARSE, };
-               }
-       }
-
-       while (optind < argc) {
-               /* TODO: We don't want to call log_filter_set_filterspec/dlogutil_config_filter_filterspec here,
-                * as we want the option parser to be general. Unfortunately, this means that the user has to parse
-                * the filterspecs and not us. Any idea on how to make this nicer? */
-               if (!list_add(&filterspecs, argv[optind++]))
-                       return (struct parse_result) { .status = PARSE_OOM, };
-       }
-
-       if (enabled_buffers == 0)
-               enabled_buffers = default_buffers;
-
-       if (!buffer_made && mode == DLOGUTIL_MODE_DUMP)
-               write_buffer_size = DEFAULT_WRITE_BUFFER_SIZE;
-
-       struct parse_result ret = (struct parse_result) {
-               .status = PARSE_OK,
-               .colors_auto = colors_auto,
-               .colors_force = colors_force,
-               .format = format,
-               .rotate_size_kbytes = rotate_size_kbytes,
-               .max_rotated = max_rotated,
-               .file_path = file_path,
-               .write_buffer_size = write_buffer_size,
-               .enabled_buffers = enabled_buffers,
-               .action = action,
-               .filterspecs = filterspecs,
-               .pid_filters = pid_filters,
-               .tid_filters = tid_filters,
-               .sorting_settings = sorting_settings,
-               .mode = mode,
-               .dump_size = dump_size,
-               .sort_by = sort_by,
-       };
-       filterspecs = NULL;
-       pid_filters = NULL;
-       tid_filters = NULL;
-       return ret;
-}
-
 static void config_cleanup(dlogutil_config_s *const *config) {
        assert(config);
        dlogutil_config_destroy(*config);
@@ -608,18 +352,20 @@ int main(int argc, char **argv)
                        ERR("Error: out of memory while applying TID filter\n");
        }
 
+       int enabled_buffers = pr.enabled_buffers != 0 ? pr.enabled_buffers : default_buffers;
+
        int r;
        switch (pr.action) {
        case ACTION_PRINT: {
-               r = do_print(pr.mode, pr.dump_size, pr.enabled_buffers, pr.sort_by, config, &l_file);
+               r = do_print(pr.mode, pr.dump_size, enabled_buffers, pr.sort_by, config, &l_file);
                break;
        }
        case ACTION_GET_CAPACITY: {
-               r = for_each_buffer(pr.enabled_buffers, print_buffer_capacity);
+               r = for_each_buffer(enabled_buffers, print_buffer_capacity);
                break;
        }
        case ACTION_CLEAR:
-               r = for_each_buffer(pr.enabled_buffers, clear_buffer);
+               r = for_each_buffer(enabled_buffers, clear_buffer);
                break;
        }
 
index 94921d0..b3d4d5d 100644 (file)
@@ -36,8 +36,6 @@ If you specify any other tag without priority, the priority defaults to V
 
 #include <stdbool.h>
 
-#define DEFAULT_WRITE_BUFFER_SIZE 1048576
-
 static void show_help(const char *cmd, bool requested_by_user)
 {
        static const char *format_str = "Usage: %s [options] [filterspecs]"
diff --git a/src/shared/util_parser.c b/src/shared/util_parser.c
new file mode 100644 (file)
index 0000000..a72dd54
--- /dev/null
@@ -0,0 +1,212 @@
+#include <getopt.h>
+#include <util_parser.h>
+#include <sort_vector.h>
+
+#define DEFAULT_WRITE_BUFFER_SIZE 1048576
+
+void parse_result_cleanup(struct parse_result *pr)
+{
+       if (pr && pr->status == PARSE_OK) {
+               list_clear(&pr->filterspecs);
+               list_clear_free_contents(&pr->pid_filters);
+               list_clear_free_contents(&pr->tid_filters);
+       }
+}
+
+struct parse_result parse_options(int argc, char **argv)
+{
+       bool colors_auto = true;
+       bool colors_force = false;
+       log_print_format format = FORMAT_BRIEF;
+       size_t rotate_size_kbytes = DEFAULT_ROTATE_SIZE_KB;
+       size_t max_rotated = DEFAULT_ROTATE_NUM_FILES;
+       const char *file_path = NULL;
+       size_t write_buffer_size = 0;
+       int enabled_buffers = 0;
+       action_e action = ACTION_PRINT;
+       __attribute__((cleanup(list_clear))) list_head filterspecs = NULL;
+       __attribute__((cleanup(list_clear_free_contents))) list_head pid_filters = NULL;
+       __attribute__((cleanup(list_clear_free_contents))) list_head tid_filters = NULL;
+       int sorting_settings = DEFAULT_SORT_BUFFER_SIZE;
+       dlogutil_mode_e mode = DLOGUTIL_MODE_CONTINUOUS;
+       unsigned dump_size = DLOGUTIL_MAX_DUMP_SIZE;
+       dlogutil_sorting_order_e sort_by = DLOGUTIL_SORT_DEFAULT;
+
+       bool buffer_made = false;
+
+       while (1) {
+               static const struct option long_options[] = {
+                       {"tid"    , required_argument, NULL,   0},
+                       {"pid"    , required_argument, NULL,   1},
+                       {"version",       no_argument, NULL,   2},
+                       {"color"  , required_argument, NULL,   3},
+                       {"sort-by", required_argument, NULL,   4},
+                       {"help"   ,       no_argument, NULL, 'h'},
+                       {0}
+               };
+               int option = getopt_long(argc, argv, "cdmt:gsf:r:n:v:b:u:e:h", long_options, NULL);
+
+               if (option < 0)
+                       break;
+
+               switch (option) {
+               case 0: { /* tid filter */
+                       int tid;
+                       if (sscanf(optarg, "%d", &tid) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "--tid", };
+                       else {
+                               pid_t *insert = calloc(1, sizeof(pid_t));
+                               if (insert == NULL)
+                                       return (struct parse_result) { .status = PARSE_OOM, };
+                               *insert = tid;
+                               if (!list_add(&tid_filters, insert)) {
+                                       free(insert);
+                                       return (struct parse_result) { .status = PARSE_OOM, };
+                               }
+                       }
+                       break;
+               }
+               case 1: { /* pid filter */
+                       int pid;
+                       if (sscanf(optarg, "%d", &pid) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "--pid", };
+                       else {
+                               pid_t *insert = calloc(1, sizeof(pid_t));
+                               if (insert == NULL)
+                                       return (struct parse_result) { .status = PARSE_OOM, };
+                               *insert = pid;
+                               if (!list_add(&tid_filters, insert)) {
+                                       free(insert);
+                                       return (struct parse_result) { .status = PARSE_OOM, };
+                               }
+                       }
+                       break;
+               }
+               case 2: { /* version */
+                       return (struct parse_result) { .status = PARSE_VERSION_REQUESTED, };
+               }
+               case 3: /* colored headers */
+                       colors_auto = false;
+                       if (!strcmp(optarg, "always"))
+                               colors_force = true;
+                       else if (!strcmp(optarg, "auto"))
+                               colors_auto = true;
+                       else if (!strcmp(optarg, "never"))
+                               colors_force = false;
+                       else
+                               return (struct parse_result) { .status = PARSE_BAD_COLOR, .bad_contents = optarg, };
+                       break;
+               case 4: /* timestamp */
+                       if (!strcmp(optarg, "default"))
+                               sort_by = DLOGUTIL_SORT_DEFAULT;
+                       else {
+                               sort_by = get_order_from_string(optarg);
+                               if (sort_by == DLOGUTIL_SORT_DEFAULT)
+                                       return (struct parse_result) { .status = PARSE_BAD_SORT_BY, .bad_contents = optarg, };
+                       }
+                       break;
+               case 'd':
+                       mode = DLOGUTIL_MODE_DUMP;
+                       break;
+               case 'm':
+                       mode = DLOGUTIL_MODE_MONITOR;
+                       break;
+               case 't':
+                       mode = DLOGUTIL_MODE_DUMP;
+                       if (sscanf(optarg, "%u", &dump_size) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-t", };
+                       break;
+               case 'c':
+                       action = ACTION_CLEAR;
+                       break;
+               case 'g':
+                       action = ACTION_GET_CAPACITY;
+                       break;
+               case 'b': {
+                       log_id_t id = log_id_by_name(optarg);
+                       if (id == LOG_ID_INVALID)
+                               return (struct parse_result) { .status = PARSE_BAD_BUFFER, .bad_contents = optarg, };
+                       bit_set(&enabled_buffers, id);
+                       break;
+               }
+               case 'u': {
+                       unsigned size;
+                       if (sscanf(optarg, "%u", &size) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-u", };
+                       if (size == 0)
+                               sorting_settings = 0;
+                       else
+                               sorting_settings = size;
+                       break;
+               }
+               case 'f':
+                       file_path = optarg;
+                       break;
+               case 'v': {
+                       format = log_format_from_string(optarg);
+                       if (format == FORMAT_OFF)
+                               return (struct parse_result) { .status = PARSE_BAD_FORMAT, .bad_contents = optarg, };
+                       break;
+               }
+               case 's':
+                       if (!list_add(&filterspecs, "*:S"))
+                               return (struct parse_result) { .status = PARSE_OOM, };
+                       break;
+               case 'r':
+                       if (sscanf(optarg, "%zu", &rotate_size_kbytes) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-r", };
+                       break;
+               case 'n':
+                       if (sscanf(optarg, "%zu", &max_rotated) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-n", };
+                       break;
+               case 'e': {
+                       if (buffer_made)
+                               return (struct parse_result) { .status = PARSE_OPTION_REPEATED, .which_option = "-e", };
+                       if (sscanf(optarg, "%zu", &write_buffer_size) != 1)
+                               return (struct parse_result) { .status = PARSE_OPTION_NUMERICAL_ARGUMENT, .which_option = "-e", };
+                       buffer_made = true;
+                       break;
+               }
+               case 'h':
+                       return (struct parse_result) { .status = PARSE_HELP_REQUESTED, };
+               default: // invalid option or missing mandatory parameter
+                       return (struct parse_result) { .status = PARSE_NO_PARSE, };
+               }
+       }
+
+       while (optind < argc) {
+               /* TODO: We don't want to call log_filter_set_filterspec/dlogutil_config_filter_filterspec here,
+                * as we want the option parser to be general. Unfortunately, this means that the user has to parse
+                * the filterspecs and not us. Any idea on how to make this nicer? */
+               if (!list_add(&filterspecs, argv[optind++]))
+                       return (struct parse_result) { .status = PARSE_OOM, };
+       }
+
+       if (!buffer_made && mode == DLOGUTIL_MODE_DUMP)
+               write_buffer_size = DEFAULT_WRITE_BUFFER_SIZE;
+
+       struct parse_result ret = (struct parse_result) {
+               .status = PARSE_OK,
+               .colors_auto = colors_auto,
+               .colors_force = colors_force,
+               .format = format,
+               .rotate_size_kbytes = rotate_size_kbytes,
+               .max_rotated = max_rotated,
+               .file_path = file_path,
+               .write_buffer_size = write_buffer_size,
+               .enabled_buffers = enabled_buffers,
+               .action = action,
+               .filterspecs = filterspecs,
+               .pid_filters = pid_filters,
+               .tid_filters = tid_filters,
+               .sorting_settings = sorting_settings,
+               .mode = mode,
+               .dump_size = dump_size,
+               .sort_by = sort_by,
+       };
+       filterspecs = NULL;
+       pid_filters = NULL;
+       tid_filters = NULL;
+       return ret;
+}