This needs much more work..
*.[oa]
foo*
bar*
-cmdline.[ch]
+*cmdline.[ch]
GPATH
GRTAGS
GSYMS
-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
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)
%.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
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:
# 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
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"
users. Decreasing the value causes adu to use slightly less memory.
"
-
##############################
section "Options for --select"
##############################
/* create.h */
int com_create(void);
+int com_interactive(void);
--- /dev/null
+#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;
+}
--- /dev/null
+
+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="<key>"
+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="<format>"
+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="<path>"
+optional
+default="-"
+details="
+ If empty, or not given, use stdout.
+"