From: Andre Noll Date: Sat, 1 Nov 2008 19:21:18 +0000 (+0100) Subject: Add format string doku, simplify format string handling. X-Git-Tag: v0.0.4~24 X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=commitdiff_plain;h=de525e7c5b6592b41f8681f919d5d53406801861 Add format string doku, simplify format string handling. As adu now only prints one list/summary at a time, there's only need for one format string. So replace the four format-string related option by a single --format option and add a detailed description on how adu format strings may be used. This further simplifies the select code a bit. --- diff --git a/adu.c b/adu.c index ee4dddb..757054d 100644 --- a/adu.c +++ b/adu.c @@ -1,6 +1,8 @@ #include "adu.h" #include /* readdir() */ #include +#include "format.h" +#include "select.h" #include "gcc-compat.h" #include "cmdline.h" diff --git a/adu.h b/adu.h index 8bef62f..20cef2f 100644 --- a/adu.h +++ b/adu.h @@ -194,18 +194,6 @@ int for_each_admissible_user(int (*func)(struct user_info *, void *), void *data); void sort_hash_table(int (*comp)(const void *, const void *)); -/* select.c */ -struct select_format_info { - struct format_info *global_list_fi; - struct format_info *global_summary_fi; - struct format_info *user_summary_fi; - struct format_info *user_list_fi; -}; -int parse_select_options(char *string, struct select_cmdline_parser_params *params, - struct uid_range **admissible_uids, struct select_format_info *sfi); -int run_select_query(struct uid_range *admissible_uids, struct select_format_info *sfi); -int com_select(void); - /* create.h */ int com_create(void); int com_interactive(void); diff --git a/interactive.c b/interactive.c index 2a59e79..036f7a8 100644 --- a/interactive.c +++ b/interactive.c @@ -1,5 +1,6 @@ -#include "format.h" #include "adu.h" +#include "format.h" +#include "select.h" #include "string.h" #include "error.h" #include "cmdline.h" @@ -11,7 +12,7 @@ struct interactive_command { }; static struct uid_range *admissible_uids; -static struct select_format_info sfi; +static struct format_info *fi; #define INTERACTIVE_COMMANDS \ INTERACTIVE_COMMAND(dump, "dump the current configuration") \ @@ -49,7 +50,7 @@ static int read_input_line(char *line, size_t size) static int icom_run(__a_unused char *line) { - return run_select_query(admissible_uids, &sfi); + return run_select_query(admissible_uids, fi); } static int icom_help(__a_unused char *line) @@ -76,7 +77,7 @@ static int icom_set(char *line) .check_ambiguity = 0, .print_errors = 1 }; - return parse_select_options(line, ¶ms, &admissible_uids, &sfi); + return parse_select_options(line, ¶ms, &admissible_uids, &fi); } static int icom_dump(__a_unused char *line) diff --git a/select.c b/select.c index f929c35..949fd92 100644 --- a/select.c +++ b/select.c @@ -565,28 +565,17 @@ static int print_global_list(struct format_info *fi) global_list_loop_function, &gli.ret, &gli.osl_errno); } -static int print_statistics(struct select_format_info *sli) +static int print_statistics(struct format_info *fi) { - int ret; - switch (select_conf.select_mode_arg) { case select_mode_arg_global_list: - ret = print_global_list(sli->global_list_fi); - free_format_info(sli->global_list_fi); - return ret; + return print_global_list(fi); case select_mode_arg_global_summary: - ret = print_global_summary(sli->global_summary_fi); - free_format_info(sli->global_summary_fi); - return ret; + return print_global_summary(fi); case select_mode_arg_user_list: - ret = for_each_admissible_user(print_user_list, - sli->user_list_fi); - free_format_info(sli->user_list_fi); - return ret; + return for_each_admissible_user(print_user_list, fi); case select_mode_arg_user_summary: - ret = print_user_summary(sli->user_summary_fi); - free_format_info(sli->user_summary_fi); - return ret; + return print_user_summary(fi); }; ERROR_LOG("bad select mode\n"); return ERRNO_TO_ERROR(-EINVAL); @@ -627,8 +616,7 @@ out: return ret; } -int run_select_query(struct uid_range *admissible_uids, - struct select_format_info *sfi) +int run_select_query(struct uid_range *admissible_uids, struct format_info *fi) { int ret; @@ -647,7 +635,7 @@ int run_select_query(struct uid_range *admissible_uids, if (ret < 0) goto out; check_signals(); - ret = print_statistics(sfi); + ret = print_statistics(fi); out: close_all_tables(); if (output_file != stdout) @@ -655,12 +643,19 @@ out: return ret; } +#define GLOBAL_LIST_DFLT_FMT "%(size:r:8) %(files:r:8) %(dirname)\n" +#define GLOBAL_SUMMARY_DFLT_FMT "#directories: %(dirs), #files: %(files), size: %(size)\n\n" +#define USER_LIST_DFLT_FMT "%(size:r:5) %(files:r:5) %(dirname)\n" +#define USER_SUMMARY_DFLT_FMT "%(pw_name:l:16) %(uid:r:5) %(dirs:r:5) %(files:r:5) %(size:r:5)\n" + /* return: < 0: error, >0: OK, == 0: help given */ int parse_select_options(char *string, struct select_cmdline_parser_params *params, - struct uid_range **admissible_uids, struct select_format_info *sfi) + struct uid_range **admissible_uids, struct format_info **fi) { int ret; const char **line; + char *fmt = NULL; + struct atom *atoms; if (conf.select_options_given) { int argc; @@ -676,35 +671,32 @@ int parse_select_options(char *string, struct select_cmdline_parser_params *para return -E_SYNTAX; if (select_conf.help_given || select_conf.detailed_help_given) goto help; + fmt = select_conf.format_arg; } ret = parse_uid_arg(select_conf.uid_arg, admissible_uids); if (ret < 0) return ret; - ret = parse_format_string(select_conf.user_summary_format_arg, - 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) - goto global_summary_err; - ret = parse_format_string(select_conf.global_list_format_arg, - global_list_atoms, &sfi->global_list_fi); - if (ret < 0) - goto global_list_err; - ret = parse_format_string(select_conf.user_list_format_arg, - user_list_atoms, &sfi->user_list_fi); - if (ret < 0) - goto user_list_err; - return 1; -user_list_err: - free_format_info(sfi->global_list_fi); -global_list_err: - free_format_info(sfi->global_summary_fi); -global_summary_err: - free_format_info(sfi->user_summary_fi); - return ret; + + switch (select_conf.select_mode_arg) { + case select_mode_arg_global_list: + if (!fmt) + fmt = GLOBAL_LIST_DFLT_FMT; + atoms = global_list_atoms; + case select_mode_arg_global_summary: + if (!fmt) + fmt = GLOBAL_SUMMARY_DFLT_FMT; + atoms = global_summary_atoms; + case select_mode_arg_user_list: + if (!fmt) + fmt = USER_LIST_DFLT_FMT; + atoms = user_list_atoms; + case select_mode_arg_user_summary: + if (!fmt) + fmt = USER_SUMMARY_DFLT_FMT; + atoms = user_summary_atoms; + }; + return parse_format_string(fmt, atoms, fi); help: line = select_conf.detailed_help_given? select_args_info_detailed_help : select_args_info_help; @@ -721,8 +713,8 @@ help: int com_select(void) { struct uid_range *admissible_uids = NULL; - struct select_format_info sfi; int ret; + struct format_info *fi; struct select_cmdline_parser_params params = { .override = 1, .initialize = 1, @@ -733,8 +725,10 @@ int com_select(void) select_cmdline_parser_init(&select_conf); ret = parse_select_options(conf.select_options_arg, ¶ms, - &admissible_uids, &sfi); + &admissible_uids, &fi); if (ret <= 0) /* do not run query if help was given */ return ret; - return run_select_query(admissible_uids, &sfi); + ret = run_select_query(admissible_uids, fi); + free_format_info(fi); + return ret; } diff --git a/select.ggo b/select.ggo index 660839b..e8a5f95 100644 --- a/select.ggo +++ b/select.ggo @@ -91,57 +91,94 @@ details=" to the base dir. " -######################## -section "Format strings" -######################## - -option "global-list-format" - -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -"How to format the global list" -string typestr="" -default="%(size:r:8) %(files:r:8) %(dirname)\n" -details=" - size: Total size of all files - files: The number of files - dirname: The name of the directory -" - +option "format" f +#~~~~~~~~~~~~~~~~ +"How to format the output" +string typestr="" optional -option "global-summary-format" - -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -"How to format the global summary" -string typestr="" -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 + A string that specifies how the output of the select query is + goint to be formated. Depending on the chosen select-mode, + several conversion specifiers are available and a different + default value for this option applies. -option "user-list-format" - -#~~~~~~~~~~~~~~~~~~~~~~~~~~ -"How to format the user list" -string typestr="" -default="%(size:r:5) %(files:r:5) %(dirname)\n" -details=" - pw_name: The user name - uid: The user id - files: The number of files - size: size of all files in that directory - dirname: The name of the directory -" -optional -option "user-summary-format" - -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -"How to format the user summary" -string typestr="" -default="%(pw_name:l:16) %(uid:r:5) %(dirs:r:5) %(files:r:5) %(size:r:5)\n" -details=" - pw_name: The user name - uid: The user id - dirs: The number of directories - files: The number of files - size: Total size of all files + adu knows four different types of directives: string, id, + count and size. These are explained in more detail below. + + The general syntax for string and id directives is %(name:a:w) + where \"name\" is the name of the directive, \"a\" specifies + the alignment and \"w\" is the width specifier which allows + to give a field width. + + The alignment specifier is a single character: Either \"l\", + \"r\", or \"c\" may be given to specify left, right and + centered alignment respectively. The with specifier is a + positive integer. Both \"a\" and \"w\" are optional. + + A string directive supported by adu is \"dirname\" which is + subsitituted by the name of the directory. It is available + if either user_list or global_list mode was selected via + --select-mode. + + Examples: + + \"%(diname)\" # print dirname without any padding + \"%(dirname:c:20)\" # center dirname in a 20 chars wide field + + The other two types of directives, count and size, are used + for numbers. The syntax for these is %(name:a:w:u). The \"a\" + and the \"w\" specifier have the same meaning as for the string + and id directives. The additional \"u\" specifier selects a unit + in which the number that corresponds to the directive should + be formated. All three specifiers are optional. + + Possible units are the characters of the set \" bkmgtBKMGT\" + specifying bytes, kilobytes, megabytes, gigabytes and + terabytes respectively. The difference between the lower and + the upper case variants is that the lower case specifiers + select 1024-based units while the upper case specifiers use + 1000 as the basis. + + The whitespace character is like \"b\", but a space character + is printed instead of a unit. + + Two more characters \"h\" and \"H\" (human-readable) are also + available that choose an appropriate unit depending on the + size of the number being printed. + + An asterisk prepended to the unit specifier prevents the + unit from being printed. This is useful mainly for feeding + the output of adu to scripts that do not expect units. + + In order to print a percent sign, use \"%%\". Moreover, adu + understands \"\n\" and \"\t\" and outputs a newline and a + tab character for these combinations respectively. + + Examples: + + \"%(size:r::G)\" # print size in gigabytes right-aligned + \"%(size:r5::G)\" # as before, but use 5 char wide field + \"%(size:r5::*G)\" # as before, but supress trailing \"G\" + + List of directives and types known to adu, together with their types: + + name type meaning + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + pw_name string user name + uid id user id + files count number of files + dirname string name of the directory + size size total size/ directory size + dirs count number of directories + + Not all directives are available for each mode: + + name available in directives + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + pw_name user_list, user_summary + uid user_list, user_summary + files everywhere + dirname user_list, global_list + size everywhere + dirs suer_summary, global_summary " -optional diff --git a/select.h b/select.h new file mode 100644 index 0000000..c55e97c --- /dev/null +++ b/select.h @@ -0,0 +1,4 @@ +int parse_select_options(char *string, struct select_cmdline_parser_params *params, + struct uid_range **admissible_uids, struct format_info **fi); +int run_select_query(struct uid_range *admissible_uids, struct format_info *fi); +int com_select(void);