Introduce --global-summary-format.
authorAndre Noll <maan@systemlinux.org>
Sun, 26 Oct 2008 15:06:03 +0000 (16:06 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 26 Oct 2008 15:06:03 +0000 (16:06 +0100)
This allows to pretty-format also the global summary. This patch also
closes some memory leaks.

adu.h
format.c
select.c
select.ggo

diff --git a/adu.h b/adu.h
index 7e0d34c..012fdde 100644 (file)
--- a/adu.h
+++ b/adu.h
@@ -196,6 +196,7 @@ void sort_hash_table(int (*comp)(const void *, const void *));
 
 /* select.c */
 struct select_format_info {
+       struct format_info *global_summary_fi;
        struct format_info *user_summary_fi;
 };
 int parse_select_options(char *string, struct select_cmdline_parser_params *params,
index 48aa371..6b7a2f6 100644 (file)
--- a/format.c
+++ b/format.c
@@ -423,6 +423,7 @@ char *format_items(struct format_info *info, union atom_value *values)
                                fi->width, &af->nf, type);
                }
                buf = adu_strcat(buf, val);
+               free(val);
        }
        return buf;
 }
index 362b1a6..84e18d4 100644 (file)
--- a/select.c
+++ b/select.c
@@ -27,6 +27,21 @@ static uint64_t num_bytes;
 /** The decimal representation of an uint64_t never exceeds that size. */
 #define FORMATED_VALUE_SIZE 25
 
+#define GLOBAL_SUMMARY_ATOMS \
+       ATOM(dirs, COUNT) \
+       ATOM(files, COUNT) \
+       ATOM(size, SIZE)
+
+#define ATOM(x, y) { .name = #x, .type = AT_ ## y},
+struct atom global_summary_atoms[] = {
+       GLOBAL_SUMMARY_ATOMS
+       {.name = NULL}
+};
+#undef ATOM
+#define ATOM(x, y) gsa_ ## x,
+enum global_summary_atoms {GLOBAL_SUMMARY_ATOMS};
+#undef ATOM
+
 #define USER_SUMMARY_ATOMS \
        ATOM(pw_name, STRING) \
        ATOM(uid, ID) \
@@ -44,6 +59,7 @@ struct atom user_summary_atoms[] = {
 enum user_summary_atoms {USER_SUMMARY_ATOMS};
 #undef ATOM
 
+
 /* these get filled in by the select command. */
 static char count_unit_buf[4] = "( )", size_unit_buf[4] = "( )";
 
@@ -371,31 +387,27 @@ static int adu_loop_reverse(struct osl_table *t, unsigned col_num, void *private
        return check_loop_return(ret, *loop_ret, *loop_osl_errno);
 }
 
-static int print_global_summary(void)
+static int print_global_summary(struct format_info *fi)
 {
-       char d[FORMATED_VALUE_SIZE], f[FORMATED_VALUE_SIZE],
-               s[FORMATED_VALUE_SIZE];
-       enum enum_count_unit ud, uf;
-       enum enum_size_unit us;
        int ret;
+       char *buf;
+       union atom_value values[] = {
+               [gsa_dirs] = {.num_value = (long long unsigned)num_dirs},
+               [gsa_files] = {.num_value =  (long long unsigned)num_files},
+               [gsa_size] = {.num_value =  (long long unsigned)num_bytes}
+       };
 
        if (select_conf.no_global_summary_given)
                return 1;
-       ud = format_count_value(select_conf.count_unit_arg, num_dirs, 0, d);
-       uf = format_count_value(select_conf.count_unit_arg, num_files, 0, f);
-       us = format_size_value(select_conf.size_unit_arg, num_bytes, 0, s);
-
        if (!select_conf.no_headers_given) {
-               ret = output("Global summary "
-                       "(dirs(%c)/files(%c)/size(%c))\n",
-                       count_unit_abbrevs[ud],
-                       count_unit_abbrevs[uf],
-                       size_unit_abbrevs[us]
-               );
+               ret = output("Global summary\n");
                if (ret < 0)
                        return ret;
        }
-       return output("\t%s\t%s\t%s\n\n", d, f, s);
+       buf = format_items(fi, values);
+       ret = output("%s", buf);
+       free(buf);
+       return ret;
 }
 
 static int print_user_summary_line(struct user_info *ui, __a_unused void *data)
@@ -410,7 +422,10 @@ static int print_user_summary_line(struct user_info *ui, __a_unused void *data)
                [usa_size] = {.num_value =  (long long unsigned)ui->bytes}
        };
        char *buf = format_items(fi, values);
-       return output("%s", buf);
+       int ret = output("%s", buf);
+
+       free(buf);
+       return ret;
 }
 
 static int name_comp(const void *a, const void *b)
@@ -600,13 +615,15 @@ static int print_statistics(struct select_format_info *sli)
        ret = print_global_lists();
        if (ret < 0)
                return ret;
-       ret = print_global_summary();
+       ret = print_global_summary(sli->global_summary_fi);
+       free_format_info(sli->global_summary_fi);
        if (ret < 0)
                return ret;
        ret = print_user_lists();
        if (ret < 0)
                return ret;
        ret = print_user_summary(sli->user_summary_fi);
+       free_format_info(sli->user_summary_fi);
        if (ret < 0)
                return ret;
        return 1;
@@ -714,6 +731,12 @@ int parse_select_options(char *string, struct select_cmdline_parser_params *para
                user_summary_atoms, &sfi->user_summary_fi);
        if (ret < 0)
                return ret;
+       ret = parse_format_string(select_conf.global_summary_format_arg,
+               global_summary_atoms, &sfi->global_summary_fi);
+       if (ret < 0) {
+               free_format_info(sfi->user_summary_fi);
+               return ret;
+       }
        return 1;
 help:
        line = select_conf.detailed_help_given?
index 1093d46..83d07a0 100644 (file)
@@ -159,6 +159,18 @@ details="
 section "Format strings"
 ########################
 
+option "global-summary-format" -
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+"How to format the global summary"
+string typestr="<format>"
+default="#directories: %(dirs), #files: %(files), size: %(size)\n\n"
+details="
+       dirs: The number of directories
+       files: The number of files
+       size: Total size of all files
+"
+optional
+
 option "user-summary-format" -
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 "How to format the user summary"