Make the header line configurable.
authorAndre Noll <maan@systemlinux.org>
Sun, 9 Nov 2008 19:37:09 +0000 (20:37 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 9 Nov 2008 19:37:09 +0000 (20:37 +0100)
This replaces the --no-header flag by --header string option. The
argument is the header of the summary/list.

This was not a straight-forward task because the headers for the
user lists contain the uid and the user name. So introduce another
set of format string directives to still allow this.

select.c
select.ggo

index 7537f4c..d555f1c 100644 (file)
--- a/select.c
+++ b/select.c
@@ -67,6 +67,21 @@ struct atom user_list_atoms[] = {
 enum user_list_atoms {USER_LIST_ATOMS};
 #undef ATOM
 
+/* user list header */
+#define USER_LIST_HEADER_ATOMS \
+       ATOM(pw_name, STRING) \
+       ATOM(uid, ID)
+
+#define ATOM(x, y) { .name = #x, .type = AT_ ## y},
+struct atom user_list_header_atoms[] = {
+       USER_LIST_HEADER_ATOMS
+       {.name = NULL}
+};
+#undef ATOM
+#define ATOM(x, y) ulha_ ## x,
+enum user_list_header_atoms {USER_LIST_HEADER_ATOMS};
+#undef ATOM
+
 /* user summary */
 #define USER_SUMMARY_ATOMS \
        ATOM(pw_name, STRING) \
@@ -111,6 +126,11 @@ struct user_list_info {
        int osl_errno;
 };
 
+struct user_list_format_info {
+       struct format_info *fi;
+       struct format_info *header_fi;
+};
+
 struct user_summary_info {
        struct user_info *ui;
        int ret;
@@ -295,6 +315,8 @@ static int print_global_summary(struct format_info *fi)
        int ret;
        char *buf;
        struct global_summary_info gsi = {.num_dirs = 0};
+       char *header = select_conf.header_given? select_conf.header_arg :
+               "Global summary\n";
 
        union atom_value values[] = {
                [gsa_dirs] = {.num_value = 0ULL},
@@ -309,11 +331,10 @@ static int print_global_summary(struct format_info *fi)
        values[gsa_dirs].num_value = (long long unsigned)gsi.num_dirs;
        values[gsa_files].num_value = (long long unsigned)gsi.num_files;
        values[gsa_size].num_value = (long long unsigned)gsi.num_bytes;
-       if (!select_conf.no_headers_given) {
-               ret = output("Global summary\n");
-               if (ret < 0)
-                       return ret;
-       }
+
+       ret = output("%s", header);
+       if (ret < 0)
+               return ret;
        buf = format_items(fi, values);
        ret = output("%s", buf);
        free(buf);
@@ -414,12 +435,12 @@ static int print_user_summary(struct format_info *fi)
                .fi = fi,
                .count = select_conf.limit_arg
        };
+       char *header = select_conf.header_given? select_conf.header_arg :
+               "User summary\n";
 
-       if (!select_conf.no_headers_given) {
-               ret = output("User summary\n");
-               if (ret < 0)
-                       return ret;
-       }
+       ret = output("%s", header);
+       if (ret < 0)
+               return ret;
        ret = for_each_admissible_user(compute_user_summary, NULL);
        if (ret < 0)
                return ret;
@@ -498,28 +519,47 @@ err:
 
 static int print_user_list(struct user_info *ui, void *data)
 {
-       struct format_info *fi = data;
+       struct user_list_format_info *ulfi = data;
        int ret;
-       enum user_table_columns sort_column = UT_BYTES;
+       enum user_table_columns sort_column;
        struct user_list_info uli = {
                .ui = ui,
-               .fi = fi,
+               .fi = ulfi->fi,
                .count = select_conf.limit_arg
        };
+       union atom_value header_values[] = {
+               [ulha_uid] = {.num_value = (long long unsigned)ui->uid},
+               [ulha_pw_name] = {.string_value = ui->pw_name?
+                       ui->pw_name : "?"}
+       };
+       char *buf = format_items(ulfi->header_fi, header_values);
 
+       ret = output("%s", buf);
+       free(buf);
+       if (ret < 0)
+               return ret;
        if (select_conf.list_sort_arg == list_sort_arg_file_count)
                sort_column = UT_FILES;
-
-       if (!select_conf.no_headers_given) {
-               ret = output("%s (uid %u)\n",
-                       ui->pw_name? ui->pw_name : "?", (unsigned)ui->uid);
-               if (ret < 0)
-                       return ret;
-       }
+       else
+               sort_column = UT_BYTES;
        return adu_loop_reverse(ui->table, sort_column, &uli, user_list_loop_function,
                &uli.ret, &uli.osl_errno);
 }
 
+static int print_user_lists(struct format_info *fi)
+{
+       struct user_list_format_info ulfi = {.fi = fi};
+       char *header_fmt = select_conf.header_given?
+               select_conf.header_arg : "uid %(uid)(%(pw_name)):\n";
+       int ret = parse_format_string(header_fmt,
+               user_list_header_atoms, &ulfi.header_fi);
+       if (ret < 0)
+               return ret;
+       ret = for_each_admissible_user(print_user_list, &ulfi);
+       free_format_info(ulfi.header_fi);
+       return ret;
+}
+
 static int global_list_loop_function(struct osl_row *row, void *data)
 {
        struct global_list_info *gli = data;
@@ -570,19 +610,20 @@ err:
 static int print_global_list(struct format_info *fi)
 {
        int ret;
-       enum dir_table_columns sort_column = DT_BYTES;
+       enum dir_table_columns sort_column;
        struct global_list_info gli = {
                .fi = fi,
                .count = select_conf.limit_arg
        };
-
-       if (!select_conf.no_headers_given) {
-               ret = output("Global list\n");
-               if (ret < 0)
-                       return ret;
-       }
+       char *header = select_conf.header_given?
+               select_conf.header_arg : "Global list\n";
+       ret = output("%s", header);
+       if (ret < 0)
+               return ret;
        if (select_conf.list_sort_arg == list_sort_arg_file_count)
                sort_column = DT_FILES;
+       else
+               sort_column = DT_BYTES;
        return adu_loop_reverse(dir_table, sort_column, &gli,
                global_list_loop_function, &gli.ret, &gli.osl_errno);
 }
@@ -590,14 +631,14 @@ static int print_global_list(struct format_info *fi)
 static int print_statistics(struct format_info *fi)
 {
        switch (select_conf.select_mode_arg) {
-               case select_mode_arg_global_list:
-                       return print_global_list(fi);
-               case select_mode_arg_global_summary:
-                       return print_global_summary(fi);
-               case select_mode_arg_user_list:
-                       return for_each_admissible_user(print_user_list, fi);
-               case select_mode_arg_user_summary:
-                       return print_user_summary(fi);
+       case select_mode_arg_global_list:
+               return print_global_list(fi);
+       case select_mode_arg_global_summary:
+               return print_global_summary(fi);
+       case select_mode_arg_user_list:
+               return print_user_lists(fi);
+       case select_mode_arg_user_summary:
+               return print_user_summary(fi);
        };
        ERROR_LOG("bad select mode\n");
        return -ERRNO_TO_ERROR(EINVAL);
index 914e351..f29cd2f 100644 (file)
@@ -47,12 +47,22 @@ details="
        except global_summary (which outputs only one single line).
 "
 
-option "no-headers" -
-#~~~~~~~~~~~~~~~~~~~~
-"suppress descriptions for listings/summaries"
-flag off
+option "header" H
+#~~~~~~~~~~~~~~~~
+"use a customized header for listings/summaries"
+string typestr="string"
+optional
 details="
-       This is mostly useful to feed the output of adu to scripts.
+       This option can be used to print any string instead of the
+       default header line (which depends on the selected mode).
+
+       In user_list mode the header is a format string which allows
+       to include the uid and the user name in the header. See the
+       --format option for more details.
+
+       It is possible to set this to the empty string to suppress
+       the header completely. This is mostly useful to feed the
+       output to scripts.
 "
 
 option "select-mode" m
@@ -196,19 +206,20 @@ details="
        together with their types, and for which modes each of
        them may be used.
 
-               pw_name (string): user name. Available for user_list
-               and user_summary
+               pw_name (string): user name. Available for user_list,
+               user_summary and for the header in user_list mode.
 
-               uid (id): user id. Available for user_list and
-               user_summary.
+               uid (id): user id. Available for user_list,
+               user_summary and for the header in user_list mode.
 
-               files (count): number of files. Available everywhere.
+               files (count): number of files. Available for all
+               modes.
 
                dirname (string): name of the directory. Available
                for user_list and global_list.
 
                size (size): total size/ directory size. Available
-               everywhere.
+               for all modes.
 
                dirs (count): number of directories. Available
                for user_summary and global_summary.