From: guigues Date: Thu, 12 Feb 2009 15:10:20 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: EED.02Oct2009~200 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=f08880c40f6304be640c7f8702bbbe96f8d50b40;p=creaImageIO.git *** empty log message *** --- diff --git a/appli/gimmick/CMakeLists.txt b/appli/gimmick/CMakeLists.txt index 20b6c9d..7f9f7ad 100644 --- a/appli/gimmick/CMakeLists.txt +++ b/appli/gimmick/CMakeLists.txt @@ -1,9 +1,37 @@ +IF(GGO) + #========================================================= + # Find ggo (gengetopt) files (http://www.gnu.org/software/gengetopt/) + FILE(GLOB ALL_GGO_FILES *.ggo) + MESSAGE(${ALL_GGO_FILES}) + + FOREACH(GGO_FILE ${ALL_GGO_FILES}) + #MESSAGE(input=${GGO_FILE}) + STRING(REGEX REPLACE "(.*).ggo" + "\\1" GGO_BASENAME + "${GGO_FILE}") + MESSAGE( base= ${GGO_BASENAME}) + SET(GGO_H ${GGO_BASENAME}_ggo.h) + MESSAGE(${GGO_H}) + SET(GGO_C ${GGO_BASENAME}_ggo.c) + MESSAGE(${GGO_C}) + SET(GGO_OUTPUT ${GGO_H} ${GGO_C}) + ADD_CUSTOM_COMMAND(OUTPUT ${GGO_OUTPUT} + COMMAND gengetopt + ARGS < ${GGO_FILE} --file-name=${GGO_BASENAME}_ggo -u --conf-parser + DEPENDS ${GGO_FILE} + ) + ENDFOREACH(GGO_FILE) +#========================================================= +ENDIF(GGO) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) +SET(SOURCES main gimmick_ggo.c) IF(WIN32) - ADD_EXECUTABLE(gimmick main) + ADD_EXECUTABLE(gimmick ${SOURCES}) SET_TARGET_PROPERTIES(gimmick PROPERTIES LINK_FLAGS /subsystem:console ) ELSE(WIN32) - ADD_EXECUTABLE(gimmick main) + ADD_EXECUTABLE(gimmick ${SOURCES}) ENDIF(WIN32) TARGET_LINK_LIBRARIES( gimmick creaImageIO2) diff --git a/appli/gimmick/gimmick.ggo b/appli/gimmick/gimmick.ggo new file mode 100644 index 0000000..d67d7ee --- /dev/null +++ b/appli/gimmick/gimmick.ggo @@ -0,0 +1,38 @@ +# file gimmick.ggo +package "gimmick" +version "0.1.0" +purpose "" +description "" +usage "gimmick COMMAND [OPTIONS]" + +section "COMMANDS" +option "print" p "Prints the local database tree" flag off +option "file" f "Adds the file to local database" typestr="" string optional +option "dir" d "Adds the directory to local database" typestr="" string optional +option "recurse" r "Recurse into sub-directories" flag off dependon="dir" + +section "OPTIONS" +option "verbose" v "Verbosity level" int default="1" optional + +#package "" +# version "" +# purpose "" +# usage "" +# description "" + +# args "" + +# option "" +# {details=""} +# {argtype} {typestr=""} +# {values="","",...} +# {default=""} +# {dependon=""} +# {required} {argoptional} {multiple} +# {hidden} + +# option "" flag + +# section "section name" {sectiondesc="optional section description"} + +# text "a textual sentence" diff --git a/appli/gimmick/gimmick_ggo.c b/appli/gimmick/gimmick_ggo.c new file mode 100644 index 0000000..6f5e74d --- /dev/null +++ b/appli/gimmick/gimmick_ggo.c @@ -0,0 +1,884 @@ +/* + File autogenerated by gengetopt version 2.22 + generated with the following command: + gengetopt --file-name=/home/guigues/coding/CreaTools/creaImageIO/appli/gimmick/gimmick_ggo -u --conf-parser + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "getopt.h" + +#include "/home/guigues/coding/CreaTools/creaImageIO/appli/gimmick/gimmick_ggo.h" + +const char *gengetopt_args_info_purpose = ""; + +const char *gengetopt_args_info_usage = "Usage: gimmick COMMAND [OPTIONS]"; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + "\nCOMMANDS:", + " -p, --print Prints the local database tree (default=off)", + " -f, --file= Adds the file to local database", + " -d, --dir= Adds the directory to local database", + " -r, --recurse Recurse into sub-directories (default=off)", + "\nOPTIONS:", + " -v, --verbose=INT Verbosity level (default=`1')", + 0 +}; + +typedef enum {ARG_NO + , ARG_FLAG + , ARG_STRING + , ARG_INT +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + +static int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); +struct line_list +{ + char * string_arg; + struct line_list * next; +}; + +static struct line_list *cmd_line_list = 0; +static struct line_list *cmd_line_list_tmp = 0; + +static void +free_cmd_list(void) +{ + /* free the list of a previous call */ + if (cmd_line_list) + { + while (cmd_line_list) { + cmd_line_list_tmp = cmd_line_list; + cmd_line_list = cmd_line_list->next; + free (cmd_line_list_tmp->string_arg); + free (cmd_line_list_tmp); + } + } +} + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->print_given = 0 ; + args_info->file_given = 0 ; + args_info->dir_given = 0 ; + args_info->recurse_given = 0 ; + args_info->verbose_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + args_info->print_flag = 0; + args_info->file_arg = NULL; + args_info->file_orig = NULL; + args_info->dir_arg = NULL; + args_info->dir_orig = NULL; + args_info->recurse_flag = 0; + args_info->verbose_arg = 1; + args_info->verbose_orig = NULL; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->print_help = gengetopt_args_info_help[3] ; + args_info->file_help = gengetopt_args_info_help[4] ; + args_info->dir_help = gengetopt_args_info_help[5] ; + args_info->recurse_help = gengetopt_args_info_help[6] ; + args_info->verbose_help = gengetopt_args_info_help[8] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); +} + +static void print_help_common(void) { + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + if (strlen(gengetopt_args_info_usage) > 0) + printf("\n%s\n", gengetopt_args_info_usage); + + printf("\n"); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); + + args_info->inputs = NULL; + args_info->inputs_num = 0; +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + unsigned int i; + free_string_field (&(args_info->file_arg)); + free_string_field (&(args_info->file_orig)); + free_string_field (&(args_info->dir_arg)); + free_string_field (&(args_info->dir_orig)); + free_string_field (&(args_info->verbose_orig)); + + + for (i = 0; i < args_info->inputs_num; ++i) + free (args_info->inputs [i]); + + if (args_info->inputs_num) + free (args_info->inputs); + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, char *values[]) +{ + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->print_given) + write_into_file(outfile, "print", 0, 0 ); + if (args_info->file_given) + write_into_file(outfile, "file", args_info->file_orig, 0); + if (args_info->dir_given) + write_into_file(outfile, "dir", args_info->dir_orig, 0); + if (args_info->recurse_given) + write_into_file(outfile, "recurse", 0, 0 ); + if (args_info->verbose_given) + write_into_file(outfile, "verbose", args_info->verbose_orig, 0); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = NULL; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char * const *argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, NULL); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, NULL); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + int result = EXIT_SUCCESS; + + if (cmdline_parser_required2(args_info, prog_name, NULL) > 0) + result = EXIT_FAILURE; + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +{ + int error = 0; + + /* checks for required options */ + + /* checks for dependences among options */ + if (args_info->recurse_given && ! args_info->dir_given) + { + fprintf (stderr, "%s: '--recurse' ('-r') option depends on option 'dir'%s\n", prog_name, (additional_error ? additional_error : "")); + error = 1; + } + + return error; +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, char *possible_values[], const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_FLAG: + *((int *)field) = !*((int *)field); + break; + case ARG_INT: + if (val) *((int *)field) = strtol (val, &stop_char, 0); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + /* check numeric conversion */ + switch(arg_type) { + case ARG_INT: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + case ARG_FLAG: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +int +cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + package_name = argv[0]; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "print", 0, NULL, 'p' }, + { "file", 1, NULL, 'f' }, + { "dir", 1, NULL, 'd' }, + { "recurse", 0, NULL, 'r' }, + { "verbose", 1, NULL, 'v' }, + { NULL, 0, NULL, 0 } + }; + + c = getopt_long (argc, argv, "hVpf:d:rv:", long_options, &option_index); + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'p': /* Prints the local database tree. */ + + + if (update_arg((void *)&(args_info->print_flag), 0, &(args_info->print_given), + &(local_args_info.print_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "print", 'p', + additional_error)) + goto failure; + + break; + case 'f': /* Adds the file to local database. */ + + + if (update_arg( (void *)&(args_info->file_arg), + &(args_info->file_orig), &(args_info->file_given), + &(local_args_info.file_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "file", 'f', + additional_error)) + goto failure; + + break; + case 'd': /* Adds the directory to local database. */ + + + if (update_arg( (void *)&(args_info->dir_arg), + &(args_info->dir_orig), &(args_info->dir_given), + &(local_args_info.dir_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "dir", 'd', + additional_error)) + goto failure; + + break; + case 'r': /* Recurse into sub-directories. */ + + + if (update_arg((void *)&(args_info->recurse_flag), 0, &(args_info->recurse_given), + &(local_args_info.recurse_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "recurse", 'r', + additional_error)) + goto failure; + + break; + case 'v': /* Verbosity level. */ + + + if (update_arg( (void *)&(args_info->verbose_arg), + &(args_info->verbose_orig), &(args_info->verbose_given), + &(local_args_info.verbose_given), optarg, 0, "1", ARG_INT, + check_ambiguity, override, 0, 0, + "verbose", 'v', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + if (check_required) + { + error += cmdline_parser_required2 (args_info, argv[0], additional_error); + } + + cmdline_parser_release (&local_args_info); + + if ( error ) + return (EXIT_FAILURE); + + if (optind < argc) + { + int i = 0 ; + int found_prog_name = 0; + /* whether program name, i.e., argv[0], is in the remaining args + (this may happen with some implementations of getopt, + but surely not with the one included by gengetopt) */ + + i = optind; + while (i < argc) + if (argv[i++] == argv[0]) { + found_prog_name = 1; + break; + } + i = 0; + + args_info->inputs_num = argc - optind - found_prog_name; + args_info->inputs = + (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; + while (optind < argc) + if (argv[optind++] != argv[0]) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; + } + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} + +#ifndef CONFIG_FILE_LINE_SIZE +#define CONFIG_FILE_LINE_SIZE 2048 +#endif +#define ADDITIONAL_ERROR " in configuration file " + +#define CONFIG_FILE_LINE_BUFFER_SIZE (CONFIG_FILE_LINE_SIZE+3) +/* 3 is for "--" and "=" */ + +static int +_cmdline_parser_configfile (char * const filename, int *my_argc) +{ + FILE* file; + char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1]; + char linebuf[CONFIG_FILE_LINE_SIZE]; + int line_num = 0; + int result = 0, equal; + char *fopt, *farg; + char *str_index; + size_t len, next_token; + char delimiter; + + if ((file = fopen(filename, "r")) == NULL) + { + fprintf (stderr, "%s: Error opening configuration file '%s'\n", + CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != NULL) + { + ++line_num; + my_argv[0] = '\0'; + len = strlen(linebuf); + if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1)) + { + fprintf (stderr, "%s:%s:%d: Line too long in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + break; + } + + /* find first non-whitespace character in the line */ + next_token = strspn (linebuf, " \t\r\n"); + str_index = linebuf + next_token; + + if ( str_index[0] == '\0' || str_index[0] == '#') + continue; /* empty line or comment line is skipped */ + + fopt = str_index; + + /* truncate fopt at the end of the first non-valid character */ + next_token = strcspn (fopt, " \t\r\n="); + + if (fopt[next_token] == '\0') /* the line is over */ + { + farg = NULL; + equal = 0; + goto noarg; + } + + /* remember if equal sign is present */ + equal = (fopt[next_token] == '='); + fopt[next_token++] = '\0'; + + /* advance pointers to the next token after the end of fopt */ + next_token += strspn (fopt + next_token, " \t\r\n"); + + /* check for the presence of equal sign, and if so, skip it */ + if ( !equal ) + if ((equal = (fopt[next_token] == '='))) + { + next_token++; + next_token += strspn (fopt + next_token, " \t\r\n"); + } + str_index += next_token; + + /* find argument */ + farg = str_index; + if ( farg[0] == '\"' || farg[0] == '\'' ) + { /* quoted argument */ + str_index = strchr (++farg, str_index[0] ); /* skip opening quote */ + if (! str_index) + { + fprintf + (stderr, + "%s:%s:%d: unterminated string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + break; + } + } + else + { /* read up the remaining part up to a delimiter */ + next_token = strcspn (farg, " \t\r\n#\'\""); + str_index += next_token; + } + + /* truncate farg at the delimiter and store it for further check */ + delimiter = *str_index, *str_index++ = '\0'; + + /* everything but comment is illegal at the end of line */ + if (delimiter != '\0' && delimiter != '#') + { + str_index += strspn(str_index, " \t\r\n"); + if (*str_index != '\0' && *str_index != '#') + { + fprintf + (stderr, + "%s:%s:%d: malformed string in configuration file\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + result = EXIT_FAILURE; + break; + } + } + + noarg: + if (!strcmp(fopt,"include")) { + if (farg && *farg) { + result = _cmdline_parser_configfile(farg, my_argc); + } else { + fprintf(stderr, "%s:%s:%d: include requires a filename argument.\n", + CMDLINE_PARSER_PACKAGE, filename, line_num); + } + continue; + } + len = strlen(fopt); + strcat (my_argv, len > 1 ? "--" : "-"); + strcat (my_argv, fopt); + if (len > 1 && ((farg && *farg) || equal)) + strcat (my_argv, "="); + if (farg && *farg) + strcat (my_argv, farg); + ++(*my_argc); + + cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list)); + cmd_line_list_tmp->next = cmd_line_list; + cmd_line_list = cmd_line_list_tmp; + cmd_line_list->string_arg = gengetopt_strdup(my_argv); + } /* while */ + + if (file) + fclose(file); + return result; +} + +int +cmdline_parser_configfile (char * const filename, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required) +{ + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + return cmdline_parser_config_file (filename, args_info, ¶ms); +} + +int +cmdline_parser_config_file (char * const filename, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int i, result; + int my_argc = 1; + char **my_argv_arg; + char *additional_error; + + /* store the program name */ + cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list)); + cmd_line_list_tmp->next = cmd_line_list; + cmd_line_list = cmd_line_list_tmp; + cmd_line_list->string_arg = gengetopt_strdup (CMDLINE_PARSER_PACKAGE); + + result = _cmdline_parser_configfile(filename, &my_argc); + + if (result != EXIT_FAILURE) { + my_argv_arg = (char **) malloc((my_argc+1) * sizeof(char *)); + cmd_line_list_tmp = cmd_line_list; + + for (i = my_argc - 1; i >= 0; --i) { + my_argv_arg[i] = cmd_line_list_tmp->string_arg; + cmd_line_list_tmp = cmd_line_list_tmp->next; + } + + my_argv_arg[my_argc] = 0; + + additional_error = (char *)malloc(strlen(filename) + strlen(ADDITIONAL_ERROR) + 1); + strcpy (additional_error, ADDITIONAL_ERROR); + strcat (additional_error, filename); + result = + cmdline_parser_internal (my_argc, my_argv_arg, args_info, + params, + additional_error); + + free (additional_error); + free (my_argv_arg); + } + + free_cmd_list(); + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} diff --git a/appli/gimmick/gimmick_ggo.h b/appli/gimmick/gimmick_ggo.h new file mode 100644 index 0000000..db36397 --- /dev/null +++ b/appli/gimmick/gimmick_ggo.h @@ -0,0 +1,211 @@ +/** @file gimmick_ggo.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.22 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef GIMMICK_GGO_H +#define GIMMICK_GGO_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name */ +#define CMDLINE_PARSER_PACKAGE "gimmick" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION "0.1.0" +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + int print_flag; /**< @brief Prints the local database tree (default=off). */ + const char *print_help; /**< @brief Prints the local database tree help description. */ + char * file_arg; /**< @brief Adds the file to local database. */ + char * file_orig; /**< @brief Adds the file to local database original value given at command line. */ + const char *file_help; /**< @brief Adds the file to local database help description. */ + char * dir_arg; /**< @brief Adds the directory to local database. */ + char * dir_orig; /**< @brief Adds the directory to local database original value given at command line. */ + const char *dir_help; /**< @brief Adds the directory to local database help description. */ + int recurse_flag; /**< @brief Recurse into sub-directories (default=off). */ + const char *recurse_help; /**< @brief Recurse into sub-directories help description. */ + int verbose_arg; /**< @brief Verbosity level (default='1'). */ + char * verbose_orig; /**< @brief Verbosity level original value given at command line. */ + const char *verbose_help; /**< @brief Verbosity level help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int print_given ; /**< @brief Whether print was given. */ + unsigned int file_given ; /**< @brief Whether file was given. */ + unsigned int dir_given ; /**< @brief Whether dir was given. */ + unsigned int recurse_given ; /**< @brief Whether recurse was given. */ + unsigned int verbose_given ; /**< @brief Whether verbose was given. */ + + char **inputs ; /**< @brief unamed options (options without names) */ + unsigned inputs_num ; /**< @brief unamed options number */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char * const *argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * The config file parser (deprecated version) + * @param filename the name of the config file + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_config_file() instead + */ +int cmdline_parser_configfile (char * const filename, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The config file parser + * @param filename the name of the config file + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_config_file (char * const filename, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* GIMMICK_GGO_H */ diff --git a/appli/gimmick/main.cxx b/appli/gimmick/main.cxx index d90f0b8..516dfd4 100644 --- a/appli/gimmick/main.cxx +++ b/appli/gimmick/main.cxx @@ -1,18 +1,50 @@ #include #include +#include int main(int argc, char* argv[]) { - bool debug = false; - if(argc>1) + gengetopt_args_info args; + if (cmdline_parser (argc, argv, &args) != 0) exit(1) ; + + creaImageIO::Gimmick g; + if (args.verbose_given) g.SetMessageLevel(args.verbose_arg); + + bool something_to_do = + args.dir_given | + args.file_given | + args.print_given; + + if (!something_to_do) { - debug = true; + std::cout << "Nothing to do !" << std::endl; + exit(0); } - creaImageIO::Gimmick g; - g.SetDebugMode(debug); - - if (!g.Initialize()) return 1; - if (!g.Finalize()) return 1; + try + { + if (!g.Initialize()) return 1; + + if (args.file_given) + { + g.AddFileToLocalDatabase(args.file_arg); + } + if (args.dir_given) + { + g.AddDirToLocalDatabase(args.dir_arg, args.recurse_given); + } + + if (args.print_given) + { + g.GetLocalDatabase()->LoadChildren(0,0); + g.PrintLocalDatabase(); + } + + if (!g.Finalize()) return 1; + } + catch (crea::Exception e) + { + e.Print(); + } return 0; } diff --git a/src2/creaImageIOGimmick.cpp b/src2/creaImageIOGimmick.cpp index b7cc5f7..a9f7264 100644 --- a/src2/creaImageIOGimmick.cpp +++ b/src2/creaImageIOGimmick.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -52,6 +53,7 @@ namespace creaImageIO "[Gimmick!] !! ERROR CREATING '"<SetAttribute(0,"Name","Local database"); } else { @@ -157,18 +159,41 @@ namespace creaImageIO //======================================================================== - /// Sets debug mode - void Gimmick::SetDebugMode(bool m) + /// Sets message level + void Gimmick::SetMessageLevel(int l) { - if (m) - { - crea::MessageManager::SetMessageLevel("Gimmick!",9); - } - else - { - crea::MessageManager::SetMessageLevel("Gimmick!",1); - } + crea::MessageManager::SetMessageLevel("Gimmick!",l); + } + //======================================================================== + + //======================================================================== + /// Add a file to the local database + void Gimmick::AddFileToLocalDatabase(const std::string& f) + { + ImageFinder finder(mLocalDatabase); + if (finder.IsHandledFile(f)) finder.AddFile(f); + + } + //======================================================================== + + //======================================================================== + /// Add a dir to the local database + void Gimmick::AddDirToLocalDatabase(const std::string& f, bool recurse) + { + ImageFinder finder(mLocalDatabase); + + finder.AddDirectory(f,recurse); + } //======================================================================== + //======================================================================== + /// + void Gimmick::PrintLocalDatabase() + { + mLocalDatabase->GetTree().Print(); + } + //======================================================================== + + } diff --git a/src2/creaImageIOGimmick.h b/src2/creaImageIOGimmick.h index c351332..9cd5666 100644 --- a/src2/creaImageIOGimmick.h +++ b/src2/creaImageIOGimmick.h @@ -35,10 +35,23 @@ namespace creaImageIO /// Finalize (closes databases, etc.) bool Finalize(); + /// Sets level for messages "Gimmick!" + void SetMessageLevel(int level); - /// Sets debug mode - void SetDebugMode(bool ); + /// Add a file to the local database + void AddFileToLocalDatabase(const std::string&); + /// Add a dir to the local database + void AddDirToLocalDatabase(const std::string&, bool recurse); + /// + void PrintLocalDatabase(); + + /// + SQLiteTreeHandler* GetLocalDatabase() { return mLocalDatabase; } + + const SQLiteTreeHandler* GetLocalDatabase() const { return mLocalDatabase; } + + /// const std::string& GetHomeDirectory(); const std::string& GetUserSettingsDirectory(); bool CreateUserSettingsDirectory(); diff --git a/src2/creaImageIOImageFinder.cpp b/src2/creaImageIOImageFinder.cpp index 8a28144..599c3f4 100644 --- a/src2/creaImageIOImageFinder.cpp +++ b/src2/creaImageIOImageFinder.cpp @@ -27,31 +27,21 @@ namespace creaImageIO //===================================================================== //===================================================================== - bool ImageFinder::AddFiles( const std::vector& filenames, - wxProgressDialog* progress, - UpdateSummary& summary) + bool ImageFinder::AddFiles( const std::vector& filenames) + // wxProgressDialog* progress, + // UpdateSummary& summary) { - for (int swi=0;swi<10;swi++) - { - msw[swi].Start(0); - msw[swi].Pause(); - } - - // Parse directory - wxStopWatch sw; - - - summary.added_images = 0; + unsigned int nbf = filenames.size(); std::vector::const_iterator i; for (i=filenames.begin();i!=filenames.end();++i) { - summary.scanned_files++; + // summary.scanned_files++; if (IsHandledFile(*i)) { - summary.handled_images++; - AddFile(*i,summary); - + // summary.handled_images++; + AddFile(*i);//,summary); + /* if (progress) { std::string mess("Adding "); @@ -64,40 +54,23 @@ namespace creaImageIO break; } } + */ } } - - sw.Pause(); - msw[0].Pause(); - msw[1].Pause(); - msw[2].Pause(); - - summary.total_time = sw.Time(); - summary.file_scan_time = msw[1].Time(); - summary.update_database_time = msw[2].Time(); - summary.update_structs_time = - summary.total_time - - summary.parse_time - - summary.file_scan_time - - summary.update_database_time; - return true; } //===================================================================== //===================================================================== - bool ImageFinder::AddFile( const std::string& filename, - UpdateSummary& summary) + bool ImageFinder::AddFile( const std::string& filename ) + // UpdateSummary& summary) { std::map< std::string, std::string> attr; mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr); - msw[1].Resume(); mReader.ReadAttributes(filename,attr); - // mReader.ReadDicomInfo(filename,image); - msw[1].Pause(); // image->SetFieldValue("FullFileName",filename); @@ -118,25 +91,23 @@ namespace creaImageIO */ void ImageFinder::ParseDirectory( const std::string &dirpath, std::vector &Filenames, - bool recursive, - wxProgressDialog* progress, - UpdateSummary& summary) + bool recursive) + // wxProgressDialog* progress, + // UpdateSummary& summary) { + /* if (progress) { std::string mess("Parsing "); mess += dirpath; progress->Pulse(std2wx(mess)); } - - wxStopWatch sw; - sw.Start(0); - + */ std::string fileName; std::string dirName = dirpath; - summary.scanned_dirs++; + // summary.scanned_dirs++; wxDir dir( std2wx(dirpath) ); @@ -152,6 +123,7 @@ namespace creaImageIO bool cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN ); while ( cont ) { + /* if ((progress)&&( sw.Time() >= 250 )) { // std::cout << "PULSE"<Pulse(); @@ -228,13 +200,15 @@ namespace creaImageIO wxStopWatch sw; bool was_canceled_by_user(false); + */ std::vector filenames; ParseDirectory( directory, filenames, - recurse, - progress, - summary); - + recurse ); + //, + // progress, + // summary); + /* if ( summary.cancelled_by_user ) { return false; @@ -244,12 +218,13 @@ namespace creaImageIO summary.added_images = 0; + */ unsigned int nbf = filenames.size(); // , nf = 0; std::vector::iterator i; for (i=filenames.begin();i!=filenames.end();++i) { - AddFile(*i,summary); - + AddFile(*i); //,summary); + /* if (progress) { std::string mess("Adding "); @@ -262,9 +237,10 @@ namespace creaImageIO break; } } + */ } - + /* sw.Pause(); msw[0].Pause(); msw[1].Pause(); @@ -278,7 +254,7 @@ namespace creaImageIO summary.parse_time - summary.file_scan_time - summary.update_database_time; - + */ return true; } //===================================================================== diff --git a/src2/creaImageIOImageFinder.h b/src2/creaImageIOImageFinder.h index 6e6a9e3..da3213b 100644 --- a/src2/creaImageIOImageFinder.h +++ b/src2/creaImageIOImageFinder.h @@ -24,7 +24,7 @@ namespace creaImageIO /// Dtor ~ImageFinder(); ///==================================================================== - + /* struct UpdateSummary { int scanned_dirs; @@ -59,28 +59,32 @@ namespace creaImageIO cancelled_by_user(false) {} }; - /// + */ + + /// + + bool IsHandledFile( const std::string& filename); - bool AddFile( const std::string& filename, - UpdateSummary& summary ); - bool AddFiles( const std::vector& filename, - wxProgressDialog* progress, - UpdateSummary& summary); + bool AddFile( const std::string& filename ); + // UpdateSummary& summary ); + bool AddFiles( const std::vector& filename ); + // wxProgressDialog* progress, + // UpdateSummary& summary); bool AddDirectory( const std::string& directory, - bool recurse, - wxProgressDialog* progress, - UpdateSummary& summary - ); + bool recurse ); + // wxProgressDialog* progress, + // UpdateSummary& summary + // ); void ParseDirectory( const std::string& directory, std::vector &Filenames, - bool recurse, - wxProgressDialog* progress, - UpdateSummary& summary); + bool recurse ); + // wxProgressDialog* progress, + // UpdateSummary& summary); private: TreeHandler* mTreeHandler; ImageReader mReader; - wxStopWatch msw[10]; + // wxStopWatch msw[10]; }; // EO class ImageFinder diff --git a/src2/creaImageIOImageReader.cpp b/src2/creaImageIOImageReader.cpp index 63a87ce..aa8012b 100644 --- a/src2/creaImageIOImageReader.cpp +++ b/src2/creaImageIOImageReader.cpp @@ -1,6 +1,6 @@ #include #include - +#include #include #include @@ -25,7 +25,7 @@ namespace creaImageIO { if (str == "GDCM::Unfound") { - return "----"; + return ""; } if (str[str.size()-1]==' ') { @@ -157,6 +157,7 @@ namespace creaImageIO std::map& attr) { // std::cout << "SpecificVtkReader::ReadDicomInfo '"<SetFileName(filename.c_str()); @@ -173,26 +174,36 @@ namespace creaImageIO char planes[128]; sprintf(planes,"%i",ext[5]-ext[4]); + // std::map::iterator i; - if ( (i = attr.find("Full File Name")) != attr.end()) + if ( (i = attr.find("FullFileName")) != attr.end()) + { + // boost::filesystem::path full_path(filename); + // std::string f = full_path.leaf(); + i->second = filename; + } + if ( (i = attr.find("D0004_1500")) != attr.end()) { boost::filesystem::path full_path(filename); std::string f = full_path.leaf(); i->second = f; } - if ( (i = attr.find("Columns")) != attr.end()) - { - i->second = cols; - } - if ( (i = attr.find("Rows")) != attr.end()) + if ( (i = attr.find("D0028_0010")) != attr.end()) { i->second = rows; } - if ( (i = attr.find("Planes")) != attr.end()) - { + if ( (i = attr.find("D0028_0011")) != attr.end()) + { + i->second = cols; + } + + if ( (i = attr.find("D0028_0012")) != attr.end()) + { i->second = planes; } + + GimmickMessage(2,"Attributes map:"<& attr) { // std::cout << "DicomReader::ReadDicomInfo '"<SetLoadMode( GDCM_NAME_SPACE::LD_ALL); file->SetFileName(filename.c_str()); @@ -317,21 +331,29 @@ namespace creaImageIO std::map::iterator i; for (i=attr.begin();i!=attr.end();++i) { - if ( i->first == "FullFileName" ) + if ( i->first == "D0004_1500" ) { boost::filesystem::path full_path(filename); std::string f = full_path.leaf(); i->second = f; } + else if ( i->first == "FullFileName" ) + { + i->second = filename; + } else { uint16_t gr; uint16_t el; tree::AttributeDescriptor::GetDicomGroupElementFromKey(i->first,gr,el); + // GimmickMessage(2,"Key '"<first<<"' : "<GetEntryString(gr,el); i->second = irclean(val); + // GimmickMessage(2,"Key '"<first<<"' : "<GetType())) - + " " + val + ";"; - // std::cout << "** SQL = '"<lastRowId(); - std::stringstream ri; - ri << mDB->lastRowId(); - node_id = ri.str(); - // std::cout << "LastRowId='"<lastRowId()<<"' vs '"<SetFieldValue("ID",node_id); - /* - // Insert in TypeId map - TypeId ti; - ti.type = node->GetType(); - ti.id = node_id; - mTypeIdToNodeMap[ti] = node; - // std::cout << "== Insert TypeId ("<GetType()==Node::Patient) summary.added_patients++; - if (node->GetType()==Node::Study) summary.added_studies++; - if (node->GetType()==Node::Series) summary.added_series++; - if (node->GetType()==Node::Image) summary.added_images++; - */ - } - return -1; + DBGraftToParent(parent,attr); + return (parent->GetLevel()+1); } //===================================================================== @@ -194,7 +151,16 @@ namespace creaImageIO } //===================================================================== - + //===================================================================== + /// Sets an attribute of a Node + bool SQLiteTreeHandler::SetAttribute(tree::Node* n, + const std::string& key, + const std::string& value) + { + if (n==0) n=GetTree().GetTree(); + return DBSetAttribute(n,key,value); + } + //===================================================================== @@ -231,17 +197,14 @@ namespace creaImageIO #define QUERYDB(QUER,RES) \ try \ { \ - GimmickMessage(2,"SQL: '"<execQuery(QUER.c_str()); \ } \ catch (CppSQLite3Exception& e) \ { \ - std::cout << "SQLite query '"<execDML(UP.c_str()); \ } \ catch (CppSQLite3Exception& e) \ { \ - std::cout << "SQLite update '"<0, i.e. not Root) + if (l>=0) { - command = "INSERT INTO LEVELS (Name) VALUES ('"; + command = "CREATE TABLE "; command += GetTree().GetLevelDescriptor(l).GetName(); - command += "')"; + command += "\n(\nID INTEGER PRIMARY KEY"; + if (l>1) + { + command += ",\nPARENT_ID int not null"; + } + SQLAppendAttributesDefinition(l,command); + if (l>1) + { + command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references "; + command += GetTree().GetLevelDescriptor(l-1).GetName(); + command += "(ID) on delete restrict on update restrict"; + } + command += "\n)"; UPDATEDB(command); - // Create table of level (for level>0, i.e. not Root) - if (l>0) + + // Add Attribute 'ID' to Description + GetTree().GetLevelDescriptor(l).Add + (AttributeDescriptor( "ID", + "Database Identifier", + 0,0, + AttributeDescriptor::PRIVATE + )); + + if (l>1) { - command = "CREATE TABLE "; - command += GetTree().GetLevelDescriptor(l).GetName(); - command += "\n(\nID INTEGER PRIMARY KEY"; - if (l>1) - { - command += ",\nPARENT_ID int not null"; - } - AppendAttributesSQLDefinition(l,command); - if (l>1) - { - command += ",\nconstraint FK_PARENT foreign key (PARENT_ID) references "; - command += GetTree().GetLevelDescriptor(l-1).GetName(); - command += "(ID) on delete restrict on update restrict"; - } - command += "\n)"; - UPDATEDB(command); - - - // Add Attribute 'ID' to Description - GetTree().GetAttributeDescriptorList(l).push_back - (AttributeDescriptor( "ID", - "Database Identifier", + // Add Attribute 'PARENT_ID' to Description + GetTree().GetLevelDescriptor(l).Add + (AttributeDescriptor( "PARENT_ID", + "Database Parent Identifier", 0,0, AttributeDescriptor::PRIVATE )); - - if (l>1) - { - // Add Attribute 'PARENT_ID' to Description - GetTree().GetAttributeDescriptorList(l).push_back - (AttributeDescriptor( "PARENT_ID", - "Database Parent Identifier", - 0,0, - AttributeDescriptor::PRIVATE - )); - } - } - // Create table *_ATTRIBUTES + } + + // Create table *_ATTRIBUTES + + command = "CREATE TABLE "; + command += GetTree().GetLevelDescriptor(l).GetName(); + command += "_Attributes\n(\n"; + command += "Key text,\n"; + command += "Name text,\n"; + command += "DicomGroup int,\n"; + command += "DicomElement int,\n"; + command += "Flags int\n"; + command += "\n)"; + UPDATEDB(command); + + + // Fill the table *_ATTRIBUTES + LevelDescriptor::AttributeDescriptorListType::const_iterator i; + for (i = GetTree().GetAttributeDescriptorList(l).begin(); + i != GetTree().GetAttributeDescriptorList(l).end(); + ++i) + { - command = "CREATE TABLE "; - command += GetTree().GetLevelDescriptor(l).GetName(); - command += "_Attributes\n(\n"; - command += "Key text,\n"; - command += "Name text,\n"; - command += "DicomGroup int,\n"; - command += "DicomElement int,\n"; - command += "Flags int\n"; - command += "\n)"; - UPDATEDB(command); - - - // Fill the table *_ATTRIBUTES - LevelDescriptor::AttributeDescriptorListType::const_iterator i; - for (i = GetTree().GetAttributeDescriptorList(l).begin(); - i != GetTree().GetAttributeDescriptorList(l).end(); - ++i) - { - - std::stringstream insert; - insert << "INSERT INTO " - << GetTree().GetLevelDescriptor(l).GetName() - << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) " - << "VALUES ('" - << i->GetKey() << "','" - << i->GetName() << "'," - << i->GetGroup() << "," - << i->GetElement() << "," - << i->GetFlags() << ");"; - - UPDATEDB(insert.str()); - } + std::stringstream insert; + insert << "INSERT INTO " + << GetTree().GetLevelDescriptor(l).GetName() + << "_Attributes (Key,Name,DicomGroup,DicomElement,Flags) " + << "VALUES ('" + << i->GetKey() << "','" + << i->GetName() << "'," + << i->GetGroup() << "," + << i->GetElement() << "," + << i->GetFlags() << ");"; + + UPDATEDB(insert.str()); } - } - catch (std::exception) - { - return false; - } + } // For l=0... + + // Initialize the root attributes + GetTree().InitializeAttributeMap(); + // Insert the root in the level 0 table + DBInsert(GetTree().GetTree()); + + GetTree().SetChildrenLoaded(true); GimmickMessage(1,"Creating SQLite database '"<GetKey()); + if ( i != attr.end() ) + { + v = i->second; + } + */ + GetTree().UnsafeSetAttribute( a->GetKey(), "" ); + } + + // Reading Root attributes + // Query DB + query = "SELECT * FROM "; + query += GetTree().GetLevelDescriptor(0).GetName(); + QUERYDB(query,q); + + for (int fld = 0; fld < q.numFields(); fld++) + { + GetTree().UnsafeSetAttribute(q.fieldName(fld), + q.getStringField(fld)); + } + GimmickMessage(1,"Importing tree description from database ... OK" <GetAttributeMap().begin(); + i != n->GetAttributeMap().end(); + i++) + { + if (i->first=="ID") + { + continue; + } + // std::cout << "("<first<<","<second<<")"<first + "'"; + values += "'" + SQLformat(i->second) + "'"; + atts += ","; + values += ","; + GimmickMessage(4,"'"<first<<"' = '"<second<<"'"<GetLevel()+1 >= node->GetTree()->GetNumberOfLevels() ) + return 0; + + GimmickMessage(2,"Loading children of '"<GetLabel() + <<"'"<GetChildrenLoaded()) return nbloaded; + // If children loaded we do not have to do it but we need to recurse + // in order to load the children's children if necessary, and so on... + if (node->GetChildrenLoaded()) + { + // Iterate the children + tree::Node::ChildrenListType::iterator i; + for (i = node->GetChildrenList().begin(); + i!= node->GetChildrenList().end(); + ++i) + { + nbloaded += DBLoadChildren(*i,numberoflevels-1); + } + return nbloaded; + } + + /// If children not loaded : do it and recurse // Query DB - int level = parent->GetLevel(); + int level = node->GetLevel(); std::string query = "SELECT * FROM "; query += GetTree().GetLevelDescriptor(level+1).GetName(); - if (level>1) + if (level>0) { - query += " WHERE PARENT_ID='" + parent->UnsafeGetAttribute("ID") + query += " WHERE PARENT_ID='" + node->UnsafeGetAttribute("ID") + "'"; } CppSQLite3Query q; @@ -616,7 +681,7 @@ namespace creaImageIO while (!q.eof()) { nbloaded++; - Node* n = new Node(parent); + Node* n = new Node(node); for (int fld = 0; fld < q.numFields(); fld++) { n->UnsafeSetAttribute(q.fieldName(fld),q.getStringField(fld)); @@ -629,7 +694,7 @@ namespace creaImageIO mTypeIdToNodeMap[ti] = n; */ // recurse - if ( numberoflevels > 1 ) + if ( numberoflevels != 1 ) { // msw[2].Pause(); nbloaded += DBLoadChildren(n, numberoflevels-1); @@ -639,88 +704,113 @@ namespace creaImageIO q.nextRow(); } - parent->SetChildrenLoaded(true); + node->SetChildrenLoaded(true); // msw[2].Pause(); return nbloaded; + } + //===================================================================== - // std::cout << "SQLiteTreeHandler::DBLoadChildren("<ChildrenLoaded() ) - { - // std::cout << "--> Children already loaded"<GetType() == Node::Image ) - { - return nbloaded; - } - if ( xparent->GetType() >= maxlevel ) - { - return nbloaded; - } - - // msw[2].Pause(); - // msw[2].Resume(); - - Node::Type type = xparent->GetType()+1; - - // Query DB - - std::string query = "SELECT * FROM "; - query += GetTree().GetDescriptor().GetLevelDescriptor(level).GetName(); - //SQLiteTreeHandlerStructure::Table(type); - if (parent!=0) - { - query += " WHERE PARENT_ID='" + parent->GetFieldValue("ID") + "'"; - } - - // std::cout << "** SQL = '"<GetLabel() + <<"'"<GetLevel()).GetName(); + insert += " " + val + ";"; + UPDATEDB(insert); + + // Store DB id of newly created node; + long lastrow = mDB->lastRowId(); + std::stringstream ri; + ri << mDB->lastRowId(); + n->SetAttribute("ID",ri.str()); + } + //====================================================================== - CppSQLite3Query q; - QUERYDB(query,q); + //====================================================================== + /// Graft the branch defined by the attributes to the parent + void SQLiteTreeHandler::DBGraftToParent( tree::Node* parent, + const AttributeMapType& attr) + { + GimmickMessage(2,"Grafting to parent '"<GetLabel() + <<"'"<GetLevel()+1; + level < GetTree().GetNumberOfLevels(); + level++) { - nbloaded++; - Node* n = new Node(type, - this,xparent); - for (int fld = 0; fld < q.numFields(); fld++) - { - n->SetFieldValue(q.fieldName(fld),q.getStringField(fld)); - } - // Index + // Create Node + tree::Node* child = new tree::Node(parent,attr); + + // Set PARENT_ID if necessary + if ( parent->GetLevel()>0 ) + child->SetAttribute("PARENT_ID",parent->GetAttribute("ID")); + + // Insert in DB + DBInsert(child); + /* + std::string val; + SQLAppendAttributesValues(child,val); + std::string insert("INSERT INTO "); + insert += GetTree().GetLevelDescriptor(child->GetLevel()).GetName(); + insert += " " + val + ";"; + UPDATEDB(insert); + + // Store DB id of newly created node; + long lastrow = mDB->lastRowId(); + std::stringstream ri; + ri << mDB->lastRowId(); + child->SetAttribute("ID",ri.str()); + */ + // Down one level + parent = child; + + /* + // Insert in TypeId map TypeId ti; - ti.type = type; - ti.id = n->GetFieldValue("ID"); - mTypeIdToNodeMap[ti] = n; - // recurse - if ( type < maxlevel ) - { - msw[2].Pause(); - nbloaded += DBLoadChildren(n,maxlevel); - msw[2].Resume(); - } - // next entry in db - q.nextRow(); + ti.type = node->GetType(); + ti.id = node_id; + mTypeIdToNodeMap[ti] = node; + // std::cout << "== Insert TypeId ("<GetType()==Node::Patient) summary.added_patients++; + if (node->GetType()==Node::Study) summary.added_studies++; + if (node->GetType()==Node::Series) summary.added_series++; + if (node->GetType()==Node::Image) summary.added_images++; + */ } - - xparent->SetChildrenLoaded(true); - - // msw[2].Pause(); - return nbloaded; - */ } - //===================================================================== - - + //====================================================================== + //===================================================================== + /// Sets an attribute of a Node + bool SQLiteTreeHandler::DBSetAttribute(tree::Node* n, + const std::string& key, + const std::string& value) + { + GimmickMessage(3,"Setting Attribute of '"<GetLabel()<< + "' "<SetAttribute(key,value); + std::string sql = "UPDATE "; + sql += GetTree().GetLevelDescriptor(n->GetLevel()).GetName(); + sql += " SET "; + sql += key; + sql += "='"; + sql += value; + sql += "' WHERE ID="; + sql += n->GetAttribute("ID"); + // sql += " LIMIT 1"; + UPDATEDB(sql); + } + //===================================================================== /* //===================================================================== @@ -1070,57 +1160,8 @@ namespace creaImageIO } //===================================================================== - //======================================================================== - std::string& format_sql2(std::string& str) - { - // quote must be doubled - // crea::Utils::Replace( str, "'", "''" ); - boost::algorithm::replace_all(str,"'","''"); - // Found strange strings which contained NULL char INSIDE string - int i,size=str.size(); - for (i=0;iGetLabel()<<"')"<GetFieldValueMap().begin(); - i != n->GetFieldValueMap().end(); - i++) - { - if (i->first=="ID") - { - continue; - } - // std::cout << "("<first<<","<second<<")"<first + "'"; - values += "'" + format_sql2(i->second) + "'"; - atts += ","; - values += ","; - } - atts[atts.size()-1]=' '; - values[values.size()-1]=' '; - - str = "("+atts+") VALUES ("+values+")"; + - } - //===================================================================== */ diff --git a/src2/creaImageIOSQLiteTreeHandler.h b/src2/creaImageIOSQLiteTreeHandler.h index 341b81b..c1ada2d 100644 --- a/src2/creaImageIOSQLiteTreeHandler.h +++ b/src2/creaImageIOSQLiteTreeHandler.h @@ -8,9 +8,10 @@ class CppSQLite3DB; namespace creaImageIO { -/** - * \ingroup Model - */ + + /** + * \ingroup Model + */ //======================================================================= /// Concrete TreeHandler which manages a tree stored in a sqlite database class SQLiteTreeHandler : virtual public TreeHandler @@ -95,6 +96,10 @@ namespace creaImageIO virtual int AddBranch( const AttributeMapType& attr ); /// Removes the node and its descendants virtual bool Remove(tree::Node*); + /// Sets an attribute of a Node + virtual bool SetAttribute(tree::Node*, + const std::string& key, + const std::string& value); //==================================================================== @@ -111,17 +116,42 @@ namespace creaImageIO /// Creates a new database on disk and the tables bool DBCreate(); /// Appends to string s the SQL command to create the attributes of a given level - void AppendAttributesSQLDefinition(int level, std::string& s); + void SQLAppendAttributesDefinition(int level, std::string& s); //====================================================================== //====================================================================== + /// Returns the parent to which the branch defined by the attributes + /// provided must be grafted tree::Node* DBGetParent( const AttributeMapType& attr); //====================================================================== //====================================================================== + /// Loads the children of Node parent + /// Can recurse to numberoflevels levels + /// \return The total number of Node loaded (may be at different levels) int DBLoadChildren( tree::Node* parent, int numberoflevels = 1); //====================================================================== + //====================================================================== + /// Appends to string s the SQL command to set the attributes values + /// of node n + void SQLAppendAttributesValues(tree::Node* n, std::string& s); + //====================================================================== + + //====================================================================== + /// Graft the branch defined by the attributes to the parent + void DBGraftToParent( tree::Node* parent, const AttributeMapType& attr); + //====================================================================== + //====================================================================== + /// Sets an attribute of a Node and updates the database + bool DBSetAttribute(tree::Node*, + const std::string& key, + const std::string& value); + //====================================================================== + //====================================================================== + /// Inserts the Node in the database + void DBInsert(tree::Node* n); + //====================================================================== /* /// int DBQueryNumberOfChildren(tree::Node* n); diff --git a/src2/creaImageIOSystem.h b/src2/creaImageIOSystem.h index df2bdd1..9b89002 100644 --- a/src2/creaImageIOSystem.h +++ b/src2/creaImageIOSystem.h @@ -20,6 +20,7 @@ creaMessage("Gimmick!",LEV,"[Gimmick!] "< - +#include namespace creaImageIO { @@ -9,7 +9,9 @@ namespace creaImageIO Tree::Tree() : Node(0) { - + GimmickMessage(5,"Default Tree constructor" + << std::endl); + } Tree::~Tree() @@ -17,6 +19,15 @@ namespace creaImageIO } - + void Tree::Print() const + { + GimmickMessage(1,GetLabel()<Print(); + } + + } } } diff --git a/src2/creaImageIOTree.h b/src2/creaImageIOTree.h index fe928ac..031c205 100644 --- a/src2/creaImageIOTree.h +++ b/src2/creaImageIOTree.h @@ -62,10 +62,11 @@ namespace creaImageIO GetAttributeDescriptorList(int level) const { return GetDescriptor().GetAttributeDescriptorList(level); } /// Returns the AttributeDescriptorList of a given level (ref) - LevelDescriptor::AttributeDescriptorListType& - GetAttributeDescriptorList(int level) - { return GetDescriptor().GetAttributeDescriptorList(level); } + //LevelDescriptor::AttributeDescriptorListType& + //GetAttributeDescriptorList(int level) + //{ return GetDescriptor().GetAttributeDescriptorList(level); } + virtual void Print() const; private: Descriptor mDescriptor; diff --git a/src2/creaImageIOTreeAttributeDescriptor.cpp b/src2/creaImageIOTreeAttributeDescriptor.cpp index 5a3e5b4..13616ce 100644 --- a/src2/creaImageIOTreeAttributeDescriptor.cpp +++ b/src2/creaImageIOTreeAttributeDescriptor.cpp @@ -60,13 +60,11 @@ namespace creaImageIO //GDCM_NAME_SPACE::TagKey tag(group,element); char ctag[12]; sprintf(ctag,"D%04x_%04x",group,element); - std::string tag(ctag); + mKey = ctag; - GimmickDebugMessage(3,"AttributeDescriptor : '"<