Implement --trailer select option.
authorAndre Noll <maan@systemlinux.org>
Wed, 11 Feb 2009 09:57:56 +0000 (10:57 +0100)
committerAndre Noll <maan@systemlinux.org>
Wed, 11 Feb 2009 09:57:56 +0000 (10:57 +0100)
It works just like the --header option.

select.c
select.ggo

index e30697e..9dda089 100644 (file)
--- a/select.c
+++ b/select.c
@@ -72,18 +72,18 @@ enum user_list_atoms {USER_LIST_ATOMS};
 #undef ATOM
 
 /* user list header */
-#define USER_LIST_HEADER_ATOMS \
+#define USER_LIST_HEADER_TRAILER_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
+struct atom user_list_header_trailer_atoms[] = {
+       USER_LIST_HEADER_TRAILER_ATOMS
        {.name = NULL}
 };
 #undef ATOM
 #define ATOM(x, y) ulha_ ## x,
-enum user_list_header_atoms {USER_LIST_HEADER_ATOMS};
+enum user_list_header_trailer_atoms {USER_LIST_HEADER_TRAILER_ATOMS};
 #undef ATOM
 
 /* user summary */
@@ -141,6 +141,7 @@ struct user_list_info {
 struct user_list_format_info {
        struct format_info *fi;
        struct format_info *header_fi;
+       struct format_info *trailer_fi;
 };
 
 struct user_summary_info {
@@ -430,7 +431,9 @@ static int print_global_summary(struct format_info *fi)
        buf = format_items(fi, values);
        ret = output("%s", buf);
        free(buf);
-       return ret;
+       if (ret < 0)
+               return ret;
+       return output("%s", select_conf.trailer_arg);
 }
 
 static int user_summary_loop_function(struct osl_row *row, void *data)
@@ -590,8 +593,11 @@ static int print_user_summary(struct format_info *fi)
        for (i = 0; i < usld.num_admissible_users; i++) {
                if (select_conf.limit_arg >= 0 && i > select_conf.limit_arg)
                        break;
-               print_user_summary_line(usld.usis + i, usld.fi);
+               ret = print_user_summary_line(usld.usis + i, usld.fi);
+               if (ret < 0)
+                       goto out;
        }
+       ret = output("%s", select_conf.trailer_arg);
 out:
        free(usld.usis);
        return ret;
@@ -662,12 +668,12 @@ static int print_user_list(struct user_info *ui, void *data)
                .fi = ulfi->fi,
                .count = select_conf.limit_arg
        };
-       union atom_value header_values[] = {
+       union atom_value header_trailer_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);
+       char *buf = format_items(ulfi->header_fi, header_trailer_values);
 
        ret = output("%s", buf);
        free(buf);
@@ -684,6 +690,11 @@ static int print_user_list(struct user_info *ui, void *data)
        ret = adu_loop_reverse(ui->table, sort_column, &uli,
                user_list_loop_function, &uli.ret, &uli.osl_errno);
        free_regex(uli.preg);
+       if (ret < 0)
+               return ret;
+       buf = format_items(ulfi->trailer_fi, header_trailer_values);
+       ret = output("%s", buf);
+       free(buf);
        return ret;
 }
 
@@ -692,12 +703,18 @@ 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";
+       char *trailer_fmt = select_conf.trailer_arg;
        int ret = parse_format_string(header_fmt,
-               user_list_header_atoms, &ulfi.header_fi);
+               user_list_header_trailer_atoms, &ulfi.header_fi);
+       if (ret < 0)
+               return ret;
+       ret = parse_format_string(trailer_fmt,
+               user_list_header_trailer_atoms, &ulfi.trailer_fi);
        if (ret < 0)
                return ret;
        ret = for_each_admissible_user(print_user_list, &ulfi);
        free_format_info(ulfi.header_fi);
+       free_format_info(ulfi.trailer_fi);
        return ret;
 }
 
@@ -778,7 +795,9 @@ static int print_global_list(struct format_info *fi)
        ret = adu_loop_reverse(dir_table, sort_column, &gli,
                global_list_loop_function, &gli.ret, &gli.osl_errno);
        free_regex(gli.preg);
-       return ret;
+       if (ret < 0)
+               return ret;
+       return output("%s", select_conf.trailer_arg);
 }
 
 static int print_statistics(struct format_info *fi)
@@ -928,7 +947,7 @@ out:
 /** Default format string for global_list mode. */
 #define GLOBAL_LIST_DFLT_FMT "%(size:r:8) %(files:r:8) %(dirname)\n"
 /** Default format string for global_summary mode. */
-#define GLOBAL_SUMMARY_DFLT_FMT "#directories: %(dirs), #files: %(files), size: %(size)\n\n"
+#define GLOBAL_SUMMARY_DFLT_FMT "#directories: %(dirs), #files: %(files), size: %(size)\n"
 /** Default format string for user_list mode. */
 #define USER_LIST_DFLT_FMT "%(size:r:5) %(files:r:5) %(dirname)\n"
 /** Default format string for user_summary mode. */
index c4e1ec0..e2c91f8 100644 (file)
@@ -87,6 +87,20 @@ details="
        output to scripts.
 "
 
+option "trailer" T
+#~~~~~~~~~~~~~~~~~
+"use a customized trailer for listings/summaries"
+string typestr="string"
+optional
+default=""
+details="
+       This option can be used to print any string at the end of
+       the query output.
+
+       In user_list mode the trailer is a format string with the
+       same semantics like the header string.
+"
+
 option "select-mode" m
 #~~~~~~~~~~~~~~~~~~~~~
 "How to print the results of the query"