From: Andre Noll Date: Fri, 20 Jun 2008 08:40:13 +0000 (+0200) Subject: Add rudimentary interactive support. X-Git-Tag: v0.0.3~16 X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=commitdiff_plain;h=b01ff57775258c8df4c486b0962fc67cfdfef439 Add rudimentary interactive support. This needs much more work.. --- diff --git a/.gitignore b/.gitignore index 743f60e..617d85d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.[oa] foo* bar* -cmdline.[ch] +*cmdline.[ch] GPATH GRTAGS GSYMS diff --git a/Makefile b/Makefile index 5e425da..2429a67 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -objects := adu.o string.o cmdline.o fd.o select.o create.o +objects := adu.o string.o cmdline.o fd.o select.o create.o interactive.o select.cmdline.o all: adu +version := 0.0.2 DEBUG_CPPFLAGS += -Wno-sign-compare -g -Wunused -Wundef -W DEBUG_CPPFLAGS += -Wredundant-decls @@ -14,6 +15,7 @@ CPPFLAGS += -Wunused-macros CPPFLAGS += -Wbad-function-cast CPPFLAGS += -D_LARGEFILE64_SOURCE CPPFLAGS += $(shell getconf LFS64_CFLAGS) +CPPFLAGS += -DVERSION='"$(version)"' LDFLAGS += -D_LARGEFILE64_SOURCE LDFLAGS += $(shell getconf LFS64_LDFLAGS) @@ -38,5 +40,18 @@ cmdline.c cmdline.h: adu.ggo %.o: %.c Makefile $(CC) -c $(CPPFLAGS) $(DEBUG_CPPFLAGS) $< +select.cmdline.c select.cmdline.h: select.ggo + gengetopt --string-parser \ + --set-package=select \ + --no-handle-help \ + --no-handle-error \ + --no-handle-version \ + --arg-struct-name=select_args_info \ + --file-name=$(subst .ggo,,$<).cmdline \ + --func-name $(subst .ggo,,$<)_cmdline_parser < $< + +select.cmdline.o: select.cmdline.c select.cmdline.h + $(CC) -c $(CPPFLAGS) $< + clean: rm -f *.o adu diff --git a/adu.c b/adu.c index db7a564..42d1b19 100644 --- a/adu.c +++ b/adu.c @@ -550,8 +550,10 @@ int main(int argc, char **argv) ret = -E_SYNTAX; if (conf.select_given) ret = com_select(); - else + else if (conf.create_given) ret = com_create(); + else + ret = com_interactive(); if (ret < 0) goto out; out: diff --git a/adu.ggo b/adu.ggo index a46de25..38986af 100644 --- a/adu.ggo +++ b/adu.ggo @@ -3,7 +3,6 @@ # Licensed under the GPL v2. For licencing details see COPYING. package "adu" -version "0.0.2" purpose "advanced disk usage adu creates a database containing disk usage statistics of a given @@ -107,6 +106,14 @@ details=" that directory. " +groupoption "interactive" I +#~~~~~~~~~~~~~~~~~~~~~ +"activate interactive mode" +group="mode" +details=" + In this mode, adu reads commands from stdin. +" + groupoption "select" S #~~~~~~~~~~~~~~~~~~~~~ "query a database previously created with --create" @@ -158,7 +165,6 @@ details=" users. Decreasing the value causes adu to use slightly less memory. " - ############################## section "Options for --select" ############################## diff --git a/adu.h b/adu.h index debada6..f8ef9c2 100644 --- a/adu.h +++ b/adu.h @@ -195,3 +195,4 @@ int com_select(void); /* create.h */ int com_create(void); +int com_interactive(void); diff --git a/interactive.c b/interactive.c new file mode 100644 index 0000000..686a89f --- /dev/null +++ b/interactive.c @@ -0,0 +1,107 @@ +#include "adu.h" +#include "string.h" +#include "error.h" +#include "cmdline.h" +#include "select.cmdline.h" + +struct select_args_info select_conf; + +struct interactive_command { + const char *name; + int (*handler)(char *); +}; + +#define INTERACTIVE_COMMANDS \ + INTERACTIVE_COMMAND(dump) \ + INTERACTIVE_COMMAND(set) \ + INTERACTIVE_COMMAND(def) \ + +#define INTERACTIVE_COMMAND(name) \ + static int icom_ ## name (char *line); + +INTERACTIVE_COMMANDS + +#undef INTERACTIVE_COMMAND + +#define INTERACTIVE_COMMAND(_name) \ + { \ + .name = #_name, \ + .handler = icom_ ## _name \ + }, + +struct interactive_command icmds[] = { + INTERACTIVE_COMMANDS + {.name = NULL} +}; + +static int read_input_line(char *line, size_t size) +{ + return fgets(line, size, stdin)? 1 : -1; +} + +static int icom_def(__a_unused char *line) +{ + select_cmdline_parser_init(&select_conf); + return 1; +} + +static int icom_set(char *line) +{ + struct select_cmdline_parser_params params = { + .override = 1, + .initialize = 0, + .check_required = 1, + .check_ambiguity = 0, + .print_errors = 1 + }; + return select_cmdline_parser_string_ext(line, &select_conf, "select", + ¶ms)? + -E_SYNTAX : 1; +} + +static int icom_dump(__a_unused char *line) +{ + ERROR_LOG("dump: %s\n", select_conf.format_arg); + select_cmdline_parser_dump(stdout, &select_conf); + return 1; +} + +static int exec_interactive_command(char *line) +{ + const char const *delim = "\t\n "; + int i; + char *cmd = adu_strdup(line + strspn(line, delim)); + char *p = cmd + strcspn(cmd, delim); + int ret = -E_SYNTAX; + + *p = '\0'; + p++; + for (i = 0; icmds[i].name; i++) { + ERROR_LOG("name: %s, cmd: %s.\n", icmds[i].name, cmd); + if (strcmp(icmds[i].name, cmd)) + continue; + ERROR_LOG("exec cmd: %s, args: %s\n", cmd, p); + ret = icmds[i].handler(p); + break; + } + free(cmd); + return ret; +} + +int com_interactive(void) +{ + char line[255]; + int ret = 1; + + while (read_input_line(line, sizeof(line)) >= 0) { + size_t len = strlen(line); + if (!len) + continue; + if (line[len - 1] == '\n') + line[len - 1] = '\0'; + ret = exec_interactive_command(line); + if (ret < 0) + printf("%s\n", adu_strerror(-ret)); + } + return ret; +} diff --git a/select.ggo b/select.ggo new file mode 100644 index 0000000..10c760e --- /dev/null +++ b/select.ggo @@ -0,0 +1,72 @@ + +option "uid" u +#~~~~~~~~~~~~~ +"user id(s) to take into account" +string typestr="uid_spec" +optional +multiple +details=" + An uid specifier may be a single number, or a range of uids. + Example: + + --uid 42 # only consider uid 42 + --uid 42- # only consider uids greater or equal than 42 + --uid 23-42 # only consider uids between 23 and 42, inclusively. + + This option may be given multiple times. An uid is taken into + account if it satisfies at least one --uid option. +" + +option "limit" L +#~~~~~~~~~~~~~~~ +"Limit output" +int typestr="num" +default="-1" +optional +details=" + Only print num lines of output. If negative (the default), + print all lines. +" + +option "no-headers" - +#~~~~~~~~~~~~~~~~~~~~ +"supress descriptions for listings/tables" +flag off +details=" + This is mostly useful to feed the output of adu to scripts. +" + +option "sort" s +#~~~~~~~~~~~~~~~ +"how to sort the output" +enum typestr="" +values="sizes","files","unsorted" +default="sizes" +optional +details=" + Sort by file size, file count or unsorted. +" + +option "format" f +#~~~~~~~~~~~~~~~~~ +"how to format the output" +string typestr="" +optional +details=" + %(basedir) -- the path given to --base-dir during create + %(dir) -- the name of the directory + %(dir_size) -- the size of the sum of all regular files in this directory + %(num_files) -- the number of regular files in this directory + %% -- interpolates to % + %xx -- interpolates to the character with hex code xx +" + +option "output" o +#~~~~~~~~~~~~~~~~ +"file to write output to" +string typestr="" +optional +default="-" +details=" + If empty, or not given, use stdout. +"