+++ /dev/null
-*.kdev4
-.git
-CVS
-mctools
-*.swp
-Makefile
-tags
-doc
-*.directory
-build/*
-*/.vimrc
+++ /dev/null
-CVS
-tests_jef
-mctools
-*.swp
-Makefile
-tags
-doc
-CVS
-CMakeFiles
-CMakeCache.txt
-*_ggo.*
-*.directory
-build/*
-*/.vimrc
-_*
-#*#
-notes.org
-build-release
-build-debug
-segmentation/clitkTestFilter*
#=========================================================
# CLITK = Command Line ITK
-cmake_minimum_required(VERSION 2.4)
-cmake_policy(VERSION 2.4)
+cmake_minimum_required(VERSION 2.8)
+cmake_policy(VERSION 2.8)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
INCLUDE(cmake/common.cmake)
#=========================================================
+#=========================================================
+#Support for the CTest dashboard testing system
+OPTION(BUILD_TESTING "Build the testing tree" OFF)
+IF (BUILD_TESTING)
+ OPTION(CLITK_BUILD_TESTING "Test ITK" ON)
+ INCLUDE(CTest)
+ENDIF(BUILD_TESTING)
+#=========================================================
+
#=========================================================
# Find ITK (required)
FIND_PACKAGE(ITK)
#=========================================================
#=========================================================
-# Find gengetopt
-FIND_PATH(CLITK_GENGETOPT gengetopt)
-IF (CLITK_GENGETOPT STREQUAL "CLITK_GENGETOPT-NOTFOUND")
- MESSAGE("gengetopt not found, please install it (see http://www.gnu.org/software/gengetopt/gengetopt.html)")
-ENDIF (CLITK_GENGETOPT STREQUAL "CLITK_GENGETOPT-NOTFOUND")
+# Find gengetopt, will create a target exe if not found
+SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
+FIND_PACKAGE(Gengetopt)
#=========================================================
#=========================================================
# Find libstatgrab is installed, add clitkMemoryUsage.cxx in the library
FIND_LIBRARY(LIBSTATGRAB NAMES statgrab PATHS)
IF (${LIBSTATGRAB} MATCHES "LIBSTATGRAB-NOTFOUND")
- MESSAGE("Install libstatgrab (http://www.i-scream.org/libstatgrab/) for memory usage information")
+# MESSAGE("Install libstatgrab (http://www.i-scream.org/libstatgrab/) for memory usage information")
SET(CLITK_MEMORY_INFO OFF)
ELSE (${LIBSTATGRAB} MATCHES "LIBSTATGRAB-NOTFOUND")
SET(CLITK_MEMORY_INFO ON)
# Select what is compiled
ADD_SUBDIRECTORY(common)
-add_subdirectory(tools)
-add_subdirectory(segmentation)
-add_subdirectory(registration)
+ADD_SUBDIRECTORY(tools)
+ADD_SUBDIRECTORY(segmentation)
+ADD_SUBDIRECTORY(registration)
# Compilation options
#=========================================================
-#Support for the CTest dashboard testing system
-INCLUDE(CTest)
-#=========================================================
-IF (BUILD_TESTING)
+# Build test when vv has been compiled
+IF(BUILD_TESTING)
ADD_SUBDIRECTORY(tests)
ENDIF(BUILD_TESTING)
-#=========================================================
-
#=========================================================
+# Install scripts when running make install
+SET(SCRIPTS
+ scripts/midp_common.sh
+ scripts/registration.sh
+ scripts/create_midP.sh
+ scripts/create_midP-2.0.sh
+ scripts/create_mhd_4D.sh
+ scripts/create_mhd_4D_pattern.sh
+ scripts/create_midP_masks.sh
+ scripts/create_midP_masks-2.0.sh
+ scripts/pts_to_landmarks.sh
+)
+
+INSTALL (FILES ${SCRIPTS} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
-set(CTEST_PROJECT_NAME "vv_itk4")
-set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
+MACRO(SET_IF_NOT_SET var val)
+ IF(NOT DEFINED "${var}")
+ SET("${var}" "${val}")
+ ENDIF(NOT DEFINED "${var}")
+ENDMACRO(SET_IF_NOT_SET)
-set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Insight")
-set(CTEST_DROP_SITE_CDASH TRUE)
+# Those are set for running a classical make Experimental
+SET_IF_NOT_SET(CTEST_DROP_METHOD "http")
+SET_IF_NOT_SET(CTEST_DROP_SITE "my.cdash.org")
+SET_IF_NOT_SET(CTEST_DROP_LOCATION "/submit.php?project=VV")
+SET_IF_NOT_SET(CTEST_DROP_SITE_CDASH TRUE)
+SET_IF_NOT_SET(CTEST_PROJECT_NAME "vv_itk4")
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
CeCILL-B FREE SOFTWARE LICENSE AGREEMENT
--- /dev/null
+
+# Attempt to find gengetopt. If not found, compile it.
+FIND_PROGRAM(GENGETOPT gengetopt)
+IF (GENGETOPT STREQUAL "GENGETOPT-NOTFOUND")
+ ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/cmake/gengetopt)
+ELSE(GENGETOPT STREQUAL "GENGETOPT-NOTFOUND")
+ ADD_EXECUTABLE(gengetopt IMPORTED)
+ SET_PROPERTY(TARGET gengetopt PROPERTY IMPORTED_LOCATION ${GENGETOPT})
+ENDIF(GENGETOPT STREQUAL "GENGETOPT-NOTFOUND")
+
+MACRO (WRAP_GGO GGO_SRCS)
+ FOREACH(GGO_FILE ${ARGN})
+ GET_FILENAME_COMPONENT(GGO_BASEFILENAME ${GGO_FILE} NAME_WE)
+ GET_FILENAME_COMPONENT(GGO_FILE_ABS ${GGO_FILE} ABSOLUTE)
+ SET(GGO_H ${GGO_BASEFILENAME}_ggo.h)
+ SET(GGO_C ${GGO_BASEFILENAME}_ggo.c)
+ SET(GGO_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${GGO_H} ${CMAKE_CURRENT_BINARY_DIR}/${GGO_C})
+ ADD_CUSTOM_COMMAND(OUTPUT ${GGO_OUTPUT}
+ COMMAND gengetopt
+ ARGS < ${GGO_FILE_ABS}
+ --output-dir=${CMAKE_CURRENT_BINARY_DIR}
+ --arg-struct-name=args_info_${GGO_BASEFILENAME}
+ --func-name=cmdline_parser_${GGO_BASEFILENAME}
+ --file-name=${GGO_BASEFILENAME}_ggo
+ --unamed-opts
+ --conf-parser
+ --include-getopt
+ DEPENDS ${GGO_FILE_ABS}
+ )
+ SET(${GGO_SRCS} ${${GGO_SRCS}} ${GGO_OUTPUT})
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+ ENDFOREACH(GGO_FILE)
+ SET_SOURCE_FILES_PROPERTIES(${${GGO_SRCS}} PROPERTIES GENERATED TRUE)
+ENDMACRO (WRAP_GGO)
MESSAGE(${in}=${${in}})
ENDMACRO(DD)
#=========================================================
-# Process ggo (gengetopt) files (http://www.gnu.org/software/gengetopt/)
-MACRO (WRAP_GGO GGO_SRCS)
- FOREACH(GGO_FILE ${ARGN})
- GET_FILENAME_COMPONENT(GGO_BASEFILENAME ${GGO_FILE} NAME_WE)
- GET_FILENAME_COMPONENT(GGO_FILE_ABS ${GGO_FILE} ABSOLUTE)
- SET(GGO_H ${GGO_BASEFILENAME}_ggo.h)
- SET(GGO_C ${GGO_BASEFILENAME}_ggo.c)
- SET(GGO_OUTPUT ${GGO_H} ${GGO_C})
- ADD_CUSTOM_COMMAND(OUTPUT ${GGO_OUTPUT}
- COMMAND ${CLITK_GENGETOPT}/gengetopt
- ARGS < ${GGO_FILE_ABS}
- --output-dir=${CMAKE_CURRENT_BINARY_DIR}
- --arg-struct-name=args_info_${GGO_BASEFILENAME}
- --func-name=cmdline_parser_${GGO_BASEFILENAME}
- --file-name=${GGO_BASEFILENAME}_ggo
- --unamed-opts
- --conf-parser
- --include-getopt
- DEPENDS ${GGO_FILE}
- )
- SET(${GGO_SRCS} ${${GGO_SRCS}} ${CMAKE_CURRENT_BINARY_DIR}/${GGO_BASEFILENAME}_ggo.c)
- INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) #For _ggo.h includes
- ENDFOREACH(GGO_FILE)
- SET_SOURCE_FILES_PROPERTIES(${${GGO_SRCS}} PROPERTIES GENERATED TRUE)
-ENDMACRO (WRAP_GGO)
-# Reproduce old mechanism with new macro for ggo files (for the time being)
-FILE(GLOB ALL_GGO_FILES *.ggo)
-#WRAP_GGO(ALL_GGO_SRCS ${ALL_GGO_FILES})
+
#=========================================================
#Set a reasonable build mode default if the user hasn't set any
if (NOT CMAKE_BUILD_TYPE)
--- /dev/null
+# Gengetopt: http://www.gnu.org/software/gengetopt/
+
+ADD_DEFINITIONS(-DPACKAGE=\"gengetopt\")
+ADD_DEFINITIONS(-DVERSION=\"2.22.4\")
+ADD_DEFINITIONS(-DHAVE_SSTREAM)
+ADD_DEFINITIONS(-DHAVE_NAMESPACES)
+
+IF(WIN32)
+ ADD_DEFINITIONS(-DHAVE_STRING_H)
+ ADD_DEFINITIONS(-DYY_NO_UNISTD_H)
+ ADD_DEFINITIONS(-Disatty=!)
+ INCLUDE_DIRECTORIES(include_cygwin)
+ENDIF(WIN32)
+
+ADD_EXECUTABLE(gengetopt
+ ./cmdline.c
+ ./ggos.cpp
+ ./scanner.cc
+ ./skels/required_option.cc
+ ./skels/handle_version.cc
+ ./skels/generic_option.cc
+ ./skels/clear_arg.cc
+ ./skels/update_given.cc
+ ./skels/dependant_option.cc
+ ./skels/custom_getopt_gen.cc
+ ./skels/handle_help.cc
+ ./skels/given_field.cc
+ ./skels/init_args_info.cc
+ ./skels/multiple_opt_list.cc
+ ./skels/free_list.cc
+ ./skels/exit_failure.cc
+ ./skels/clear_given.cc
+ ./skels/free_multiple.cc
+ ./skels/enum_decl.cc
+ ./skels/reset_group.cc
+ ./skels/c_source.cc
+ ./skels/group_option.cc
+ ./skels/file_save.cc
+ ./skels/check_modes.cc
+ ./skels/copyright.cc
+ ./skels/option_arg.cc
+ ./skels/group_counter.cc
+ ./skels/free_string.cc
+ ./skels/header.cc
+ ./skels/print_help_string.cc
+ ./skels/multiple_fill_array.cc
+ ./skels/file_save_multiple.cc
+ ./fileutils.cpp
+ ./getopt.c
+ ./gm.cc
+ ./globals.cpp
+ ./yywrap.c
+ ./getopt1.c
+ ./argsdef.c
+ ./gm_utils.cpp
+ ./acceptedvalues.cpp
+ ./gengetopt.cc
+ ./yyerror.cc
+ ./parser.cc)
+
+INCLUDE_DIRECTORIES(.)
+INCLUDE_DIRECTORIES(skels)
+#INCLUDE_DIRECTORIES(includes)
--- /dev/null
+# Copyright (C) 1999-2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU gengetopt
+#
+# GNU gengetopt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU gengetopt is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with gengetopt; see the file COPYING. If not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+SUBDIRS = includes skels tests
+
+#INCLUDES = -I@top_srcdir@/src/skels
+
+SUFFIXES = .text .c .ggo
+
+.text.o:
+ $(TXTC) $<
+
+bin_PROGRAMS = gengetopt
+
+noinst_LTLIBRARIES = libgengetopt.la
+
+libgengetopt_la_SOURCES = parser.cc scanner.cc \
+globals.cpp \
+argsdef.c cmdline.ggo gm.cc \
+yyerror.cc gm_utils.cpp fileutils.cpp acceptedvalues.cpp ggos.cpp
+
+gengetopt_SOURCES = gengetopt.cc
+
+scanner.cc: $(srcdir)/scanner.ll
+ $(LEX) $(LFLAGS) -o $(srcdir)/scanner.cc $(srcdir)/scanner.ll
+
+parser.cc: $(srcdir)/parser.yy
+ $(YACC) -o $(srcdir)/parser.cc $(srcdir)/parser.yy --defines=$(srcdir)/parser.h
+
+#gengetopt_LDADD = @LIBOBJS@ @LEXLIB@ skels/libgen.a
+
+# these are for gnulib
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_builddir)/gl
+
+libgengetopt_la_LIBADD = $(top_builddir)/gl/libgnu.la \
+ @LTLIBOBJS@ \
+ skels/libgen.la
+
+LDADD = $(top_builddir)/src/libgengetopt.la
+
+EXTRA_DIST = parser.h argsdef.h gengetopt.h ggos.h gm.h gnugetopt.h \
+cmdline.c cmdline.h my_sstream.h my_string.h my_map.h \
+global_opts.h \
+ggo_options.h \
+groups.h \
+parser.yy scanner.ll \
+globals.h \
+$(pkgdata_DATA)
+
+# version of gengetopt linked to the ElectricFence library
+# don't use it anymore: use valgrind
+#EXTRA_PROGRAMS = gengetopt-efence
+#gengetopt_efence_SOURCES = $(gengetopt_SOURCES)
+#gengetopt_efence_LDADD = -lefence $(gengetopt_LDADD)
+
+PROGNAME = $(top_builddir)/src/gengetopt$(EXEEXT)
+
+# to have flex generate a case insensitive scanner
+AM_LFLAGS = -i
+
+# it may happen, usually if the sources have been downloaded from CVS
+# repository, that cmdline.ggo is more recent than cmdline.c, but
+# cmdline.c cannot be re-generated, even because gengetopt has
+# to be built first. For instance if you only change spaces in cmdline.ggo
+# cmdline.c will not be different, and thus it is not updated in the CVS
+# repository; then when you make a checkout on another place, make
+# would try to build cmdline.c, but to do this it would need gengetopt
+# which is not built yet; so we simply touch cmdline.c (and this is safe)
+
+.ggo.c:
+ if test -f $(PROGNAME); then \
+ $(PROGNAME) --input=$< --output-dir=$(srcdir) ; \
+ else touch $(srcdir)/$@ ; fi
+
+cmdline.h: cmdline.c
+
+BUILT_SOURCES = cmdline.h cmdline.c parser.cc scanner.cc
+
+# automatically generate gengetopt_strdup() from the replacement function
+# strdup().
+# gengetopt_strdup.text: strdup.c
+# echo "/* gengetopt_strdup(): automatically generated from strdup.c. */" > $@
+# cat strdup.c | sed -e 's/^strdup (/gengetopt_&/' \
+# -e 's/^char \* *$$/&/' \
+# -e '/^#include.*$$/D' -e '/^$$/D' >> $@
+
+# we distribute these files because who uses gengetopt might need them
+# these are installed in $(prefix)/share/gengetopt
+pkgdata_DATA = gnugetopt.h getopt.c getopt1.c
+
+# yywrap.c is added only if it is not found on lex (flex) lib, and will be
+# added automatically by automake
+
+# automake (maybe due to a bug) doesn't added these files well,
+# so we explicitely declare them
+MAINTAINERCLEANFILES = scanner.cc parser.h parser.cc
+
+noinst_HEADERS = acceptedvalues.h errorcodes.h fileutils.h \
+ gm_utils.h yyerror.h
+
--- /dev/null
+//
+// C++ Implementation: acceptedvalues
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "acceptedvalues.h"
+#include "my_sstream.h"
+
+using namespace std;
+
+void
+AcceptedValues::insert(const string &s)
+{
+ push_back(s);
+ values.insert(s);
+}
+
+bool
+AcceptedValues::contains(const string &s) const
+{
+ return (values.count(s) > 0);
+}
+
+const string
+AcceptedValues::toString(bool escape) const
+{
+ ostringstream buf;
+
+ for (const_iterator it = begin(); it != end(); ) {
+ buf << (escape ? "\\\"" : "\"") << *it
+ << (escape ? "\\\"" : "\"");
+ if (++it != end())
+ buf << ", ";
+ }
+
+ return buf.str();
+}
--- /dev/null
+//
+// C++ Interface: acceptedvalues
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef ACCEPTEDVALUES_H
+#define ACCEPTEDVALUES_H
+
+#include <list>
+#include <set>
+#include <string>
+
+/**
+the values that can be passed to an option
+
+@author Lorenzo Bettini
+*/
+class AcceptedValues : protected std::list<std::string>
+{
+ private:
+ typedef std::set<std::string> value_set;
+ value_set values;
+
+ public:
+ using std::list<std::string>::const_iterator;
+ using std::list<std::string>::begin;
+ using std::list<std::string>::end;
+
+ void insert(const std::string &s);
+ const std::string toString(bool escape = true) const;
+ bool contains(const std::string &s) const;
+};
+
+#endif
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "argsdef.h"
+
+const char * arg_names [] = { (const char*)0, (const char*)0, "STRING", "INT",
+ "SHORT", "LONG", "FLOAT", "DOUBLE", "LONGDOUBLE", "LONGLONG", "ENUM" };
+
+const char * arg_type_constants [] = { "ARG_NO", "ARG_FLAG", "ARG_STRING",
+ "ARG_INT", "ARG_SHORT", "ARG_LONG", "ARG_FLOAT", "ARG_DOUBLE",
+ "ARG_LONGDOUBLE", "ARG_LONGLONG", "ARG_ENUM" };
+
+const char * arg_types [] = { (const char*)0, "int", "char *", "int", "short",
+ "long", "float", "double", "long double", "long long int", "enum" };
+
+const char * arg_types_names [] = { (const char*)0, "int", "string", "int",
+ "short", "long", "float", "double", "longdouble", "longlong", "int" };
+
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GENGETOPT_ARGSDEF_H
+#define GENGETOPT_ARGSDEF_H
+
+#define ARG_NO 0
+#define ARG_FLAG 1
+#define ARG_STRING 2
+#define ARG_INT 3
+#define ARG_SHORT 4
+#define ARG_LONG 5
+#define ARG_FLOAT 6
+#define ARG_DOUBLE 7
+#define ARG_LONGDOUBLE 8
+#define ARG_LONGLONG 9
+#define ARG_ENUM 10
+
+/** corresponding strings for above defines */
+extern const char * arg_type_constants [];
+/** symbolic names for argument types */
+extern const char * arg_names [];
+/** corresponding C types */
+extern const char * arg_types [];
+/** string representation of types */
+extern const char * arg_types_names [];
+
+#define ARGS_STRUCT "args_info"
+
+#endif /* GENGETOPT_ARGSDEF_H */
+
--- /dev/null
+/*
+ File autogenerated by gengetopt version 2.22.4
+ generated with the following command:
+ ../src/gengetopt --input=../../src/cmdline.ggo --output-dir=../../src --no-handle-version --no-handle-help --no-handle-error --string-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef FIX_UNUSED
+#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
+#endif
+
+#include <getopt.h>
+
+#include "cmdline.h"
+
+const char *gengetopt_args_info_purpose = "This program generates a C function that uses getopt_long function\nto parse the command line options, validate them and fill a struct.";
+
+const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTIONS]...";
+
+const char *gengetopt_args_info_description = "";
+
+const char *gengetopt_args_info_detailed_help[] = {
+ " -h, --help Print help and exit",
+ " --detailed-help Print help, including all details and hidden \n options, and exit",
+ " -V, --version Print version and exit",
+ "\nMain options:",
+ "",
+ " -i, --input=filename input file (default std input)",
+ " -f, --func-name=name name of generated function \n (default=`cmdline_parser')",
+ " -a, --arg-struct-name=name name of generated args info struct \n (default=`gengetopt_args_info')",
+ " -F, --file-name=name name of generated file (default=`cmdline')",
+ " --output-dir=path output directory",
+ " \n if this option is not specified, the files are generated in the current \n directory.\n",
+ " --header-output-dir=path header output directory",
+ " --src-output-dir=path source output directory",
+ " -c, --c-extension=ext extension of c file (default=`c')",
+ " -H, --header-extension=ext extension of header file (default=`h')",
+ " -l, --long-help long usage line in help",
+ " \n The usage line will print all the options, e.g.,\n\n sample1 -iINT|--int-opt=INT [-h|--help]\n",
+ " --default-optional by default, an option is considered optional if \n not specified otherwise",
+ " -u, --unamed-opts[=STRING] accept options without names (e.g., file names) \n (default=`FILES')",
+ "\nThe parser generated is thought to be used to parse the command line arguments. \nHowever, you can also generate parsers for configuration files, or strings that \ncontain the arguments to parse, by using the following two options.\n",
+ " -C, --conf-parser generate a config file parser",
+ " -S, --string-parser generate a string parser (the string contains \n the command line)",
+ "",
+ "\nAdditional options:",
+ " -G, --include-getopt adds the code for getopt_long in the generated \n C file",
+ " -n, --no-handle-help do not handle --help|-h automatically",
+ " \n If --no-handle-help is specified, the command line option --help|-h will not \n be handled automatically, so the programmer will be able to print some other \n information; then the function for printing the standard help output can be \n used; this function is called <parser-name>_print_help.\n\n Notice that, although the programmer can handle --help|-h manually, the \n parser will return after finding such option: the other command line options, \n if any, will be ignored. In case you want to have full control on --help|-h, \n you should use --ho-help.\n",
+ " --no-help do not add --help|-h automatically",
+ " \n With this option you can disable the automatic addition of options --help|-h. \n The programmer will then be able to add this option in the input file and \n handle it as he sees fit. Notice that --no-help will also disable the \n automatic options --detailed-help and --full-help.\n\n The programmer can still define options with short character h as he wants, \n but he cannot define options help, unless he specifies --no-help (otherwise \n an error will be printed).\n",
+ " -N, --no-handle-version do not handle --version|-V automatically",
+ " --no-version do not add --version|-V automatically",
+ " \n See above the details about --no-handle-help and --no-help, respectively.\n",
+ " -e, --no-handle-error do not exit on errors",
+ " \n With this option, if the generated parser encounters an error (e.g., an \n unknown option) it does not make the main program exit; instead, the parser \n function returns a value different 0, and the main program can print a help \n message.\n",
+ " --show-required[=STRING] in the output of help will specify which \n options are mandatory, by using the optional \n passed string (default=`(mandatory)')",
+ " -g, --gen-version put gengetopt version in the generated file \n (default=on)",
+ " --set-package=STRING set the package name (override package defined \n in the .ggo file)",
+ " --set-version=STRING set the version number (override version \n defined in the .ggo file)",
+ " --show-help show the output of --help instead of generating \n code",
+ " --show-full-help show the output of --full-help (i.e., including \n hidden options) instead of generating code",
+ " --show-detailed-help show the output of --detailed-help (i.e., \n including details and hidden options) instead \n of generating code",
+ " --show-version show the output of --version instead of \n generating code",
+ "\nPlease refer to the info manual for further explanations.",
+ 0
+};
+
+static void
+init_help_array(void)
+{
+ gengetopt_args_info_help[0] = gengetopt_args_info_detailed_help[0];
+ gengetopt_args_info_help[1] = gengetopt_args_info_detailed_help[1];
+ gengetopt_args_info_help[2] = gengetopt_args_info_detailed_help[2];
+ gengetopt_args_info_help[3] = gengetopt_args_info_detailed_help[3];
+ gengetopt_args_info_help[4] = gengetopt_args_info_detailed_help[4];
+ gengetopt_args_info_help[5] = gengetopt_args_info_detailed_help[5];
+ gengetopt_args_info_help[6] = gengetopt_args_info_detailed_help[6];
+ gengetopt_args_info_help[7] = gengetopt_args_info_detailed_help[7];
+ gengetopt_args_info_help[8] = gengetopt_args_info_detailed_help[8];
+ gengetopt_args_info_help[9] = gengetopt_args_info_detailed_help[9];
+ gengetopt_args_info_help[10] = gengetopt_args_info_detailed_help[11];
+ gengetopt_args_info_help[11] = gengetopt_args_info_detailed_help[12];
+ gengetopt_args_info_help[12] = gengetopt_args_info_detailed_help[13];
+ gengetopt_args_info_help[13] = gengetopt_args_info_detailed_help[14];
+ gengetopt_args_info_help[14] = gengetopt_args_info_detailed_help[15];
+ gengetopt_args_info_help[15] = gengetopt_args_info_detailed_help[17];
+ gengetopt_args_info_help[16] = gengetopt_args_info_detailed_help[18];
+ gengetopt_args_info_help[17] = gengetopt_args_info_detailed_help[19];
+ gengetopt_args_info_help[18] = gengetopt_args_info_detailed_help[20];
+ gengetopt_args_info_help[19] = gengetopt_args_info_detailed_help[21];
+ gengetopt_args_info_help[20] = gengetopt_args_info_detailed_help[22];
+ gengetopt_args_info_help[21] = gengetopt_args_info_detailed_help[23];
+ gengetopt_args_info_help[22] = gengetopt_args_info_detailed_help[24];
+ gengetopt_args_info_help[23] = gengetopt_args_info_detailed_help[25];
+ gengetopt_args_info_help[24] = gengetopt_args_info_detailed_help[27];
+ gengetopt_args_info_help[25] = gengetopt_args_info_detailed_help[29];
+ gengetopt_args_info_help[26] = gengetopt_args_info_detailed_help[30];
+ gengetopt_args_info_help[27] = gengetopt_args_info_detailed_help[32];
+ gengetopt_args_info_help[28] = gengetopt_args_info_detailed_help[34];
+ gengetopt_args_info_help[29] = gengetopt_args_info_detailed_help[35];
+ gengetopt_args_info_help[30] = gengetopt_args_info_detailed_help[36];
+ gengetopt_args_info_help[31] = gengetopt_args_info_detailed_help[37];
+ gengetopt_args_info_help[32] = gengetopt_args_info_detailed_help[38];
+ gengetopt_args_info_help[33] = gengetopt_args_info_detailed_help[39];
+ gengetopt_args_info_help[34] = gengetopt_args_info_detailed_help[40];
+ gengetopt_args_info_help[35] = gengetopt_args_info_detailed_help[41];
+ gengetopt_args_info_help[36] = gengetopt_args_info_detailed_help[42];
+ gengetopt_args_info_help[37] = 0;
+
+}
+
+const char *gengetopt_args_info_help[38];
+
+typedef enum {ARG_NO
+ , ARG_FLAG
+ , ARG_STRING
+} 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 **argv, struct gengetopt_args_info *args_info,
+ struct cmdline_parser_params *params, 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->detailed_help_given = 0 ;
+ args_info->version_given = 0 ;
+ args_info->input_given = 0 ;
+ args_info->func_name_given = 0 ;
+ args_info->arg_struct_name_given = 0 ;
+ args_info->file_name_given = 0 ;
+ args_info->output_dir_given = 0 ;
+ args_info->header_output_dir_given = 0 ;
+ args_info->src_output_dir_given = 0 ;
+ args_info->c_extension_given = 0 ;
+ args_info->header_extension_given = 0 ;
+ args_info->long_help_given = 0 ;
+ args_info->default_optional_given = 0 ;
+ args_info->unamed_opts_given = 0 ;
+ args_info->conf_parser_given = 0 ;
+ args_info->string_parser_given = 0 ;
+ args_info->include_getopt_given = 0 ;
+ args_info->no_handle_help_given = 0 ;
+ args_info->no_help_given = 0 ;
+ args_info->no_handle_version_given = 0 ;
+ args_info->no_version_given = 0 ;
+ args_info->no_handle_error_given = 0 ;
+ args_info->show_required_given = 0 ;
+ args_info->gen_version_given = 0 ;
+ args_info->set_package_given = 0 ;
+ args_info->set_version_given = 0 ;
+ args_info->show_help_given = 0 ;
+ args_info->show_full_help_given = 0 ;
+ args_info->show_detailed_help_given = 0 ;
+ args_info->show_version_given = 0 ;
+}
+
+static
+void clear_args (struct gengetopt_args_info *args_info)
+{
+ FIX_UNUSED (args_info);
+ args_info->input_arg = NULL;
+ args_info->input_orig = NULL;
+ args_info->func_name_arg = gengetopt_strdup ("cmdline_parser");
+ args_info->func_name_orig = NULL;
+ args_info->arg_struct_name_arg = gengetopt_strdup ("gengetopt_args_info");
+ args_info->arg_struct_name_orig = NULL;
+ args_info->file_name_arg = gengetopt_strdup ("cmdline");
+ args_info->file_name_orig = NULL;
+ args_info->output_dir_arg = NULL;
+ args_info->output_dir_orig = NULL;
+ args_info->header_output_dir_arg = NULL;
+ args_info->header_output_dir_orig = NULL;
+ args_info->src_output_dir_arg = NULL;
+ args_info->src_output_dir_orig = NULL;
+ args_info->c_extension_arg = gengetopt_strdup ("c");
+ args_info->c_extension_orig = NULL;
+ args_info->header_extension_arg = gengetopt_strdup ("h");
+ args_info->header_extension_orig = NULL;
+ args_info->unamed_opts_arg = gengetopt_strdup ("FILES");
+ args_info->unamed_opts_orig = NULL;
+ args_info->show_required_arg = gengetopt_strdup ("(mandatory)");
+ args_info->show_required_orig = NULL;
+ args_info->gen_version_flag = 1;
+ args_info->set_package_arg = NULL;
+ args_info->set_package_orig = NULL;
+ args_info->set_version_arg = NULL;
+ args_info->set_version_orig = NULL;
+
+}
+
+static
+void init_args_info(struct gengetopt_args_info *args_info)
+{
+
+ init_help_array();
+ args_info->help_help = gengetopt_args_info_detailed_help[0] ;
+ args_info->detailed_help_help = gengetopt_args_info_detailed_help[1] ;
+ args_info->version_help = gengetopt_args_info_detailed_help[2] ;
+ args_info->input_help = gengetopt_args_info_detailed_help[5] ;
+ args_info->func_name_help = gengetopt_args_info_detailed_help[6] ;
+ args_info->arg_struct_name_help = gengetopt_args_info_detailed_help[7] ;
+ args_info->file_name_help = gengetopt_args_info_detailed_help[8] ;
+ args_info->output_dir_help = gengetopt_args_info_detailed_help[9] ;
+ args_info->header_output_dir_help = gengetopt_args_info_detailed_help[11] ;
+ args_info->src_output_dir_help = gengetopt_args_info_detailed_help[12] ;
+ args_info->c_extension_help = gengetopt_args_info_detailed_help[13] ;
+ args_info->header_extension_help = gengetopt_args_info_detailed_help[14] ;
+ args_info->long_help_help = gengetopt_args_info_detailed_help[15] ;
+ args_info->default_optional_help = gengetopt_args_info_detailed_help[17] ;
+ args_info->unamed_opts_help = gengetopt_args_info_detailed_help[18] ;
+ args_info->conf_parser_help = gengetopt_args_info_detailed_help[20] ;
+ args_info->string_parser_help = gengetopt_args_info_detailed_help[21] ;
+ args_info->include_getopt_help = gengetopt_args_info_detailed_help[24] ;
+ args_info->no_handle_help_help = gengetopt_args_info_detailed_help[25] ;
+ args_info->no_help_help = gengetopt_args_info_detailed_help[27] ;
+ args_info->no_handle_version_help = gengetopt_args_info_detailed_help[29] ;
+ args_info->no_version_help = gengetopt_args_info_detailed_help[30] ;
+ args_info->no_handle_error_help = gengetopt_args_info_detailed_help[32] ;
+ args_info->show_required_help = gengetopt_args_info_detailed_help[34] ;
+ args_info->gen_version_help = gengetopt_args_info_detailed_help[35] ;
+ args_info->set_package_help = gengetopt_args_info_detailed_help[36] ;
+ args_info->set_version_help = gengetopt_args_info_detailed_help[37] ;
+ args_info->show_help_help = gengetopt_args_info_detailed_help[38] ;
+ args_info->show_full_help_help = gengetopt_args_info_detailed_help[39] ;
+ args_info->show_detailed_help_help = gengetopt_args_info_detailed_help[40] ;
+ args_info->show_version_help = gengetopt_args_info_detailed_help[41] ;
+
+}
+
+void
+cmdline_parser_print_version (void)
+{
+ printf ("%s %s\n",
+ (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : 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\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_print_detailed_help (void)
+{
+ int i = 0;
+ print_help_common();
+ while (gengetopt_args_info_detailed_help[i])
+ printf("%s\n", gengetopt_args_info_detailed_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);
+}
+
+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)
+{
+
+ free_string_field (&(args_info->input_arg));
+ free_string_field (&(args_info->input_orig));
+ free_string_field (&(args_info->func_name_arg));
+ free_string_field (&(args_info->func_name_orig));
+ free_string_field (&(args_info->arg_struct_name_arg));
+ free_string_field (&(args_info->arg_struct_name_orig));
+ free_string_field (&(args_info->file_name_arg));
+ free_string_field (&(args_info->file_name_orig));
+ free_string_field (&(args_info->output_dir_arg));
+ free_string_field (&(args_info->output_dir_orig));
+ free_string_field (&(args_info->header_output_dir_arg));
+ free_string_field (&(args_info->header_output_dir_orig));
+ free_string_field (&(args_info->src_output_dir_arg));
+ free_string_field (&(args_info->src_output_dir_orig));
+ free_string_field (&(args_info->c_extension_arg));
+ free_string_field (&(args_info->c_extension_orig));
+ free_string_field (&(args_info->header_extension_arg));
+ free_string_field (&(args_info->header_extension_orig));
+ free_string_field (&(args_info->unamed_opts_arg));
+ free_string_field (&(args_info->unamed_opts_orig));
+ free_string_field (&(args_info->show_required_arg));
+ free_string_field (&(args_info->show_required_orig));
+ free_string_field (&(args_info->set_package_arg));
+ free_string_field (&(args_info->set_package_orig));
+ free_string_field (&(args_info->set_version_arg));
+ free_string_field (&(args_info->set_version_orig));
+
+
+
+ clear_given (args_info);
+}
+
+
+static void
+write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
+{
+ FIX_UNUSED (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->detailed_help_given)
+ write_into_file(outfile, "detailed-help", 0, 0 );
+ if (args_info->version_given)
+ write_into_file(outfile, "version", 0, 0 );
+ if (args_info->input_given)
+ write_into_file(outfile, "input", args_info->input_orig, 0);
+ if (args_info->func_name_given)
+ write_into_file(outfile, "func-name", args_info->func_name_orig, 0);
+ if (args_info->arg_struct_name_given)
+ write_into_file(outfile, "arg-struct-name", args_info->arg_struct_name_orig, 0);
+ if (args_info->file_name_given)
+ write_into_file(outfile, "file-name", args_info->file_name_orig, 0);
+ if (args_info->output_dir_given)
+ write_into_file(outfile, "output-dir", args_info->output_dir_orig, 0);
+ if (args_info->header_output_dir_given)
+ write_into_file(outfile, "header-output-dir", args_info->header_output_dir_orig, 0);
+ if (args_info->src_output_dir_given)
+ write_into_file(outfile, "src-output-dir", args_info->src_output_dir_orig, 0);
+ if (args_info->c_extension_given)
+ write_into_file(outfile, "c-extension", args_info->c_extension_orig, 0);
+ if (args_info->header_extension_given)
+ write_into_file(outfile, "header-extension", args_info->header_extension_orig, 0);
+ if (args_info->long_help_given)
+ write_into_file(outfile, "long-help", 0, 0 );
+ if (args_info->default_optional_given)
+ write_into_file(outfile, "default-optional", 0, 0 );
+ if (args_info->unamed_opts_given)
+ write_into_file(outfile, "unamed-opts", args_info->unamed_opts_orig, 0);
+ if (args_info->conf_parser_given)
+ write_into_file(outfile, "conf-parser", 0, 0 );
+ if (args_info->string_parser_given)
+ write_into_file(outfile, "string-parser", 0, 0 );
+ if (args_info->include_getopt_given)
+ write_into_file(outfile, "include-getopt", 0, 0 );
+ if (args_info->no_handle_help_given)
+ write_into_file(outfile, "no-handle-help", 0, 0 );
+ if (args_info->no_help_given)
+ write_into_file(outfile, "no-help", 0, 0 );
+ if (args_info->no_handle_version_given)
+ write_into_file(outfile, "no-handle-version", 0, 0 );
+ if (args_info->no_version_given)
+ write_into_file(outfile, "no-version", 0, 0 );
+ if (args_info->no_handle_error_given)
+ write_into_file(outfile, "no-handle-error", 0, 0 );
+ if (args_info->show_required_given)
+ write_into_file(outfile, "show-required", args_info->show_required_orig, 0);
+ if (args_info->gen_version_given)
+ write_into_file(outfile, "gen-version", 0, 0 );
+ if (args_info->set_package_given)
+ write_into_file(outfile, "set-package", args_info->set_package_orig, 0);
+ if (args_info->set_version_given)
+ write_into_file(outfile, "set-version", args_info->set_version_orig, 0);
+ if (args_info->show_help_given)
+ write_into_file(outfile, "show-help", 0, 0 );
+ if (args_info->show_full_help_given)
+ write_into_file(outfile, "show-full-help", 0, 0 );
+ if (args_info->show_detailed_help_given)
+ write_into_file(outfile, "show-detailed-help", 0, 0 );
+ if (args_info->show_version_given)
+ write_into_file(outfile, "show-version", 0, 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 = 0;
+ 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 **argv, struct gengetopt_args_info *args_info)
+{
+ return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
+}
+
+int
+cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
+ struct cmdline_parser_params *params)
+{
+ int result;
+ result = cmdline_parser_internal (argc, argv, args_info, params, 0);
+
+ return result;
+}
+
+int
+cmdline_parser2 (int argc, char **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, 0);
+
+ return result;
+}
+
+int
+cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
+{
+ FIX_UNUSED (args_info);
+ FIX_UNUSED (prog_name);
+ return EXIT_SUCCESS;
+}
+
+
+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, const 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;
+ FIX_UNUSED (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 */
+ }
+
+ FIX_UNUSED (default_value);
+
+ 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_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;
+ };
+
+
+ /* 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 **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' },
+ { "detailed-help", 0, NULL, 0 },
+ { "version", 0, NULL, 'V' },
+ { "input", 1, NULL, 'i' },
+ { "func-name", 1, NULL, 'f' },
+ { "arg-struct-name", 1, NULL, 'a' },
+ { "file-name", 1, NULL, 'F' },
+ { "output-dir", 1, NULL, 0 },
+ { "header-output-dir", 1, NULL, 0 },
+ { "src-output-dir", 1, NULL, 0 },
+ { "c-extension", 1, NULL, 'c' },
+ { "header-extension", 1, NULL, 'H' },
+ { "long-help", 0, NULL, 'l' },
+ { "default-optional", 0, NULL, 0 },
+ { "unamed-opts", 2, NULL, 'u' },
+ { "conf-parser", 0, NULL, 'C' },
+ { "string-parser", 0, NULL, 'S' },
+ { "include-getopt", 0, NULL, 'G' },
+ { "no-handle-help", 0, NULL, 'n' },
+ { "no-help", 0, NULL, 0 },
+ { "no-handle-version", 0, NULL, 'N' },
+ { "no-version", 0, NULL, 0 },
+ { "no-handle-error", 0, NULL, 'e' },
+ { "show-required", 2, NULL, 0 },
+ { "gen-version", 0, NULL, 'g' },
+ { "set-package", 1, NULL, 0 },
+ { "set-version", 1, NULL, 0 },
+ { "show-help", 0, NULL, 0 },
+ { "show-full-help", 0, NULL, 0 },
+ { "show-detailed-help", 0, NULL, 0 },
+ { "show-version", 0, NULL, 0 },
+ { 0, 0, 0, 0 }
+ };
+
+ c = getopt_long (argc, argv, "hVi:f:a:F:c:H:lu::CSGnNeg", long_options, &option_index);
+
+ if (c == -1) break; /* Exit from `while (1)' loop. */
+
+ switch (c)
+ {
+ case 'h': /* Print help and exit. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->help_given),
+ &(local_args_info.help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "help", 'h',
+ additional_error))
+ goto failure;
+ cmdline_parser_free (&local_args_info);
+ return 0;
+
+ break;
+ case 'V': /* Print version and exit. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->version_given),
+ &(local_args_info.version_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "version", 'V',
+ additional_error))
+ goto failure;
+ cmdline_parser_free (&local_args_info);
+ return 0;
+
+ break;
+ case 'i': /* input file (default std input). */
+
+
+ if (update_arg( (void *)&(args_info->input_arg),
+ &(args_info->input_orig), &(args_info->input_given),
+ &(local_args_info.input_given), optarg, 0, 0, ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "input", 'i',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'f': /* name of generated function. */
+
+
+ if (update_arg( (void *)&(args_info->func_name_arg),
+ &(args_info->func_name_orig), &(args_info->func_name_given),
+ &(local_args_info.func_name_given), optarg, 0, "cmdline_parser", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "func-name", 'f',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'a': /* name of generated args info struct. */
+
+
+ if (update_arg( (void *)&(args_info->arg_struct_name_arg),
+ &(args_info->arg_struct_name_orig), &(args_info->arg_struct_name_given),
+ &(local_args_info.arg_struct_name_given), optarg, 0, "gengetopt_args_info", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "arg-struct-name", 'a',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'F': /* name of generated file. */
+
+
+ if (update_arg( (void *)&(args_info->file_name_arg),
+ &(args_info->file_name_orig), &(args_info->file_name_given),
+ &(local_args_info.file_name_given), optarg, 0, "cmdline", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "file-name", 'F',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'c': /* extension of c file. */
+
+
+ if (update_arg( (void *)&(args_info->c_extension_arg),
+ &(args_info->c_extension_orig), &(args_info->c_extension_given),
+ &(local_args_info.c_extension_given), optarg, 0, "c", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "c-extension", 'c',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'H': /* extension of header file. */
+
+
+ if (update_arg( (void *)&(args_info->header_extension_arg),
+ &(args_info->header_extension_orig), &(args_info->header_extension_given),
+ &(local_args_info.header_extension_given), optarg, 0, "h", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "header-extension", 'H',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'l': /* long usage line in help. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->long_help_given),
+ &(local_args_info.long_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "long-help", 'l',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'u': /* accept options without names (e.g., file names). */
+
+
+ if (update_arg( (void *)&(args_info->unamed_opts_arg),
+ &(args_info->unamed_opts_orig), &(args_info->unamed_opts_given),
+ &(local_args_info.unamed_opts_given), optarg, 0, "FILES", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "unamed-opts", 'u',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'C': /* generate a config file parser. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->conf_parser_given),
+ &(local_args_info.conf_parser_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "conf-parser", 'C',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'S': /* generate a string parser (the string contains the command line). */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->string_parser_given),
+ &(local_args_info.string_parser_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "string-parser", 'S',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'G': /* adds the code for getopt_long in the generated C file. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->include_getopt_given),
+ &(local_args_info.include_getopt_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "include-getopt", 'G',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'n': /* do not handle --help|-h automatically. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->no_handle_help_given),
+ &(local_args_info.no_handle_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "no-handle-help", 'n',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'N': /* do not handle --version|-V automatically. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->no_handle_version_given),
+ &(local_args_info.no_handle_version_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "no-handle-version", 'N',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'e': /* do not exit on errors. */
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->no_handle_error_given),
+ &(local_args_info.no_handle_error_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "no-handle-error", 'e',
+ additional_error))
+ goto failure;
+
+ break;
+ case 'g': /* put gengetopt version in the generated file. */
+
+
+ if (update_arg((void *)&(args_info->gen_version_flag), 0, &(args_info->gen_version_given),
+ &(local_args_info.gen_version_given), optarg, 0, 0, ARG_FLAG,
+ check_ambiguity, override, 1, 0, "gen-version", 'g',
+ additional_error))
+ goto failure;
+
+ break;
+
+ case 0: /* Long option with no short option */
+ /* Print help, including all details and hidden options, and exit. */
+ if (strcmp (long_options[option_index].name, "detailed-help") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->detailed_help_given),
+ &(local_args_info.detailed_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "detailed-help", '-',
+ additional_error))
+ goto failure;
+ cmdline_parser_free (&local_args_info);
+ return 0;
+
+ }
+ /* output directory. */
+ else if (strcmp (long_options[option_index].name, "output-dir") == 0)
+ {
+
+
+ if (update_arg( (void *)&(args_info->output_dir_arg),
+ &(args_info->output_dir_orig), &(args_info->output_dir_given),
+ &(local_args_info.output_dir_given), optarg, 0, 0, ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "output-dir", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* header output directory. */
+ else if (strcmp (long_options[option_index].name, "header-output-dir") == 0)
+ {
+
+
+ if (update_arg( (void *)&(args_info->header_output_dir_arg),
+ &(args_info->header_output_dir_orig), &(args_info->header_output_dir_given),
+ &(local_args_info.header_output_dir_given), optarg, 0, 0, ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "header-output-dir", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* source output directory. */
+ else if (strcmp (long_options[option_index].name, "src-output-dir") == 0)
+ {
+
+
+ if (update_arg( (void *)&(args_info->src_output_dir_arg),
+ &(args_info->src_output_dir_orig), &(args_info->src_output_dir_given),
+ &(local_args_info.src_output_dir_given), optarg, 0, 0, ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "src-output-dir", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* by default, an option is considered optional if not specified otherwise. */
+ else if (strcmp (long_options[option_index].name, "default-optional") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->default_optional_given),
+ &(local_args_info.default_optional_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "default-optional", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* do not add --help|-h automatically. */
+ else if (strcmp (long_options[option_index].name, "no-help") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->no_help_given),
+ &(local_args_info.no_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "no-help", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* do not add --version|-V automatically. */
+ else if (strcmp (long_options[option_index].name, "no-version") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->no_version_given),
+ &(local_args_info.no_version_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "no-version", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* in the output of help will specify which options are mandatory, by using the optional passed string. */
+ else if (strcmp (long_options[option_index].name, "show-required") == 0)
+ {
+
+
+ if (update_arg( (void *)&(args_info->show_required_arg),
+ &(args_info->show_required_orig), &(args_info->show_required_given),
+ &(local_args_info.show_required_given), optarg, 0, "(mandatory)", ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "show-required", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* set the package name (override package defined in the .ggo file). */
+ else if (strcmp (long_options[option_index].name, "set-package") == 0)
+ {
+
+
+ if (update_arg( (void *)&(args_info->set_package_arg),
+ &(args_info->set_package_orig), &(args_info->set_package_given),
+ &(local_args_info.set_package_given), optarg, 0, 0, ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "set-package", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* set the version number (override version defined in the .ggo file). */
+ else if (strcmp (long_options[option_index].name, "set-version") == 0)
+ {
+
+
+ if (update_arg( (void *)&(args_info->set_version_arg),
+ &(args_info->set_version_orig), &(args_info->set_version_given),
+ &(local_args_info.set_version_given), optarg, 0, 0, ARG_STRING,
+ check_ambiguity, override, 0, 0,
+ "set-version", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* show the output of --help instead of generating code. */
+ else if (strcmp (long_options[option_index].name, "show-help") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->show_help_given),
+ &(local_args_info.show_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "show-help", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* show the output of --full-help (i.e., including hidden options) instead of generating code. */
+ else if (strcmp (long_options[option_index].name, "show-full-help") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->show_full_help_given),
+ &(local_args_info.show_full_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "show-full-help", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* show the output of --detailed-help (i.e., including details and hidden options) instead of generating code. */
+ else if (strcmp (long_options[option_index].name, "show-detailed-help") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->show_detailed_help_given),
+ &(local_args_info.show_detailed_help_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "show-detailed-help", '-',
+ additional_error))
+ goto failure;
+
+ }
+ /* show the output of --version instead of generating code. */
+ else if (strcmp (long_options[option_index].name, "show-version") == 0)
+ {
+
+
+ if (update_arg( 0 ,
+ 0 , &(args_info->show_version_given),
+ &(local_args_info.show_version_given), optarg, 0, 0, ARG_NO,
+ check_ambiguity, override, 0, 0,
+ "show-version", '-',
+ additional_error))
+ goto failure;
+
+ }
+
+ break;
+ 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 */
+
+
+
+
+ cmdline_parser_release (&local_args_info);
+
+ if ( error )
+ return (EXIT_FAILURE);
+
+ return 0;
+
+failure:
+
+ cmdline_parser_release (&local_args_info);
+ return (EXIT_FAILURE);
+}
+
+static unsigned int
+cmdline_parser_create_argv(const char *cmdline_, char ***argv_ptr, const char *prog_name)
+{
+ char *cmdline, *p;
+ size_t n = 0, j;
+ int i;
+
+ if (prog_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 (prog_name);
+
+ ++n;
+ }
+
+ cmdline = gengetopt_strdup(cmdline_);
+ p = cmdline;
+
+ while (p && strlen(p))
+ {
+ j = strcspn(p, " \t");
+ ++n;
+ if (j && j < strlen(p))
+ {
+ p[j] = '\0';
+
+ 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 (p);
+
+ p += (j+1);
+ p += strspn(p, " \t");
+ }
+ else
+ {
+ 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 (p);
+
+ break;
+ }
+ }
+
+ *argv_ptr = (char **) malloc((n + 1) * sizeof(char *));
+ cmd_line_list_tmp = cmd_line_list;
+ for (i = (n-1); i >= 0; --i)
+ {
+ (*argv_ptr)[i] = cmd_line_list_tmp->string_arg;
+ cmd_line_list_tmp = cmd_line_list_tmp->next;
+ }
+
+ (*argv_ptr)[n] = 0;
+
+ free(cmdline);
+ return n;
+}
+
+int
+cmdline_parser_string(const char *cmdline, struct gengetopt_args_info *args_info, const char *prog_name)
+{
+ return cmdline_parser_string2(cmdline, args_info, prog_name, 0, 1, 1);
+}
+
+int
+cmdline_parser_string2(const char *cmdline, struct gengetopt_args_info *args_info, const char *prog_name,
+ 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_string_ext(cmdline, args_info, prog_name, ¶ms);
+}
+
+int
+cmdline_parser_string_ext(const char *cmdline, struct gengetopt_args_info *args_info, const char *prog_name,
+ struct cmdline_parser_params *params)
+{
+ char **argv_ptr = 0;
+ int result;
+ unsigned int argc;
+
+ argc = cmdline_parser_create_argv(cmdline, &argv_ptr, prog_name);
+
+ result =
+ cmdline_parser_internal (argc, argv_ptr, args_info, params, 0);
+
+ if (argv_ptr)
+ {
+ free (argv_ptr);
+ }
+
+ free_cmd_list();
+
+ return result;
+}
+
--- /dev/null
+# Copyright (C) 1999-2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU gengetopt
+#
+# GNU gengetopt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU gengetopt is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with gengetopt; see the file COPYING. If not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+# Specification file format:
+#
+# This file consist in lines of sentences with the following format:
+#
+# package <packname>
+# version <version>
+# purpose <string>
+# option <long> <short> <desc> <argtype> <required>
+# option <long> <short> <desc> flag <onoff>
+# option <long> <short> <desc> <required>
+# ... # ...
+#
+# Where:
+#
+# <packname> = Double quoted string.
+# <version> = Double quoted string.
+# <purpose> = What the program does
+# Double quoted string (even on more than one line)
+# <long> = Double quoted string with upper and lower case chars, digits,
+# '-' and '.'. No spaces allowed.
+# <short> = A single upper or lower case char, or a digit.
+# <desc> = String with upper and lower case chars, digits, '-', '.' and
+# spaces.
+# <argtype> = string, int, short, long, float, double, longdouble or longlong.
+# <required> = required or optional.
+# <onoff> = on or off.
+# Comments begins with '#' in any place of the line and ends in the
+# end of line.
+# The third form of option is used if the option does not take an argument;
+# it must not be required.
+
+
+# Name of our program
+#package "gengetopt" # we don't use it: we're using automake
+# Version of our program
+#version "1.0.1" # we don't use it: we're using automake
+
+purpose "This program generates a C function that uses getopt_long function
+to parse the command line options, validate them and fill a struct."
+
+# options that will be added to command line options of gengetopt
+args "--no-handle-version --no-handle-help --no-handle-error --string-parser"
+
+# Options
+
+section "Main options"
+
+text ""
+
+option "input" i "input file (default std input)" string typestr="filename" optional
+option "func-name" f "name of generated function" string typestr="name" default="cmdline_parser" optional
+option "arg-struct-name" a "name of generated args info struct" string typestr="name" default="gengetopt_args_info" optional
+option "file-name" F "name of generated file" string typestr="name" default="cmdline" optional
+option "output-dir" - "output directory" string typestr="path" optional
+ details="\nif this option is not specified, the \
+files are generated in the current directory.\n"
+option "header-output-dir" - "header output directory" string typestr="path" optional
+option "src-output-dir" - "source output directory" string typestr="path" optional
+option "c-extension" c "extension of c file" string typestr="ext" default="c" optional
+option "header-extension" H "extension of header file" string typestr="ext" default="h" optional
+option "long-help" l "long usage line in help" optional
+ details="\nThe usage line will print all the options, e.g.,
+
+sample1 -iINT|--int-opt=INT [-h|--help]\n"
+option "default-optional" - "by default, an option is considered optional if not specified otherwise" optional
+option "unamed-opts" u "accept options without names (e.g., file names)" string default="FILES" optional argoptional
+
+text "\nThe parser generated is thought to be used to parse the command line arguments. "
+text "However, you can also generate parsers for configuration files, or strings "
+text "that contain the arguments to parse, by using the following two options.\n"
+
+option "conf-parser" C "generate a config file parser" optional
+option "string-parser" S "generate a string parser (the string contains the command line)" optional
+
+text ""
+
+section "Additional options"
+
+option "include-getopt" G "adds the code for getopt_long in the generated C file" optional
+
+option "no-handle-help" n "do not handle --help|-h automatically" optional
+ details="\nIf --no-handle-help is specified, the command line option \
+--help|-h will not be handled automatically, so the programmer will be able \
+to print some \
+other information; then the function for printing the standard help \
+output can be used; this function is called \
+<parser-name>_print_help.\n\nNotice \
+that, although the programmer can handle --help|-h manually, the \
+parser will return after finding such option: the other command \
+line options, if any, will be ignored. In case you want to have full \
+control on --help|-h, you should use --ho-help.\n"
+
+option "no-help" - "do not add --help|-h automatically" optional
+ details="\nWith this option you can disable the \
+automatic addition of options --help|-h. The programmer \
+will then be able to add this option in \
+the input file and handle it as he sees fit. Notice that \
+--no-help will also disable the automatic options \
+--detailed-help and --full-help.
+
+The programmer can still \
+define options with short character h as he wants, \
+but he cannot define options help, unless he \
+specifies --no-help \
+(otherwise an error will be printed).\n"
+
+option "no-handle-version" N "do not handle --version|-V automatically" optional
+option "no-version" - "do not add --version|-V automatically" optional
+ details="\nSee above the details about \
+--no-handle-help and --no-help, respectively.\n"
+
+option "no-handle-error" e "do not exit on errors" optional
+ details="\nWith this option, if the generated parser encounters an error \
+(e.g., an unknown option) it does not make the main program exit; instead, the parser \
+function returns a value different 0, and the main program can print a help message.\n"
+
+option "show-required" - "in the output of help will specify which options are mandatory, \
+by using the optional passed string" string default="(mandatory)" optional argoptional
+
+option "gen-version" g "put gengetopt version in the generated file" flag on
+option "set-package" - "set the package name (override package defined in the .ggo file)" string optional
+option "set-version" - "set the version number (override version defined in the .ggo file)" string optional
+option "show-help" - "show the output of --help instead of generating code" optional
+option "show-full-help" - "show the output of --full-help (i.e., including hidden options) instead of generating code" optional
+option "show-detailed-help" - "show the output of --detailed-help (i.e., including details and hidden options) instead of generating code" optional
+option "show-version" - "show the output of --version instead of generating code" optional
+
+text "\nPlease refer to the info manual for further explanations."
--- /dev/null
+/** @file cmdline.h
+ * @brief The header file for the command line option parser
+ * generated by GNU Gengetopt version 2.22.4
+ * http://www.gnu.org/software/gengetopt.
+ * DO NOT modify this file, since it can be overwritten
+ * @author GNU Gengetopt by Lorenzo Bettini */
+
+#ifndef CMDLINE_H
+#define CMDLINE_H
+
+/* If we use autoconf. */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* for FILE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef CMDLINE_PARSER_PACKAGE
+/** @brief the program name (used for printing errors) */
+#define CMDLINE_PARSER_PACKAGE PACKAGE
+#endif
+
+#ifndef CMDLINE_PARSER_PACKAGE_NAME
+/** @brief the complete program name (used for help and version) */
+#ifdef PACKAGE_NAME
+#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE_NAME
+#else
+#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE
+#endif
+#endif
+
+#ifndef CMDLINE_PARSER_VERSION
+/** @brief the program version */
+#define CMDLINE_PARSER_VERSION VERSION
+#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 *detailed_help_help; /**< @brief Print help, including all details and hidden options, and exit help description. */
+ const char *version_help; /**< @brief Print version and exit help description. */
+ char * input_arg; /**< @brief input file (default std input). */
+ char * input_orig; /**< @brief input file (default std input) original value given at command line. */
+ const char *input_help; /**< @brief input file (default std input) help description. */
+ char * func_name_arg; /**< @brief name of generated function (default='cmdline_parser'). */
+ char * func_name_orig; /**< @brief name of generated function original value given at command line. */
+ const char *func_name_help; /**< @brief name of generated function help description. */
+ char * arg_struct_name_arg; /**< @brief name of generated args info struct (default='gengetopt_args_info'). */
+ char * arg_struct_name_orig; /**< @brief name of generated args info struct original value given at command line. */
+ const char *arg_struct_name_help; /**< @brief name of generated args info struct help description. */
+ char * file_name_arg; /**< @brief name of generated file (default='cmdline'). */
+ char * file_name_orig; /**< @brief name of generated file original value given at command line. */
+ const char *file_name_help; /**< @brief name of generated file help description. */
+ char * output_dir_arg; /**< @brief output directory. */
+ char * output_dir_orig; /**< @brief output directory original value given at command line. */
+ const char *output_dir_help; /**< @brief output directory help description. */
+ char * header_output_dir_arg; /**< @brief header output directory. */
+ char * header_output_dir_orig; /**< @brief header output directory original value given at command line. */
+ const char *header_output_dir_help; /**< @brief header output directory help description. */
+ char * src_output_dir_arg; /**< @brief source output directory. */
+ char * src_output_dir_orig; /**< @brief source output directory original value given at command line. */
+ const char *src_output_dir_help; /**< @brief source output directory help description. */
+ char * c_extension_arg; /**< @brief extension of c file (default='c'). */
+ char * c_extension_orig; /**< @brief extension of c file original value given at command line. */
+ const char *c_extension_help; /**< @brief extension of c file help description. */
+ char * header_extension_arg; /**< @brief extension of header file (default='h'). */
+ char * header_extension_orig; /**< @brief extension of header file original value given at command line. */
+ const char *header_extension_help; /**< @brief extension of header file help description. */
+ const char *long_help_help; /**< @brief long usage line in help help description. */
+ const char *default_optional_help; /**< @brief by default, an option is considered optional if not specified otherwise help description. */
+ char * unamed_opts_arg; /**< @brief accept options without names (e.g., file names) (default='FILES'). */
+ char * unamed_opts_orig; /**< @brief accept options without names (e.g., file names) original value given at command line. */
+ const char *unamed_opts_help; /**< @brief accept options without names (e.g., file names) help description. */
+ const char *conf_parser_help; /**< @brief generate a config file parser help description. */
+ const char *string_parser_help; /**< @brief generate a string parser (the string contains the command line) help description. */
+ const char *include_getopt_help; /**< @brief adds the code for getopt_long in the generated C file help description. */
+ const char *no_handle_help_help; /**< @brief do not handle --help|-h automatically help description. */
+ const char *no_help_help; /**< @brief do not add --help|-h automatically help description. */
+ const char *no_handle_version_help; /**< @brief do not handle --version|-V automatically help description. */
+ const char *no_version_help; /**< @brief do not add --version|-V automatically help description. */
+ const char *no_handle_error_help; /**< @brief do not exit on errors help description. */
+ char * show_required_arg; /**< @brief in the output of help will specify which options are mandatory, by using the optional passed string (default='(mandatory)'). */
+ char * show_required_orig; /**< @brief in the output of help will specify which options are mandatory, by using the optional passed string original value given at command line. */
+ const char *show_required_help; /**< @brief in the output of help will specify which options are mandatory, by using the optional passed string help description. */
+ int gen_version_flag; /**< @brief put gengetopt version in the generated file (default=on). */
+ const char *gen_version_help; /**< @brief put gengetopt version in the generated file help description. */
+ char * set_package_arg; /**< @brief set the package name (override package defined in the .ggo file). */
+ char * set_package_orig; /**< @brief set the package name (override package defined in the .ggo file) original value given at command line. */
+ const char *set_package_help; /**< @brief set the package name (override package defined in the .ggo file) help description. */
+ char * set_version_arg; /**< @brief set the version number (override version defined in the .ggo file). */
+ char * set_version_orig; /**< @brief set the version number (override version defined in the .ggo file) original value given at command line. */
+ const char *set_version_help; /**< @brief set the version number (override version defined in the .ggo file) help description. */
+ const char *show_help_help; /**< @brief show the output of --help instead of generating code help description. */
+ const char *show_full_help_help; /**< @brief show the output of --full-help (i.e., including hidden options) instead of generating code help description. */
+ const char *show_detailed_help_help; /**< @brief show the output of --detailed-help (i.e., including details and hidden options) instead of generating code help description. */
+ const char *show_version_help; /**< @brief show the output of --version instead of generating code help description. */
+
+ unsigned int help_given ; /**< @brief Whether help was given. */
+ unsigned int detailed_help_given ; /**< @brief Whether detailed-help was given. */
+ unsigned int version_given ; /**< @brief Whether version was given. */
+ unsigned int input_given ; /**< @brief Whether input was given. */
+ unsigned int func_name_given ; /**< @brief Whether func-name was given. */
+ unsigned int arg_struct_name_given ; /**< @brief Whether arg-struct-name was given. */
+ unsigned int file_name_given ; /**< @brief Whether file-name was given. */
+ unsigned int output_dir_given ; /**< @brief Whether output-dir was given. */
+ unsigned int header_output_dir_given ; /**< @brief Whether header-output-dir was given. */
+ unsigned int src_output_dir_given ; /**< @brief Whether src-output-dir was given. */
+ unsigned int c_extension_given ; /**< @brief Whether c-extension was given. */
+ unsigned int header_extension_given ; /**< @brief Whether header-extension was given. */
+ unsigned int long_help_given ; /**< @brief Whether long-help was given. */
+ unsigned int default_optional_given ; /**< @brief Whether default-optional was given. */
+ unsigned int unamed_opts_given ; /**< @brief Whether unamed-opts was given. */
+ unsigned int conf_parser_given ; /**< @brief Whether conf-parser was given. */
+ unsigned int string_parser_given ; /**< @brief Whether string-parser was given. */
+ unsigned int include_getopt_given ; /**< @brief Whether include-getopt was given. */
+ unsigned int no_handle_help_given ; /**< @brief Whether no-handle-help was given. */
+ unsigned int no_help_given ; /**< @brief Whether no-help was given. */
+ unsigned int no_handle_version_given ; /**< @brief Whether no-handle-version was given. */
+ unsigned int no_version_given ; /**< @brief Whether no-version was given. */
+ unsigned int no_handle_error_given ; /**< @brief Whether no-handle-error was given. */
+ unsigned int show_required_given ; /**< @brief Whether show-required was given. */
+ unsigned int gen_version_given ; /**< @brief Whether gen-version was given. */
+ unsigned int set_package_given ; /**< @brief Whether set-package was given. */
+ unsigned int set_version_given ; /**< @brief Whether set-version was given. */
+ unsigned int show_help_given ; /**< @brief Whether show-help was given. */
+ unsigned int show_full_help_given ; /**< @brief Whether show-full-help was given. */
+ unsigned int show_detailed_help_given ; /**< @brief Whether show-detailed-help was given. */
+ unsigned int show_version_given ; /**< @brief Whether show-version was given. */
+
+} ;
+
+/** @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[];
+/** @brief all the lines making the detailed help output (including hidden options and details) */
+extern const char *gengetopt_args_info_detailed_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 **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 **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 **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 detailed help (including hidden options and details)
+ */
+void cmdline_parser_print_detailed_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 string parser (interprets the passed string as a command line)
+ * @param cmdline the command line stirng
+ * @param args_info the structure where option information will be stored
+ * @param prog_name the name of the program that will be used to print
+ * possible errors
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_string (const char *cmdline, struct gengetopt_args_info *args_info,
+ const char *prog_name);
+/**
+ * The string parser (version with additional parameters - deprecated)
+ * @param cmdline the command line stirng
+ * @param args_info the structure where option information will be stored
+ * @param prog_name the name of the program that will be used to print
+ * possible errors
+ * @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_string_ext() instead
+ */
+int cmdline_parser_string2 (const char *cmdline, struct gengetopt_args_info *args_info,
+ const char *prog_name,
+ int override, int initialize, int check_required);
+/**
+ * The string parser (version with additional parameters)
+ * @param cmdline the command line stirng
+ * @param args_info the structure where option information will be stored
+ * @param prog_name the name of the program that will be used to print
+ * possible errors
+ * @param params additional parameters for the parser
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_string_ext (const char *cmdline, struct gengetopt_args_info *args_info,
+ const char *prog_name,
+ 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 /* CMDLINE_H */
--- /dev/null
+//
+// C++ Interface: errorcodes
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef ERRORCODES_H
+#define ERRORCODES_H
+
+#define NOT_ENOUGH_MEMORY 1
+#define REQ_LONG_OPTION 2
+#define REQ_SHORT_OPTION 3
+#define FOUND_BUG 4
+#define GROUP_UNDEFINED 5
+#define INVALID_DEFAULT_VALUE 6
+#define NOT_REQUESTED_TYPE 7
+#define NOT_VALID_SPECIFICATION 8
+#define SPECIFY_FLAG_STAT 9
+#define NOT_GROUP_OPTION 10
+#define SPECIFY_GROUP 11
+#define INVALID_NUMERIC_VALUE 12
+#define INVALID_ENUM_TYPE_USE 13
+#define MODE_UNDEFINED 14
+#define NOT_MODE_OPTION 15
+#define SPECIFY_MODE 16
+#define HELP_REDEFINED 17
+#define VERSION_REDEFINED 18
+
+#endif
--- /dev/null
+//
+// C++ Implementation: fileutils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include "fileutils.h"
+
+using namespace std;
+
+char *
+create_filename (char *name, char *ext)
+{
+ char *filename ;
+
+ filename = (char *) malloc (strlen (name) + strlen (ext) + 2);
+ /* 2 = 1 for the . and one for the '\0' */
+ if (! filename)
+ {
+ fprintf (stderr, "Error in memory allocation! %s %d\n",
+ __FILE__, __LINE__);
+ abort ();
+ }
+
+ sprintf (filename, "%s.%s", name, ext);
+
+ return filename ;
+}
+
+ofstream *
+open_fstream (const char *filename)
+{
+ ofstream *fstream = new ofstream (filename);
+
+ if ( ! (*fstream) )
+ {
+ fprintf( stderr, "Error creating %s\n", filename ) ;
+ abort() ;
+ }
+
+ return fstream;
+}
--- /dev/null
+//
+// C++ Interface: fileutils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef FILEUTILS_H
+#define FILEUTILS_H
+
+#include <fstream>
+
+using std::ofstream;
+
+char *create_filename (char *name, char *ext);
+ofstream *open_fstream (const char *filename);
+
+#endif
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+void gengetopt_free (void);
+
+/* The following one is generated by gengetopt itself */
+#include "cmdline.h"
+
+extern int yyparse () ;
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+
+#include "argsdef.h"
+#include "global_opts.h"
+
+#include "my_sstream.h"
+#include "my_string.h"
+
+#include "gm.h"
+#include "groups.h"
+#include "gm_utils.h"
+
+#include "skels/copyright.h"
+
+#include "yyerror.h"
+#include "globals.h"
+
+char * gengetopt_package = NULL;
+char * gengetopt_version = NULL;
+char * gengetopt_purpose = NULL;
+char * gengetopt_description = NULL;
+char * gengetopt_usage = NULL;
+
+modes_collection_t gengetopt_modes;
+
+int gengetopt_count_line = 1;
+char * gengetopt_input_filename = 0;
+char *current_section = 0;
+char *current_section_desc = 0;
+char *current_text = 0;
+char *current_args = 0;
+
+/// whether, if not specified, an option is considered optional
+bool default_to_optional = false;
+
+int canonize_vars (void);
+static void set_default_required_properties(void);
+
+static void print_copyright();
+static void print_reportbugs();
+
+static void output_formatted_string(const string &);
+
+static bool check_dependencies();
+
+static int gengetopt_create_option (gengetopt_option *&opt, const char * long_opt, char short_opt,
+ const char * desc,
+ int type, int flagstat, int required,
+ const char *default_value,
+ const char * group_value,
+ const char * mode_value,
+ const char * type_str,
+ const AcceptedValues *acceptedvalues,
+ int multiple = 0,
+ int argoptional = 0);
+
+
+#include <algorithm>
+#include <iterator>
+
+using namespace std;
+
+/// the structure for command line arguments
+struct gengetopt_args_info args_info ;
+
+int
+main (int argc, char **argv)
+{
+ char *cmdline_parser_name ; /* name of the generated function */
+ char *cmdline_filename ; /* name of generated file */
+ char *c_ext ; /* extenstion of c file */
+ char *header_ext ; /* extenstion of header file */
+ string output_dir, header_output_dir, src_output_dir; /* output directory (default empty -> current dir)*/
+
+ int i, has_help, has_version;
+ FILE *input_file ;
+
+ if (cmdline_parser (argc, argv, &args_info) != 0) {
+ fprintf (stderr, "Run gengetopt --help to see the list of options.\n");
+ exit(1) ;
+ }
+
+ if (args_info.help_given)
+ {
+ cmdline_parser_print_help ();
+ print_reportbugs ();
+ exit (0);
+ }
+
+ if (args_info.detailed_help_given)
+ {
+ cmdline_parser_print_detailed_help ();
+ print_reportbugs ();
+ exit (0);
+ }
+
+ if (args_info.version_given)
+ {
+ cmdline_parser_print_version ();
+ print_copyright ();
+ exit (0);
+ }
+
+ if ( args_info.input_arg )
+ {
+ gengetopt_input_filename = strdup (args_info.input_arg);
+ input_file = freopen (args_info.input_arg, "r", stdin) ;
+ if (!input_file)
+ {
+ fprintf (stderr, "Error opening input file: %s\n",
+ args_info.input_arg);
+ exit (1);
+ }
+ } /* else standard input is used */
+
+ if (yyparse () != 0) {
+ gengetopt_free ();
+ return 1;
+ }
+
+ // check whether some options were given in the input file
+ bool no_options = (gengetopt_options.size() == 0);
+
+ if (current_args) {
+ // parse the arguments passed in the "args" part of the input file
+ // by possibily overriding those given at command line
+ if (cmdline_parser_string2 (current_args, &args_info, "gengetopt", 1, 0, 0) != 0) {
+ fprintf (stderr, "Error in the args specification of the input_file.\n");
+ exit(1) ;
+ }
+ }
+
+ cmdline_parser_name = args_info.func_name_arg ;
+ cmdline_filename = args_info.file_name_arg ;
+ c_ext = args_info.c_extension_arg;
+ header_ext = args_info.header_extension_arg;
+
+ default_to_optional = args_info.default_optional_given;
+
+ // now set the default "required" property for options
+ set_default_required_properties();
+
+ if (! check_dependencies()) {
+ gengetopt_free();
+ return 1;
+ }
+
+ // insert options for help and version if not already present
+ gengetopt_option *opt;
+
+ if (current_section)
+ free(current_section);
+ current_section = 0;
+
+ has_version = gengetopt_has_option (VERSION_LONG_OPT, VERSION_SHORT_OPT);
+
+ if (has_version != REQ_LONG_OPTION && !args_info.no_version_given) {
+ gengetopt_create_option (opt, VERSION_LONG_OPT, has_version ? '-' : VERSION_SHORT_OPT,
+ VERSION_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+ gengetopt_options.push_front(opt);
+ }
+
+ if (!args_info.no_help_given && has_hidden_options() && gengetopt_has_option(FULL_HELP_LONG_OPT, 0) == 0) {
+ gengetopt_create_option (opt, FULL_HELP_LONG_OPT, '-',
+ FULL_HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+ gengetopt_options.push_front(opt);
+ }
+
+ if (!args_info.no_help_given && has_options_with_details() && gengetopt_has_option(DETAILED_HELP_LONG_OPT, 0) == 0) {
+ gengetopt_create_option (opt, DETAILED_HELP_LONG_OPT, '-',
+ DETAILED_HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+ gengetopt_options.push_front(opt);
+ }
+
+ has_help = gengetopt_has_option(HELP_LONG_OPT, HELP_SHORT_OPT);
+
+ if (has_help != REQ_LONG_OPTION && !args_info.no_help_given) {
+ gengetopt_create_option (opt, HELP_LONG_OPT, has_help ? '-' : HELP_SHORT_OPT,
+ HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+ gengetopt_options.push_front(opt);
+ }
+
+ // check whether there's pending text after all options and
+ // in case, set it to the last option
+ if (current_text && gengetopt_options.size()) {
+ gengetopt_options.back()->text_after = current_text;
+ gengetopt_set_text(0);
+ }
+
+ if (canonize_vars ()) {
+ gengetopt_free ();
+ return 1;
+ }
+
+ if (args_info.set_package_given) {
+ if (gengetopt_package)
+ free (gengetopt_package);
+ gengetopt_package = args_info.set_package_arg;
+ }
+
+ if (args_info.set_version_given) {
+ if (gengetopt_version)
+ free (gengetopt_version);
+ gengetopt_version = args_info.set_version_arg;
+ }
+
+ ostringstream command_line;
+ for ( i = 0; i < argc ; ++i )
+ command_line << argv[i] << " ";
+
+ // add also possible args specification in the input file
+ if (current_args)
+ command_line << current_args;
+
+ if (args_info.output_dir_given)
+ output_dir = args_info.output_dir_arg;
+ if (args_info.header_output_dir_given)
+ header_output_dir = args_info.header_output_dir_arg;
+ if (args_info.src_output_dir_given)
+ src_output_dir = args_info.src_output_dir_arg;
+
+ CmdlineParserCreator cmdline_parser_creator
+ (cmdline_parser_name,
+ args_info.arg_struct_name_arg,
+ (args_info.unamed_opts_given ? args_info.unamed_opts_arg : 0),
+ cmdline_filename,
+ header_ext,
+ c_ext,
+ args_info.long_help_given,
+ args_info.no_handle_help_given,
+ args_info.no_help_given,
+ args_info.no_handle_version_given,
+ args_info.no_version_given,
+ args_info.no_handle_error_given,
+ args_info.conf_parser_given,
+ args_info.string_parser_given,
+ args_info.gen_version_flag,
+ args_info.include_getopt_given,
+ no_options,
+ command_line.str (),
+ output_dir,
+ header_output_dir,
+ src_output_dir,
+ (args_info.show_required_given ? args_info.show_required_arg : ""));
+
+ if (! gengetopt_package && (args_info.show_version_given || args_info.show_help_given))
+ {
+ cerr << "package not defined; please specify it with --set-package" << endl;
+ return 1;
+ }
+ else if (! gengetopt_version && (args_info.show_version_given || args_info.show_help_given))
+ {
+ cerr << "version not defined; please specify it with --set-version" << endl;
+ return 1;
+ }
+ else if (args_info.show_version_given)
+ {
+ cout << gengetopt_package << " " << gengetopt_version << endl;
+ }
+ else if (args_info.show_help_given ||
+ args_info.show_full_help_given || args_info.show_detailed_help_given)
+ {
+ cout << gengetopt_package << " " << gengetopt_version << "\n" << endl;
+
+ if (gengetopt_purpose) {
+ output_formatted_string(cmdline_parser_creator.generate_purpose());
+ cout << endl;
+ }
+
+ output_formatted_string("Usage: " +
+ cmdline_parser_creator.generate_usage_string(false) + "\n");
+
+ if (gengetopt_description) {
+ output_formatted_string(cmdline_parser_creator.generate_description());
+ cout << endl;
+ }
+
+ // if --show-full-help is specified we have to generate also hidden options
+ OptionHelpList *option_list =
+ cmdline_parser_creator.generate_help_option_list(args_info.show_full_help_given, args_info.show_detailed_help_given);
+
+ std::for_each(option_list->begin(), option_list->end(),
+ output_formatted_string);
+
+ delete option_list;
+ }
+ else if (cmdline_parser_creator.generate ())
+ {
+ gengetopt_free ();
+ return 1;
+ }
+
+ gengetopt_free ();
+
+ return 0;
+}
+
+void
+output_formatted_string(const string &s)
+{
+ for (string::const_iterator it = s.begin(); it != s.end(); ++it)
+ {
+ if (*it == '\\' && ((it+1) != s.end()) && *(it+1) == 'n') {
+ cout << "\n";
+ ++it;
+ } else if (*it == '\\' && ((it+1) != s.end()) && *(it+1) == '"') {
+ cout << "\"";
+ ++it;
+ } else
+ cout << *it;
+ }
+
+ cout << endl;
+}
+
+/* ************* */
+
+int
+gengetopt_define_package (char * s)
+{
+ gengetopt_package = strdup (s);
+ if (gengetopt_package == NULL)
+ return 1;
+ return 0;
+}
+
+int
+gengetopt_define_version (char * s)
+{
+ gengetopt_version = strdup (s);
+ if (gengetopt_version == NULL)
+ return 1;
+ return 0;
+}
+
+int
+gengetopt_define_purpose (char * s)
+{
+ gengetopt_purpose = strdup (s);
+ if (gengetopt_purpose == NULL)
+ return 1;
+ return 0;
+}
+
+int
+gengetopt_define_description (char * s)
+{
+ gengetopt_description = strdup (s);
+ if (gengetopt_description == NULL)
+ return 1;
+ return 0;
+}
+
+int gengetopt_define_usage (char * s)
+{
+ gengetopt_usage = strdup (s);
+ if (gengetopt_usage == NULL)
+ return 1;
+ return 0;
+}
+
+int
+gengetopt_add_group (const char *s, const char *desc, int required)
+{
+ string group_desc;
+ if (desc)
+ group_desc = desc;
+ if ( !gengetopt_groups.insert
+ (make_pair(string(s),Group (group_desc, required != 0))).second )
+ return 1;
+ else
+ return 0;
+}
+
+int
+gengetopt_add_mode (const char *s, const char *desc)
+{
+ string mode_desc;
+ if (desc)
+ mode_desc = desc;
+ if ( !gengetopt_modes.insert
+ (make_pair(string(s),Mode (mode_desc))).second )
+ return 1;
+ else
+ return 0;
+}
+
+void
+gengetopt_set_section (const char * s, const char *desc)
+{
+ if (current_section)
+ free (current_section);
+ if (current_section_desc)
+ free (current_section_desc);
+ current_section = strdup (s);
+ if (desc)
+ current_section_desc = strdup (desc);
+ else
+ current_section_desc = 0;
+}
+
+void
+gengetopt_set_text (const char * desc)
+{
+ /*
+ no need to free it, since it will be then owned by the
+ option only
+
+ if (current_text)
+ free (current_text);
+ */
+
+ // the current text is reset
+ if (!desc) {
+ current_text = 0;
+ return;
+ }
+
+ if (current_text) {
+ // a previous text was collected, so we append the new text
+ // to the current one.
+ string buffer = current_text;
+ buffer += desc;
+ current_text = strdup(buffer.c_str());
+ return;
+ }
+
+ // otherwise simply copy the passed text
+ current_text = strdup (desc);
+}
+
+void gengetopt_set_args(const char *a)
+{
+ if (current_args)
+ free(current_args);
+
+ if (a)
+ current_args = strdup(a);
+ else
+ current_args = 0;
+}
+
+int
+gengetopt_has_option (const char * long_opt, char short_opt)
+{
+ gengetopt_option * n;
+
+ for (gengetopt_option_list::const_iterator it = gengetopt_options.begin();
+ it != gengetopt_options.end(); ++it)
+ {
+ n = *it;
+ if (!strcmp (n->long_opt, long_opt)) return REQ_LONG_OPTION;
+ if (short_opt && n->short_opt == short_opt)
+ return REQ_SHORT_OPTION;
+ }
+
+ return 0;
+}
+
+bool check_numeric_validity(const char *val, int opt_type)
+{
+ char *end_of_string, *expected_eos;
+
+ expected_eos = (char *) (val + strlen(val));
+
+ switch ( opt_type )
+ {
+ case ARG_INT :
+ case ARG_SHORT :
+ case ARG_LONG :
+ case ARG_LONGLONG :
+ (void) strtol(val, &end_of_string, 0);
+ break;
+
+ case ARG_FLOAT:
+ case ARG_DOUBLE:
+ case ARG_LONGDOUBLE:
+ (void) strtod(val, &end_of_string);
+ break;
+
+ default :
+ // This will allow us to factorise as a single line the
+ // test for correctness of the default value
+ end_of_string = expected_eos;
+ break;
+ }
+ return ( end_of_string == expected_eos );
+}
+
+bool
+check_values(const AcceptedValues *acceptedvalues, int opt_type)
+{
+ for (AcceptedValues::const_iterator it = acceptedvalues->begin();
+ it != acceptedvalues->end(); ++it) {
+ if (!check_numeric_validity((*it).c_str(), opt_type))
+ return false;
+ }
+
+ return true;
+}
+
+int
+gengetopt_create_option (gengetopt_option *&n, const char * long_opt, char short_opt,
+ const char * desc,
+ int type, int flagstat, int required,
+ const char * default_value,
+ const char * group_value,
+ const char * mode_value,
+ const char * type_str,
+ const AcceptedValues *acceptedvalues,
+ int multiple,
+ int argoptional)
+{
+ if ((long_opt == NULL) ||
+ (long_opt[0] == 0) ||
+ (desc == NULL))
+ return FOUND_BUG;
+
+ n = new gengetopt_option;
+ if (n == NULL)
+ return NOT_ENOUGH_MEMORY;
+
+ // here we will set required anyway
+ n->required_set = true;
+
+ n->long_opt = strdup (long_opt);
+ if (n->long_opt == NULL)
+ {
+ free (n);
+ return NOT_ENOUGH_MEMORY;
+ }
+
+ n->desc = strdup (desc);
+ if (n->desc == NULL)
+ {
+ free (n->long_opt);
+ free (n);
+ return NOT_ENOUGH_MEMORY;
+ }
+
+ n->short_opt = ((short_opt == '-') ? 0 : short_opt);
+ n->type = type;
+ n->flagstat = flagstat;
+ n->required = required;
+ n->multiple = (multiple != 0);
+ n->arg_is_optional = (argoptional != 0);
+
+ if (type_str != 0)
+ n->type_str = strdup(type_str);
+ else
+ n->type_str = NULL;
+
+ n->section = 0;
+ n->section_desc = 0;
+ if (current_section)
+ n->section = strdup (current_section);
+ if (current_section_desc)
+ n->section_desc = strdup (current_section_desc);
+
+ if (group_value != 0)
+ {
+ n->group_value = strdup(group_value);
+ n->required = 0;
+ groups_collection_t::const_iterator it =
+ gengetopt_groups.find(string(n->group_value));
+ if (it == gengetopt_groups.end())
+ return GROUP_UNDEFINED;
+ n->group_desc = strdup (it->second.desc.c_str ());
+ }
+ else
+ {
+ n->group_value = 0;
+ }
+
+ if (mode_value != 0) {
+ n->mode_value = strdup(mode_value);
+ modes_collection_t::const_iterator it =
+ gengetopt_modes.find(string(n->mode_value));
+ if (it == gengetopt_modes.end())
+ return MODE_UNDEFINED;
+ n->mode_desc = strdup (it->second.desc.c_str ());
+ } else {
+ n->mode_value = 0;
+ }
+
+ if (n->group_value && n->mode_value)
+ return FOUND_BUG;
+
+
+ n->acceptedvalues = acceptedvalues;
+
+ // if (acceptedvalues && type != ARG_NO)
+ // return NOT_REQUESTED_TYPE;
+
+ if (acceptedvalues && ! (n->type))
+ n->type = ARG_STRING;
+
+ n->default_string = 0;
+ n->default_given = (default_value != 0);
+ if (n->default_given)
+ {
+ n->default_string = strdup (default_value);
+ if ( ! check_numeric_validity(default_value, n->type) )
+ {
+ free (n);
+ return INVALID_DEFAULT_VALUE;
+ }
+
+ if (acceptedvalues)
+ {
+ if (! acceptedvalues->contains(n->default_string))
+ return INVALID_DEFAULT_VALUE;
+ }
+ }
+
+ if (acceptedvalues) {
+ if (!check_values(acceptedvalues, n->type))
+ return INVALID_NUMERIC_VALUE;
+ }
+
+ n->var_arg = NULL;
+
+ return 0;
+}
+
+int
+gengetopt_check_option (gengetopt_option *n, bool groupoption, bool modeoption)
+{
+ if ((n->long_opt == NULL) ||
+ (n->long_opt[0] == 0) ||
+ (n->desc == NULL))
+ return FOUND_BUG;
+
+ if (strcmp(n->long_opt, HELP_LONG_OPT) == 0 && !args_info.no_help_given)
+ return HELP_REDEFINED;
+
+ if (strcmp(n->long_opt, VERSION_LONG_OPT) == 0 && !args_info.no_version_given)
+ return VERSION_REDEFINED;
+
+ n->section = 0;
+ n->section_desc = 0;
+ if (current_section)
+ n->section = strdup (current_section);
+ if (current_section_desc)
+ n->section_desc = strdup (current_section_desc);
+
+ n->text_before = current_text;
+ // reset the description
+ gengetopt_set_text(0);
+
+ if (n->group_value != 0)
+ {
+ if (! groupoption)
+ return NOT_GROUP_OPTION;
+
+ n->required = 0;
+ n->required_set = true;
+
+ groups_collection_t::const_iterator it =
+ gengetopt_groups.find(string(n->group_value));
+ if (it == gengetopt_groups.end())
+ return GROUP_UNDEFINED;
+ n->group_desc = strdup (it->second.desc.c_str ());
+ }
+ else
+ {
+ if (groupoption)
+ return SPECIFY_GROUP;
+ }
+
+ if (n->mode_value != 0)
+ {
+ if (! modeoption)
+ return NOT_MODE_OPTION;
+
+ modes_collection_t::const_iterator it =
+ gengetopt_modes.find(string(n->mode_value));
+ if (it == gengetopt_modes.end())
+ return MODE_UNDEFINED;
+ n->mode_desc = strdup (it->second.desc.c_str ());
+ }
+ else
+ {
+ if (modeoption)
+ return SPECIFY_MODE;
+ }
+
+ if (n->group_value && n->mode_value)
+ return FOUND_BUG;
+
+ // now we have to check for flag options
+ if (n->type == ARG_FLAG)
+ {
+ if (n->flagstat < 0)
+ return SPECIFY_FLAG_STAT;
+
+ if (n->default_string || n->multiple || n->arg_is_optional
+ || n->type_str || n->acceptedvalues || n->required_set)
+ return NOT_VALID_SPECIFICATION;
+
+ n->required = 0;
+ n->required_set = true;
+ }
+ else
+ {
+ if (n->flagstat >= 0)
+ return NOT_VALID_SPECIFICATION;
+ }
+
+ // enum type can only be specified with options with values
+ if (n->type == ARG_ENUM && !(n->acceptedvalues)) {
+ return INVALID_ENUM_TYPE_USE;
+ }
+
+ // if (acceptedvalues && type != ARG_NO)
+ // return NOT_REQUESTED_TYPE;
+
+ if (n->acceptedvalues && ! (n->type))
+ n->type = ARG_STRING;
+
+ n->default_given = (n->default_string != 0);
+ if (n->default_given)
+ {
+ if ( !check_numeric_validity(n->default_string, n->type) )
+ {
+ return INVALID_DEFAULT_VALUE;
+ }
+
+ if (n->acceptedvalues)
+ {
+ if (! n->acceptedvalues->contains(n->default_string))
+ return INVALID_DEFAULT_VALUE;
+ }
+ }
+
+ if (n->acceptedvalues) {
+ if (!check_values(n->acceptedvalues, n->type))
+ return INVALID_NUMERIC_VALUE;
+ }
+
+ n->var_arg = NULL;
+
+ return 0;
+}
+
+int
+gengetopt_add_option (const char * long_opt, char short_opt,
+ const char * desc,
+ int type, int flagstat, int required,
+ const char * default_value,
+ const char * group_value,
+ const char * mode_value,
+ const char * type_str,
+ const AcceptedValues *acceptedvalues,
+ int multiple,
+ int argoptional)
+{
+ gengetopt_option * n;
+
+ /* search for collisions */
+ int res = gengetopt_has_option(long_opt, short_opt);
+ if (res != 0)
+ return res;
+
+ res = gengetopt_create_option(n, long_opt, short_opt,
+ desc, type, flagstat, required, default_value, group_value, mode_value,
+ type_str, acceptedvalues, multiple, argoptional);
+ if (res != 0)
+ return res;
+
+ gengetopt_options.push_back(n);
+
+ return 0;
+}
+
+int
+gengetopt_add_option (gengetopt_option * n)
+{
+ /* search for collisions */
+ int res = gengetopt_has_option(n);
+ if (res != 0)
+ return res;
+
+ gengetopt_options.push_back(n);
+
+ return 0;
+}
+
+int
+gengetopt_has_option (gengetopt_option * opt)
+{
+ gengetopt_option * n;
+
+ for (gengetopt_option_list::const_iterator it = gengetopt_options.begin();
+ it != gengetopt_options.end(); ++it)
+ {
+ n = *it;
+ if (!strcmp (n->long_opt, opt->long_opt))
+ return REQ_LONG_OPTION;
+ if (opt->short_opt && n->short_opt == opt->short_opt)
+ return REQ_SHORT_OPTION;
+ }
+
+ return 0;
+}
+
+bool
+check_dependencies()
+{
+ gengetopt_option * n;
+ bool result = true;
+
+ for (gengetopt_option_list::const_iterator it = gengetopt_options.begin();
+ it != gengetopt_options.end(); ++it)
+ {
+ n = *it;
+ if (n->dependon) {
+ if (strcmp(n->dependon, n->long_opt) == 0) {
+ yyerror(n, "option depends on itself");
+ result = false;
+ continue;
+ }
+
+ bool found = false;
+ for (gengetopt_option_list::const_iterator it2 = gengetopt_options.begin();
+ it2 != gengetopt_options.end(); ++it2)
+ {
+ if (strcmp(n->dependon, (*it2)->long_opt) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ if (! found) {
+ yyerror (n, "option depends on undefined option");
+ result = false;
+ }
+ }
+ }
+
+ return result;
+}
+
+void
+gengetopt_free (void)
+{
+ gengetopt_option *p;
+
+ if (gengetopt_package != NULL)
+ free (gengetopt_package);
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it != gengetopt_options.end(); ++it)
+ {
+ p = *it;
+ if (p->long_opt != NULL) free (p->long_opt);
+ if (p->desc != NULL) free (p->desc);
+ if (p->var_arg != NULL) free (p->var_arg);
+ if (p->acceptedvalues) delete p->acceptedvalues;
+ delete p;
+ }
+}
+
+static void
+canonize_var (gengetopt_option *p)
+{
+ char *pvar;
+
+ p->var_arg = strdup (p->long_opt);
+ if (p->var_arg == NULL) {
+ printf ("gengetopt: not enough memory to canonize vars\n");
+ abort();
+ }
+
+ for (pvar = p->var_arg; *pvar; pvar++)
+ if (*pvar == '.' || *pvar == '-') *pvar = '_';
+}
+
+int
+canonize_vars (void)
+{
+ for_each(gengetopt_options.begin(), gengetopt_options.end(), canonize_var);
+
+ return 0;
+}
+
+static void
+set_default_required_prop (gengetopt_option *p)
+{
+ if (!p->required_set)
+ p->required = (default_to_optional ? 0 : 1);
+}
+
+static void set_default_required_properties(void)
+{
+ for_each(gengetopt_options.begin(), gengetopt_options.end(), set_default_required_prop);
+}
+
+void
+print_copyright()
+{
+ copyright_gen_class copyright_g;
+
+ copyright_g.set_year ("1999-2009");
+ copyright_g.generate_copyright (cout);
+}
+
+void
+print_reportbugs()
+{
+ cout << endl;
+ cout << "Maintained by Lorenzo Bettini <http://www.lorenzobettini.it>" << endl;
+ cout << "Report bugs to <bug-gengetopt at gnu.org>" << endl;
+}
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GENGETOPT_H
+#define _GENGETOPT_H
+
+#include "acceptedvalues.h"
+#include "ggos.h"
+
+int gengetopt_define_package (char * s) ;
+int gengetopt_define_version (char * s) ;
+int gengetopt_define_purpose (char * s) ;
+int gengetopt_define_description (char * s) ;
+int gengetopt_define_usage (char * s) ;
+
+/**
+ * Sets the "global" section specification that will be then set
+ * in the following options
+ * @param s The section
+ * @param sd The section description
+ */
+void gengetopt_set_section (const char * s, const char *sd) ;
+
+/**
+ * Sets the "global" text string that will be inserted in
+ * a specific field of the next option
+ * @param desc The text string
+ */
+void gengetopt_set_text (const char * desc) ;
+
+/**
+ * Sets the "global" text string containing the arguments
+ * that complement the command line arguments of gengetopt.
+ * @param args
+ */
+void gengetopt_set_args (const char *args);
+
+int gengetopt_add_group (const char * s, const char *desc, int required) ;
+int gengetopt_add_mode (const char * s, const char *desc) ;
+
+int gengetopt_has_option (const char * long_opt, char short_opt);
+int gengetopt_add_option (const char * long_opt, char short_opt,
+ const char * desc,
+ int type, int flagstat, int required,
+ const char *default_value,
+ const char * group_value,
+ const char * mode_value,
+ const char * type_str,
+ const AcceptedValues *acceptedvalues,
+ int multiple = 0,
+ int argoptional = 0);
+
+int gengetopt_has_option (gengetopt_option *opt);
+int gengetopt_check_option (gengetopt_option *opt,
+ bool groupoption = false, bool modeoption = false);
+int gengetopt_add_option (gengetopt_option *opt);
+
+#endif /* _GENGETOPT_H */
--- /dev/null
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages. */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (posixly_correct == NULL
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ int print_errors = opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
--- /dev/null
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
--- /dev/null
+#ifndef GGO_OPTIONS_H
+#define GGO_OPTIONS_H
+
+#include "ggos.h"
+
+extern gengetopt_option_list gengetopt_options;
+
+#define foropt for (gengetopt_option_list::iterator it = gengetopt_options.begin(); \
+ it != gengetopt_options.end() && (opt = *it); \
+ ++it)
+
+#endif /* GGO_OPTIONS_H */
--- /dev/null
+//
+// C++ Implementation: ggos
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2005-2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "ggos.h"
+
+using namespace std;
+
+gengetopt_option::gengetopt_option() :
+ short_opt(0), long_opt(0), desc(0), type(ARG_NO), flagstat(-1),
+ required(1), required_set(false), var_arg(0), default_string(0),
+ group_value(0), group_desc(0),
+ mode_value(0), mode_desc(0),
+ multiple(false),
+ arg_is_optional(false), hidden(false), type_str(0),
+ acceptedvalues(0), section(0), section_desc(0), dependon(0),
+ text_before(0), text_after(0), details(0), filename(0), linenum(0) {
+}
+
+ostream & operator <<(std::ostream &s, gengetopt_option &opt) {
+ s << "long: " << opt.long_opt << ", short: " << opt.short_opt << "\n"
+ << "desc: " << opt.desc;
+
+ s << endl;
+
+ return s;
+}
--- /dev/null
+/*
+This file is licensed to you under the license specified in the included file
+`LICENSE'. Look there for further details.
+*/
+
+
+#ifndef _GENGETOPT_GGOS_H
+#define _GENGETOPT_GGOS_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <list>
+#include <iostream>
+
+#include "acceptedvalues.h"
+#include "argsdef.h"
+
+/**
+ * The structure for storing an option specified in the .ggo file
+ */
+struct gengetopt_option
+{
+ char short_opt; /**< the short option specification (one char) */
+ char * long_opt; /**< the short option specification */
+ char * desc; /**< the option description */
+ int type; /**< the type of the option (possible values in `argsdef.h') */
+ int flagstat ; /**< if the option is of type flag, this indicates its state (on/off) */
+ int required; /**< whether the option required */
+ bool required_set; /**< whether the required property was set */
+ char * var_arg; /**< canonized long_opt + "_arg" = argument var */
+ int default_given ; /**< if a default is given */
+ char * default_string ; /**< default value for this option, if string */
+ char * group_value; /**< group name, if it's part of an option group */
+ char * group_desc; /**< group description, if it's part of an option group */
+ char * mode_value; /**< mode name, if it's part of an option mode */
+ char * mode_desc; /**< mode description, if it's part of an option mode */
+ bool multiple; /**< whether this option can be given more than once */
+ char * multiple_min; /**< minimum occurrences of a multiple option (-1: not specified) */
+ char * multiple_max; /**< maximum occurrences of a multiple option (-1: not specified) */
+ bool arg_is_optional; /**< whether the argument is optional */
+ bool hidden; /**< whether this option will be hidden from the help output */
+ char *type_str; /**< Alternative name for type,
+ e.g. "URL" or "SECONDS" */
+ const AcceptedValues *acceptedvalues; /**< values that can be passed to this option */
+ char *section; /**< the section of this option */
+ char *section_desc; /**< the description associated with the possible section */
+ char *dependon; /**< the name of the option this one depends on */
+
+ char *text_before; /**< a possible text specified before this option */
+ char *text_after; /**< a possible text specified after this option */
+
+ char *details; /**< possible further details for this option that will be
+ printed only if --detailed-help is specified */
+
+ /**< parser information */
+ char *filename; /**< source file */
+ int linenum; /**< line number */
+
+ gengetopt_option();
+};
+
+/** the list storing gengetopt options */
+typedef std::list<gengetopt_option *> gengetopt_option_list;
+
+std::ostream & operator <<(std::ostream &s, gengetopt_option &opt);
+
+#endif /* _GENGETOPT_GGOS_H */
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLOBAL_OPTS_H
+#define GLOBAL_OPTS_H
+
+#define HELP_LONG_OPT "help"
+#define HELP_SHORT_OPT 'h'
+#define HELP_SHORT_OPT_STR "h"
+#define HELP_OPT_DESCR "Print help and exit"
+
+#define FULL_HELP_LONG_OPT "full-help"
+#define FULL_HELP_LONG_OPT_FIELD "full_help"
+#define FULL_HELP_OPT_DESCR "Print help, including hidden options, and exit"
+
+#define DETAILED_HELP_LONG_OPT "detailed-help"
+#define DETAILED_HELP_LONG_OPT_FIELD "detailed_help"
+#define DETAILED_HELP_OPT_DESCR "Print help, including all details and hidden options, and exit"
+
+#define VERSION_LONG_OPT "version"
+#define VERSION_SHORT_OPT 'V'
+#define VERSION_SHORT_OPT_STR "V"
+#define VERSION_OPT_DESCR "Print version and exit"
+
+#endif /* GLOBAL_OPTS_H */
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "globals.h"
+
+gengetopt_option_list gengetopt_options;
+
+groups_collection_t gengetopt_groups;
--- /dev/null
+/**
+ * Copyright (C) 1999-2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLOBALS_H_
+#define GLOBALS_H_
+
+#include "ggos.h"
+#include "groups.h"
+
+extern gengetopt_option_list gengetopt_options;
+
+extern groups_collection_t gengetopt_groups;
+
+#endif /* GLOBALS_H_ */
--- /dev/null
+/**
+ * Copyright (C) 1999-2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <set>
+#include <algorithm> // for pair
+
+#include <fstream>
+
+extern "C"
+{
+#include "argsdef.h"
+#include "global_opts.h"
+};
+
+#include "ggo_options.h"
+
+#include "gm.h"
+#include "my_sstream.h"
+
+#include "groups.h"
+#include "skels/option_arg.h"
+#include "skels/required_option.h"
+#include "skels/dependant_option.h"
+#include "skels/generic_option.h"
+#include "skels/group_option.h"
+#include "skels/group_counter.h"
+#include "skels/handle_help.h"
+#include "skels/handle_version.h"
+#include "skels/print_help_string.h"
+#include "skels/multiple_opt_list.h"
+#include "skels/multiple_fill_array.h"
+#include "skels/free_string.h"
+#include "skels/free_multiple.h"
+#include "skels/reset_group.h"
+#include "skels/exit_failure.h"
+#include "skels/update_given.h"
+#include "skels/given_field.h"
+#include "skels/clear_given.h"
+#include "skels/clear_arg.h"
+#include "skels/free_list.h"
+#include "skels/file_save.h"
+#include "skels/file_save_multiple.h"
+#include "skels/init_args_info.h"
+#include "skels/custom_getopt_gen.h"
+#include "skels/check_modes.h"
+#include "skels/enum_decl.h"
+#include "gm_utils.h"
+#include "fileutils.h"
+
+#ifndef FIX_UNUSED
+#define FIX_UNUSED(X) (void) (X)
+#endif // FIX_UNUSED
+
+#define MAX_STARTING_COLUMN 32
+
+#define EXE_NAME "argv[0]"
+
+#define PARSER_NAME_PREFIX (c_source_gen_class::parser_name + "_")
+#define OPTION_VALUES_NAME(n) (PARSER_NAME_PREFIX + n + "_values")
+
+using std::endl;
+using std::set;
+
+extern char * gengetopt_package;
+extern char * gengetopt_version;
+extern char * gengetopt_purpose;
+extern char * gengetopt_description;
+extern char * gengetopt_usage;
+extern char * gengetopt_input_filename;
+
+extern groups_collection_t gengetopt_groups;
+extern modes_collection_t gengetopt_modes;
+
+// a map where for each mode we store the corresponding given field names
+// and the options
+typedef std::pair<string, string> OptionValueElem;
+typedef std::list<OptionValueElem> ModeOptions;
+typedef std::map<string, ModeOptions> ModeOptionMap;
+
+static ModeOptionMap modeOptionMap;
+
+static const ModeOptionMap &getModeOptionMap() {
+ if (modeOptionMap.size() == 0) {
+ // it's the first time, so we build it
+ struct gengetopt_option * opt;
+ foropt {
+ if (opt->mode_value) {
+ modeOptionMap[opt->mode_value].push_back
+ (std::make_pair("args_info->" + string(opt->var_arg) + "_given",
+ string("\"--") + opt->long_opt + "\""));
+ }
+ }
+ }
+
+ return modeOptionMap;
+}
+
+// a map associating to a mode the list of gengetopt_options
+typedef std::map<string, gengetopt_option_list> ModeOptMap;
+
+static ModeOptMap modeOptMap;
+
+static const ModeOptMap &getModeOptMap() {
+ if (modeOptMap.size() == 0) {
+ // it's the first time, so we build it
+ struct gengetopt_option * opt;
+ foropt {
+ if (opt->mode_value) {
+ modeOptMap[opt->mode_value].push_back(opt);
+ }
+ }
+ }
+
+ return modeOptMap;
+}
+
+static void _generate_option_arg(ostream &stream,
+ unsigned int indent,
+ struct gengetopt_option * opt);
+
+static void
+generate_help_desc_print(ostream &stream,
+ unsigned int desc_column,
+ const char *descript, const char *defval,
+ const string &values,
+ const string &show_required_string);
+
+CmdlineParserCreator::CmdlineParserCreator (char *function_name,
+ char *struct_name,
+ char *unamed_options_,
+ char *filename_,
+ char *header_ext, char *c_ext,
+ bool long_help_,
+ bool no_handle_help_,
+ bool no_help_,
+ bool no_handle_version_,
+ bool no_version_,
+ bool no_handle_error_,
+ bool conf_parser_,
+ bool string_parser_,
+ bool gen_version,
+ bool gen_getopt,
+ bool no_options_,
+ const string &comment_,
+ const string &outdir,
+ const string &header_outdir,
+ const string &src_outdir,
+ const string &show_required) :
+ filename (filename_),
+ args_info_name (struct_name),
+ output_dir (outdir),
+ header_output_dir (header_outdir),
+ src_output_dir (src_outdir),
+ comment (comment_),
+ unamed_options (unamed_options_),
+ show_required_string (show_required),
+ long_help (long_help_), no_handle_help (no_handle_help_),
+ no_help (no_help_),
+ no_handle_version (no_handle_version_),
+ no_version (no_version_),
+ no_handle_error (no_handle_error_),
+ conf_parser (conf_parser_), string_parser (string_parser_),
+ gen_gengetopt_version (gen_version),
+ tab_indentation (0)
+{
+ parser_function_name = canonize_names (function_name);
+ c_filename = create_filename (filename, c_ext);
+ header_filename = create_filename (filename, header_ext);
+
+ // header_gen_class
+ const string stripped_header_file_name = strip_path (filename);
+ set_header_file_name (stripped_header_file_name);
+ header_gen_class::set_header_file_ext (header_ext);
+ c_source_gen_class::set_header_file_ext (header_ext);
+ if (gen_gengetopt_version)
+ header_gen_class::set_generator_version
+ ("version " VERSION);
+ const string my_ifndefname =
+ to_upper (strip_path (stripped_header_file_name));
+ set_ifndefname (canonize_names (my_ifndefname.c_str ()));
+ header_gen_class::set_parser_name (parser_function_name);
+ const string my_package_var_name =
+ to_upper (parser_function_name) + "_PACKAGE";
+ const string my_version_var_name =
+ to_upper (parser_function_name) + "_VERSION";
+ header_gen_class::set_package_var_name (my_package_var_name);
+ c_source_gen_class::set_package_var_name (my_package_var_name);
+ header_gen_class::set_version_var_name (my_version_var_name);
+ c_source_gen_class::set_version_var_name (my_version_var_name);
+ header_gen_class::set_args_info (args_info_name);
+ c_source_gen_class::set_args_info (args_info_name);
+ const string uppersand = "\"";
+
+ // if no_options then we don't need to generate update_arg,
+ // but if we need to handle help or version we still need to generate it
+ set_no_options (no_options_ && !no_handle_help && !no_handle_version);
+
+ if (gengetopt_package)
+ set_package_var_val
+ (uppersand + gengetopt_package + uppersand);
+ else
+ set_package_var_val ("PACKAGE");
+
+ if (gengetopt_version)
+ set_version_var_val
+ (uppersand + gengetopt_version + uppersand);
+ else
+ set_version_var_val ("VERSION");
+
+ header_gen_class::set_generate_config_parser (conf_parser);
+
+ header_gen_class::set_generate_string_parser (string_parser);
+ c_source_gen_class::set_generate_string_parser (string_parser);
+
+ // c_source_gen_class
+ set_command_line (comment);
+ if (gen_gengetopt_version)
+ c_source_gen_class::set_generator_version
+ ("version " VERSION);
+ c_source_gen_class::set_parser_name (parser_function_name);
+ set_source_name (filename);
+
+ ostringstream exit_failure_str;
+ exit_failure_gen_class exit_gen;
+ exit_gen.set_parser_name (c_source_gen_class::parser_name);
+ exit_gen.set_handle_error (! no_handle_error);
+ exit_gen.generate_exit_failure (exit_failure_str);
+ set_final_exit (exit_failure_str.str ());
+
+ set_conf_parser (conf_parser);
+ set_cmd_list (conf_parser || string_parser);
+ set_include_getopt (gen_getopt);
+
+ struct gengetopt_option * opt;
+ gen_strdup = (unamed_options != 0 || conf_parser || string_parser);
+
+ if (! gen_strdup)
+ {
+ foropt
+ if (opt->type != ARG_FLAG || opt->type != ARG_NO) {
+ gen_strdup = true;
+ break;
+ }
+ }
+
+ set_do_generate_strdup(gen_strdup);
+ set_check_possible_values(has_values());
+ set_multiple_token_functions(has_multiple_options_with_type());
+ set_multiple_options_with_default(has_multiple_options_with_default());
+ set_multiple_options(has_multiple_options());
+ set_multiple_options_string(has_multiple_options_string());
+ set_multiple_options_all_string(has_multiple_options_all_string());
+ set_has_typed_options(has_options_with_type());
+ set_has_modes(has_options_with_mode());
+ set_handle_unamed(unamed_options);
+ set_check_required_options(has_required() || has_dependencies() || has_multiple_options());
+ set_purpose(generate_purpose());
+ set_description(generate_description());
+ set_no_package((gengetopt_package == 0));
+ c_source_gen_class::set_has_hidden(has_hidden_options());
+ header_gen_class::set_has_hidden(c_source_gen_class::has_hidden);
+ c_source_gen_class::set_has_details(has_options_with_details());
+ header_gen_class::set_has_details(c_source_gen_class::has_details);
+
+ set_has_arg_types();
+}
+
+void CmdlineParserCreator::set_has_arg_types() {
+ struct gengetopt_option * opt;
+
+ set_has_arg_flag(false);
+ set_has_arg_string(false);
+ set_has_arg_int(false);
+ set_has_arg_short(false);
+ set_has_arg_long(false);
+ set_has_arg_float(false);
+ set_has_arg_double(false);
+ set_has_arg_longdouble(false);
+ set_has_arg_longlong(false);
+
+ foropt
+ {
+ switch (opt->type) {
+ case ARG_NO:
+ break;
+ case ARG_FLAG:
+ set_has_arg_flag(true);
+ break;
+ case ARG_STRING:
+ set_has_arg_string(true);
+ break;
+ case ARG_INT:
+ set_has_arg_int(true);
+ break;
+ case ARG_SHORT:
+ set_has_arg_short(true);
+ break;
+ case ARG_LONG:
+ set_has_arg_long(true);
+ break;
+ case ARG_FLOAT:
+ set_has_arg_float(true);
+ break;
+ case ARG_DOUBLE:
+ set_has_arg_double(true);
+ break;
+ case ARG_LONGDOUBLE:
+ set_has_arg_longdouble(true);
+ break;
+ case ARG_LONGLONG:
+ set_has_arg_longlong(true);
+ break;
+ case ARG_ENUM:
+ set_has_arg_enum(true);
+ break;
+ default:
+ fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+ __FILE__, __LINE__);
+ abort ();
+ }
+ }
+
+}
+
+void
+CmdlineParserCreator::generateBreak(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+
+ stream << endl;
+ stream << indent_str;
+ stream << "break;";
+}
+
+int
+CmdlineParserCreator::generate ()
+{
+ int head_result;
+
+ head_result = generate_header_file ();
+ if (head_result)
+ return head_result;
+
+ return generate_source ();
+}
+
+int
+CmdlineParserCreator::generate_header_file ()
+{
+ if (! gengetopt_options.size())
+ {
+ fprintf (stderr, "gengetopt: none option given\n");
+ return 1;
+ }
+
+ /* ****************************************************** */
+ /* HEADER FILE******************************************* */
+ /* ****************************************************** */
+
+ string header_file = header_filename;
+ if (header_output_dir.size())
+ header_file = header_output_dir + "/" + header_file;
+ else if (output_dir.size())
+ header_file = output_dir + "/" + header_file;
+
+ ofstream *output_file = open_fstream
+ (header_file.c_str());
+ generate_header (*output_file);
+ output_file->close ();
+ delete output_file;
+
+ return 0;
+}
+
+/**
+ * generate the enum value from a given option
+ * @param name the (canonized) name of the option
+ * @param val the value of the option
+ * @return the enum value string
+ */
+static const string from_value_to_enum(const string &name, const string &val) {
+ return name + "_arg_" + canonize_enum(val);
+}
+
+void
+CmdlineParserCreator::generate_enum_types(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ FIX_UNUSED (indent);
+
+ if (has_arg_enum)
+ stream << endl;
+
+ foropt {
+ // if type is enum then it should also have values (checked during parsing)
+ // but it's better to check it
+ if (opt->type == ARG_ENUM) {
+ if (! (opt->acceptedvalues)) {
+ fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+ __FILE__, __LINE__);
+ abort ();
+ }
+ ostringstream enum_values;
+ enum_decl_gen_class enum_gen;
+ enum_gen.set_var_arg(opt->var_arg);
+ for (AcceptedValues::const_iterator it = opt->acceptedvalues->begin();
+ it != opt->acceptedvalues->end(); ++it) {
+ enum_values << ", ";
+ // the first enum element is set to 0
+ enum_values << from_value_to_enum(opt->var_arg, *it);
+ if (it == opt->acceptedvalues->begin())
+ enum_values << " = 0";
+
+ }
+ enum_gen.set_enum_values(enum_values.str());
+ enum_gen.generate_enum_decl(stream);
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_option_arg(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+
+ foropt {
+ _generate_option_arg (stream, indent, opt);
+ }
+}
+
+void
+_generate_option_arg(ostream &stream,
+ unsigned int indent,
+ struct gengetopt_option *opt)
+{
+ option_arg_gen_class option_arg_gen;
+
+ string type = "";
+ if (opt->type)
+ type = arg_types[opt->type];
+ string origtype = "char *";
+
+ if (opt->multiple) {
+ type += "*";
+ origtype += "*";
+ option_arg_gen.set_multiple(true);
+ } else {
+ option_arg_gen.set_multiple(false);
+ }
+
+ option_arg_gen.set_type(type);
+ option_arg_gen.set_origtype(origtype);
+ option_arg_gen.set_flag_arg((opt->type == ARG_FLAG));
+ option_arg_gen.set_desc(opt->desc);
+ option_arg_gen.set_name(opt->var_arg);
+ option_arg_gen.set_has_arg(opt->type != ARG_NO);
+ option_arg_gen.set_has_enum(opt->type == ARG_ENUM);
+
+ if (opt->default_given)
+ {
+ option_arg_gen.set_has_default(true);
+ option_arg_gen.set_default_value(opt->default_string);
+ }
+
+ if (opt->type == ARG_FLAG)
+ {
+ option_arg_gen.set_default_on(opt->flagstat);
+ }
+
+ if (opt->type == ARG_LONGLONG)
+ {
+ // the fallback type in case longlong is not supported by the compiler
+ string longtype = arg_types[ARG_LONG];
+ if (opt->multiple)
+ longtype += "*";
+
+ option_arg_gen.set_long_long_arg(true);
+ option_arg_gen.set_longtype(longtype);
+ }
+
+ option_arg_gen.generate_option_arg(stream, indent);
+}
+
+void
+CmdlineParserCreator::generate_option_given(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ string indent_str (indent, ' ');
+ bool first = true;
+ given_field_gen_class given_gen;
+
+ foropt
+ {
+ switch (opt->type) {
+ case ARG_NO:
+ case ARG_FLAG:
+ case ARG_STRING:
+ case ARG_INT:
+ case ARG_SHORT:
+ case ARG_LONG:
+ case ARG_FLOAT:
+ case ARG_DOUBLE:
+ case ARG_LONGDOUBLE:
+ case ARG_LONGLONG:
+ case ARG_ENUM:
+ break;
+ default:
+ fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+ __FILE__, __LINE__);
+ abort ();
+ }
+ if (! first)
+ stream << indent_str;
+ else
+ first = false;
+
+ given_gen.set_arg_name (opt->var_arg);
+ given_gen.set_long_opt (opt->long_opt);
+ given_gen.set_group (opt->multiple && opt->group_value);
+ given_gen.generate_given_field (stream);
+ }
+
+ if (unamed_options)
+ {
+ stream << endl;
+ stream << indent_str;
+ stream << "char **inputs ; /**< @brief unamed options (options without names) */\n" ;
+ stream << indent_str;
+ stream << "unsigned inputs_num ; /**< @brief unamed options number */" ;
+ }
+}
+
+void
+CmdlineParserCreator::generate_option_values_decl(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ bool first = true;
+ FIX_UNUSED (indent);
+
+ foropt
+ {
+ if (opt->acceptedvalues) {
+ if (first) {
+ first = false;
+ }
+
+ stream << "extern const char *" << OPTION_VALUES_NAME(opt->var_arg) <<
+ "[]; /**< @brief Possible values for " << opt->long_opt << ". */\n";
+ }
+ }
+
+ if (! first)
+ stream << "\n";
+}
+
+void
+CmdlineParserCreator::generate_option_values(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ bool first = true;
+ FIX_UNUSED (indent);
+
+ foropt
+ {
+ if (opt->acceptedvalues) {
+ if (first) {
+ first = false;
+ }
+
+ stream << "const char *" << OPTION_VALUES_NAME(opt->var_arg) <<
+ "[] = {" << opt->acceptedvalues->toString(false) <<
+ ", 0}; /*< Possible values for " << opt->long_opt << ". */\n";
+ }
+ }
+
+ if (! first)
+ stream << "\n";
+}
+
+static void generate_option_usage_string(gengetopt_option * opt, ostream &usage) {
+ const char *type_str;
+
+ usage << " ";
+
+ if (!opt->required)
+ usage << "[";
+
+ switch (opt->type) {
+ case ARG_NO:
+ case ARG_FLAG:
+ if (opt->short_opt)
+ usage << "-" << opt->short_opt << "|";
+ usage << "--" << opt->long_opt;
+ break;
+ case ARG_INT:
+ case ARG_SHORT:
+ case ARG_LONG:
+ case ARG_FLOAT:
+ case ARG_DOUBLE:
+ case ARG_LONGDOUBLE:
+ case ARG_LONGLONG:
+ case ARG_STRING:
+ case ARG_ENUM:
+ if (opt->type_str)
+ type_str = opt->type_str;
+ else
+ type_str = arg_names[opt->type];
+
+ if (opt->short_opt)
+ usage << "-" << opt->short_opt << type_str << "|";
+ usage << "--" << opt->long_opt << "=" << type_str;
+
+ break;
+ default: fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+ __FILE__, __LINE__);
+ abort ();
+ }
+
+ if (!opt->required)
+ usage << "]";
+}
+
+const string
+CmdlineParserCreator::generate_usage_string(bool use_config_package)
+{
+ FIX_UNUSED (use_config_package);
+ // if specified by the programmer, the usage string has the precedence
+ if (gengetopt_usage) {
+ return gengetopt_usage;
+ }
+
+ struct gengetopt_option * opt;
+ ostringstream usage;
+
+ // otherwise the config.h package constant will be used
+ if (gengetopt_package)
+ usage << gengetopt_package;
+
+ if ( long_help ) {
+ // we first generate usage strings of required options
+ // handle mode options separately
+ foropt
+ if (opt->required && !opt->hidden && !opt->mode_value) {
+ generate_option_usage_string(opt, usage);
+ }
+
+ foropt
+ if (!opt->required && !opt->hidden && !opt->mode_value) {
+ generate_option_usage_string(opt, usage);
+ }
+ } else { /* if not long help we generate it as GNU standards */
+ usage << " [OPTIONS]...";
+ }
+
+ string wrapped;
+
+ if ( unamed_options )
+ usage << " [" << unamed_options << "]...";
+
+ wrap_cstr ( wrapped, strlen("Usage: "), 2, usage.str() );
+
+ // now deal with modes
+ if (has_modes && long_help) {
+ const ModeOptMap &modeOptMap = getModeOptMap();
+
+ for (ModeOptMap::const_iterator map_it = modeOptMap.begin(); map_it != modeOptMap.end(); ++map_it) {
+ string mode_line; // a mode alternative in the usage string
+ gengetopt_option_list::const_iterator opt_it;
+ usage.str(""); // reset the usage string buffer
+
+ for (opt_it = map_it->second.begin(); opt_it != map_it->second.end(); ++opt_it) {
+ if (((*opt_it)->required) && !((*opt_it)->hidden)) {
+ generate_option_usage_string(*opt_it, usage);
+ }
+ }
+
+ for (opt_it = map_it->second.begin(); opt_it != map_it->second.end(); ++opt_it) {
+ if (!((*opt_it)->required) && !((*opt_it)->hidden)) {
+ generate_option_usage_string(*opt_it, usage);
+ }
+ }
+
+ wrap_cstr ( mode_line, strlen(" or : "), 2, gengetopt_package + usage.str() );
+ wrapped += "\\n or : ";
+ wrapped += mode_line;
+ }
+ }
+
+ return wrapped;
+}
+
+static void
+generate_help_desc_print(ostream &stream,
+ unsigned int desc_column,
+ const char *descript, const char *defval,
+ const string &values,
+ const string &show_required_string)
+{
+ string desc;
+ string desc_with_default = descript;
+
+ if (defval || values.size()) {
+ desc_with_default += " (";
+
+ if (values.size()) {
+ desc_with_default += "possible values=";
+ desc_with_default += values;
+ if (defval)
+ desc_with_default += " ";
+ }
+
+ if (defval) {
+ desc_with_default += "default=";
+ desc_with_default += defval;
+ }
+
+ desc_with_default += ")";
+ }
+
+ if (show_required_string != "")
+ desc_with_default += " " + show_required_string;
+
+ wrap_cstr ( desc, desc_column, 2, desc_with_default );
+
+ stream << desc;
+}
+
+
+void
+CmdlineParserCreator::generate_help_option_print_from_lists(ostream &stream,
+ unsigned int indent, OptionHelpList *full_option_list,
+ OptionHelpList *option_list, const std::string &target_array,
+ const std::string &source_array) {
+ print_help_string_gen_class print_gen;
+
+ // the index into the help arrays
+ int i = 0, full_i = 0;
+ // num of help strings
+ int help_num = 0;
+
+ print_gen.set_target(target_array);
+ print_gen.set_from(source_array);
+ print_gen.set_shared(true);
+ print_gen.set_last(false);
+
+ OptionHelpList::const_iterator it = option_list->begin();
+ OptionHelpList::const_iterator it2 = full_option_list->begin();
+ // the second list is surely longer so we scan that one
+ for (; it != option_list->end() && it2 != full_option_list->end(); ++it2)
+ {
+ if (*it == *it2) {
+ // when the two strings are the same it means that's a non-hidden
+ // option, so we share it with the full help array
+ ostringstream converted_int;
+ converted_int << i;
+
+ // the index into the help array
+ print_gen.set_index(converted_int.str());
+
+ converted_int.str("");
+ converted_int << full_i;
+
+ // the index into the full help array
+ print_gen.set_full_index(converted_int.str());
+ print_gen.generate_print_help_string(stream, indent);
+
+ ++help_num;
+ ++i;
+ ++it;
+ }
+ ++full_i;
+ }
+
+ ostringstream converted_int;
+ converted_int << help_num;
+
+ // the final 0
+ print_gen.set_last(true);
+ print_gen.set_index(converted_int.str());
+ print_gen.generate_print_help_string(stream, indent);
+
+ // we increment it to store the final 0
+ converted_int.str("");
+ converted_int << ++help_num;
+
+ set_help_string_num(converted_int.str());
+
+}
+
+void
+CmdlineParserCreator::generate_help_option_print(ostream &stream,
+ unsigned int indent)
+{
+ OptionHelpList *option_list = generate_help_option_list();
+
+ if (!c_source_gen_class::has_hidden && !c_source_gen_class::has_details) {
+ print_help_string_gen_class print_gen;
+ print_gen.set_shared(false);
+
+ // simple help generation
+ for (OptionHelpList::const_iterator it = option_list->begin();
+ it != option_list->end(); ++it)
+ {
+ print_gen.set_helpstring(*it);
+ print_gen.generate_print_help_string(stream, indent);
+ }
+ } else {
+ // in order to avoid generating the same help string twice, and thus
+ // to save memory, in case of hidden options (or details), we try to share most
+ // of the strings with the full help array
+ OptionHelpList *full_option_list = generate_help_option_list(true, true);
+
+ generate_help_option_print_from_lists
+ (stream, indent, full_option_list, option_list,
+ c_source_gen_class::args_info + "_help",
+ (c_source_gen_class::has_details ?
+ c_source_gen_class::args_info + "_detailed_help" :
+ c_source_gen_class::args_info + "_full_help"));
+
+ delete full_option_list;
+ }
+
+ delete option_list;
+}
+
+void
+CmdlineParserCreator::generate_full_help_option_print(ostream &stream,
+ unsigned int indent)
+{
+ // generate also hidden options
+ OptionHelpList *option_list = generate_help_option_list(true);
+
+ if (!c_source_gen_class::has_details) {
+ print_help_string_gen_class print_gen;
+ print_gen.set_shared(false);
+
+ for (OptionHelpList::const_iterator it = option_list->begin();
+ it != option_list->end(); ++it)
+ {
+ print_gen.set_helpstring(*it);
+ print_gen.generate_print_help_string(stream, indent);
+ }
+ } else {
+ // in order to avoid generating the same help string twice, and thus
+ // to save memory, in case of options with details, we try to share most
+ // of the strings with the full help array
+ OptionHelpList *full_option_list = generate_help_option_list(true, true);
+
+ generate_help_option_print_from_lists
+ (stream, indent, full_option_list, option_list,
+ c_source_gen_class::args_info + "_full_help",
+ c_source_gen_class::args_info + "_detailed_help");
+
+ delete full_option_list;
+ }
+
+ delete option_list;
+}
+
+void
+CmdlineParserCreator::generate_detailed_help_option_print(ostream &stream,
+ unsigned int indent)
+{
+ // generate also hidden options and details
+ OptionHelpList *option_list = generate_help_option_list(true, true);
+
+ print_help_string_gen_class print_gen;
+ print_gen.set_shared(false);
+
+ for (OptionHelpList::const_iterator it = option_list->begin();
+ it != option_list->end(); ++it)
+ {
+ print_gen.set_helpstring(*it);
+ print_gen.generate_print_help_string(stream, indent);
+ }
+
+ delete option_list;
+}
+
+void
+CmdlineParserCreator::generate_init_args_info(ostream &stream, unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ init_args_info_gen_class init_args_info_gen;
+ int i = 0;
+ ostringstream index;
+
+ string help_string = c_source_gen_class::args_info;
+
+ if (c_source_gen_class::has_details) {
+ help_string += "_detailed_help";
+ } else if (c_source_gen_class::has_hidden) {
+ help_string += "_full_help";
+ } else {
+ help_string += "_help";
+ }
+ init_args_info_gen.set_help_strings(help_string);
+
+ const char *current_section = 0, *current_group = 0, *current_mode = 0;
+
+ // we have to skip section description references (that appear in the help vector)
+ foropt {
+ index.str("");
+
+ if (opt->section) {
+ if (!current_section || (strcmp(current_section, opt->section) != 0)) {
+ // a different section reference, skip it
+ current_section = opt->section;
+ ++i;
+
+ if (opt->section_desc) {
+ // section description takes another line, thus we have to skip this too
+ ++i;
+ }
+ }
+ }
+
+ // skip group desc
+ if (opt->group_value) {
+ if (!current_group || strcmp(current_group, opt->group_value) != 0) {
+ current_group = opt->group_value;
+ ++i;
+ }
+ }
+
+ // skip mode desc
+ if (opt->mode_value) {
+ if (!current_mode || strcmp(current_mode, opt->mode_value) != 0) {
+ current_mode = opt->mode_value;
+ ++i;
+ }
+ }
+
+ // also skip the text before
+ if (opt->text_before)
+ ++i;
+
+ index << i++;
+
+ init_args_info_gen.set_var_arg(opt->var_arg);
+ init_args_info_gen.set_num(index.str());
+
+ if (opt->multiple) {
+ init_args_info_gen.set_multiple(true);
+ init_args_info_gen.set_min(opt->multiple_min);
+ init_args_info_gen.set_max(opt->multiple_max);
+ } else {
+ init_args_info_gen.set_multiple(false);
+ }
+
+ init_args_info_gen.generate_init_args_info(stream, indent);
+
+ // skip the details
+ if (opt->details)
+ ++i;
+
+ // skip the text after
+ if (opt->text_after)
+ ++i;
+
+ }
+}
+
+void CmdlineParserCreator::generate_custom_getopt(ostream &stream, unsigned int indent)
+{
+ custom_getopt_gen_gen_class custom_getopt;
+
+ custom_getopt.generate_custom_getopt_gen (stream, indent);
+}
+
+const string
+CmdlineParserCreator::generate_purpose()
+{
+ string wrapped_purpose;
+
+ if (gengetopt_purpose != NULL)
+ {
+ wrap_cstr(wrapped_purpose, 0, 0, gengetopt_purpose);
+ }
+
+ return wrapped_purpose;
+}
+
+const string
+CmdlineParserCreator::generate_description()
+{
+ string wrapped_description;
+
+ if (gengetopt_description != NULL)
+ {
+ wrap_cstr(wrapped_description, 0, 0, gengetopt_description);
+ }
+
+ return wrapped_description;
+}
+
+
+OptionHelpList *
+CmdlineParserCreator::generate_help_option_list(bool generate_hidden, bool generate_details)
+{
+ OptionHelpList *option_list = new OptionHelpList;
+
+ unsigned long desc_col;
+ struct gengetopt_option * opt;
+
+ int type_len;
+ const char *type_str;
+ ostringstream stream;
+
+ // if we want to generate details then we will also generate hidden options
+ if (generate_details)
+ generate_hidden = true;
+
+ /* calculate columns */
+ desc_col = 0;
+ foropt {
+ // if (opt->hidden && !generate_hidden)
+ // continue;
+ // when computing columns, we also consider hidden_options, so that
+ // the --help and --full-help will be aligned just the same
+ // IMPORTANT: this is also crucial due to how the help string array
+ // is built starting from the full-help string array:
+ // we iterate over the two lists of options and check whether the
+ // corresponding strings are the same; thus, the help strings must
+ // have the same space alignments, otherwise they're not equal
+
+ unsigned int width = 2 + 4 + 2; // ws + "-a, " + ws
+
+ width += strlen (opt->long_opt) + 2; // "--"
+
+ if ((opt->type != ARG_FLAG) &&
+ (opt->type != ARG_NO))
+ {
+ if (opt->type_str)
+ type_str = opt->type_str;
+ else
+ type_str = arg_names[opt->type];
+ type_len = strlen(type_str);
+
+ width += type_len + 1; // "="
+
+ if (opt->arg_is_optional)
+ width += 2; // "[" and "]"
+ }
+
+ if (width > desc_col)
+ desc_col = width;
+ }
+
+ if (desc_col > MAX_STARTING_COLUMN)
+ desc_col = MAX_STARTING_COLUMN;
+
+ /* print justified options */
+ char *prev_group = 0;
+ char *prev_mode = 0;
+ char *curr_section = 0;
+ bool first_option = true;
+
+ foropt
+ {
+ // if the option is hidden, avoid to print a section containing only
+ // hidden options
+ if (opt->section &&
+ (!curr_section || strcmp (curr_section, opt->section)) &&
+ (!opt->hidden || generate_hidden))
+ {
+ curr_section = opt->section;
+
+ ostringstream sec_string;
+
+ if (! first_option)
+ sec_string << "\\n";
+
+ sec_string << opt->section << ":" ;
+
+ string wrapped_def;
+ wrap_cstr(wrapped_def, 0, 0, sec_string.str());
+ option_list->push_back(wrapped_def);
+
+ if (opt->section_desc)
+ {
+ string wrapped_desc ( 2, ' ');
+ wrap_cstr ( wrapped_desc, 2, 0, opt->section_desc );
+
+ option_list->push_back(wrapped_desc);
+ }
+ }
+
+ if (opt->group_value &&
+ (! prev_group || strcmp (opt->group_value, prev_group) != 0))
+ {
+ string group_string = "\\n Group: ";
+ string wrapped_desc;
+
+ if (opt->group_desc && strlen (opt->group_desc))
+ {
+ wrapped_desc = "\\n ";
+ wrap_cstr (wrapped_desc, 2, 0, opt->group_desc);
+ }
+
+ group_string += opt->group_value + wrapped_desc;
+
+ option_list->push_back (group_string);
+
+ prev_group = opt->group_value;
+ }
+
+ if (opt->mode_value &&
+ (! prev_mode || strcmp (opt->mode_value, prev_mode) != 0))
+ {
+ string mode_string = "\\n Mode: ";
+ string wrapped_desc;
+
+ if (opt->mode_desc && strlen (opt->mode_desc))
+ {
+ wrapped_desc = "\\n ";
+ wrap_cstr (wrapped_desc, 2, 0, opt->mode_desc);
+ }
+
+ mode_string += opt->mode_value + wrapped_desc;
+
+ option_list->push_back (mode_string);
+
+ prev_mode = opt->mode_value;
+ }
+
+ // a possible description to be printed before this option
+ if (opt->text_before)
+ {
+ string wrapped_desc;
+ wrap_cstr ( wrapped_desc, 0, 0, opt->text_before);
+
+ option_list->push_back(wrapped_desc);
+ }
+
+ if (!opt->hidden || generate_hidden) {
+ first_option = false;
+ const char * def_val = NULL;
+ string def_str = "`";
+
+ ostringstream option_stream;
+
+ if (opt->type == ARG_FLAG || opt->type == ARG_NO)
+ {
+ def_val = NULL;
+
+ if (opt->short_opt)
+ option_stream << " -" << opt->short_opt << ", ";
+ else
+ option_stream << " ";
+
+ option_stream << "--" << opt->long_opt;
+
+ if (opt->type == ARG_FLAG)
+ def_val = opt->flagstat ? "on" : "off";
+ }
+ else
+ {
+ def_val = NULL;
+
+ if (opt->type_str)
+ type_str = opt->type_str;
+ else
+ type_str = arg_names[opt->type];
+
+ type_len = strlen(type_str);
+
+ if (opt->short_opt)
+ {
+ option_stream << " -" << opt->short_opt << ", ";
+ }
+ else
+ {
+ option_stream << " ";
+ }
+
+ bool arg_optional = opt->arg_is_optional;
+ option_stream << "--" << opt->long_opt
+ << (arg_optional ? "[" : "")
+ << "=" << type_str
+ << (arg_optional ? "]" : "");
+
+ if (opt->default_string)
+ {
+ def_str += opt->default_string;
+ def_str += "'";
+ def_val = def_str.c_str();
+ }
+ }
+
+ const string &option_string = option_stream.str();
+ stream << option_string;
+ const char *opt_desc = opt->desc;
+
+ if ((option_string.size() >= MAX_STARTING_COLUMN) ||
+ (desc_col <= option_string.size()))
+ {
+ string indent (MAX_STARTING_COLUMN, ' ');
+ stream << "\\n" << indent;
+ }
+ else
+ {
+ string indent (desc_col - option_string.size(), ' ');
+ stream << indent;
+ }
+
+ generate_help_desc_print(stream, desc_col, opt_desc, def_val,
+ (opt->acceptedvalues ? opt->acceptedvalues->toString() : ""),
+ (opt->required && show_required_string != "" ? show_required_string : ""));
+
+ option_list->push_back(stream.str());
+ stream.str("");
+ }
+
+ // before the text after we generate details if we need to
+ if (opt->details && generate_details) {
+ string wrapped_desc ( 2, ' ');
+ // details are indented
+ wrap_cstr ( wrapped_desc, 2, 0, opt->details);
+
+ option_list->push_back(wrapped_desc);
+ }
+
+ // a possible description to be printed after this option
+ if (opt->text_after)
+ {
+ string wrapped_desc;
+ wrap_cstr ( wrapped_desc, 0, 0, opt->text_after);
+
+ option_list->push_back(wrapped_desc);
+ }
+ }
+
+ return option_list;
+}
+
+template <typename Collection>
+void generate_counter_init(const Collection &collection, const string &name, ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ typename Collection::const_iterator end = collection.end();
+
+ for ( typename Collection::const_iterator idx = collection.begin(); idx != end; ++idx)
+ {
+ stream << indent_str;
+ stream << ARGS_STRUCT << "->" << canonize_name (idx->first) << "_" <<
+ name << "_counter = 0 ;";
+ stream << endl;
+ }
+}
+
+void
+CmdlineParserCreator::generate_given_init(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ string indent_str (indent, ' ');
+ clear_given_gen_class clear_given;
+ clear_given.set_arg_struct(ARGS_STRUCT);
+
+ /* now we initialize "given" fields */
+ foropt
+ {
+ stream << indent_str;
+ clear_given.set_var_arg(opt->var_arg);
+ clear_given.set_group(opt->multiple && opt->group_value);
+ clear_given.generate_clear_given(stream);
+ }
+
+ // for group counter initialization
+ generate_counter_init(gengetopt_groups, "group", stream, indent);
+
+ // for mode counter initialization
+ generate_counter_init(gengetopt_modes, "mode", stream, indent);
+}
+
+void
+CmdlineParserCreator::generate_reset_groups(ostream &stream, unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ string indent_str (indent, ' ');
+ ostringstream body;
+ reset_group_gen_class reset_group;
+ clear_given_gen_class clear_given;
+ clear_given.set_arg_struct(ARGS_STRUCT);
+
+ reset_group.set_args_info (c_source_gen_class::args_info);
+
+ groups_collection_t::const_iterator end = gengetopt_groups.end();
+ for ( groups_collection_t::const_iterator idx = gengetopt_groups.begin();
+ idx != end; ++idx)
+ {
+ body.str ("");
+ bool found_option = false;
+ bool multiple_arg = false;
+
+ foropt
+ {
+ if (opt->group_value && strcmp(opt->group_value, idx->first.c_str()) == 0)
+ {
+ /* now we reset "given" fields */
+ stream << indent_str;
+ clear_given.set_var_arg(opt->var_arg);
+ if (opt->multiple && opt->group_value)
+ multiple_arg = true;
+ clear_given.set_group(opt->multiple && opt->group_value);
+ clear_given.generate_clear_given(body);
+
+ free_option (opt, body, indent);
+ found_option = true;
+ }
+ }
+
+ if (found_option)
+ {
+ reset_group.set_name (canonize_name (idx->first));
+ reset_group.set_body (body.str ());
+ reset_group.generate_reset_group (stream);
+ }
+ }
+}
+
+void
+CmdlineParserCreator::free_option(struct gengetopt_option *opt,
+ ostream &stream, unsigned int indent)
+{
+ if (opt->type == ARG_NO)
+ return;
+
+ if (opt->type != ARG_FLAG)
+ {
+ if (opt->multiple)
+ {
+ free_multiple_gen_class free_multiple;
+ free_multiple.set_has_string_type(opt->type == ARG_STRING);
+ free_multiple.set_structure (ARGS_STRUCT);
+
+ free_multiple.set_opt_var (opt->var_arg);
+ free_multiple.generate_free_multiple
+ (stream, indent);
+ }
+ else
+ {
+ free_string_gen_class free_string;
+ free_string.set_has_string_type(opt->type == ARG_STRING);
+ free_string.set_structure (ARGS_STRUCT);
+
+ free_string.set_opt_var (opt->var_arg);
+ free_string.generate_free_string (stream, indent);
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_list_def(ostream &stream, unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ string indent_str (indent, ' ');
+ multiple_opt_list_gen_class multiple_opt_list;
+
+ /* define linked-list structs for multiple options */
+ foropt
+ {
+ if (opt->multiple)
+ {
+ if (opt->type)
+ {
+ stream << indent_str;
+ multiple_opt_list.set_arg_name (opt->var_arg);
+ multiple_opt_list.generate_multiple_opt_list (stream, indent);
+ stream << endl;
+ }
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_multiple_fill_array(ostream &stream, unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ string indent_str (indent, ' ');
+ multiple_fill_array_gen_class filler;
+
+ /* copy linked list into the array */
+ foropt
+ {
+ if (opt->multiple && opt->type)
+ {
+ stream << indent_str;
+ filler.set_option_var_name (opt->var_arg);
+ filler.set_arg_type(arg_type_constants[opt->type]);
+ filler.set_type (arg_types_names[opt->type]);
+ string default_string = "0";
+ if (opt->default_string) {
+ if (opt->type == ARG_STRING)
+ default_string = string("\"") + opt->default_string + "\"";
+ else if (opt->type == ARG_ENUM)
+ default_string = from_value_to_enum(opt->var_arg, opt->default_string);
+ else
+ default_string = opt->default_string;
+ }
+ filler.set_default_value (default_string);
+
+ filler.generate_multiple_fill_array (stream, indent);
+
+ stream << endl;
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_update_multiple_given(ostream &stream, unsigned int indent)
+{
+ if (! has_multiple_options())
+ return;
+
+ string indent_str (indent, ' ');
+
+ stream << endl;
+ stream << indent_str;
+
+ update_given_gen_class update_given_gen;
+ struct gengetopt_option * opt;
+
+ foropt
+ {
+ if (opt->multiple)
+ {
+ update_given_gen.set_option_var_name (opt->var_arg);
+ update_given_gen.generate_update_given (stream, indent);
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_check_modes(ostream &stream, unsigned int indent)
+{
+ // no need to check for conflict if there's only one mode
+ if (gengetopt_modes.size() < 2)
+ return;
+
+ string indent_str (indent, ' ');
+
+ stream << endl;
+ stream << indent_str;
+
+ const ModeOptionMap &modeOptionMap = getModeOptionMap();
+
+ check_modes_gen_class check_modes_gen;
+
+ // now we check each mode options against every other mode options:
+ // the first one with the other n-1, the second one with the other n-2, etc.
+ ModeOptionMap::const_iterator map_it1, map_it2;
+ for (ModeOptionMap::const_iterator map_it = modeOptionMap.begin(); map_it != modeOptionMap.end(); ++map_it) {
+ map_it1 = map_it;
+ ++map_it;
+ if (map_it == modeOptionMap.end())
+ break;
+ for (map_it2 = map_it; map_it2 != modeOptionMap.end(); ++map_it2) {
+ const string mode1 = canonize_name(map_it1->first);
+ const string mode2 = canonize_name(map_it2->first);
+
+ check_modes_gen.set_mode1_name(mode1);
+ check_modes_gen.set_mode2_name(mode2);
+
+ ostringstream mode1_given, mode2_given, mode1_options, mode2_options;
+
+ std::for_each(map_it1->second.begin(), map_it1->second.end(), pair_print_f<OptionValueElem>(mode1_given, mode1_options));
+ std::for_each(map_it2->second.begin(), map_it2->second.end(), pair_print_f<OptionValueElem>(mode2_given, mode2_options));
+
+ check_modes_gen.set_mode1_given_fields(mode1_given.str());
+ check_modes_gen.set_mode1_options(mode1_options.str());
+ check_modes_gen.set_mode2_given_fields(mode2_given.str());
+ check_modes_gen.set_mode2_options(mode2_options.str());
+
+ check_modes_gen.generate_check_modes(stream, indent);
+ }
+ map_it = map_it1;
+ }
+}
+
+void
+CmdlineParserCreator::generate_clear_arg(ostream &stream, unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ clear_arg_gen_class clear_arg;
+
+ /* now we initialize value fields */
+ foropt
+ {
+ if (opt->type == ARG_NO)
+ continue;
+
+ clear_arg.set_name(opt->var_arg);
+ clear_arg.set_suffix("arg");
+ clear_arg.set_value("NULL");
+ clear_arg.set_has_orig(opt->type != ARG_FLAG);
+ clear_arg.set_has_arg(false);
+
+ if (opt->multiple && opt->type)
+ {
+ clear_arg.set_has_arg(true);
+ }
+ else if (opt->type == ARG_STRING)
+ {
+ clear_arg.set_has_arg(true);
+ if (opt->default_given)
+ clear_arg.set_value
+ ("gengetopt_strdup (\"" + string(opt->default_string) +
+ "\")");
+ }
+ else if (opt->type == ARG_FLAG)
+ {
+ clear_arg.set_has_arg(true);
+ clear_arg.set_suffix("flag");
+ clear_arg.set_value(opt->flagstat ? "1" : "0");
+ }
+ else if (opt->type == ARG_ENUM)
+ {
+ // initialize enum arguments to -1 (unless they have a default)
+ clear_arg.set_has_arg(true);
+ if (opt->default_given)
+ clear_arg.set_value(from_value_to_enum(opt->var_arg, opt->default_string));
+ else
+ clear_arg.set_value(string(opt->var_arg) + "__NULL");
+ }
+ else if (opt->default_given)
+ {
+ clear_arg.set_has_arg(true);
+ clear_arg.set_value(opt->default_string);
+ }
+
+ clear_arg.generate_clear_arg(stream, indent);
+ }
+}
+
+void
+CmdlineParserCreator::generate_long_option_struct(ostream &stream,
+ unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ struct gengetopt_option * opt;
+
+ foropt
+ {
+ stream << indent_str;
+
+ stream << "{ \"" << opt->long_opt << "\",\t"
+ << (opt->type == ARG_NO || opt->type == ARG_FLAG ? 0 :
+ (opt->arg_is_optional ? 2 : 1))
+ << ", NULL, ";
+
+ if (opt->short_opt)
+ stream << "\'" << opt->short_opt << "\'";
+ else
+ stream << "0";
+
+ stream << " }," << endl;
+ }
+}
+
+string
+CmdlineParserCreator::generate_getopt_string()
+{
+ struct gengetopt_option * opt;
+ ostringstream built_getopt_string;
+
+ foropt
+ if (opt->short_opt)
+ {
+ built_getopt_string << opt->short_opt <<
+ (opt->type == ARG_NO || opt->type == ARG_FLAG ? "" : ":");
+ built_getopt_string <<
+ (opt->arg_is_optional ? ":" : "");
+ }
+
+ return built_getopt_string.str ();
+}
+
+void
+CmdlineParserCreator::generate_handle_no_short_option(ostream &stream,
+ unsigned int indent)
+{
+ handle_options(stream, indent, false);
+}
+
+void
+CmdlineParserCreator::generate_handle_option(ostream &stream,
+ unsigned int indent)
+{
+ handle_options(stream, indent, true);
+}
+
+void
+CmdlineParserCreator::handle_options(ostream &stream, unsigned int indent, bool has_short)
+{
+ struct gengetopt_option * opt;
+ generic_option_gen_class option_gen;
+ string indent_str (indent, ' ');
+ bool first = true;
+
+ option_gen.set_has_short_option (has_short);
+
+ // by default we handle '?' case in the switch
+ // unless the user defined a short option as ?
+ set_handle_question_mark(true);
+
+ foropt
+ {
+ if (opt->short_opt == '?')
+ set_handle_question_mark(false);
+
+ if ((has_short && opt->short_opt) || (!has_short && !opt->short_opt))
+ {
+ if (has_short || first)
+ stream << indent_str;
+
+ option_gen.set_option_comment (opt->desc);
+ option_gen.set_long_option (opt->long_opt);
+ option_gen.set_short_option(opt->short_opt ? string (1, opt->short_opt) : "-");
+ option_gen.set_option_var_name (opt->var_arg);
+ option_gen.set_final_instructions("");
+
+ if (!no_help && ((opt->short_opt == HELP_SHORT_OPT &&
+ strcmp(opt->long_opt, HELP_LONG_OPT) == 0)
+ || strcmp(opt->long_opt, HELP_LONG_OPT) == 0
+ || strcmp(opt->long_opt, FULL_HELP_LONG_OPT) == 0
+ || strcmp(opt->long_opt, DETAILED_HELP_LONG_OPT) == 0)) {
+ bool full_help = (strcmp(opt->long_opt, FULL_HELP_LONG_OPT) == 0);
+ bool detailed_help = (strcmp(opt->long_opt, DETAILED_HELP_LONG_OPT) == 0);
+ if (no_handle_help) {
+ // we use the final_instructions parameter to call the free function
+ // and to return 0
+ const string final_instructions =
+ parser_function_name +
+ string("_free (&local_args_info);\nreturn 0;");
+
+ option_gen.set_final_instructions(final_instructions);
+
+ if (full_help) {
+ option_gen.set_long_option (FULL_HELP_LONG_OPT);
+ option_gen.set_option_comment (FULL_HELP_OPT_DESCR);
+ } else if (detailed_help) {
+ option_gen.set_long_option (DETAILED_HELP_LONG_OPT);
+ option_gen.set_option_comment (DETAILED_HELP_OPT_DESCR);
+ } else {
+ option_gen.set_long_option (HELP_LONG_OPT);
+ option_gen.set_short_option (HELP_SHORT_OPT_STR);
+ option_gen.set_option_comment (HELP_OPT_DESCR);
+ }
+ //option_gen.set_has_short_option (!full_help);
+ } else {
+ handle_help_gen_class help_gen;
+ help_gen.set_parser_name (parser_function_name);
+ help_gen.set_full_help(full_help);
+ help_gen.set_detailed_help(detailed_help);
+ help_gen.set_short_opt(opt->short_opt == HELP_SHORT_OPT);
+ help_gen.generate_handle_help (stream, indent);
+ stream << endl;
+ stream << endl;
+ continue;
+ }
+ }
+
+ if (!no_version && ((opt->short_opt == VERSION_SHORT_OPT && strcmp(opt->long_opt, VERSION_LONG_OPT) == 0)
+ || strcmp(opt->long_opt, VERSION_LONG_OPT) == 0)) {
+ if (no_handle_version) {
+ option_gen.set_long_option (VERSION_LONG_OPT);
+ option_gen.set_short_option (VERSION_SHORT_OPT_STR);
+ option_gen.set_option_comment (VERSION_OPT_DESCR);
+ //option_gen.set_has_short_option (true);
+
+ // we use the final_instrauctions parameter to call the free function
+ // and to return 0
+ const string final_instructions =
+ parser_function_name +
+ string("_free (&local_args_info);\nreturn 0;");
+
+ option_gen.set_final_instructions(final_instructions);
+ } else {
+ handle_version_gen_class version_gen;
+ version_gen.set_parser_name (parser_function_name);
+ version_gen.set_short_opt (opt->short_opt == VERSION_SHORT_OPT);
+ version_gen.generate_handle_version (stream, indent);
+ stream << endl;
+ stream << endl;
+ continue;
+ }
+ }
+
+ if (opt->acceptedvalues != 0)
+ option_gen.set_possible_values (OPTION_VALUES_NAME(opt->var_arg));
+ else
+ option_gen.set_possible_values ("0");
+
+ string default_string = "0";
+ if (opt->default_string)
+ default_string = string("\"") + opt->default_string + "\"";
+ option_gen.set_default_value (default_string);
+
+ option_gen.set_arg_type(arg_type_constants[opt->type]);
+
+ if (opt->group_value) {
+ option_gen.set_group_var_name (canonize_name (opt->group_value));
+ option_gen.set_option_has_group(true);
+ } else
+ option_gen.set_option_has_group(false);
+
+ if (opt->mode_value) {
+ // we reuse the variable group_var_name also for modes
+ option_gen.set_group_var_name (canonize_name (opt->mode_value));
+ option_gen.set_option_has_mode(true);
+ } else
+ option_gen.set_option_has_mode(false);
+
+ option_gen.set_option_has_type(opt->type != 0);
+
+ if (opt->multiple) {
+ option_gen.set_multiple(true);
+ option_gen.set_structure (string (opt->var_arg) + "_list");
+ } else {
+ option_gen.set_multiple(false);
+ option_gen.set_structure (ARGS_STRUCT);
+ }
+
+ option_gen.generate_generic_option (stream, indent);
+
+ if (has_short)
+ {
+ stream << endl;
+ }
+
+ if (first && !has_short)
+ {
+ first = false;
+ option_gen.set_gen_else ("else ");
+ }
+ }
+ }
+
+ if (! first && !has_short) // something has been generated
+ {
+ generateBreak(stream, indent);
+ stream << endl;
+ }
+}
+
+#define GROUP_REQUIRED_COMPARISON "!="
+#define GROUP_NOT_REQUIRED_COMPARISON ">"
+#define GROUP_REQUIRED_MESSAGE "One"
+#define GROUP_NOT_REQUIRED_MESSAGE "At most one"
+
+void
+CmdlineParserCreator::generate_handle_group(ostream &stream,
+ unsigned int indent)
+{
+ group_option_gen_class opt_gen;
+ string indent_str (indent, ' ');
+ opt_gen.set_package_var_name (EXE_NAME);
+
+ opt_gen.set_Comparison_rule(GROUP_NOT_REQUIRED_COMPARISON " 1");
+
+ groups_collection_t::const_iterator end = gengetopt_groups.end();
+ for ( groups_collection_t::const_iterator idx = gengetopt_groups.begin();
+ idx != end; ++idx)
+ {
+ stream << indent_str;
+ opt_gen.set_group_name (idx->first);
+ opt_gen.set_group_var_name (canonize_name (idx->first));
+ if (idx->second.required)
+ {
+ opt_gen.set_number_required(GROUP_REQUIRED_MESSAGE);
+ }
+ else
+ {
+ opt_gen.set_number_required(GROUP_NOT_REQUIRED_MESSAGE);
+ }
+
+ opt_gen.generate_group_option (stream, indent);
+ stream << endl;
+ }
+}
+
+void
+CmdlineParserCreator::generate_handle_required(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ required_option_gen_class opt_gen;
+ opt_gen.set_package_var_name ("prog_name");
+
+ /* write test for required options or for multiple options
+ (occurrence number check) */
+ foropt
+ if ( opt->required || opt->multiple )
+ {
+ if (opt->mode_value) {
+ opt_gen.set_mode_condition("args_info->" +
+ canonize_name(opt->mode_value) + "_mode_counter && ");
+ } else {
+ opt_gen.set_mode_condition("");
+ }
+
+ // build the option command line representation
+ ostringstream req_opt;
+ req_opt << "'--" << opt->long_opt << "'";
+ if (opt->short_opt)
+ req_opt << " ('-" << opt->short_opt << "')";
+
+ opt_gen.set_option_var_name (opt->var_arg);
+ opt_gen.set_option_descr (req_opt.str ());
+
+ // if the option is required this is the standard check
+ if (opt->required) {
+ opt_gen.set_checkrange(false);
+
+ opt_gen.generate_required_option (stream, indent);
+ }
+
+ // if the option is multiple we generate also the
+ // occurrence range check
+ if (opt->multiple) {
+ opt_gen.set_checkrange(true);
+
+ opt_gen.generate_required_option (stream, indent);
+ }
+
+ // notice that the above ifs are not mutual exclusive:
+ // a multiple option can have a range check without being
+ // required.
+ }
+
+ // now generate the checks for required group options
+ group_option_gen_class group_opt_gen;
+ group_opt_gen.set_package_var_name ("prog_name");
+
+ group_opt_gen.set_Comparison_rule("== 0");
+ group_opt_gen.set_number_required(GROUP_REQUIRED_MESSAGE);
+
+ groups_collection_t::const_iterator end = gengetopt_groups.end();
+ for ( groups_collection_t::const_iterator idx = gengetopt_groups.begin();
+ idx != end; ++idx)
+ {
+ if (idx->second.required)
+ {
+ group_opt_gen.set_group_name (idx->first);
+ group_opt_gen.set_group_var_name (canonize_name (idx->first));
+
+ group_opt_gen.generate_group_option (stream, indent);
+ stream << endl;
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_handle_dependencies(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+ dependant_option_gen_class opt_gen;
+ opt_gen.set_package_var_name ("prog_name");
+ string indent_str (indent, ' ');
+
+ /* write test for required options */
+ foropt
+ if ( opt->dependon )
+ {
+ stream << indent_str;
+
+ ostringstream req_opt;
+ req_opt << "'--" << opt->long_opt << "'";
+ if (opt->short_opt)
+ req_opt << " ('-" << opt->short_opt << "')";
+
+ opt_gen.set_option_var_name (opt->var_arg);
+ opt_gen.set_dep_option (canonize_name(opt->dependon));
+ opt_gen.set_option_descr (req_opt.str ());
+ opt_gen.set_dep_option_descr (opt->dependon);
+
+ opt_gen.generate_dependant_option (stream, indent);
+
+ stream << endl;
+ }
+}
+
+template <typename Collection>
+void generate_counters(const Collection &collection, const string &name, ostream &stream, unsigned int indent)
+{
+ group_counter_gen_class counter_gen;
+ string indent_str (indent, ' ');
+
+ counter_gen.set_name(name);
+
+ typename Collection::const_iterator end = collection.end();
+ for ( typename Collection::const_iterator idx = collection.begin(); idx != end; ++idx) {
+ stream << indent_str;
+ counter_gen.set_group_name (canonize_name (idx->first));
+ counter_gen.generate_group_counter (stream, indent);
+ stream << endl;
+ }
+}
+
+void
+CmdlineParserCreator::generate_group_counters(ostream &stream,
+ unsigned int indent)
+{
+ generate_counters(gengetopt_groups, "group", stream, indent);
+}
+
+void
+CmdlineParserCreator::generate_mode_counters(ostream &stream,
+ unsigned int indent)
+{
+ // we can reuse group counter gen class also for modes
+ generate_counters(gengetopt_modes, "mode", stream, indent);
+}
+
+int
+CmdlineParserCreator::generate_source ()
+{
+ /* ****************************************************** */
+ /* ********************************************** C FILE */
+ /* ****************************************************** */
+
+ set_usage_string (generate_usage_string ());
+ set_getopt_string (generate_getopt_string ());
+
+ string output_source = c_filename;
+
+ if (src_output_dir.size())
+ output_source = src_output_dir + "/" + output_source;
+ else if (output_dir.size())
+ output_source = output_dir + "/" + output_source;
+
+ ofstream *output_file = open_fstream (output_source.c_str());
+ generate_c_source (*output_file);
+ output_file->close ();
+ delete output_file;
+
+ return 0;
+}
+
+void
+CmdlineParserCreator::generate_free(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+
+ foropt
+ {
+ free_option (opt, stream, indent);
+ }
+}
+
+void
+CmdlineParserCreator::generate_list_free(ostream &stream,
+ unsigned int indent)
+{
+ struct gengetopt_option * opt;
+
+ if (! has_multiple_options())
+ return;
+
+ free_list_gen_class free_list;
+
+ foropt
+ {
+ if (opt->multiple && opt->type) {
+ free_list.set_list_name(opt->var_arg);
+ free_list.set_string_list(opt->type == ARG_STRING);
+ free_list.generate_free_list(stream, indent);
+ }
+ }
+}
+
+void
+CmdlineParserCreator::generate_file_save_loop(ostream &stream, unsigned int indent)
+{
+ struct gengetopt_option * opt;
+
+ file_save_multiple_gen_class file_save_multiple;
+ file_save_gen_class file_save;
+
+ const string suffix = "_orig";
+ const string suffix_given = "_given";
+
+ foropt {
+ if (opt->multiple) {
+ file_save_multiple.set_has_arg(opt->type != ARG_NO);
+ file_save_multiple.set_opt_var(opt->var_arg);
+ file_save_multiple.set_opt_name(opt->long_opt);
+ file_save_multiple.set_values
+ ((opt->acceptedvalues ? OPTION_VALUES_NAME(opt->var_arg) : "0"));
+
+ file_save_multiple.generate_file_save_multiple(stream, indent);
+ } else {
+ file_save.set_opt_name(opt->long_opt);
+ file_save.set_given(opt->var_arg + suffix_given);
+ file_save.set_values
+ ((opt->acceptedvalues ? OPTION_VALUES_NAME(opt->var_arg) : "0"));
+
+ if (opt->type != ARG_NO && opt->type != ARG_FLAG) {
+ file_save.set_arg(opt->var_arg + suffix + (opt->multiple ? " [i]" : ""));
+ } else {
+ file_save.set_arg("");
+ }
+ file_save.generate_file_save(stream, indent);
+ }
+ }
+}
+
+
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GM_H
+#define _GM_H
+
+#include "skels/header.h"
+#include "skels/c_source.h"
+
+#include <list>
+#include <string>
+
+#define TAB_LEN 2
+
+struct gengetopt_option;
+
+typedef std::list<std::string> OptionHelpList;
+
+class CmdlineParserCreator : public header_gen_class, public c_source_gen_class
+{
+ protected:
+ char *parser_function_name;
+ char *filename;
+ char *args_info_name;
+ char *header_filename;
+ char *c_filename;
+ string output_dir;
+ string header_output_dir;
+ string src_output_dir;
+ string comment;
+ char *unamed_options;
+ string show_required_string;
+
+ bool long_help;
+ bool no_handle_help;
+ bool no_help;
+ bool no_handle_version;
+ bool no_version;
+ bool no_handle_error;
+ bool conf_parser;
+ bool string_parser;
+ bool gen_gengetopt_version;
+ bool gen_strdup;
+
+ unsigned int tab_indentation ; /* tab indentation level */
+
+ void inc_indent()
+ {
+ tab_indentation += TAB_LEN ;
+ }
+
+ void dec_indent()
+ {
+ tab_indentation -= TAB_LEN ;
+ }
+
+ void indent()
+ {
+ unsigned int i ;
+
+ for ( i = 1 ; i <= tab_indentation ; ++i )
+ printf (" ");
+ }
+
+ void free_option(struct gengetopt_option *opt,
+ ostream &stream, unsigned int indent);
+
+ int generate_header_file();
+ int generate_source();
+
+ string generate_getopt_string();
+
+ // to be implemented in header_gen_class
+ virtual void generate_enum_types(ostream &stream, unsigned int indent);
+ virtual void generate_option_arg(ostream &stream, unsigned int indent);
+ virtual void generate_option_given(ostream &stream, unsigned int indent);
+ virtual void generate_option_values_decl(ostream &stream, unsigned int indent);
+
+ // to be implemented in c_source_gen_class
+ virtual void generate_clear_arg(ostream &stream, unsigned int indent);
+ virtual void generate_given_init(ostream &stream, unsigned int indent);
+ virtual void generate_option_values(ostream &stream, unsigned int indent);
+
+ virtual void generate_handle_no_short_option(ostream &stream,
+ unsigned int indent);
+ virtual void generate_handle_option(ostream &stream, unsigned int indent);
+ virtual void generate_handle_required(ostream &stream, unsigned int indent);
+ virtual void generate_handle_dependencies(ostream &stream, unsigned int indent);
+ virtual void generate_handle_group(ostream &stream, unsigned int indent);
+ virtual void generate_group_counters(ostream &stream, unsigned int indent);
+ virtual void generate_mode_counters(ostream &stream, unsigned int indent);
+ virtual void generate_help_option_print(ostream &stream,
+ unsigned int indent);
+ virtual void generate_full_help_option_print(ostream &stream,
+ unsigned int indent);
+ virtual void generate_detailed_help_option_print(ostream &stream,
+ unsigned int indent);
+ virtual void generate_long_option_struct(ostream &stream,
+ unsigned int indent);
+ virtual void generate_reset_groups(ostream &stream, unsigned int indent);
+
+ virtual void generate_free(ostream &stream, unsigned int indent);
+ virtual void generate_list_free(ostream &stream, unsigned int indent);
+
+ virtual void generate_file_save_loop(ostream &stream, unsigned int indent);
+ virtual void generate_init_args_info(ostream &stream, unsigned int indent);
+
+ virtual void generate_custom_getopt(ostream &stream, unsigned int indent);
+
+ void generateBreak(ostream &stream, unsigned int indent = 0);
+
+ void handle_options(ostream &, unsigned int, bool has_short);
+
+ public:
+
+ CmdlineParserCreator (char *function_name, char *struct_name,
+ char *unamed_options,
+ char *filename, char *header_ext, char *c_ext,
+ bool long_help,
+ bool no_handle_help, bool no_help,
+ bool no_handle_version, bool no_version,
+ bool no_handle_error, bool conf_parser, bool string_parser,
+ bool gen_version, bool gen_getopt, bool no_options,
+ const string &comment,
+ const string &outdir,
+ const string &header_outdir,
+ const string &src_outdir,
+ const string &show_required);
+
+ int generate();
+
+ virtual void generate_list_def(ostream &stream, unsigned int indent);
+ virtual void generate_multiple_fill_array(ostream &stream, unsigned int indent);
+ virtual void generate_update_multiple_given(ostream &stream, unsigned int indent);
+ virtual void generate_check_modes(ostream &stream, unsigned int indent);
+
+ const string generate_purpose();
+ const string generate_description();
+ const string generate_usage_string(bool use_config_package = true);
+
+ /**
+ * generate a list of option descriptions that will be printed in the
+ * help output
+ *
+ * @param generate_hidden if true, include also the hidden options
+ * @param generate_details if true, include also the hidden options and
+ * details for options that have them.
+ */
+ OptionHelpList *generate_help_option_list(bool generate_hidden = false,
+ bool generate_details = false);
+
+ /**
+ * generate the sharing between a list of help string, using the
+ * complete_list as the list with all the strings (both for hidden
+ * options and details, e.g.) and the smaller_list as the list
+ * with less strings
+ *
+ * @param target_array the name of the array to copy to
+ * @param source_array the name of the array to copy from
+ */
+ void generate_help_option_print_from_lists(ostream &stream,
+ unsigned int indent, OptionHelpList *complete_list,
+ OptionHelpList *smaller_list, const std::string &target_array,
+ const std::string &source_array);
+
+ /**
+ * Sets the has_arg_XXX by inspecting all the options types
+ */
+ void set_has_arg_types();
+};
+
+#endif /* _GM_H */
--- /dev/null
+//
+// C++ Implementation: gm_utils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "gm_utils.h"
+#include "my_sstream.h"
+#include "ggo_options.h"
+#include "argsdef.h"
+#include "groups.h"
+
+extern groups_collection_t gengetopt_groups;
+
+char *
+canonize_names(const char *name) {
+ char *pvar;
+ char *p;
+
+ pvar = strdup(name);
+
+ for (p = pvar; *p; ++p)
+ if (*p == '.' || *p == '-')
+ *p = '_';
+
+ return pvar;
+}
+
+// remove the path from the file name
+const string strip_path(const string &s) {
+ string::size_type pos_of_sep;
+
+ pos_of_sep = s.rfind("/");
+ if (pos_of_sep == string::npos)
+ pos_of_sep = s.rfind("\\"); // try also with DOS path sep
+
+ if (pos_of_sep == string::npos)
+ return s; // no path
+
+ return s.substr(pos_of_sep + 1);
+}
+
+const string to_upper(const string &old) {
+ string upper = old;
+
+ for (string::iterator s = upper.begin(); s != upper.end(); ++s)
+ *s = toupper(*s);
+
+ return upper;
+}
+
+const string canonize_name(const string &old) {
+ string canonized = old;
+
+ for (string::iterator s = canonized.begin(); s != canonized.end(); ++s)
+ if (*s == '.' || *s == '-' || *s == ' ')
+ *s = '_';
+
+ return canonized;
+}
+
+const string canonize_enum(const string &old) {
+ string canonized;
+
+ for (string::const_iterator s = old.begin(); s != old.end(); ++s)
+ if (*s == '-')
+ canonized += "MINUS_";
+ else if (*s == '+')
+ canonized += "PLUS_";
+ else
+ canonized += *s;
+
+ return canonized;
+}
+
+bool has_multiple_options_all_string() {
+ if (!has_multiple_options())
+ return false;
+
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->multiple && (opt->type && opt->type != ARG_STRING))
+ return false;
+ }
+
+ return true;
+}
+
+bool has_multiple_options_string() {
+ if (!has_multiple_options())
+ return false;
+
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->multiple && opt->type == ARG_STRING)
+ return true;
+ }
+
+ return false;
+}
+
+bool has_multiple_options() {
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->multiple)
+ return true;
+ }
+
+ return false;
+}
+
+bool has_multiple_options_with_type() {
+ gengetopt_option * opt = 0;
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+ != gengetopt_options.end() && (opt = *it); ++it)
+ if (opt->multiple && opt->type)
+ return true;
+
+ return false;
+}
+
+bool has_multiple_options_with_default() {
+ gengetopt_option * opt = 0;
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+ != gengetopt_options.end() && (opt = *it); ++it)
+ if (opt->multiple && opt->default_given)
+ return true;
+
+ return false;
+}
+
+bool has_options_with_details() {
+ gengetopt_option * opt = 0;
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+ != gengetopt_options.end() && (opt = *it); ++it)
+ if (opt->details)
+ return true;
+
+ return false;
+}
+
+bool has_options_with_type() {
+ gengetopt_option * opt = 0;
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+ != gengetopt_options.end() && (opt = *it); ++it)
+ if (opt->type && opt->type != ARG_FLAG)
+ return true;
+
+ return false;
+}
+
+bool has_options_with_mode() {
+ gengetopt_option * opt = 0;
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+ != gengetopt_options.end() && (opt = *it); ++it)
+ if (opt->mode_value)
+ return true;
+
+ return false;
+}
+
+bool has_required() {
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->required)
+ return true;
+ }
+
+ groups_collection_t::const_iterator end = gengetopt_groups.end();
+ for (groups_collection_t::const_iterator idx = gengetopt_groups.begin(); idx
+ != end; ++idx) {
+ if (idx->second.required) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool has_dependencies() {
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->dependon)
+ return true;
+ }
+
+ return false;
+}
+
+bool has_options() {
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->short_opt) {
+ if (opt->short_opt != 'h' && opt->short_opt != 'V')
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool has_hidden_options() {
+ struct gengetopt_option * opt = 0;
+
+ foropt {
+ if (opt->hidden) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool has_values() {
+ struct gengetopt_option * opt = 0;
+
+ for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+ != gengetopt_options.end(); ++it) {
+ opt = *it;
+ if (opt->acceptedvalues) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int not_newlines(const string &buf, int &num_of_newlines) {
+ num_of_newlines = 0;
+ // searches for the first non newline char
+ string::size_type notnewline = buf.find_first_not_of("\r\n");
+
+ if (notnewline == string::npos) {
+ // a string made only of newlines
+ num_of_newlines = buf.size();
+ return num_of_newlines;
+ }
+
+ if (notnewline) {
+ // everything before the non newline char is a newline
+ num_of_newlines = notnewline;
+ return notnewline;
+ }
+
+ return 0;
+}
+
+void wrap_cstr(string& wrapped, unsigned int from_column,
+ unsigned int second_indent, const string &orig) {
+ int next_space = from_column;
+ string next_word;
+ const char * out_buf = orig.c_str();
+ ostringstream stream;
+ const unsigned int second_line_column = from_column + second_indent;
+ string indent(second_line_column, ' ');
+ int newline_chars = 0;
+ int num_of_newlines = 0;
+
+ while (*out_buf) {
+ // check for a new line
+ if (*out_buf) {
+ if ((newline_chars = not_newlines(out_buf, num_of_newlines))) {
+ for (int i = 1; i <= num_of_newlines; ++i)
+ stream << "\\n";
+
+ out_buf += newline_chars;
+
+ if (*out_buf) {
+ stream << indent;
+ next_space = second_line_column;
+ continue;
+ } else
+ break;
+ } else {
+ stream << *out_buf++;
+ next_space++;
+ }
+ }
+ // search next whitespace, i.e., next word
+ while ((*out_buf) && (*out_buf != ' ') &&
+ !not_newlines(out_buf, num_of_newlines)) {
+ next_word += *out_buf++;
+ next_space++;
+ }
+
+ // wrap line if it's too long
+ if (next_space > 79) {
+ stream << "\\n" << indent << next_word;
+ next_space = second_line_column + next_word.size();
+ } else
+ stream << next_word; // simply write word
+
+ next_word = "";
+ }
+
+ wrapped += stream.str();
+}
+
+bool is_numeric(const gengetopt_option *opt) {
+ switch (opt->type) {
+ case ARG_INT:
+ case ARG_SHORT:
+ case ARG_LONG:
+ case ARG_FLOAT:
+ case ARG_DOUBLE:
+ case ARG_LONGDOUBLE:
+ case ARG_LONGLONG:
+ return true;
+ default:
+ return false;
+ }
+}
--- /dev/null
+//
+// C++ Interface: gm_utils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef GM_UTILS_H
+#define GM_UTILS_H
+
+#include <string>
+#include <iostream>
+
+#include "ggos.h"
+
+using std::string;
+
+/**
+ * @param name
+ * @return a copy of the string passed after canonizing it (i.e. '-' and
+ * '.' are transformed in '_').
+ */
+char *canonize_names(const char * name);
+
+/**
+ * @param name
+ * @return a copy of the string passed after canonizing it (i.e. '-' and
+ * '.' are transformed in '_').
+ */
+const string canonize_name(const string &name);
+
+/**
+ * @param s the string representing an enum value
+ * @return a copy of the string passed after canonizing it (i.e. '-' and
+ * becomes _MINUS_, '+' becomes _PLUS_)
+ */
+const string canonize_enum(const string &s);
+
+const string strip_path(const string &);
+const string to_upper(const string &);
+
+/**
+ * All multiple options are of type string
+ * @return All multiple options are of type string
+ */
+bool has_multiple_options_all_string();
+
+/**
+ * Has multiple options and at least one is of type string
+ * @return Has multiple options and at least one is of type string
+ */
+bool has_multiple_options_string();
+
+/**
+ * Has multiple options and at least one has a default value
+ * @return Has multiple options and at least one has a default value
+ */
+bool has_multiple_options_with_default();
+
+bool has_multiple_options();
+bool has_multiple_options_with_type();
+bool has_required();
+bool has_dependencies();
+bool has_options_with_type();
+bool has_options_with_mode();
+bool has_options();
+bool has_hidden_options();
+bool has_options_with_details();
+bool has_values();
+
+/**
+ * Whether the specified option deals with number
+ *
+ * @param opt
+ * @return
+ */
+bool is_numeric(const gengetopt_option *opt);
+
+/**
+ * Performs word wrapping on the passed string (and return the result in the first
+ * parameter).
+ *
+ * @param wrapped the output parameter
+ * @param from_column the string start from this column
+ * @param second_indent an additional indentation for lines after the
+ * first one
+ * @param orig the original string that must be wrapped
+ */
+void wrap_cstr (string &wrapped, unsigned int from_column, unsigned int second_indent, const string &orig);
+
+/**
+ * Searches for characters which are not newlines.
+ *
+ * @param buf where to search for new characters
+ * @param num_of_newlines where the number of newlines
+ * before the first non newline char will be stored
+ * @return the position in the string after the (possible) new line char
+ */
+int not_newlines(const string &buf, int &num_of_newlines);
+
+/**
+ * Function object to print something into a stream (to be used with for_each)
+ */
+template<class T>
+struct print_f : public std::unary_function<T, void>
+{
+ print_f(std::ostream& out, const string &s = ", ") : os(out), sep(s) {}
+ void operator() (T x) { os << x << sep; }
+ std::ostream& os;
+ const string &sep;
+};
+
+/**
+ * Function object to print a pair into two streams (to be used with for_each)
+ */
+template<class T>
+struct pair_print_f : public std::unary_function<T, void>
+{
+ pair_print_f(std::ostream& out1, std::ostream& out2, const string &s = ", ") :
+ os1(out1), os2(out2), sep(s) {}
+ void operator() (T x) { os1 << x.first << sep; os2 << x.second << sep;}
+ std::ostream &os1, &os2;
+ const string &sep;
+};
+
+#endif
--- /dev/null
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
--- /dev/null
+/**
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GGO_GROUPS_H
+#define GGO_GROUPS_H
+
+#include "my_string.h"
+#include "my_map.h"
+
+/**
+ * Represents a group of options
+ */
+struct Group
+{
+ string desc;
+ bool required;
+
+ Group(const string &s, bool r) : desc (s), required (r) {}
+};
+
+typedef map<string,Group> groups_collection_t;
+
+/**
+ * Represents a mode of options
+ */
+struct Mode
+{
+ string desc;
+
+ Mode(const string &s) : desc (s) {}
+};
+
+typedef map<string,Mode> modes_collection_t;
+
+#endif // GROUPS_H
--- /dev/null
+/*
+ * Copyright (c) 1987, 1993, 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef _COMPILING_NEWLIB
+#include_next "getopt.h"
+#else
+#ifndef __GETOPT_H__
+#define __GETOPT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __INSIDE_CYGWIN__
+extern int __declspec(dllimport) opterr; /* if error message should be printed */
+extern int __declspec(dllimport) optind; /* index into parent argv vector */
+extern int __declspec(dllimport) optopt; /* character checked for validity */
+extern int __declspec(dllimport) optreset; /* reset getopt */
+extern char __declspec(dllimport) *optarg; /* argument associated with option */
+#endif
+
+int getopt (int, char * const *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GETOPT_H__ */
+
+#ifndef __UNISTD_GETOPT__
+#ifndef __GETOPT_LONG_H__
+#define __GETOPT_LONG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+int getopt_long (int, char *const *, const char *, const struct option *, int *);
+int getopt_long_only (int, char *const *, const char *, const struct option *, int *);
+
+#ifndef HAVE_DECL_GETOPT
+#define HAVE_DECL_GETOPT 1
+#endif
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GETOPT_LONG_H__ */
+#endif /* __UNISTD_GETOPT__ */
+#endif /*_INSIDE_NEWLIB*/
--- /dev/null
+// handle namespaces
+
+#ifndef _MY_MAP_H
+#define _MY_MAP_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <map>
+
+#ifdef HAVE_NAMESPACES
+using std::map;
+using std::make_pair;
+#endif
+
+#endif // _MY_MAP_H
--- /dev/null
+// deal with namespace problems
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#ifdef HAVE_SSTREAM
+#include <sstream>
+#else
+#include "includes/sstream"
+#endif
+
+#ifdef HAVE_NAMESPACES
+using std::ostringstream;
+#endif
--- /dev/null
+// deal with namespace problems
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <string>
+
+#ifdef HAVE_NAMESPACES
+using std::string;
+#endif
--- /dev/null
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.4.1"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+
+
+/* Copy the first part of user declarations. */
+
+/* Line 189 of yacc.c */
+#line 22 "../../src/parser.yy"
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <string>
+
+#include "my_sstream.h"
+
+#include "acceptedvalues.h"
+
+#include "argsdef.h"
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+#include "ggos.h"
+#include "yyerror.h"
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+static int gengetopt_package_given = 0;
+static int gengetopt_version_given = 0;
+static int gengetopt_purpose_given = 0;
+static int gengetopt_usage_given = 0;
+static int gengetopt_description_given = 0;
+
+/// the last option parsed
+static gengetopt_option *current_option = 0;
+
+extern int yylex (void) ;
+
+//#define YYERROR_VERBOSE 1
+
+void check_result(int o, gengetopt_option *opt)
+{
+ if (o)
+ {
+ ostringstream err;
+
+ switch (o)
+ {
+ case NOT_ENOUGH_MEMORY:
+ yyerror (opt, "not enough memory");
+ break;
+ case REQ_LONG_OPTION:
+ err << "long option redefined \'" << opt->long_opt << "\'";
+ yyerror (opt, err.str().c_str());
+ break;
+ case REQ_SHORT_OPTION:
+ err << "short option redefined \'" << opt->short_opt << "\'";
+ yyerror (opt, err.str().c_str());
+ break;
+ case FOUND_BUG:
+ yyerror (opt, "bug found!!");
+ break;
+ case GROUP_UNDEFINED:
+ yyerror (opt, "group undefined");
+ break;
+ case MODE_UNDEFINED:
+ yyerror (opt, "mode undefined");
+ break;
+ case INVALID_DEFAULT_VALUE:
+ yyerror (opt, "invalid default value");
+ break;
+ case NOT_REQUESTED_TYPE:
+ yyerror (opt, "type specification not requested");
+ break;
+ case NOT_VALID_SPECIFICATION:
+ yyerror (opt, "invalid specification for this kind of option");
+ break;
+ case SPECIFY_FLAG_STAT:
+ yyerror (opt, "you must specify the default flag status");
+ break;
+ case NOT_GROUP_OPTION:
+ yyerror (opt, "group specification for a non group option");
+ break;
+ case NOT_MODE_OPTION:
+ yyerror (opt, "mode specification for an option not belonging to a mode");
+ break;
+ case SPECIFY_GROUP:
+ yyerror (opt, "missing group specification");
+ break;
+ case SPECIFY_MODE:
+ yyerror (opt, "missing mode specification");
+ break;
+ case INVALID_NUMERIC_VALUE:
+ yyerror (opt, "invalid numeric value");
+ break;
+ case INVALID_ENUM_TYPE_USE:
+ yyerror (opt, "enum type can only be specified for options with values");
+ break;
+ case HELP_REDEFINED:
+ yyerror (opt, "if you want to redefine --help, please use option --no-help");
+ break;
+ case VERSION_REDEFINED:
+ yyerror (opt, "if you want to redefine --version, please use option --no-version");
+ break;
+ }
+ }
+}
+
+/* the number of allowed occurrences of a multiple option */
+struct multiple_size
+{
+ /* these strings are allocated dynamically and NOT
+ automatically freed upon destruction */
+ char *min;
+ char *max;
+
+ /* if no limit is specified then initialized to 0.
+ if the same size is specified for min and max, it means that an exact
+ number of occurrences is required*/
+ multiple_size(const char *m = "0", const char *M = "0") :
+ min(strdup(m)), max(strdup(M))
+ {}
+};
+
+#define check_error if (o) YYERROR;
+
+
+
+/* Line 189 of yacc.c */
+#line 200 "../../src/parser.cc"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ TOK_PACKAGE = 258,
+ TOK_VERSION = 259,
+ TOK_OPTION = 260,
+ TOK_DEFGROUP = 261,
+ TOK_GROUPOPTION = 262,
+ TOK_DEFMODE = 263,
+ TOK_MODEOPTION = 264,
+ TOK_YES = 265,
+ TOK_NO = 266,
+ TOK_ON = 267,
+ TOK_OFF = 268,
+ TOK_FLAG = 269,
+ TOK_PURPOSE = 270,
+ TOK_DESCRIPTION = 271,
+ TOK_USAGE = 272,
+ TOK_DEFAULT = 273,
+ TOK_GROUP = 274,
+ TOK_GROUPDESC = 275,
+ TOK_MODE = 276,
+ TOK_MODEDESC = 277,
+ TOK_MULTIPLE = 278,
+ TOK_ARGOPTIONAL = 279,
+ TOK_TYPESTR = 280,
+ TOK_SECTION = 281,
+ TOK_DETAILS = 282,
+ TOK_SECTIONDESC = 283,
+ TOK_TEXT = 284,
+ TOK_ARGS = 285,
+ TOK_VALUES = 286,
+ TOK_HIDDEN = 287,
+ TOK_DEPENDON = 288,
+ TOK_STRING = 289,
+ TOK_CHAR = 290,
+ TOK_ARGTYPE = 291,
+ TOK_SIZE = 292
+ };
+#endif
+/* Tokens. */
+#define TOK_PACKAGE 258
+#define TOK_VERSION 259
+#define TOK_OPTION 260
+#define TOK_DEFGROUP 261
+#define TOK_GROUPOPTION 262
+#define TOK_DEFMODE 263
+#define TOK_MODEOPTION 264
+#define TOK_YES 265
+#define TOK_NO 266
+#define TOK_ON 267
+#define TOK_OFF 268
+#define TOK_FLAG 269
+#define TOK_PURPOSE 270
+#define TOK_DESCRIPTION 271
+#define TOK_USAGE 272
+#define TOK_DEFAULT 273
+#define TOK_GROUP 274
+#define TOK_GROUPDESC 275
+#define TOK_MODE 276
+#define TOK_MODEDESC 277
+#define TOK_MULTIPLE 278
+#define TOK_ARGOPTIONAL 279
+#define TOK_TYPESTR 280
+#define TOK_SECTION 281
+#define TOK_DETAILS 282
+#define TOK_SECTIONDESC 283
+#define TOK_TEXT 284
+#define TOK_ARGS 285
+#define TOK_VALUES 286
+#define TOK_HIDDEN 287
+#define TOK_DEPENDON 288
+#define TOK_STRING 289
+#define TOK_CHAR 290
+#define TOK_ARGTYPE 291
+#define TOK_SIZE 292
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c */
+#line 148 "../../src/parser.yy"
+
+ char *str;
+ char chr;
+ int argtype;
+ int boolean;
+ class AcceptedValues *ValueList;
+ struct gengetopt_option *gengetopt_option;
+ struct multiple_size *multiple_size;
+
+
+
+/* Line 214 of yacc.c */
+#line 322 "../../src/parser.cc"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 264 of yacc.c */
+#line 347 "../../src/parser.cc"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 43
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 92
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 43
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 27
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 66
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 116
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 292
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 40, 41, 2, 2, 39, 42, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 38, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint8 yyprhs[] =
+{
+ 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
+ 19, 21, 23, 25, 27, 29, 31, 33, 36, 39,
+ 42, 45, 48, 52, 55, 58, 63, 67, 73, 79,
+ 85, 87, 90, 93, 98, 103, 108, 113, 118, 123,
+ 128, 131, 135, 138, 141, 144, 145, 147, 149, 150,
+ 152, 154, 156, 158, 159, 163, 164, 168, 169, 173,
+ 175, 179, 181, 182, 186, 191, 196
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
+{
+ 44, 0, -1, -1, 45, 44, -1, 46, -1, 47,
+ -1, 53, -1, 48, -1, 49, -1, 50, -1, 51,
+ -1, 56, -1, 52, -1, 57, -1, 54, -1, 58,
+ -1, 55, -1, 3, 34, -1, 4, 34, -1, 15,
+ 59, -1, 16, 59, -1, 17, 59, -1, 26, 59,
+ 66, -1, 29, 59, -1, 30, 34, -1, 6, 34,
+ 64, 62, -1, 8, 34, 65, -1, 5, 34, 35,
+ 59, 60, -1, 7, 34, 35, 59, 60, -1, 9,
+ 34, 35, 59, 60, -1, 34, -1, 60, 63, -1,
+ 60, 36, -1, 60, 25, 38, 34, -1, 60, 27,
+ 38, 59, -1, 60, 31, 38, 67, -1, 60, 18,
+ 38, 34, -1, 60, 19, 38, 34, -1, 60, 21,
+ 38, 34, -1, 60, 33, 38, 34, -1, 60, 24,
+ -1, 60, 23, 69, -1, 60, 14, -1, 60, 32,
+ -1, 60, 61, -1, -1, 12, -1, 13, -1, -1,
+ 10, -1, 11, -1, 10, -1, 11, -1, -1, 20,
+ 38, 34, -1, -1, 22, 38, 34, -1, -1, 28,
+ 38, 34, -1, 68, -1, 67, 39, 68, -1, 34,
+ -1, -1, 40, 37, 41, -1, 40, 37, 42, 41,
+ -1, 40, 42, 37, 41, -1, 40, 37, 42, 37,
+ 41, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 209, 209, 211, 216, 217, 218, 219, 220, 221,
+ 222, 223, 224, 225, 226, 227, 228, 233, 253, 273,
+ 293, 313, 334, 341, 358, 365, 376, 387, 407, 426,
+ 448, 451, 457, 462, 467, 472, 477, 482, 487, 492,
+ 497, 502, 510, 515, 520, 525, 529, 530, 534, 535,
+ 536, 540, 541, 545, 546, 550, 551, 555, 556, 560,
+ 561, 565, 569, 570, 571, 572, 573
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "\"package\"", "\"version\"",
+ "\"option\"", "\"defgroup\"", "\"groupoption\"", "\"defmode\"",
+ "\"modeoption\"", "\"yes\"", "\"no\"", "\"on\"", "\"off\"", "\"flag\"",
+ "\"purpose\"", "\"description\"", "\"usage\"", "\"default\"",
+ "\"group\"", "\"groupdesc\"", "\"mode\"", "\"modedesc\"", "\"multiple\"",
+ "\"argoptional\"", "\"typestr\"", "\"section\"", "\"details\"",
+ "\"sectiondesc\"", "\"text\"", "\"args\"", "\"values\"", "\"hidden\"",
+ "\"dependon\"", "TOK_STRING", "TOK_CHAR", "TOK_ARGTYPE", "TOK_SIZE",
+ "'='", "','", "'('", "')'", "'-'", "$accept", "input", "statement",
+ "package", "version", "purpose", "description", "usage", "sectiondef",
+ "text", "args", "groupdef", "modedef", "option", "groupoption",
+ "modeoption", "quoted_string", "option_parts", "req_onoff",
+ "optional_yesno", "opt_yesno", "opt_groupdesc", "opt_modedesc",
+ "opt_sectiondesc", "listofvalues", "acceptedvalue", "multiple_size", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 61, 44,
+ 40, 41, 45
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 43, 44, 44, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 61, 61, 62, 62,
+ 62, 63, 63, 64, 64, 65, 65, 66, 66, 67,
+ 67, 68, 69, 69, 69, 69, 69
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 2, 3, 2, 2, 4, 3, 5, 5, 5,
+ 1, 2, 2, 4, 4, 4, 4, 4, 4, 4,
+ 2, 3, 2, 2, 2, 0, 1, 1, 0, 1,
+ 1, 1, 1, 0, 3, 0, 3, 0, 3, 1,
+ 3, 1, 0, 3, 4, 4, 5
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 4, 5, 7, 8,
+ 9, 10, 12, 6, 14, 16, 11, 13, 15, 17,
+ 18, 0, 53, 0, 55, 0, 30, 19, 20, 21,
+ 57, 23, 24, 1, 3, 0, 0, 48, 0, 0,
+ 26, 0, 0, 22, 45, 0, 49, 50, 25, 45,
+ 0, 45, 0, 27, 54, 28, 56, 29, 58, 51,
+ 52, 46, 47, 42, 0, 0, 0, 62, 40, 0,
+ 0, 0, 43, 0, 32, 44, 31, 0, 0, 0,
+ 0, 41, 0, 0, 0, 0, 36, 37, 38, 0,
+ 0, 33, 34, 61, 35, 59, 39, 63, 0, 0,
+ 0, 0, 64, 65, 60, 66
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 37, 63, 85, 58,
+ 86, 47, 50, 53, 104, 105, 91
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -40
+static const yytype_int8 yypact[] =
+{
+ 1, -13, -8, -6, -5, -2, -1, 0, 3, 3,
+ 3, 3, 3, 4, 25, 1, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, 5, 15, 6, 26, 14, -40, -40, -40, -40,
+ 22, -40, -40, -40, -40, 3, 17, 2, 3, 21,
+ -40, 3, 23, -40, -40, 19, -40, -40, -40, -40,
+ 28, -40, 29, 33, -40, 33, -40, 33, -40, -40,
+ -40, -40, -40, -40, 30, 32, 34, 27, -40, 35,
+ 36, 37, -40, 38, -40, -40, -40, 43, 44, 45,
+ -23, -40, 46, 3, 47, 48, -40, -40, -40, -18,
+ 49, -40, -40, -40, 50, -40, -40, -40, -26, 42,
+ 47, 51, -40, -40, -40, -40
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -40, 56, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -9, -39, -40, -40,
+ -40, -40, -40, -40, -40, -25, -40
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+ 38, 39, 40, 41, 1, 2, 3, 4, 5, 6,
+ 7, 111, 56, 57, 99, 112, 8, 9, 10, 100,
+ 65, 29, 67, 107, 108, 43, 30, 11, 31, 32,
+ 12, 13, 33, 34, 35, 46, 54, 36, 42, 59,
+ 45, 48, 61, 69, 70, 71, 72, 73, 49, 51,
+ 52, 74, 75, 64, 76, 55, 77, 78, 79, 60,
+ 80, 62, 66, 68, 81, 82, 83, 90, 87, 84,
+ 88, 44, 89, 92, 93, 94, 95, 96, 97, 98,
+ 101, 103, 106, 113, 102, 114, 109, 0, 0, 110,
+ 0, 0, 115
+};
+
+static const yytype_int8 yycheck[] =
+{
+ 9, 10, 11, 12, 3, 4, 5, 6, 7, 8,
+ 9, 37, 10, 11, 37, 41, 15, 16, 17, 42,
+ 59, 34, 61, 41, 42, 0, 34, 26, 34, 34,
+ 29, 30, 34, 34, 34, 20, 45, 34, 34, 48,
+ 35, 35, 51, 10, 11, 12, 13, 14, 22, 35,
+ 28, 18, 19, 34, 21, 38, 23, 24, 25, 38,
+ 27, 38, 34, 34, 31, 32, 33, 40, 38, 36,
+ 38, 15, 38, 38, 38, 38, 38, 34, 34, 34,
+ 34, 34, 34, 41, 93, 110, 37, -1, -1, 39,
+ -1, -1, 41
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 4, 5, 6, 7, 8, 9, 15, 16,
+ 17, 26, 29, 30, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 34,
+ 34, 34, 34, 34, 34, 34, 34, 59, 59, 59,
+ 59, 59, 34, 0, 44, 35, 20, 64, 35, 22,
+ 65, 35, 28, 66, 59, 38, 10, 11, 62, 59,
+ 38, 59, 38, 60, 34, 60, 34, 60, 34, 10,
+ 11, 12, 13, 14, 18, 19, 21, 23, 24, 25,
+ 27, 31, 32, 33, 36, 61, 63, 38, 38, 38,
+ 40, 69, 38, 38, 38, 38, 34, 34, 34, 37,
+ 42, 34, 59, 34, 67, 68, 34, 41, 42, 37,
+ 39, 37, 41, 41, 68, 41
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+\f
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[2];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+
+#if YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 17:
+
+/* Line 1455 of yacc.c */
+#line 234 "../../src/parser.yy"
+ {
+ if (gengetopt_package_given)
+ {
+ yyerror ("package redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_package_given = 1;
+ if (gengetopt_define_package ((yyvsp[(2) - (2)].str)))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ break;
+
+ case 18:
+
+/* Line 1455 of yacc.c */
+#line 254 "../../src/parser.yy"
+ {
+ if (gengetopt_version_given)
+ {
+ yyerror ("version redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_version_given = 1;
+ if (gengetopt_define_version ((yyvsp[(2) - (2)].str)))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ break;
+
+ case 19:
+
+/* Line 1455 of yacc.c */
+#line 274 "../../src/parser.yy"
+ {
+ if (gengetopt_purpose_given)
+ {
+ yyerror ("purpose redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_purpose_given = 1;
+ if (gengetopt_define_purpose ((yyvsp[(2) - (2)].str)))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ break;
+
+ case 20:
+
+/* Line 1455 of yacc.c */
+#line 294 "../../src/parser.yy"
+ {
+ if (gengetopt_description_given)
+ {
+ yyerror ("description redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_description_given = 1;
+ if (gengetopt_define_description ((yyvsp[(2) - (2)].str)))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ break;
+
+ case 21:
+
+/* Line 1455 of yacc.c */
+#line 314 "../../src/parser.yy"
+ {
+ if (gengetopt_usage_given)
+ {
+ yyerror ("usage redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_usage_given = 1;
+ if (gengetopt_define_usage ((yyvsp[(2) - (2)].str)))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ break;
+
+ case 22:
+
+/* Line 1455 of yacc.c */
+#line 335 "../../src/parser.yy"
+ {
+ gengetopt_set_section ((yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str));
+ }
+ break;
+
+ case 23:
+
+/* Line 1455 of yacc.c */
+#line 342 "../../src/parser.yy"
+ {
+ if (current_option) {
+ std::string current_option_text;
+ if (current_option->text_after) {
+ current_option_text = std::string(current_option->text_after) + (yyvsp[(2) - (2)].str);
+ current_option->text_after = strdup(current_option_text.c_str());
+ } else {
+ current_option->text_after = strdup((yyvsp[(2) - (2)].str));
+ }
+ } else {
+ gengetopt_set_text((yyvsp[(2) - (2)].str));
+ }
+ }
+ break;
+
+ case 24:
+
+/* Line 1455 of yacc.c */
+#line 359 "../../src/parser.yy"
+ {
+ gengetopt_set_args((yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 25:
+
+/* Line 1455 of yacc.c */
+#line 366 "../../src/parser.yy"
+ {
+ if (gengetopt_add_group ((yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].str), (yyvsp[(4) - (4)].boolean)))
+ {
+ yyerror ("group redefined");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 26:
+
+/* Line 1455 of yacc.c */
+#line 377 "../../src/parser.yy"
+ {
+ if (gengetopt_add_mode ((yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str)))
+ {
+ yyerror ("mode redefined");
+ YYERROR;
+ }
+ }
+ break;
+
+ case 27:
+
+/* Line 1455 of yacc.c */
+#line 389 "../../src/parser.yy"
+ {
+ (yyvsp[(5) - (5)].gengetopt_option)->filename = gengetopt_input_filename;
+ (yyvsp[(5) - (5)].gengetopt_option)->linenum = (yylsp[(1) - (5)]).first_line;
+ (yyvsp[(5) - (5)].gengetopt_option)->long_opt = strdup((yyvsp[(2) - (5)].str));
+ if ((yyvsp[(3) - (5)].chr) != '-')
+ (yyvsp[(5) - (5)].gengetopt_option)->short_opt = (yyvsp[(3) - (5)].chr);
+ (yyvsp[(5) - (5)].gengetopt_option)->desc = strdup((yyvsp[(4) - (5)].str));
+ int o = gengetopt_check_option ((yyvsp[(5) - (5)].gengetopt_option), false);
+ check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+ check_error;
+ o = gengetopt_add_option ((yyvsp[(5) - (5)].gengetopt_option));
+ check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+ check_error;
+ current_option = (yyvsp[(5) - (5)].gengetopt_option);
+ }
+ break;
+
+ case 28:
+
+/* Line 1455 of yacc.c */
+#line 409 "../../src/parser.yy"
+ {
+ (yyvsp[(5) - (5)].gengetopt_option)->filename = gengetopt_input_filename;
+ (yyvsp[(5) - (5)].gengetopt_option)->linenum = (yylsp[(1) - (5)]).first_line;
+ (yyvsp[(5) - (5)].gengetopt_option)->long_opt = strdup((yyvsp[(2) - (5)].str));
+ if ((yyvsp[(3) - (5)].chr) != '-')
+ (yyvsp[(5) - (5)].gengetopt_option)->short_opt = (yyvsp[(3) - (5)].chr);
+ (yyvsp[(5) - (5)].gengetopt_option)->desc = strdup((yyvsp[(4) - (5)].str));
+ int o = gengetopt_check_option ((yyvsp[(5) - (5)].gengetopt_option), true);
+ check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+ check_error;
+ o = gengetopt_add_option ((yyvsp[(5) - (5)].gengetopt_option));
+ check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+ check_error;
+ }
+ break;
+
+ case 29:
+
+/* Line 1455 of yacc.c */
+#line 428 "../../src/parser.yy"
+ {
+ (yyvsp[(5) - (5)].gengetopt_option)->filename = gengetopt_input_filename;
+ (yyvsp[(5) - (5)].gengetopt_option)->linenum = (yylsp[(1) - (5)]).first_line;
+ (yyvsp[(5) - (5)].gengetopt_option)->long_opt = strdup((yyvsp[(2) - (5)].str));
+ if ((yyvsp[(3) - (5)].chr) != '-')
+ (yyvsp[(5) - (5)].gengetopt_option)->short_opt = (yyvsp[(3) - (5)].chr);
+ (yyvsp[(5) - (5)].gengetopt_option)->desc = strdup((yyvsp[(4) - (5)].str));
+ int o = gengetopt_check_option ((yyvsp[(5) - (5)].gengetopt_option), false, true);
+ check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+ check_error;
+ o = gengetopt_add_option ((yyvsp[(5) - (5)].gengetopt_option));
+ check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+ check_error;
+ }
+ break;
+
+ case 31:
+
+/* Line 1455 of yacc.c */
+#line 452 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+ (yyval.gengetopt_option)->required = (yyvsp[(2) - (2)].boolean);
+ (yyval.gengetopt_option)->required_set = true;
+ }
+ break;
+
+ case 32:
+
+/* Line 1455 of yacc.c */
+#line 458 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+ (yyval.gengetopt_option)->type = (yyvsp[(2) - (2)].argtype);
+ }
+ break;
+
+ case 33:
+
+/* Line 1455 of yacc.c */
+#line 463 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->type_str = strdup((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 34:
+
+/* Line 1455 of yacc.c */
+#line 468 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->details = strdup((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 35:
+
+/* Line 1455 of yacc.c */
+#line 473 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->acceptedvalues = (yyvsp[(4) - (4)].ValueList);
+ }
+ break;
+
+ case 36:
+
+/* Line 1455 of yacc.c */
+#line 478 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->default_string = strdup((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 37:
+
+/* Line 1455 of yacc.c */
+#line 483 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->group_value = strdup((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 38:
+
+/* Line 1455 of yacc.c */
+#line 488 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->mode_value = strdup((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 39:
+
+/* Line 1455 of yacc.c */
+#line 493 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+ (yyval.gengetopt_option)->dependon = strdup((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 40:
+
+/* Line 1455 of yacc.c */
+#line 498 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+ (yyval.gengetopt_option)->arg_is_optional = true;
+ }
+ break;
+
+ case 41:
+
+/* Line 1455 of yacc.c */
+#line 503 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (3)].gengetopt_option);
+ (yyval.gengetopt_option)->multiple = true;
+ (yyval.gengetopt_option)->multiple_min = (yyvsp[(3) - (3)].multiple_size)->min;
+ (yyval.gengetopt_option)->multiple_max = (yyvsp[(3) - (3)].multiple_size)->max;
+ delete (yyvsp[(3) - (3)].multiple_size);
+ }
+ break;
+
+ case 42:
+
+/* Line 1455 of yacc.c */
+#line 511 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+ (yyval.gengetopt_option)->type = ARG_FLAG;
+ }
+ break;
+
+ case 43:
+
+/* Line 1455 of yacc.c */
+#line 516 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+ (yyval.gengetopt_option)->hidden = true;
+ }
+ break;
+
+ case 44:
+
+/* Line 1455 of yacc.c */
+#line 521 "../../src/parser.yy"
+ {
+ (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+ (yyval.gengetopt_option)->flagstat = (yyvsp[(2) - (2)].boolean);
+ }
+ break;
+
+ case 45:
+
+/* Line 1455 of yacc.c */
+#line 525 "../../src/parser.yy"
+ { (yyval.gengetopt_option) = new gengetopt_option; }
+ break;
+
+ case 46:
+
+/* Line 1455 of yacc.c */
+#line 529 "../../src/parser.yy"
+ { (yyval.boolean) = 1; }
+ break;
+
+ case 47:
+
+/* Line 1455 of yacc.c */
+#line 530 "../../src/parser.yy"
+ { (yyval.boolean) = 0; }
+ break;
+
+ case 48:
+
+/* Line 1455 of yacc.c */
+#line 534 "../../src/parser.yy"
+ { (yyval.boolean) = 0; }
+ break;
+
+ case 49:
+
+/* Line 1455 of yacc.c */
+#line 535 "../../src/parser.yy"
+ { (yyval.boolean) = 1; }
+ break;
+
+ case 50:
+
+/* Line 1455 of yacc.c */
+#line 536 "../../src/parser.yy"
+ { (yyval.boolean) = 0; }
+ break;
+
+ case 51:
+
+/* Line 1455 of yacc.c */
+#line 540 "../../src/parser.yy"
+ { (yyval.boolean) = 1; }
+ break;
+
+ case 52:
+
+/* Line 1455 of yacc.c */
+#line 541 "../../src/parser.yy"
+ { (yyval.boolean) = 0; }
+ break;
+
+ case 53:
+
+/* Line 1455 of yacc.c */
+#line 545 "../../src/parser.yy"
+ { (yyval.str) = 0; }
+ break;
+
+ case 54:
+
+/* Line 1455 of yacc.c */
+#line 546 "../../src/parser.yy"
+ { (yyval.str) = (yyvsp[(3) - (3)].str); }
+ break;
+
+ case 55:
+
+/* Line 1455 of yacc.c */
+#line 550 "../../src/parser.yy"
+ { (yyval.str) = 0; }
+ break;
+
+ case 56:
+
+/* Line 1455 of yacc.c */
+#line 551 "../../src/parser.yy"
+ { (yyval.str) = (yyvsp[(3) - (3)].str); }
+ break;
+
+ case 57:
+
+/* Line 1455 of yacc.c */
+#line 555 "../../src/parser.yy"
+ { (yyval.str) = 0; }
+ break;
+
+ case 58:
+
+/* Line 1455 of yacc.c */
+#line 556 "../../src/parser.yy"
+ { (yyval.str) = (yyvsp[(3) - (3)].str); }
+ break;
+
+ case 59:
+
+/* Line 1455 of yacc.c */
+#line 560 "../../src/parser.yy"
+ { (yyval.ValueList) = new AcceptedValues; (yyval.ValueList)->insert((yyvsp[(1) - (1)].str)); }
+ break;
+
+ case 60:
+
+/* Line 1455 of yacc.c */
+#line 561 "../../src/parser.yy"
+ { (yyvsp[(1) - (3)].ValueList)->insert((yyvsp[(3) - (3)].str)); (yyval.ValueList) = (yyvsp[(1) - (3)].ValueList); }
+ break;
+
+ case 61:
+
+/* Line 1455 of yacc.c */
+#line 565 "../../src/parser.yy"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); }
+ break;
+
+ case 62:
+
+/* Line 1455 of yacc.c */
+#line 569 "../../src/parser.yy"
+ { (yyval.multiple_size) = new multiple_size; }
+ break;
+
+ case 63:
+
+/* Line 1455 of yacc.c */
+#line 570 "../../src/parser.yy"
+ { (yyval.multiple_size) = new multiple_size((yyvsp[(2) - (3)].str), (yyvsp[(2) - (3)].str)); }
+ break;
+
+ case 64:
+
+/* Line 1455 of yacc.c */
+#line 571 "../../src/parser.yy"
+ { (yyval.multiple_size) = new multiple_size((yyvsp[(2) - (4)].str), "0"); free((yyvsp[(2) - (4)].str)); }
+ break;
+
+ case 65:
+
+/* Line 1455 of yacc.c */
+#line 572 "../../src/parser.yy"
+ { (yyval.multiple_size) = new multiple_size("0", (yyvsp[(3) - (4)].str)); free((yyvsp[(3) - (4)].str)); }
+ break;
+
+ case 66:
+
+/* Line 1455 of yacc.c */
+#line 573 "../../src/parser.yy"
+ { (yyval.multiple_size) = new multiple_size((yyvsp[(2) - (5)].str), (yyvsp[(4) - (5)].str)); free((yyvsp[(2) - (5)].str)); free((yyvsp[(4) - (5)].str)); }
+ break;
+
+
+
+/* Line 1455 of yacc.c */
+#line 2212 "../../src/parser.cc"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+ yyerror_range[0] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[0] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[0] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[1] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+/* Line 1675 of yacc.c */
+#line 576 "../../src/parser.yy"
+
+
--- /dev/null
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ TOK_PACKAGE = 258,
+ TOK_VERSION = 259,
+ TOK_OPTION = 260,
+ TOK_DEFGROUP = 261,
+ TOK_GROUPOPTION = 262,
+ TOK_DEFMODE = 263,
+ TOK_MODEOPTION = 264,
+ TOK_YES = 265,
+ TOK_NO = 266,
+ TOK_ON = 267,
+ TOK_OFF = 268,
+ TOK_FLAG = 269,
+ TOK_PURPOSE = 270,
+ TOK_DESCRIPTION = 271,
+ TOK_USAGE = 272,
+ TOK_DEFAULT = 273,
+ TOK_GROUP = 274,
+ TOK_GROUPDESC = 275,
+ TOK_MODE = 276,
+ TOK_MODEDESC = 277,
+ TOK_MULTIPLE = 278,
+ TOK_ARGOPTIONAL = 279,
+ TOK_TYPESTR = 280,
+ TOK_SECTION = 281,
+ TOK_DETAILS = 282,
+ TOK_SECTIONDESC = 283,
+ TOK_TEXT = 284,
+ TOK_ARGS = 285,
+ TOK_VALUES = 286,
+ TOK_HIDDEN = 287,
+ TOK_DEPENDON = 288,
+ TOK_STRING = 289,
+ TOK_CHAR = 290,
+ TOK_ARGTYPE = 291,
+ TOK_SIZE = 292
+ };
+#endif
+/* Tokens. */
+#define TOK_PACKAGE 258
+#define TOK_VERSION 259
+#define TOK_OPTION 260
+#define TOK_DEFGROUP 261
+#define TOK_GROUPOPTION 262
+#define TOK_DEFMODE 263
+#define TOK_MODEOPTION 264
+#define TOK_YES 265
+#define TOK_NO 266
+#define TOK_ON 267
+#define TOK_OFF 268
+#define TOK_FLAG 269
+#define TOK_PURPOSE 270
+#define TOK_DESCRIPTION 271
+#define TOK_USAGE 272
+#define TOK_DEFAULT 273
+#define TOK_GROUP 274
+#define TOK_GROUPDESC 275
+#define TOK_MODE 276
+#define TOK_MODEDESC 277
+#define TOK_MULTIPLE 278
+#define TOK_ARGOPTIONAL 279
+#define TOK_TYPESTR 280
+#define TOK_SECTION 281
+#define TOK_DETAILS 282
+#define TOK_SECTIONDESC 283
+#define TOK_TEXT 284
+#define TOK_ARGS 285
+#define TOK_VALUES 286
+#define TOK_HIDDEN 287
+#define TOK_DEPENDON 288
+#define TOK_STRING 289
+#define TOK_CHAR 290
+#define TOK_ARGTYPE 291
+#define TOK_SIZE 292
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c */
+#line 148 "../../src/parser.yy"
+
+ char *str;
+ char chr;
+ int argtype;
+ int boolean;
+ class AcceptedValues *ValueList;
+ struct gengetopt_option *gengetopt_option;
+ struct multiple_size *multiple_size;
+
+
+
+/* Line 1676 of yacc.c */
+#line 138 "../../src/parser.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYLTYPE yylloc;
+
--- /dev/null
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <string>
+
+#include "my_sstream.h"
+
+#include "acceptedvalues.h"
+
+#include "argsdef.h"
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+#include "ggos.h"
+#include "yyerror.h"
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+static int gengetopt_package_given = 0;
+static int gengetopt_version_given = 0;
+static int gengetopt_purpose_given = 0;
+static int gengetopt_usage_given = 0;
+static int gengetopt_description_given = 0;
+
+/// the last option parsed
+static gengetopt_option *current_option = 0;
+
+extern int yylex (void) ;
+
+//#define YYERROR_VERBOSE 1
+
+void check_result(int o, gengetopt_option *opt)
+{
+ if (o)
+ {
+ ostringstream err;
+
+ switch (o)
+ {
+ case NOT_ENOUGH_MEMORY:
+ yyerror (opt, "not enough memory");
+ break;
+ case REQ_LONG_OPTION:
+ err << "long option redefined \'" << opt->long_opt << "\'";
+ yyerror (opt, err.str().c_str());
+ break;
+ case REQ_SHORT_OPTION:
+ err << "short option redefined \'" << opt->short_opt << "\'";
+ yyerror (opt, err.str().c_str());
+ break;
+ case FOUND_BUG:
+ yyerror (opt, "bug found!!");
+ break;
+ case GROUP_UNDEFINED:
+ yyerror (opt, "group undefined");
+ break;
+ case MODE_UNDEFINED:
+ yyerror (opt, "mode undefined");
+ break;
+ case INVALID_DEFAULT_VALUE:
+ yyerror (opt, "invalid default value");
+ break;
+ case NOT_REQUESTED_TYPE:
+ yyerror (opt, "type specification not requested");
+ break;
+ case NOT_VALID_SPECIFICATION:
+ yyerror (opt, "invalid specification for this kind of option");
+ break;
+ case SPECIFY_FLAG_STAT:
+ yyerror (opt, "you must specify the default flag status");
+ break;
+ case NOT_GROUP_OPTION:
+ yyerror (opt, "group specification for a non group option");
+ break;
+ case NOT_MODE_OPTION:
+ yyerror (opt, "mode specification for an option not belonging to a mode");
+ break;
+ case SPECIFY_GROUP:
+ yyerror (opt, "missing group specification");
+ break;
+ case SPECIFY_MODE:
+ yyerror (opt, "missing mode specification");
+ break;
+ case INVALID_NUMERIC_VALUE:
+ yyerror (opt, "invalid numeric value");
+ break;
+ case INVALID_ENUM_TYPE_USE:
+ yyerror (opt, "enum type can only be specified for options with values");
+ break;
+ case HELP_REDEFINED:
+ yyerror (opt, "if you want to redefine --help, please use option --no-help");
+ break;
+ case VERSION_REDEFINED:
+ yyerror (opt, "if you want to redefine --version, please use option --no-version");
+ break;
+ }
+ }
+}
+
+/* the number of allowed occurrences of a multiple option */
+struct multiple_size
+{
+ /* these strings are allocated dynamically and NOT
+ automatically freed upon destruction */
+ char *min;
+ char *max;
+
+ /* if no limit is specified then initialized to 0.
+ if the same size is specified for min and max, it means that an exact
+ number of occurrences is required*/
+ multiple_size(const char *m = "0", const char *M = "0") :
+ min(strdup(m)), max(strdup(M))
+ {}
+};
+
+#define check_error if (o) YYERROR;
+
+%}
+
+%union {
+ char *str;
+ char chr;
+ int argtype;
+ int boolean;
+ class AcceptedValues *ValueList;
+ struct gengetopt_option *gengetopt_option;
+ struct multiple_size *multiple_size;
+}
+
+%token TOK_PACKAGE "package"
+%token TOK_VERSION "version"
+%token TOK_OPTION "option"
+%token TOK_DEFGROUP "defgroup"
+%token TOK_GROUPOPTION "groupoption"
+%token TOK_DEFMODE "defmode"
+%token TOK_MODEOPTION "modeoption"
+%token TOK_YES "yes"
+%token TOK_NO "no"
+%token TOK_ON "on"
+%token TOK_OFF "off"
+%token TOK_FLAG "flag"
+%token TOK_PURPOSE "purpose"
+%token TOK_DESCRIPTION "description"
+%token TOK_USAGE "usage"
+%token TOK_DEFAULT "default"
+%token TOK_GROUP "group"
+%token TOK_GROUPDESC "groupdesc"
+%token TOK_MODE "mode"
+%token TOK_MODEDESC "modedesc"
+%token TOK_MULTIPLE "multiple"
+%token TOK_ARGOPTIONAL "argoptional"
+%token TOK_TYPESTR "typestr"
+%token TOK_SECTION "section"
+%token TOK_DETAILS "details"
+%token TOK_SECTIONDESC "sectiondesc"
+%token TOK_TEXT "text"
+%token TOK_ARGS "args"
+%token TOK_VALUES "values"
+%token TOK_HIDDEN "hidden"
+%token TOK_DEPENDON "dependon"
+%token <str> TOK_STRING
+%token <chr> TOK_CHAR
+%token <argtype> TOK_ARGTYPE
+%token <str> TOK_SIZE
+
+%type <boolean> req_onoff
+%type <boolean> opt_yesno optional_yesno
+%type <str> quoted_string
+%type <str> opt_groupdesc
+%type <str> opt_sectiondesc
+%type <str> opt_modedesc
+%type <ValueList> listofvalues
+%type <str> acceptedvalue
+%type <gengetopt_option> option_parts
+%type <multiple_size> multiple_size
+
+
+%% /* ====================================================================== */
+
+
+input
+ : /* empty */
+ | statement input
+ ;
+
+
+statement
+ : package
+ | version
+ | args
+ | purpose
+ | description
+ | usage
+ | sectiondef
+ | option
+ | text
+ | groupoption
+ | groupdef
+ | modeoption
+ | modedef
+ ;
+
+
+package
+ : TOK_PACKAGE TOK_STRING
+ {
+ if (gengetopt_package_given)
+ {
+ yyerror ("package redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_package_given = 1;
+ if (gengetopt_define_package ($2))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+version
+ : TOK_VERSION TOK_STRING
+ {
+ if (gengetopt_version_given)
+ {
+ yyerror ("version redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_version_given = 1;
+ if (gengetopt_define_version ($2))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+purpose
+ : TOK_PURPOSE quoted_string
+ {
+ if (gengetopt_purpose_given)
+ {
+ yyerror ("purpose redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_purpose_given = 1;
+ if (gengetopt_define_purpose ($2))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+description
+ : TOK_DESCRIPTION quoted_string
+ {
+ if (gengetopt_description_given)
+ {
+ yyerror ("description redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_description_given = 1;
+ if (gengetopt_define_description ($2))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+usage
+ : TOK_USAGE quoted_string
+ {
+ if (gengetopt_usage_given)
+ {
+ yyerror ("usage redefined");
+ YYERROR;
+ }
+ else
+ {
+ gengetopt_usage_given = 1;
+ if (gengetopt_define_usage ($2))
+ {
+ yyerror ("not enough memory");
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+
+sectiondef
+ : TOK_SECTION quoted_string opt_sectiondesc
+ {
+ gengetopt_set_section ($2, $3);
+ }
+ ;
+
+text
+ : TOK_TEXT quoted_string
+ {
+ if (current_option) {
+ std::string current_option_text;
+ if (current_option->text_after) {
+ current_option_text = std::string(current_option->text_after) + $2;
+ current_option->text_after = strdup(current_option_text.c_str());
+ } else {
+ current_option->text_after = strdup($2);
+ }
+ } else {
+ gengetopt_set_text($2);
+ }
+ }
+ ;
+
+args
+ : TOK_ARGS TOK_STRING
+ {
+ gengetopt_set_args($2);
+ }
+ ;
+
+groupdef
+ : TOK_DEFGROUP TOK_STRING opt_groupdesc optional_yesno
+ {
+ if (gengetopt_add_group ($2, $3, $4))
+ {
+ yyerror ("group redefined");
+ YYERROR;
+ }
+ }
+ ;
+
+modedef
+ : TOK_DEFMODE TOK_STRING opt_modedesc
+ {
+ if (gengetopt_add_mode ($2, $3))
+ {
+ yyerror ("mode redefined");
+ YYERROR;
+ }
+ }
+ ;
+
+option
+ : TOK_OPTION TOK_STRING TOK_CHAR quoted_string
+ option_parts
+ {
+ $5->filename = gengetopt_input_filename;
+ $5->linenum = @1.first_line;
+ $5->long_opt = strdup($2);
+ if ($3 != '-')
+ $5->short_opt = $3;
+ $5->desc = strdup($4);
+ int o = gengetopt_check_option ($5, false);
+ check_result(o, $5);
+ check_error;
+ o = gengetopt_add_option ($5);
+ check_result(o, $5);
+ check_error;
+ current_option = $5;
+ }
+ ;
+
+groupoption
+ : TOK_GROUPOPTION TOK_STRING TOK_CHAR quoted_string
+ option_parts
+ {
+ $5->filename = gengetopt_input_filename;
+ $5->linenum = @1.first_line;
+ $5->long_opt = strdup($2);
+ if ($3 != '-')
+ $5->short_opt = $3;
+ $5->desc = strdup($4);
+ int o = gengetopt_check_option ($5, true);
+ check_result(o, $5);
+ check_error;
+ o = gengetopt_add_option ($5);
+ check_result(o, $5);
+ check_error;
+ }
+ ;
+
+modeoption
+ : TOK_MODEOPTION TOK_STRING TOK_CHAR quoted_string
+ option_parts
+ {
+ $5->filename = gengetopt_input_filename;
+ $5->linenum = @1.first_line;
+ $5->long_opt = strdup($2);
+ if ($3 != '-')
+ $5->short_opt = $3;
+ $5->desc = strdup($4);
+ int o = gengetopt_check_option ($5, false, true);
+ check_result(o, $5);
+ check_error;
+ o = gengetopt_add_option ($5);
+ check_result(o, $5);
+ check_error;
+ }
+ ;
+
+
+/* ---------------------------------------------------------------------- */
+
+quoted_string
+ : TOK_STRING
+ ;
+
+option_parts: option_parts opt_yesno
+ {
+ $$ = $1;
+ $$->required = $2;
+ $$->required_set = true;
+ }
+ | option_parts TOK_ARGTYPE
+ {
+ $$ = $1;
+ $$->type = $2;
+ }
+ | option_parts TOK_TYPESTR '=' TOK_STRING
+ {
+ $$ = $1;
+ $$->type_str = strdup($4);
+ }
+ | option_parts TOK_DETAILS '=' quoted_string
+ {
+ $$ = $1;
+ $$->details = strdup($4);
+ }
+ | option_parts TOK_VALUES '=' listofvalues
+ {
+ $$ = $1;
+ $$->acceptedvalues = $4;
+ }
+ | option_parts TOK_DEFAULT '=' TOK_STRING
+ {
+ $$ = $1;
+ $$->default_string = strdup($4);
+ }
+ | option_parts TOK_GROUP '=' TOK_STRING
+ {
+ $$ = $1;
+ $$->group_value = strdup($4);
+ }
+ | option_parts TOK_MODE '=' TOK_STRING
+ {
+ $$ = $1;
+ $$->mode_value = strdup($4);
+ }
+ | option_parts TOK_DEPENDON '=' TOK_STRING
+ {
+ $$ = $1;
+ $$->dependon = strdup($4);
+ }
+ | option_parts TOK_ARGOPTIONAL
+ {
+ $$ = $1;
+ $$->arg_is_optional = true;
+ }
+ | option_parts TOK_MULTIPLE multiple_size
+ {
+ $$ = $1;
+ $$->multiple = true;
+ $$->multiple_min = $3->min;
+ $$->multiple_max = $3->max;
+ delete $3;
+ }
+ | option_parts TOK_FLAG
+ {
+ $$ = $1;
+ $$->type = ARG_FLAG;
+ }
+ | option_parts TOK_HIDDEN
+ {
+ $$ = $1;
+ $$->hidden = true;
+ }
+ | option_parts req_onoff
+ {
+ $$ = $1;
+ $$->flagstat = $2;
+ }
+ | { $$ = new gengetopt_option; }
+ ;
+
+req_onoff
+ : TOK_ON { $$ = 1; }
+ | TOK_OFF { $$ = 0; }
+ ;
+
+optional_yesno
+ : /* empty */ { $$ = 0; }
+ | TOK_YES { $$ = 1; }
+ | TOK_NO { $$ = 0; }
+ ;
+
+opt_yesno
+ : TOK_YES { $$ = 1; }
+ | TOK_NO { $$ = 0; }
+ ;
+
+opt_groupdesc
+ : /* empty */ { $$ = 0; }
+ | TOK_GROUPDESC '=' TOK_STRING { $$ = $3; }
+ ;
+
+opt_modedesc
+ : /* empty */ { $$ = 0; }
+ | TOK_MODEDESC '=' TOK_STRING { $$ = $3; }
+ ;
+
+opt_sectiondesc
+ : /* empty */ { $$ = 0; }
+ | TOK_SECTIONDESC '=' TOK_STRING { $$ = $3; }
+ ;
+
+listofvalues
+ : acceptedvalue { $$ = new AcceptedValues; $$->insert($1); }
+ | listofvalues ',' acceptedvalue { $1->insert($3); $$ = $1; }
+ ;
+
+acceptedvalue
+ : TOK_STRING { $$ = $1; }
+ ;
+
+multiple_size
+ : { $$ = new multiple_size; }
+ | '(' TOK_SIZE ')' { $$ = new multiple_size($2, $2); }
+ | '(' TOK_SIZE '-' ')' { $$ = new multiple_size($2, "0"); free($2); }
+ | '(' '-' TOK_SIZE ')' { $$ = new multiple_size("0", $3); free($3); }
+ | '(' TOK_SIZE '-' TOK_SIZE ')' { $$ = new multiple_size($2, $4); free($2); free($4); }
+ ;
+
+%%
--- /dev/null
+#line 2 "../../src/scanner.cc"
+
+#line 4 "../../src/scanner.cc"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE yylex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+ #define YY_LESS_LINENO(n) \
+ do { \
+ int yyl;\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
+ if ( yytext[yyl] == '\n' )\
+ --yylineno;\
+ }while(0)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 62
+#define YY_END_OF_BUFFER 63
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[246] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 63, 61, 57, 59,
+ 60, 56, 48, 58, 43, 42, 47, 41, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 62, 46, 44, 45,
+ 55, 51, 55, 54, 55, 57, 59, 56, 58, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 0, 18, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 45, 51, 52, 0,
+ 53, 0, 50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 19, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 14, 49, 0, 40, 0, 0, 0, 0, 0,
+ 0, 0, 9, 17, 0, 0, 0, 4, 28, 0,
+ 0, 0, 0, 0, 0, 0, 0, 39, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 25, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 22, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 36,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 0,
+ 1, 0, 35, 0, 0, 23, 0, 30, 0, 0,
+
+ 38, 0, 0, 0, 0, 0, 0, 0, 0, 10,
+ 20, 0, 34, 24, 11, 0, 27, 37, 0, 0,
+ 0, 0, 8, 29, 0, 31, 0, 0, 0, 26,
+ 0, 0, 0, 0, 0, 0, 0, 7, 13, 0,
+ 32, 21, 12, 33, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 1, 6, 7, 1, 1, 1, 1, 8,
+ 9, 1, 1, 10, 11, 1, 1, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 1, 1, 1,
+ 13, 1, 14, 1, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 1, 16, 1, 1, 1, 1, 17, 18, 19, 20,
+
+ 21, 22, 23, 24, 25, 15, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 15, 38,
+ 39, 15, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[40] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[250] =
+ { 0,
+ 0, 0, 37, 47, 39, 57, 271, 272, 268, 0,
+ 272, 264, 272, 0, 272, 272, 272, 272, 235, 32,
+ 238, 239, 232, 239, 234, 232, 34, 231, 43, 30,
+ 239, 47, 36, 225, 59, 237, 272, 272, 272, 245,
+ 272, 253, 272, 272, 78, 253, 0, 249, 0, 230,
+ 55, 216, 215, 61, 220, 229, 213, 218, 226, 218,
+ 272, 222, 272, 208, 223, 208, 208, 220, 208, 204,
+ 198, 204, 217, 206, 199, 197, 218, 226, 272, 64,
+ 272, 199, 272, 58, 70, 206, 207, 208, 206, 195,
+ 199, 204, 184, 199, 272, 195, 196, 181, 272, 190,
+
+ 188, 182, 176, 176, 177, 184, 173, 186, 183, 169,
+ 170, 272, 272, 172, 272, 166, 168, 170, 170, 165,
+ 172, 169, 272, 272, 160, 163, 172, 75, 76, 167,
+ 161, 173, 159, 163, 162, 151, 156, 272, 150, 162,
+ 161, 156, 145, 152, 148, 157, 156, 150, 147, 152,
+ 272, 79, 143, 141, 140, 148, 137, 136, 137, 142,
+ 130, 130, 132, 272, 138, 125, 272, 125, 128, 132,
+ 121, 119, 133, 123, 121, 117, 272, 129, 118, 272,
+ 112, 118, 112, 110, 117, 126, 121, 120, 119, 110,
+ 272, 105, 272, 108, 106, 272, 104, 272, 105, 98,
+
+ 272, 98, 96, 112, 106, 109, 102, 105, 98, 272,
+ 272, 104, 103, 272, 272, 93, 272, 272, 96, 101,
+ 94, 91, 272, 272, 87, 272, 95, 98, 84, 272,
+ 78, 84, 75, 69, 74, 71, 68, 272, 272, 66,
+ 272, 272, 272, 272, 272, 109, 111, 78, 51
+ } ;
+
+static yyconst flex_int16_t yy_def[250] =
+ { 0,
+ 245, 1, 246, 246, 247, 247, 245, 245, 245, 248,
+ 245, 245, 245, 249, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 248, 245, 249, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 0, 245, 245, 245, 245
+ } ;
+
+static yyconst flex_int16_t yy_nxt[312] =
+ { 0,
+ 8, 9, 10, 11, 12, 13, 14, 15, 8, 16,
+ 17, 17, 18, 17, 17, 8, 19, 17, 17, 20,
+ 21, 22, 23, 24, 25, 17, 26, 27, 28, 29,
+ 30, 17, 31, 32, 33, 34, 35, 17, 36, 37,
+ 11, 42, 43, 14, 44, 38, 65, 39, 40, 37,
+ 11, 49, 51, 14, 45, 38, 71, 39, 40, 42,
+ 43, 52, 44, 59, 62, 66, 79, 68, 80, 60,
+ 69, 63, 45, 64, 72, 74, 85, 91, 47, 75,
+ 79, 70, 80, 81, 244, 86, 116, 114, 87, 88,
+ 92, 115, 117, 82, 154, 156, 243, 118, 178, 242,
+
+ 241, 155, 240, 239, 238, 157, 83, 237, 179, 8,
+ 8, 41, 41, 236, 235, 234, 233, 232, 231, 230,
+ 229, 228, 227, 112, 61, 226, 225, 224, 223, 222,
+ 221, 220, 219, 218, 217, 216, 215, 214, 213, 212,
+ 211, 210, 209, 208, 207, 206, 205, 204, 203, 202,
+ 201, 200, 199, 198, 197, 196, 195, 194, 193, 192,
+ 191, 190, 189, 188, 187, 186, 185, 184, 183, 182,
+ 181, 180, 177, 176, 175, 174, 173, 172, 171, 170,
+ 169, 168, 167, 166, 165, 164, 163, 162, 161, 160,
+ 159, 158, 153, 152, 151, 150, 149, 148, 147, 146,
+
+ 145, 144, 143, 142, 141, 140, 139, 138, 137, 136,
+ 135, 134, 133, 132, 131, 130, 129, 128, 127, 126,
+ 125, 124, 123, 122, 121, 120, 119, 113, 78, 77,
+ 112, 111, 110, 109, 108, 107, 106, 105, 104, 103,
+ 102, 101, 100, 99, 98, 97, 96, 95, 94, 93,
+ 90, 89, 84, 48, 46, 78, 77, 76, 73, 67,
+ 61, 58, 57, 56, 55, 54, 53, 50, 48, 46,
+ 245, 7, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245
+ } ;
+
+static yyconst flex_int16_t yy_chk[312] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 3, 5, 5, 3, 5, 3, 30, 3, 3, 4,
+ 4, 249, 20, 4, 5, 4, 33, 4, 4, 6,
+ 6, 20, 6, 27, 29, 30, 80, 32, 80, 27,
+ 32, 29, 6, 29, 33, 35, 51, 54, 248, 35,
+ 45, 32, 45, 45, 240, 51, 85, 84, 51, 51,
+ 54, 84, 85, 45, 128, 129, 237, 85, 152, 236,
+
+ 235, 128, 234, 233, 232, 129, 45, 231, 152, 246,
+ 246, 247, 247, 229, 228, 227, 225, 222, 221, 220,
+ 219, 216, 213, 212, 209, 208, 207, 206, 205, 204,
+ 203, 202, 200, 199, 197, 195, 194, 192, 190, 189,
+ 188, 187, 186, 185, 184, 183, 182, 181, 179, 178,
+ 176, 175, 174, 173, 172, 171, 170, 169, 168, 166,
+ 165, 163, 162, 161, 160, 159, 158, 157, 156, 155,
+ 154, 153, 150, 149, 148, 147, 146, 145, 144, 143,
+ 142, 141, 140, 139, 137, 136, 135, 134, 133, 132,
+ 131, 130, 127, 126, 125, 122, 121, 120, 119, 118,
+
+ 117, 116, 114, 111, 110, 109, 108, 107, 106, 105,
+ 104, 103, 102, 101, 100, 98, 97, 96, 94, 93,
+ 92, 91, 90, 89, 88, 87, 86, 82, 78, 77,
+ 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,
+ 66, 65, 64, 62, 60, 59, 58, 57, 56, 55,
+ 53, 52, 50, 48, 46, 42, 40, 36, 34, 31,
+ 28, 26, 25, 24, 23, 22, 21, 19, 12, 9,
+ 7, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+
+ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245,
+ 245
+ } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[63] =
+ { 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, };
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "../../src/scanner.ll"
+/**
+ * Copyright (C) 1999-2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 23 "../../src/scanner.ll"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "argsdef.h"
+#include "parser.h"
+extern int gengetopt_count_line;
+
+#include "my_sstream.h"
+
+static void update_count_line (char *str);
+static void updateTokenInfo (int pos);
+
+// the buffer for strings (possibly spanning more lines)
+static std::ostringstream buff;
+
+static void buffer(const char *s);
+static char *flush_buffer();
+
+#define LINEBUF_LEN 1024
+
+#define PUSH(s) yy_push_state(s);
+#define POP() yy_pop_state();
+
+int tokenpos = 0;
+char linebuf[LINEBUF_LEN] ; /* current line */
+
+//#define DEBUG_SCANNER
+#ifdef DEBUG_SCANNER
+#include <iostream> // for debug
+#define DEB(s) std::cerr << s << std::endl;
+#define DEB2(s,s2) std::cerr << s << ": " << s2 << std::endl;
+#else
+#define DEB(s)
+#define DEB2(s,s2)
+#endif
+
+
+#line 692 "../../src/scanner.cc"
+
+#define INITIAL 0
+#define SIZE_STATE 1
+#define STRING_STATE 2
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+ static int yy_start_stack_ptr = 0;
+ static int yy_start_stack_depth = 0;
+ static int *yy_start_stack = NULL;
+
+ static void yy_push_state (int new_state );
+
+ static void yy_pop_state (void );
+
+ static int yy_top_state (void );
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 71 "../../src/scanner.ll"
+
+
+
+#line 893 "../../src/scanner.cc"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 246 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 272 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+ if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+ {
+ int yyl;
+ for ( yyl = 0; yyl < yyleng; ++yyl )
+ if ( yytext[yyl] == '\n' )
+
+ yylineno++;
+;
+ }
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 74 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_STRING; return TOK_ARGTYPE;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 75 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_INT; return TOK_ARGTYPE;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 76 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_SHORT; return TOK_ARGTYPE;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 77 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_LONG; return TOK_ARGTYPE;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 78 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_FLOAT; return TOK_ARGTYPE;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 79 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_DOUBLE; return TOK_ARGTYPE;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 80 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_LONGDOUBLE; return TOK_ARGTYPE;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 81 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_LONGLONG; return TOK_ARGTYPE;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 82 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_ENUM; return TOK_ARGTYPE;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 84 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_PACKAGE;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 85 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_VERSION;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 86 "../../src/scanner.ll"
+updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_GROUPOPTION;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 87 "../../src/scanner.ll"
+updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_MODEOPTION;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 88 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_YES;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 89 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_NO;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 90 "../../src/scanner.ll"
+updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_OPTION;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 91 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_FLAG;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 92 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_ON;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 93 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_OFF;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 94 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_PURPOSE;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 95 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DESCRIPTION;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 96 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_USAGE;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 97 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEFAULT;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 98 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_TYPESTR;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 99 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_GROUP;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 100 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_GROUPDESC;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 101 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEFGROUP;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 102 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_MODE;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 103 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_MODEDESC;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 104 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEFMODE;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 105 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_MULTIPLE;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 106 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_ARGOPTIONAL;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 107 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_SECTIONDESC;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 108 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_SECTION;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 109 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_VALUES;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 110 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_HIDDEN;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 111 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEPENDON;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 112 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DETAILS;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 113 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_TEXT;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 114 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_ARGS;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 116 "../../src/scanner.ll"
+{ updateTokenInfo (-1); return '='; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 117 "../../src/scanner.ll"
+{ updateTokenInfo (-1); return ','; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 119 "../../src/scanner.ll"
+{ PUSH(SIZE_STATE); updateTokenInfo (-1); return '('; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 120 "../../src/scanner.ll"
+{ updateTokenInfo (-1); return '-'; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 121 "../../src/scanner.ll"
+{ updateTokenInfo (-1); yylval.str = strdup(yytext); return TOK_SIZE; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 122 "../../src/scanner.ll"
+{ POP(); updateTokenInfo (-1); return ')'; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 124 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.chr = yytext[0]; return TOK_CHAR;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 126 "../../src/scanner.ll"
+{ updateTokenInfo (-1); DEB("start string"); PUSH(STRING_STATE) ; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 127 "../../src/scanner.ll"
+{ updateTokenInfo (2); buffer("\\\\n"); }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 128 "../../src/scanner.ll"
+{ updateTokenInfo (1); buffer("\n"); }
+ YY_BREAK
+case 51:
+/* rule 51 can match eol */
+YY_RULE_SETUP
+#line 129 "../../src/scanner.ll"
+{ update_count_line (yytext); buffer( yytext ) ; }
+ YY_BREAK
+case 52:
+/* rule 52 can match eol */
+YY_RULE_SETUP
+#line 130 "../../src/scanner.ll"
+{ update_count_line (yytext); /* a line break */ }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 131 "../../src/scanner.ll"
+{ updateTokenInfo (-1); buffer(yytext); }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 132 "../../src/scanner.ll"
+{ updateTokenInfo (-1); DEB("end string"); POP() ; yylval.str = flush_buffer(); return TOK_STRING; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 133 "../../src/scanner.ll"
+{ updateTokenInfo (-1); buffer( yytext ) ; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 135 "../../src/scanner.ll"
+updateTokenInfo (-1);
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 136 "../../src/scanner.ll"
+updateTokenInfo (8*yyleng);
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 138 "../../src/scanner.ll"
+/* comments begin with # in any place (but strings) */
+ YY_BREAK
+case 59:
+/* rule 59 can match eol */
+YY_RULE_SETUP
+#line 139 "../../src/scanner.ll"
+update_count_line (0); yyless(1) ; /* give back all but the \n to rescan */
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 141 "../../src/scanner.ll"
+{}
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 143 "../../src/scanner.ll"
+{
+ return 1000; /* little hack to produce a parse error too. */
+}
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 147 "../../src/scanner.ll"
+ECHO;
+ YY_BREAK
+#line 1301 "../../src/scanner.cc"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(SIZE_STATE):
+case YY_STATE_EOF(STRING_STATE):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 246 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 246 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 245);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ if ( c == '\n' )
+
+ yylineno++;
+;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+ static void yy_push_state (int new_state )
+{
+ if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+ {
+ yy_size_t new_size;
+
+ (yy_start_stack_depth) += YY_START_STACK_INCR;
+ new_size = (yy_start_stack_depth) * sizeof( int );
+
+ if ( ! (yy_start_stack) )
+ (yy_start_stack) = (int *) yyalloc(new_size );
+
+ else
+ (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size );
+
+ if ( ! (yy_start_stack) )
+ YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+ }
+
+ (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
+
+ BEGIN(new_state);
+}
+
+ static void yy_pop_state (void)
+{
+ if ( --(yy_start_stack_ptr) < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+ static int yy_top_state (void)
+{
+ return (yy_start_stack)[(yy_start_stack_ptr) - 1];
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ /* We do not touch yylineno unless the option is enabled. */
+ yylineno = 1;
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+ (yy_start_stack_ptr) = 0;
+ (yy_start_stack_depth) = 0;
+ (yy_start_stack) = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree((yy_start_stack) );
+ (yy_start_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 147 "../../src/scanner.ll"
+
+
+
+/*
+ Otherwise '\n' within a TOK_MLSTRING would not be counted
+*/
+void
+update_count_line (char *str)
+{
+ if (str)
+ {
+ char *p;
+ for (p = str; *p; ++p)
+ if (*p == '\n') {
+ ++gengetopt_count_line;
+ tokenpos = 0 ; /* reset token position */
+ strncpy (linebuf, ( (p+1) ? p+1 : ""), LINEBUF_LEN - 1);
+ }
+ }
+ else
+ {
+ ++gengetopt_count_line;
+ tokenpos = 0 ; /* reset token position */
+ strncpy (linebuf, yytext+1, LINEBUF_LEN - 1); /* save the next line */
+ }
+}
+
+void
+updateTokenInfo( int pos )
+{
+ if ( pos >= 0 )
+ tokenpos += pos ;
+ else
+ tokenpos += yyleng ;
+}
+
+void buffer(const char *s)
+{
+ buff << s;
+}
+
+char *flush_buffer()
+{
+ char *ret = strdup(buff.str().c_str());
+ buff.str("");
+ return ret;
+}
+
--- /dev/null
+# Copyright (C) 1999-2008 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# if gengen is not installed we simply ignore the changes
+
+SUFFIXES = .h_skel
+
+if NO_GENGEN
+#.h_skel.cc:
+# echo "Not regenerating $@ since gengen is not installed"
+# better not to use touch, otherwise we will create an empty file in
+# the build directory
+# touch $@
+
+else
+GENERATE = $(GENGEN)
+
+.h_skel.cc:
+ name="`echo $* | sed 's/^.*\///g'`"; \
+ echo "$$name"; \
+ $(GENERATE) -i $< -F $*.h -f $$name --separate-files --expand-tabs --output-dir=$(srcdir) --force
+endif
+
+INCLUDES = -I@top_srcdir@/src
+
+noinst_LTLIBRARIES = libgen.la
+
+libgen_la_SOURCES = $(BUILT_SOURCES)
+
+BUILT_SOURCES = header.h header.cc c_source.h c_source.cc \
+handle_help.h handle_version.h handle_help.cc handle_version.cc \
+generic_option.h required_option.h dependant_option.h \
+generic_option.cc required_option.cc dependant_option.cc \
+group_counter.h group_option.h \
+group_counter.cc group_option.cc \
+print_help_string.h print_help_string.cc \
+multiple_opt_list.cc multiple_opt_list.h \
+multiple_fill_array.cc multiple_fill_array.h \
+copyright.cc copyright.h \
+free_string.cc free_string.h \
+free_multiple.cc free_multiple.h \
+reset_group.cc reset_group.h \
+exit_failure.cc exit_failure.h \
+update_given.cc update_given.h \
+option_arg.cc option_arg.h \
+given_field.cc given_field.h \
+clear_given.cc clear_given.h \
+clear_arg.cc clear_arg.h \
+free_list.cc free_list.h \
+file_save.cc file_save.h \
+file_save_multiple.cc file_save_multiple.h \
+init_args_info.cc init_args_info.h \
+custom_getopt_gen.cc custom_getopt_gen.h \
+check_modes.cc check_modes.h \
+enum_decl.cc enum_decl.h
+
+EXTRA_DIST = header.h_skel c_source.h_skel handle_help.h_skel \
+handle_version.h_skel generic_option.h_skel \
+required_option.h_skel dependant_option.h_skel \
+group_counter.h_skel group_option.h_skel \
+print_help_string.h_skel \
+multiple_opt_list.h_skel \
+multiple_fill_array.h_skel \
+copyright.h_skel free_string.h_skel \
+free_multiple.h_skel \
+reset_group.h_skel \
+exit_failure.h_skel \
+update_given.h_skel \
+option_arg.h_skel \
+given_field.h_skel \
+clear_given.h_skel \
+clear_arg.h_skel \
+free_list.h_skel \
+file_save.h_skel \
+file_save_multiple.h_skel \
+init_args_info.h_skel \
+custom_getopt_gen.h_skel \
+check_modes.h_skel \
+enum_decl.h_skel \
+$(BUILT_SOURCES)
+
+built-clean:
+ cd @srcdir@ && rm -f $(BUILT_SOURCES)
\ No newline at end of file
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "c_source.h"
+
+void
+c_source_gen_class::generate_c_source(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " File autogenerated by gengetopt ";
+ generate_string (generator_version, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << " generated with the following command:";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (command_line, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " The developers of gengetopt consider the fixed text that goes in all";
+ stream << "\n";
+ stream << indent_str;
+ stream << " gengetopt output files to be in the public domain:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " we make no copyright claims on it.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "*/";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* If we use autoconf. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef HAVE_CONFIG_H";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include \"config.h\"";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include <stdio.h>";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include <stdlib.h>";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include <string.h>";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef FIX_UNUSED";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (( ! include_getopt ))
+ {
+ stream << "#include <getopt.h>";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include \"";
+ generate_string (source_name, stream, indent + indent_str.length ());
+ stream << ".";
+ generate_string (header_file_ext, stream, indent + indent_str.length ());
+ stream << "\"";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_purpose = \"";
+ generate_string (purpose, stream, indent + indent_str.length ());
+ stream << "\";";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_usage = \"Usage: ";
+ if (no_package)
+ {
+ stream << "\" ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << " \"";
+ }
+ generate_string (usage_string, stream, indent + indent_str.length ());
+ stream << "\";";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_description = \"";
+ generate_string (description, stream, indent + indent_str.length ());
+ stream << "\";";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (( has_hidden || has_details ))
+ {
+ if (has_details)
+ {
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_detailed_help[] = {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (detailed_help_option_print.size () > 0)
+ generate_string (detailed_help_option_print, stream, indent + indent_str.length ());
+ else
+ generate_detailed_help_option_print (stream, indent + indent_str.length ());
+ stream << " 0";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ if (has_hidden)
+ {
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "init_full_help_array(void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (full_help_option_print.size () > 0)
+ generate_string (full_help_option_print, stream, indent + indent_str.length ());
+ else
+ generate_full_help_option_print (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_full_help[";
+ generate_string (help_string_num, stream, indent + indent_str.length ());
+ stream << "];";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ else
+ {
+ if (has_hidden)
+ {
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_full_help[] = {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (full_help_option_print.size () > 0)
+ generate_string (full_help_option_print, stream, indent + indent_str.length ());
+ else
+ generate_full_help_option_print (stream, indent + indent_str.length ());
+ stream << " 0";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "init_help_array(void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (help_option_print.size () > 0)
+ generate_string (help_option_print, stream, indent + indent_str.length ());
+ else
+ generate_help_option_print (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_help[";
+ generate_string (help_string_num, stream, indent + indent_str.length ());
+ stream << "];";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_help[] = {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (help_option_print.size () > 0)
+ generate_string (help_option_print, stream, indent + indent_str.length ());
+ else
+ generate_help_option_print (stream, indent + indent_str.length ());
+ stream << " 0";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "typedef enum {ARG_NO";
+ stream << "\n";
+ stream << indent_str;
+ if (has_arg_flag)
+ {
+ stream << " , ARG_FLAG";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_string)
+ {
+ stream << " , ARG_STRING";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_int)
+ {
+ stream << " , ARG_INT";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " , ARG_SHORT";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " , ARG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " , ARG_FLOAT";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " , ARG_DOUBLE";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " , ARG_LONGDOUBLE";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << " , ARG_LONGLONG";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_enum)
+ {
+ stream << " , ARG_ENUM";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "} ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_arg_type;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void clear_given (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void clear_args (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_internal (int argc, char **argv, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params, const char *additional_error);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (check_required_options)
+ {
+ stream << "static int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_required2 (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, const char *prog_name, const char *additional_error);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (cmd_list)
+ {
+ stream << "struct line_list";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char * string_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct line_list * next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static struct line_list *cmd_line_list = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static struct line_list *cmd_line_list_tmp = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "free_cmd_list(void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* free the list of a previous call */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (cmd_line_list)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (cmd_line_list) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list = cmd_line_list->next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (cmd_line_list_tmp->string_arg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (cmd_line_list_tmp);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (option_values.size () > 0)
+ generate_string (option_values, stream, indent + indent_str.length ());
+ else
+ generate_option_values (stream, indent + indent_str.length ());
+ stream << indent_str;
+ if (do_generate_strdup)
+ {
+ stream << "static char *";
+ stream << "\n";
+ stream << indent_str;
+ stream << "gengetopt_strdup (const char *s);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void clear_given (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ if (given_init.size () > 0)
+ generate_string (given_init, stream, indent + indent_str.length ());
+ else
+ generate_given_init (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void clear_args (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " FIX_UNUSED (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (clear_arg.size () > 0)
+ generate_string (clear_arg, stream, indent + indent_str.length ());
+ else
+ generate_clear_arg (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void init_args_info(struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ if (( has_hidden && has_details ))
+ {
+ stream << " init_full_help_array(); ";
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (( has_hidden || has_details ))
+ {
+ stream << " init_help_array(); ";
+ }
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (init_args_info.size () > 0)
+ generate_string (init_args_info, stream, indent + indent_str.length ());
+ else
+ generate_init_args_info (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_version (void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf (\"%s %s\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (strlen(";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "_NAME) ? ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "_NAME : ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "),";
+ stream << "\n";
+ stream << indent_str;
+ indent = 5;
+ stream << " ";
+ generate_string (version_var_name, stream, indent + indent_str.length ());
+ stream << ");";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void print_help_common(void) {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_version ();";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (strlen(";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_purpose) > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"\\n%s\\n\", ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_purpose);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (strlen(";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_usage) > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"\\n%s\\n\", ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_usage);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"\\n\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (strlen(";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_description) > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"%s\\n\\n\", ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_description);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_help (void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " print_help_common();";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_help[i])";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"%s\\n\", ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_help[i++]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (has_hidden)
+ {
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_full_help (void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " print_help_common();";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_full_help[i])";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"%s\\n\", ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_full_help[i++]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_details)
+ {
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_detailed_help (void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " print_help_common();";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_detailed_help[i])";
+ stream << "\n";
+ stream << indent_str;
+ stream << " printf(\"%s\\n\", ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_detailed_help[i++]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_init (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " clear_given (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " clear_args (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " init_args_info (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ if (handle_unamed)
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->inputs = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->inputs_num = 0;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params_init(struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (params)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " { ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params->override = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params->initialize = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params->check_required = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params->check_ambiguity = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params->print_errors = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params_create(void)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params = ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *)malloc(sizeof(struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params));";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params_init(params); ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return params;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (has_typed_options)
+ {
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "free_string_field (char **s)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*s)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (*s);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *s = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (multiple_token_functions)
+ {
+ stream << "/** ";
+ stream << "@";
+ stream << "brief generic value variable */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "union generic_value {";
+ stream << "\n";
+ stream << indent_str;
+ if (( has_arg_int || has_arg_enum ))
+ {
+ stream << " int int_arg;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " short short_arg;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " long long_arg;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " float float_arg;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " double double_arg;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " long double longdouble_arg;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << "#ifdef HAVE_LONG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ stream << " long long int longlong_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " long longlong_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " char *string_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *default_string_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief holds temporary values for multiple options */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct generic_list";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " union generic_value arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *orig;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct generic_list *next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "brief add a node at the head of the list ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void add_node(struct generic_list **list) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " new_node->next = *list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *list = new_node;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " new_node->arg.string_arg = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " new_node->orig = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (( ( ! multiple_options_all_string ) && multiple_token_functions ))
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The passed arg parameter is NOT set to 0 from this function";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "free_multiple_field(unsigned int len, void *arg, char ***orig)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " unsigned int i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (arg) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = 0; i < len; ++i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free_string_field(&((*orig)[i]));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (arg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (*orig);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *orig = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (multiple_options_string)
+ {
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "free_multiple_string_field(unsigned int len, char ***arg, char ***orig)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " unsigned int i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*arg) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = 0; i < len; ++i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free_string_field(&((*arg)[i]));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free_string_field(&((*orig)[i]));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free_string_field(&((*arg)[0])); /* free default string */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (*arg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *arg = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (*orig);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *orig = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_release (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ if (handle_unamed)
+ {
+ stream << " unsigned int i;";
+ }
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (free.size () > 0)
+ generate_string (free, stream, indent + indent_str.length ());
+ else
+ generate_free (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ if (handle_unamed)
+ {
+ stream << " for (i = 0; i < args_info->inputs_num; ++i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (args_info->inputs [i]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (args_info->inputs_num)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (args_info->inputs);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << " clear_given (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (check_possible_values)
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param val the value to check";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param values the possible values";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return the index of the matched value:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * -1 if no value matched,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * -2 if more than one value has matched";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int";
+ stream << "\n";
+ stream << indent_str;
+ stream << "check_possible_values(const char *val, const char *values[])";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i, found, last;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " size_t len;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!val) /* otherwise strlen() crashes below */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return -1; /* -1 means no argument for the option */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " found = last = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = 0, len = strlen(val); values[i]; ++i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (strncmp(val, values[i], len) == 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++found;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " last = i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (strlen(values[i]) == len)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return i; /* exact macth no need to check more */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (found == 1) /* one match: OK */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return last;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return (found ? -2 : -1); /* return many values or none matched */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ if (check_possible_values)
+ {
+ stream << " int found = -1;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " FIX_UNUSED (values);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " if (arg) {";
+ stream << "\n";
+ stream << indent_str;
+ if (check_possible_values)
+ {
+ stream << " if (values) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " found = check_possible_values(arg, values); ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (found >= 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(outfile, \"%s=\\\"%s\\\" # %s\\n\", opt, arg, values[found]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(outfile, \"%s=\\\"%s\\\"\\n\", opt, arg);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " fprintf(outfile, \"%s=\\\"%s\\\"\\n\", opt, arg);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(outfile, \"%s\\n\", opt);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (multiple_options)
+ {
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = 0; i < len; ++i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " write_into_file(outfile, opt, (arg ? arg[i] : 0), values);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_dump(FILE *outfile, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!outfile)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: cannot dump options to stream\\n\", ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (file_save_loop.size () > 0)
+ generate_string (file_save_loop, stream, indent + indent_str.length ());
+ else
+ generate_file_save_loop (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " i = EXIT_SUCCESS;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_file_save(const char *filename, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " FILE *outfile;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " outfile = fopen(filename, \"w\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!outfile)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: cannot open file for writing: %s\\n\", ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", filename);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " i = ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_dump(outfile, args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fclose (outfile);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "void";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_free (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_release (args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (do_generate_strdup)
+ {
+ stream << "/** ";
+ stream << "@";
+ stream << "brief replacement of strdup, which is not standard */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "char *";
+ stream << "\n";
+ stream << indent_str;
+ stream << "gengetopt_strdup (const char *s)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *result = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!s)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = (char*)malloc(strlen(s) + 1);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (result == (char*)0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return (char*)0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcpy(result, s);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (multiple_token_functions)
+ {
+ stream << "static char *";
+ stream << "\n";
+ stream << indent_str;
+ stream << "get_multiple_arg_token(const char *arg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *tok;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *ret;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " size_t len, num_of_escape, i, j;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!arg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " tok = strchr (arg, ',');";
+ stream << "\n";
+ stream << indent_str;
+ stream << " num_of_escape = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* make sure it is not escaped */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (tok)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*(tok-1) == '\\\\')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* find the next one */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " tok = strchr (tok+1, ',');";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++num_of_escape;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (tok)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " len = (size_t)(tok - arg + 1);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " len = strlen (arg) + 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " len -= num_of_escape;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " ret = (char *) malloc (len);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " j = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (arg[i] && (j < len-1))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (arg[i] == '\\\\' && ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " arg[ i + 1 ] && ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " arg[ i + 1 ] == ',')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " ret[j++] = arg[i++];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " ret[len-1] = '\\0';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return ret;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static const char *";
+ stream << "\n";
+ stream << indent_str;
+ stream << "get_multiple_arg_token_next(const char *arg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *tok;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!arg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " tok = strchr (arg, ',');";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* make sure it is not escaped */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (tok)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*(tok-1) == '\\\\')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* find the next one */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " tok = strchr (tok+1, ',');";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! tok || strlen(tok) == 1)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return tok+1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (multiple_options)
+ {
+ stream << "static int";
+ stream << "\n";
+ stream << indent_str;
+ stream << "check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ stream << "check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int error = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (option_given && (min > 0 || max > 0))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (min > 0 && max > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (min == max)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* specific occurrences */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (option_given != (unsigned int) min)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %s option occurrences must be %d\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " prog_name, option_desc, min);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else if (option_given < (unsigned int) min";
+ stream << "\n";
+ stream << indent_str;
+ stream << " || option_given > (unsigned int) max)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* range occurrences */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %s option occurrences must be between %d and %d\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " prog_name, option_desc, min, max);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else if (min > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* at least check */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (option_given < min)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %s option occurrences must be at least %d\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " prog_name, option_desc, min);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else if (max > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* at most check */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (option_given > max)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %s option occurrences must be at most %d\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " prog_name, option_desc, max);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ indent = 4;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return error;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (reset_groups.size () > 0)
+ generate_string (reset_groups, stream, indent + indent_str.length ());
+ else
+ generate_reset_groups (stream, indent + indent_str.length ());
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << " (int argc, char **argv, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "2 (argc, argv, args_info, 0, 1, 1);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_ext (int argc, char **argv, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_internal (argc, argv, args_info, params, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (final_exit, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "2 (int argc, char **argv, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, int override, int initialize, int check_required)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params params;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.override = override;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.initialize = initialize;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.check_required = check_required;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.check_ambiguity = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.print_errors = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_internal (argc, argv, args_info, ¶ms, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (final_exit, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_required (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, const char *prog_name)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ if (check_required_options)
+ {
+ stream << " int result = EXIT_SUCCESS;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_required2(args_info, prog_name, 0) > 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (final_exit, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " FIX_UNUSED (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " FIX_UNUSED (prog_name);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return EXIT_SUCCESS;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (check_required_options)
+ {
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_required2 (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, const char *prog_name, const char *additional_error)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int error = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " FIX_UNUSED (additional_error);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* checks for required options */";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (handle_required.size () > 0)
+ generate_string (handle_required, stream, indent + indent_str.length ());
+ else
+ generate_handle_required (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* checks for dependences among options */";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ if (handle_dependencies.size () > 0)
+ generate_string (handle_dependencies, stream, indent + indent_str.length ());
+ else
+ generate_handle_dependencies (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return error;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (include_getopt)
+ {
+ if (custom_getopt.size () > 0)
+ generate_string (custom_getopt, stream, indent + indent_str.length ());
+ else
+ generate_custom_getopt (stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "static char *package_name = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (( ! no_options ))
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "brief updates an option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param field the generic pointer to the field to update";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param orig_field the pointer to the orig field";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param field_given the pointer to the number of occurrence of this option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param prev_given the pointer to the number of occurrence already seen";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param value the argument for this option (if null no arg was specified)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param possible_values the possible values for this option (if specified)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param default_value the default value (in case the option only accepts fixed values)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param arg_type the type of this option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param check_ambiguity ";
+ stream << "@";
+ stream << "see ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params.check_ambiguity";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param override ";
+ stream << "@";
+ stream << "see ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params.override";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param no_free whether to free a possible previous value";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param multiple_option whether this is a multiple option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param long_opt the corresponding long option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param short_opt the corresponding short option (or '-' if none)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param additional_error possible further error specification";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int update_arg(void *field, char **orig_field,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " unsigned int *field_given, unsigned int *prev_given, ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *value, const char *possible_values[],";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *default_value,";
+ stream << "\n";
+ stream << indent_str;
+ indent = 15;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_arg_type arg_type,";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " int check_ambiguity, int override,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int no_free, int multiple_option,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *long_opt, char short_opt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *additional_error)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *stop_char = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *val = value;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int found;";
+ stream << "\n";
+ stream << indent_str;
+ if (has_arg_string)
+ {
+ stream << " char **string_field;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " FIX_UNUSED (field);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " stop_char = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " found = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (short_opt != '-')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: `--%s' (`-%c') option given more than once%s\\n\", ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " package_name, long_opt, short_opt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: `--%s' option given more than once%s\\n\", ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " package_name, long_opt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 1; /* failure */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (check_possible_values)
+ {
+ stream << " if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (short_opt != '-')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %s argument, \\\"%s\\\", for option `--%s' (`-%c')%s\\n\", ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " package_name, (found == -2) ? \"ambiguous\" : \"invalid\", value, long_opt, short_opt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %s argument, \\\"%s\\\", for option `--%s'%s\\n\", ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " package_name, (found == -2) ? \"ambiguous\" : \"invalid\", value, long_opt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 1; /* failure */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " FIX_UNUSED (default_value);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (field_given && *field_given && ! override)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (prev_given)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*prev_given)++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (field_given)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*field_given)++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (possible_values)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " val = possible_values[found];";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch(arg_type) {";
+ stream << "\n";
+ stream << indent_str;
+ if (has_arg_flag)
+ {
+ stream << " case ARG_FLAG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((int *)field) = !*((int *)field);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_int)
+ {
+ stream << " case ARG_INT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((int *)field) = strtol (val, &stop_char, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " case ARG_SHORT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((short *)field) = (short)strtol (val, &stop_char, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " case ARG_LONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((long *)field) = (long)strtol (val, &stop_char, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " case ARG_FLOAT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((float *)field) = (float)strtod (val, &stop_char);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " case ARG_DOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((double *)field) = strtod (val, &stop_char);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " case ARG_LONGDOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((long double *)field) = (long double)strtod (val, &stop_char);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << " case ARG_LONGLONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef HAVE_LONG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((long long int*)field) = (long long int) strtol (val, &stop_char, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((long *)field) = (long)strtol (val, &stop_char, 0);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_enum)
+ {
+ stream << " case ARG_ENUM:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) *((int *)field) = found;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_string)
+ {
+ stream << " case ARG_STRING:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (val) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " string_field = (char **)field;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!no_free && *string_field)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (*string_field); /* free previous string */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *string_field = gengetopt_strdup (val);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " default:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " };";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (( ( ( ( ( ( has_arg_int || has_arg_short ) || has_arg_long ) || has_arg_float ) || has_arg_double ) || has_arg_longdouble ) || has_arg_longlong ))
+ {
+ stream << " /* check numeric conversion */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch(arg_type) {";
+ stream << "\n";
+ stream << indent_str;
+ if (has_arg_int)
+ {
+ stream << " case ARG_INT:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " case ARG_SHORT:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " case ARG_LONG:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " case ARG_FLOAT:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " case ARG_DOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " case ARG_LONGDOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << " case ARG_LONGLONG:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " if (val && !(stop_char && *stop_char == '\\0')) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr, \"%s: invalid numeric value: %s\\n\", package_name, val);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 1; /* failure */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " default:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " };";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* store the original value */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch(arg_type) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " case ARG_NO:";
+ stream << "\n";
+ stream << indent_str;
+ if (has_arg_flag)
+ {
+ stream << " case ARG_FLAG:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " default:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (value && orig_field) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (no_free) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *orig_field = value;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*orig_field)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (*orig_field); /* free previous string */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *orig_field = gengetopt_strdup (value);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " };";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0; /* OK */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (multiple_token_functions)
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "brief store information about a multiple option in a temporary list";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param list where to (temporarily) store multiple options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int update_multiple_arg_temp(struct generic_list **list,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " unsigned int *prev_given, const char *val,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *possible_values[], const char *default_value,";
+ stream << "\n";
+ stream << indent_str;
+ indent = 15;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_arg_type arg_type,";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *long_opt, char short_opt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *additional_error)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* store single arguments */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *multi_token;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *multi_next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (arg_type == ARG_NO) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*prev_given)++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0; /* OK */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " multi_token = get_multiple_arg_token(val);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " multi_next = get_multiple_arg_token_next (val);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (1)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " add_node (list);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " prev_given, multi_token, possible_values, default_value, ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (multi_token) free(multi_token);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 1; /* failure */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (multi_next)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " multi_token = get_multiple_arg_token(multi_next);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " multi_next = get_multiple_arg_token_next (multi_next);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0; /* OK */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "brief free the passed list (including possible string argument)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void free_list(struct generic_list *list, short string_arg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (list) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct generic_list *tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (list)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " tmp = list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (string_arg && list->arg.string_arg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (list->arg.string_arg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (list->orig)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (list->orig);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " list = list->next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (tmp);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "brief updates a multiple option starting from the passed list";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void update_multiple_arg(void *field, char ***orig_field,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " unsigned int field_given, unsigned int prev_given, union generic_value *default_value,";
+ stream << "\n";
+ stream << indent_str;
+ indent = 15;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_arg_type arg_type,";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct generic_list *list)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct generic_list *tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (prev_given && list) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch(arg_type) {";
+ stream << "\n";
+ stream << indent_str;
+ if (( has_arg_int || has_arg_enum ))
+ {
+ if (has_arg_int)
+ {
+ stream << " case ARG_INT:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_enum)
+ {
+ stream << " case ARG_ENUM:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " case ARG_SHORT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((short **)field) = (short *)realloc (*((short **)field), (field_given + prev_given) * sizeof (short)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " case ARG_LONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long **)field) = (long *)realloc (*((long **)field), (field_given + prev_given) * sizeof (long)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " case ARG_FLOAT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((float **)field) = (float *)realloc (*((float **)field), (field_given + prev_given) * sizeof (float)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " case ARG_DOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " case ARG_LONGDOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long double **)field) = (long double *)realloc (*((long double **)field), (field_given + prev_given) * sizeof (long double)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << " case ARG_LONGLONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef HAVE_LONG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long long int **)field) = (long long int *)realloc (*((long long int **)field), (field_given + prev_given) * sizeof (long long int)); break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long **)field) = (long *)realloc (*((long **)field), (field_given + prev_given) * sizeof (long)); break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_string)
+ {
+ stream << " case ARG_STRING:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " default:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " };";
+ stream << "\n";
+ stream << indent_str;
+ indent = 4;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = (prev_given - 1); i >= 0; --i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " tmp = list;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 8;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch(arg_type) {";
+ stream << "\n";
+ stream << indent_str;
+ if (has_arg_int)
+ {
+ stream << " case ARG_INT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " case ARG_SHORT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((short **)field))[i + field_given] = tmp->arg.short_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " case ARG_LONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long **)field))[i + field_given] = tmp->arg.long_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " case ARG_FLOAT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((float **)field))[i + field_given] = tmp->arg.float_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " case ARG_DOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " case ARG_LONGDOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long double **)field))[i + field_given] = tmp->arg.longdouble_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << " case ARG_LONGLONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef HAVE_LONG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long long int **)field))[i + field_given] = tmp->arg.longlong_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long **)field))[i + field_given] = tmp->arg.longlong_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_enum)
+ {
+ stream << " case ARG_ENUM:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_string)
+ {
+ stream << " case ARG_STRING:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " default:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*orig_field) [i + field_given] = list->orig;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " list = list->next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (tmp);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else { /* set the default value */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (default_value && ! field_given) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch(arg_type) {";
+ stream << "\n";
+ stream << indent_str;
+ if (( has_arg_int || has_arg_enum ))
+ {
+ if (has_arg_int)
+ {
+ stream << " case ARG_INT:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_enum)
+ {
+ stream << " case ARG_ENUM:";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " if (! *((int **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((int **)field) = (int *)malloc (sizeof (int));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((int **)field))[0] = default_value->int_arg; ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_short)
+ {
+ stream << " case ARG_SHORT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((short **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((short **)field) = (short *)malloc (sizeof (short));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((short **)field))[0] = default_value->short_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_long)
+ {
+ stream << " case ARG_LONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((long **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long **)field) = (long *)malloc (sizeof (long));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long **)field))[0] = default_value->long_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_float)
+ {
+ stream << " case ARG_FLOAT:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((float **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((float **)field) = (float *)malloc (sizeof (float));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((float **)field))[0] = default_value->float_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_double)
+ {
+ stream << " case ARG_DOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((double **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((double **)field) = (double *)malloc (sizeof (double));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((double **)field))[0] = default_value->double_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longdouble)
+ {
+ stream << " case ARG_LONGDOUBLE:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((long double **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long double **)field) = (long double *)malloc (sizeof (long double));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long double **)field))[0] = default_value->longdouble_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_longlong)
+ {
+ stream << " case ARG_LONGLONG:";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef HAVE_LONG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((long long int **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long long int **)field) = (long long int *)malloc (sizeof (long long int));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long long int **)field))[0] = default_value->longlong_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((long **)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((long **)field) = (long *)malloc (sizeof (long));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((long **)field))[0] = default_value->longlong_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_arg_string)
+ {
+ stream << " case ARG_STRING:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! *((char ***)field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *((char ***)field) = (char **)malloc (sizeof (char *));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " default: break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!(*orig_field)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *orig_field = (char **) malloc (sizeof (char *));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*orig_field)[0] = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_modes)
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int check_modes(";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int given1[], const char *options1[],";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int given2[], const char *options2[])";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0, j = 0, errors = 0;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (given1[i] >= 0) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (given1[i]) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (given2[j] >= 0) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (given2[j]) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++errors;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr, \"%s: option %s conflicts with option %s\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " package_name, options1[i], options2[j]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++j;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return errors;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_internal (";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int argc, char **argv, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params, const char *additional_error)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int c; /* Character of the parsed option. */";
+ stream << "\n";
+ stream << indent_str;
+ if (multiple_options_with_default)
+ {
+ stream << " union generic_value multiple_default_value;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ if (list_def.size () > 0)
+ generate_string (list_def, stream, indent + indent_str.length ());
+ else
+ generate_list_def (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << " int error = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " local_args_info;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int initialize;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int check_required;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int check_ambiguity;";
+ stream << "\n";
+ stream << indent_str;
+ if (include_getopt)
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *optarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int opterr;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int optopt;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " package_name = argv[0];";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " override = params->override;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " initialize = params->initialize;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " check_required = params->check_required;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " check_ambiguity = params->check_ambiguity;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (initialize)";
+ stream << "\n";
+ stream << indent_str;
+ indent = 4;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_init (args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_init (&local_args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " optarg = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " optind = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " opterr = params->print_errors;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " optopt = '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (1)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int option_index = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " static struct option long_options[] = {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 8;
+ if (long_option_struct.size () > 0)
+ generate_string (long_option_struct, stream, indent + indent_str.length ());
+ else
+ generate_long_option_struct (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << " { 0, 0, 0, 0 }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " };";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (include_getopt)
+ {
+ stream << " custom_optarg = optarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_optind = optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_opterr = opterr;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_optopt = optopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " c = custom_getopt_long (argc, argv, \"";
+ generate_string (getopt_string, stream, indent + indent_str.length ());
+ stream << "\", long_options, &option_index);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " optarg = custom_optarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " optind = custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " opterr = custom_opterr;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " optopt = custom_optopt;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " c = getopt_long (argc, argv, \"";
+ generate_string (getopt_string, stream, indent + indent_str.length ());
+ stream << "\", long_options, &option_index);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (c == -1) break; /* Exit from `while (1)' loop. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " switch (c)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 8;
+ if (handle_option.size () > 0)
+ generate_string (handle_option, stream, indent + indent_str.length ());
+ else
+ generate_handle_option (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " case 0: /* Long option with no short option */";
+ stream << "\n";
+ stream << indent_str;
+ indent = 10;
+ if (handle_no_short_option.size () > 0)
+ generate_string (handle_no_short_option, stream, indent + indent_str.length ());
+ else
+ generate_handle_no_short_option (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ if (handle_question_mark)
+ {
+ stream << " case '?': /* Invalid option. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* `getopt_long' already printed an error message. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " goto failure;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << " default: /* bug: option not considered. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: option unknown: %c%s\\n\", ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", c, (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " abort ();";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } /* switch */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } /* while */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ if (handle_group.size () > 0)
+ generate_string (handle_group, stream, indent + indent_str.length ());
+ else
+ generate_handle_group (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ if (multiple_fill_array.size () > 0)
+ generate_string (multiple_fill_array, stream, indent + indent_str.length ());
+ else
+ generate_multiple_fill_array (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ indent = 2;
+ if (update_multiple_given.size () > 0)
+ generate_string (update_multiple_given, stream, indent + indent_str.length ());
+ else
+ generate_update_multiple_given (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ indent = 2;
+ if (check_modes.size () > 0)
+ generate_string (check_modes, stream, indent + indent_str.length ());
+ else
+ generate_check_modes (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (check_required_options)
+ {
+ stream << " if (check_required)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error += ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_required2 (args_info, argv[0], additional_error);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_release (&local_args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ( error )";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return (EXIT_FAILURE);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (handle_unamed)
+ {
+ stream << " if (optind < argc)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i = 0 ;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int found_prog_name = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* whether program name, i.e., argv[0], is in the remaining args";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (this may happen with some implementations of getopt,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " but surely not with the one included by gengetopt) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (include_getopt)
+ {
+
+
+ }
+ else
+ {
+ stream << " i = optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (i < argc)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (argv[i++] == argv[0]) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " found_prog_name = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " i = 0;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->inputs_num = argc - optind - found_prog_name;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->inputs =";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (optind < argc)";
+ stream << "\n";
+ stream << indent_str;
+ if (include_getopt)
+ {
+ stream << " args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " if (argv[optind++] != argv[0])";
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "failure:";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (list_free.size () > 0)
+ generate_string (list_free, stream, indent + indent_str.length ());
+ else
+ generate_list_free (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_release (&local_args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return (EXIT_FAILURE);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ if (conf_parser)
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef CONFIG_FILE_LINE_SIZE";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define CONFIG_FILE_LINE_SIZE 2048";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define ADDITIONAL_ERROR \" in configuration file \"";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define CONFIG_FILE_LINE_BUFFER_SIZE (CONFIG_FILE_LINE_SIZE+3)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* 3 is for \"--\" and \"=\" */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int";
+ stream << "\n";
+ stream << indent_str;
+ stream << "_";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_configfile (const char *filename, int *my_argc)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " FILE* file;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char linebuf[CONFIG_FILE_LINE_SIZE];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int line_num = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int result = 0, equal;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *fopt, *farg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *str_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " size_t len, next_token;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char delimiter;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ((file = fopen(filename, \"r\")) == 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: Error opening configuration file '%s'\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ indent = 15;
+ stream << " ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", filename);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++line_num;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " my_argv[0] = '\\0';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " len = strlen(linebuf);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s:%s:%d: Line too long in configuration file\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ indent = 19;
+ stream << " ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", filename, line_num);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* find first non-whitespace character in the line */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " next_token = strspn (linebuf, \" \\t\\r\\n\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " str_index = linebuf + next_token;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ( str_index[0] == '\\0' || str_index[0] == '#')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " continue; /* empty line or comment line is skipped */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " fopt = str_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* truncate fopt at the end of the first non-valid character */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " next_token = strcspn (fopt, \" \\t\\r\\n=\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (fopt[next_token] == '\\0') /* the line is over */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " farg = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " equal = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " goto noarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* remember if equal sign is present */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " equal = (fopt[next_token] == '=');";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fopt[next_token++] = '\\0';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* advance pointers to the next token after the end of fopt */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " next_token += strspn (fopt + next_token, \" \\t\\r\\n\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* check for the presence of equal sign, and if so, skip it */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ( !equal )";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ((equal = (fopt[next_token] == '=')))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " next_token++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " next_token += strspn (fopt + next_token, \" \\t\\r\\n\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " str_index += next_token;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* find argument */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " farg = str_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ( farg[0] == '\\\"' || farg[0] == '\\'' )";
+ stream << "\n";
+ stream << indent_str;
+ stream << " { /* quoted argument */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " str_index = strchr (++farg, str_index[0] ); /* skip opening quote */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! str_index)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s:%s:%d: unterminated string in configuration file\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ indent = 17;
+ stream << " ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", filename, line_num);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " { /* read up the remaining part up to a delimiter */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " next_token = strcspn (farg, \" \\t\\r\\n#\\'\\\"\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " str_index += next_token;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* truncate farg at the delimiter and store it for further check */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " delimiter = *str_index, *str_index++ = '\\0';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* everything but comment is illegal at the end of line */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (delimiter != '\\0' && delimiter != '#')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " str_index += strspn(str_index, \" \\t\\r\\n\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*str_index != '\\0' && *str_index != '#')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s:%s:%d: malformed string in configuration file\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ indent = 17;
+ stream << " ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", filename, line_num);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = EXIT_FAILURE;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " noarg:";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!strcmp(fopt,\"include\")) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (farg && *farg) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = _";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_configfile(farg, my_argc);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr, \"%s:%s:%d: include requires a filename argument.\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ indent = 18;
+ stream << " ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", filename, line_num);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " continue;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " len = strlen(fopt);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcat (my_argv, len > 1 ? \"--\" : \"-\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcat (my_argv, fopt);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (len > 1 && ((farg && *farg) || equal))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcat (my_argv, \"=\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (farg && *farg)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcat (my_argv, farg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++(*my_argc);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp->next = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list = cmd_line_list_tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list->string_arg = gengetopt_strdup(my_argv);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } /* while */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (file)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fclose(file);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_configfile (";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *filename,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override, int initialize, int check_required)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params params;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.override = override;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.initialize = initialize;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.check_required = check_required;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.check_ambiguity = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.print_errors = 1;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_config_file (filename, args_info, ¶ms);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_config_file (const char *filename,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i, result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int my_argc = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char **my_argv_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *additional_error;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* store the program name */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp->next = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list = cmd_line_list_tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list->string_arg = gengetopt_strdup (";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ");";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = _";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_configfile(filename, &my_argc);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (result != EXIT_FAILURE) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " my_argv_arg = (char **) malloc((my_argc+1) * sizeof(char *));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = my_argc - 1; i >= 0; --i) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " my_argv_arg[i] = cmd_line_list_tmp->string_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = cmd_line_list_tmp->next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " my_argv_arg[my_argc] = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " additional_error = (char *)malloc(strlen(filename) + strlen(ADDITIONAL_ERROR) + 1);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcpy (additional_error, ADDITIONAL_ERROR);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " strcat (additional_error, filename);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " result =";
+ stream << "\n";
+ stream << indent_str;
+ indent = 6;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_internal (my_argc, my_argv_arg, args_info,";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " params,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " additional_error);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (additional_error);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (my_argv_arg);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " free_cmd_list();";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (final_exit, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (generate_string_parser)
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << "static unsigned int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_create_argv(const char *cmdline_, char ***argv_ptr, const char *prog_name)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *cmdline, *p;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " size_t n = 0, j;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (prog_name) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp->next = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list = cmd_line_list_tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list->string_arg = gengetopt_strdup (prog_name);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++n;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmdline = gengetopt_strdup(cmdline_);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " p = cmdline;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (p && strlen(p))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " j = strcspn(p, \" \\t\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++n;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (j && j < strlen(p))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " p[j] = '\\0';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp->next = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list = cmd_line_list_tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list->string_arg = gengetopt_strdup (p);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " p += (j+1);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " p += strspn(p, \" \\t\");";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp->next = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list = cmd_line_list_tmp;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list->string_arg = gengetopt_strdup (p);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " *argv_ptr = (char **) malloc((n + 1) * sizeof(char *));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = cmd_line_list;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = (n-1); i >= 0; --i)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*argv_ptr)[i] = cmd_line_list_tmp->string_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " cmd_line_list_tmp = cmd_line_list_tmp->next;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " (*argv_ptr)[n] = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " free(cmdline);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return n;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string(const char *cmdline, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, const char *prog_name)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string2(cmdline, args_info, prog_name, 0, 1, 1);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string2(const char *cmdline, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, const char *prog_name,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override, int initialize, int check_required)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params params;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.override = override;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.initialize = initialize;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.check_required = check_required;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.check_ambiguity = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " params.print_errors = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " return ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string_ext(cmdline, args_info, prog_name, ¶ms);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "int";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string_ext(const char *cmdline, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info, const char *prog_name,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char **argv_ptr = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " unsigned int argc;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " argc = ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_create_argv(cmdline, &argv_ptr, prog_name);";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " result =";
+ stream << "\n";
+ stream << indent_str;
+ indent = 4;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_internal (argc, argv_ptr, args_info, params, 0);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (argv_ptr)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " free (argv_ptr);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " free_cmd_list();";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (final_exit, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef C_SOURCE_GEN_CLASS_H
+#define C_SOURCE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class c_source_gen_class
+{
+ protected:
+ string args_info;
+ string check_modes;
+ bool check_possible_values;
+ bool check_required_options;
+ string clear_arg;
+ bool cmd_list;
+ string command_line;
+ bool conf_parser;
+ string custom_getopt;
+ string description;
+ string detailed_help_option_print;
+ bool do_generate_strdup;
+ string file_save_loop;
+ string final_exit;
+ string free;
+ string full_help_option_print;
+ bool generate_string_parser;
+ string generator_version;
+ string getopt_string;
+ string given_init;
+ string handle_dependencies;
+ string handle_group;
+ string handle_no_short_option;
+ string handle_option;
+ bool handle_question_mark;
+ string handle_required;
+ bool handle_unamed;
+ bool has_arg_double;
+ bool has_arg_enum;
+ bool has_arg_flag;
+ bool has_arg_float;
+ bool has_arg_int;
+ bool has_arg_long;
+ bool has_arg_longdouble;
+ bool has_arg_longlong;
+ bool has_arg_short;
+ bool has_arg_string;
+ bool has_details;
+ bool has_hidden;
+ bool has_modes;
+ bool has_typed_options;
+ string header_file_ext;
+ string help_option_print;
+ string help_string_num;
+ bool include_getopt;
+ string init_args_info;
+ string list_def;
+ string list_free;
+ string long_option_struct;
+ string multiple_fill_array;
+ bool multiple_options;
+ bool multiple_options_all_string;
+ bool multiple_options_string;
+ bool multiple_options_with_default;
+ bool multiple_token_functions;
+ bool no_options;
+ bool no_package;
+ string option_values;
+ string package_var_name;
+ string parser_name;
+ string purpose;
+ string reset_groups;
+ string source_name;
+ string update_multiple_given;
+ string usage_string;
+ string version_var_name;
+
+ public:
+ c_source_gen_class() :
+ check_possible_values (false), check_required_options (false), cmd_list (false), conf_parser (false), do_generate_strdup (false), generate_string_parser (false), handle_question_mark (false), handle_unamed (false), has_arg_double (false), has_arg_enum (false), has_arg_flag (false), has_arg_float (false), has_arg_int (false), has_arg_long (false), has_arg_longdouble (false), has_arg_longlong (false), has_arg_short (false), has_arg_string (false), has_details (false), has_hidden (false), has_modes (false), has_typed_options (false), include_getopt (false), multiple_options (false), multiple_options_all_string (false), multiple_options_string (false), multiple_options_with_default (false), multiple_token_functions (false), no_options (false), no_package (false)
+ {
+ }
+
+ c_source_gen_class(const string &_args_info, const string &_check_modes, bool _check_possible_values, bool _check_required_options, const string &_clear_arg, bool _cmd_list, const string &_command_line, bool _conf_parser, const string &_custom_getopt, const string &_description, const string &_detailed_help_option_print, bool _do_generate_strdup, const string &_file_save_loop, const string &_final_exit, const string &_free, const string &_full_help_option_print, bool _generate_string_parser, const string &_generator_version, const string &_getopt_string, const string &_given_init, const string &_handle_dependencies, const string &_handle_group, const string &_handle_no_short_option, const string &_handle_option, bool _handle_question_mark, const string &_handle_required, bool _handle_unamed, bool _has_arg_double, bool _has_arg_enum, bool _has_arg_flag, bool _has_arg_float, bool _has_arg_int, bool _has_arg_long, bool _has_arg_longdouble, bool _has_arg_longlong, bool _has_arg_short, bool _has_arg_string, bool _has_details, bool _has_hidden, bool _has_modes, bool _has_typed_options, const string &_header_file_ext, const string &_help_option_print, const string &_help_string_num, bool _include_getopt, const string &_init_args_info, const string &_list_def, const string &_list_free, const string &_long_option_struct, const string &_multiple_fill_array, bool _multiple_options, bool _multiple_options_all_string, bool _multiple_options_string, bool _multiple_options_with_default, bool _multiple_token_functions, bool _no_options, bool _no_package, const string &_option_values, const string &_package_var_name, const string &_parser_name, const string &_purpose, const string &_reset_groups, const string &_source_name, const string &_update_multiple_given, const string &_usage_string, const string &_version_var_name) :
+ args_info (_args_info), check_modes (_check_modes), check_possible_values (_check_possible_values), check_required_options (_check_required_options), clear_arg (_clear_arg), cmd_list (_cmd_list), command_line (_command_line), conf_parser (_conf_parser), custom_getopt (_custom_getopt), description (_description), detailed_help_option_print (_detailed_help_option_print), do_generate_strdup (_do_generate_strdup), file_save_loop (_file_save_loop), final_exit (_final_exit), free (_free), full_help_option_print (_full_help_option_print), generate_string_parser (_generate_string_parser), generator_version (_generator_version), getopt_string (_getopt_string), given_init (_given_init), handle_dependencies (_handle_dependencies), handle_group (_handle_group), handle_no_short_option (_handle_no_short_option), handle_option (_handle_option), handle_question_mark (_handle_question_mark), handle_required (_handle_required), handle_unamed (_handle_unamed), has_arg_double (_has_arg_double), has_arg_enum (_has_arg_enum), has_arg_flag (_has_arg_flag), has_arg_float (_has_arg_float), has_arg_int (_has_arg_int), has_arg_long (_has_arg_long), has_arg_longdouble (_has_arg_longdouble), has_arg_longlong (_has_arg_longlong), has_arg_short (_has_arg_short), has_arg_string (_has_arg_string), has_details (_has_details), has_hidden (_has_hidden), has_modes (_has_modes), has_typed_options (_has_typed_options), header_file_ext (_header_file_ext), help_option_print (_help_option_print), help_string_num (_help_string_num), include_getopt (_include_getopt), init_args_info (_init_args_info), list_def (_list_def), list_free (_list_free), long_option_struct (_long_option_struct), multiple_fill_array (_multiple_fill_array), multiple_options (_multiple_options), multiple_options_all_string (_multiple_options_all_string), multiple_options_string (_multiple_options_string), multiple_options_with_default (_multiple_options_with_default), multiple_token_functions (_multiple_token_functions), no_options (_no_options), no_package (_no_package), option_values (_option_values), package_var_name (_package_var_name), parser_name (_parser_name), purpose (_purpose), reset_groups (_reset_groups), source_name (_source_name), update_multiple_given (_update_multiple_given), usage_string (_usage_string), version_var_name (_version_var_name)
+ {
+ }
+
+ virtual ~c_source_gen_class()
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_args_info(const string &_args_info)
+ {
+ args_info = _args_info;
+ }
+
+ virtual void generate_check_modes(ostream &stream, unsigned int indent) = 0;
+
+ void set_check_modes(const string &_check_modes)
+ {
+ check_modes = _check_modes;
+ }
+
+ void set_check_possible_values(bool _check_possible_values)
+ {
+ check_possible_values = _check_possible_values;
+ }
+
+ void set_check_required_options(bool _check_required_options)
+ {
+ check_required_options = _check_required_options;
+ }
+
+ virtual void generate_clear_arg(ostream &stream, unsigned int indent) = 0;
+
+ void set_clear_arg(const string &_clear_arg)
+ {
+ clear_arg = _clear_arg;
+ }
+
+ void set_cmd_list(bool _cmd_list)
+ {
+ cmd_list = _cmd_list;
+ }
+
+ void set_command_line(const string &_command_line)
+ {
+ command_line = _command_line;
+ }
+
+ void set_conf_parser(bool _conf_parser)
+ {
+ conf_parser = _conf_parser;
+ }
+
+ virtual void generate_custom_getopt(ostream &stream, unsigned int indent) = 0;
+
+ void set_custom_getopt(const string &_custom_getopt)
+ {
+ custom_getopt = _custom_getopt;
+ }
+
+ void set_description(const string &_description)
+ {
+ description = _description;
+ }
+
+ virtual void generate_detailed_help_option_print(ostream &stream, unsigned int indent) = 0;
+
+ void set_detailed_help_option_print(const string &_detailed_help_option_print)
+ {
+ detailed_help_option_print = _detailed_help_option_print;
+ }
+
+ void set_do_generate_strdup(bool _do_generate_strdup)
+ {
+ do_generate_strdup = _do_generate_strdup;
+ }
+
+ virtual void generate_file_save_loop(ostream &stream, unsigned int indent) = 0;
+
+ void set_file_save_loop(const string &_file_save_loop)
+ {
+ file_save_loop = _file_save_loop;
+ }
+
+ void set_final_exit(const string &_final_exit)
+ {
+ final_exit = _final_exit;
+ }
+
+ virtual void generate_free(ostream &stream, unsigned int indent) = 0;
+
+ void set_free(const string &_free)
+ {
+ free = _free;
+ }
+
+ virtual void generate_full_help_option_print(ostream &stream, unsigned int indent) = 0;
+
+ void set_full_help_option_print(const string &_full_help_option_print)
+ {
+ full_help_option_print = _full_help_option_print;
+ }
+
+ void set_generate_string_parser(bool _generate_string_parser)
+ {
+ generate_string_parser = _generate_string_parser;
+ }
+
+ void set_generator_version(const string &_generator_version)
+ {
+ generator_version = _generator_version;
+ }
+
+ void set_getopt_string(const string &_getopt_string)
+ {
+ getopt_string = _getopt_string;
+ }
+
+ virtual void generate_given_init(ostream &stream, unsigned int indent) = 0;
+
+ void set_given_init(const string &_given_init)
+ {
+ given_init = _given_init;
+ }
+
+ virtual void generate_handle_dependencies(ostream &stream, unsigned int indent) = 0;
+
+ void set_handle_dependencies(const string &_handle_dependencies)
+ {
+ handle_dependencies = _handle_dependencies;
+ }
+
+ virtual void generate_handle_group(ostream &stream, unsigned int indent) = 0;
+
+ void set_handle_group(const string &_handle_group)
+ {
+ handle_group = _handle_group;
+ }
+
+ virtual void generate_handle_no_short_option(ostream &stream, unsigned int indent) = 0;
+
+ void set_handle_no_short_option(const string &_handle_no_short_option)
+ {
+ handle_no_short_option = _handle_no_short_option;
+ }
+
+ virtual void generate_handle_option(ostream &stream, unsigned int indent) = 0;
+
+ void set_handle_option(const string &_handle_option)
+ {
+ handle_option = _handle_option;
+ }
+
+ void set_handle_question_mark(bool _handle_question_mark)
+ {
+ handle_question_mark = _handle_question_mark;
+ }
+
+ virtual void generate_handle_required(ostream &stream, unsigned int indent) = 0;
+
+ void set_handle_required(const string &_handle_required)
+ {
+ handle_required = _handle_required;
+ }
+
+ void set_handle_unamed(bool _handle_unamed)
+ {
+ handle_unamed = _handle_unamed;
+ }
+
+ void set_has_arg_double(bool _has_arg_double)
+ {
+ has_arg_double = _has_arg_double;
+ }
+
+ void set_has_arg_enum(bool _has_arg_enum)
+ {
+ has_arg_enum = _has_arg_enum;
+ }
+
+ void set_has_arg_flag(bool _has_arg_flag)
+ {
+ has_arg_flag = _has_arg_flag;
+ }
+
+ void set_has_arg_float(bool _has_arg_float)
+ {
+ has_arg_float = _has_arg_float;
+ }
+
+ void set_has_arg_int(bool _has_arg_int)
+ {
+ has_arg_int = _has_arg_int;
+ }
+
+ void set_has_arg_long(bool _has_arg_long)
+ {
+ has_arg_long = _has_arg_long;
+ }
+
+ void set_has_arg_longdouble(bool _has_arg_longdouble)
+ {
+ has_arg_longdouble = _has_arg_longdouble;
+ }
+
+ void set_has_arg_longlong(bool _has_arg_longlong)
+ {
+ has_arg_longlong = _has_arg_longlong;
+ }
+
+ void set_has_arg_short(bool _has_arg_short)
+ {
+ has_arg_short = _has_arg_short;
+ }
+
+ void set_has_arg_string(bool _has_arg_string)
+ {
+ has_arg_string = _has_arg_string;
+ }
+
+ void set_has_details(bool _has_details)
+ {
+ has_details = _has_details;
+ }
+
+ void set_has_hidden(bool _has_hidden)
+ {
+ has_hidden = _has_hidden;
+ }
+
+ void set_has_modes(bool _has_modes)
+ {
+ has_modes = _has_modes;
+ }
+
+ void set_has_typed_options(bool _has_typed_options)
+ {
+ has_typed_options = _has_typed_options;
+ }
+
+ void set_header_file_ext(const string &_header_file_ext)
+ {
+ header_file_ext = _header_file_ext;
+ }
+
+ virtual void generate_help_option_print(ostream &stream, unsigned int indent) = 0;
+
+ void set_help_option_print(const string &_help_option_print)
+ {
+ help_option_print = _help_option_print;
+ }
+
+ void set_help_string_num(const string &_help_string_num)
+ {
+ help_string_num = _help_string_num;
+ }
+
+ void set_include_getopt(bool _include_getopt)
+ {
+ include_getopt = _include_getopt;
+ }
+
+ virtual void generate_init_args_info(ostream &stream, unsigned int indent) = 0;
+
+ void set_init_args_info(const string &_init_args_info)
+ {
+ init_args_info = _init_args_info;
+ }
+
+ virtual void generate_list_def(ostream &stream, unsigned int indent) = 0;
+
+ void set_list_def(const string &_list_def)
+ {
+ list_def = _list_def;
+ }
+
+ virtual void generate_list_free(ostream &stream, unsigned int indent) = 0;
+
+ void set_list_free(const string &_list_free)
+ {
+ list_free = _list_free;
+ }
+
+ virtual void generate_long_option_struct(ostream &stream, unsigned int indent) = 0;
+
+ void set_long_option_struct(const string &_long_option_struct)
+ {
+ long_option_struct = _long_option_struct;
+ }
+
+ virtual void generate_multiple_fill_array(ostream &stream, unsigned int indent) = 0;
+
+ void set_multiple_fill_array(const string &_multiple_fill_array)
+ {
+ multiple_fill_array = _multiple_fill_array;
+ }
+
+ void set_multiple_options(bool _multiple_options)
+ {
+ multiple_options = _multiple_options;
+ }
+
+ void set_multiple_options_all_string(bool _multiple_options_all_string)
+ {
+ multiple_options_all_string = _multiple_options_all_string;
+ }
+
+ void set_multiple_options_string(bool _multiple_options_string)
+ {
+ multiple_options_string = _multiple_options_string;
+ }
+
+ void set_multiple_options_with_default(bool _multiple_options_with_default)
+ {
+ multiple_options_with_default = _multiple_options_with_default;
+ }
+
+ void set_multiple_token_functions(bool _multiple_token_functions)
+ {
+ multiple_token_functions = _multiple_token_functions;
+ }
+
+ void set_no_options(bool _no_options)
+ {
+ no_options = _no_options;
+ }
+
+ void set_no_package(bool _no_package)
+ {
+ no_package = _no_package;
+ }
+
+ virtual void generate_option_values(ostream &stream, unsigned int indent) = 0;
+
+ void set_option_values(const string &_option_values)
+ {
+ option_values = _option_values;
+ }
+
+ void set_package_var_name(const string &_package_var_name)
+ {
+ package_var_name = _package_var_name;
+ }
+
+ void set_parser_name(const string &_parser_name)
+ {
+ parser_name = _parser_name;
+ }
+
+ void set_purpose(const string &_purpose)
+ {
+ purpose = _purpose;
+ }
+
+ virtual void generate_reset_groups(ostream &stream, unsigned int indent) = 0;
+
+ void set_reset_groups(const string &_reset_groups)
+ {
+ reset_groups = _reset_groups;
+ }
+
+ void set_source_name(const string &_source_name)
+ {
+ source_name = _source_name;
+ }
+
+ virtual void generate_update_multiple_given(ostream &stream, unsigned int indent) = 0;
+
+ void set_update_multiple_given(const string &_update_multiple_given)
+ {
+ update_multiple_given = _update_multiple_given;
+ }
+
+ void set_usage_string(const string &_usage_string)
+ {
+ usage_string = _usage_string;
+ }
+
+ void set_version_var_name(const string &_version_var_name)
+ {
+ version_var_name = _version_var_name;
+ }
+
+ void generate_c_source(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // C_SOURCE_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "check_modes.h"
+
+void
+check_modes_gen_class::generate_check_modes(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "if (args_info->";
+ generate_string (mode1_name, stream, indent + indent_str.length ());
+ stream << "_mode_counter && args_info->";
+ generate_string (mode2_name, stream, indent + indent_str.length ());
+ stream << "_mode_counter) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int ";
+ generate_string (mode1_name, stream, indent + indent_str.length ());
+ stream << "_given[] = {";
+ generate_string (mode1_given_fields, stream, indent + indent_str.length ());
+ stream << " -1};";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *";
+ generate_string (mode1_name, stream, indent + indent_str.length ());
+ stream << "_desc[] = {";
+ generate_string (mode1_options, stream, indent + indent_str.length ());
+ stream << " 0};";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int ";
+ generate_string (mode2_name, stream, indent + indent_str.length ());
+ stream << "_given[] = {";
+ generate_string (mode2_given_fields, stream, indent + indent_str.length ());
+ stream << " -1};";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *";
+ generate_string (mode2_name, stream, indent + indent_str.length ());
+ stream << "_desc[] = {";
+ generate_string (mode2_options, stream, indent + indent_str.length ());
+ stream << " 0};";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error += check_modes(";
+ generate_string (mode1_name, stream, indent + indent_str.length ());
+ stream << "_given, ";
+ generate_string (mode1_name, stream, indent + indent_str.length ());
+ stream << "_desc, ";
+ generate_string (mode2_name, stream, indent + indent_str.length ());
+ stream << "_given, ";
+ generate_string (mode2_name, stream, indent + indent_str.length ());
+ stream << "_desc);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CHECK_MODES_GEN_CLASS_H
+#define CHECK_MODES_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class check_modes_gen_class
+{
+ protected:
+ string mode1_given_fields;
+ string mode1_name;
+ string mode1_options;
+ string mode2_given_fields;
+ string mode2_name;
+ string mode2_options;
+
+ public:
+ check_modes_gen_class()
+ {
+ }
+
+ check_modes_gen_class(const string &_mode1_given_fields, const string &_mode1_name, const string &_mode1_options, const string &_mode2_given_fields, const string &_mode2_name, const string &_mode2_options) :
+ mode1_given_fields (_mode1_given_fields), mode1_name (_mode1_name), mode1_options (_mode1_options), mode2_given_fields (_mode2_given_fields), mode2_name (_mode2_name), mode2_options (_mode2_options)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_mode1_given_fields(const string &_mode1_given_fields)
+ {
+ mode1_given_fields = _mode1_given_fields;
+ }
+
+ void set_mode1_name(const string &_mode1_name)
+ {
+ mode1_name = _mode1_name;
+ }
+
+ void set_mode1_options(const string &_mode1_options)
+ {
+ mode1_options = _mode1_options;
+ }
+
+ void set_mode2_given_fields(const string &_mode2_given_fields)
+ {
+ mode2_given_fields = _mode2_given_fields;
+ }
+
+ void set_mode2_name(const string &_mode2_name)
+ {
+ mode2_name = _mode2_name;
+ }
+
+ void set_mode2_options(const string &_mode2_options)
+ {
+ mode2_options = _mode2_options;
+ }
+
+ void generate_check_modes(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // CHECK_MODES_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "clear_arg.h"
+
+void
+clear_arg_gen_class::generate_clear_arg(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (has_arg)
+ {
+ stream << "args_info->";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_";
+ generate_string (suffix, stream, indent + indent_str.length ());
+ stream << " = ";
+ generate_string (value, stream, indent + indent_str.length ());
+ stream << ";";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_orig)
+ {
+ stream << "args_info->";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_orig = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CLEAR_ARG_GEN_CLASS_H
+#define CLEAR_ARG_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class clear_arg_gen_class
+{
+ protected:
+ bool has_arg;
+ bool has_orig;
+ string name;
+ string suffix;
+ string value;
+
+ public:
+ clear_arg_gen_class() :
+ has_arg (false), has_orig (false)
+ {
+ }
+
+ clear_arg_gen_class(bool _has_arg, bool _has_orig, const string &_name, const string &_suffix, const string &_value) :
+ has_arg (_has_arg), has_orig (_has_orig), name (_name), suffix (_suffix), value (_value)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_has_arg(bool _has_arg)
+ {
+ has_arg = _has_arg;
+ }
+
+ void set_has_orig(bool _has_orig)
+ {
+ has_orig = _has_orig;
+ }
+
+ void set_name(const string &_name)
+ {
+ name = _name;
+ }
+
+ void set_suffix(const string &_suffix)
+ {
+ suffix = _suffix;
+ }
+
+ void set_value(const string &_value)
+ {
+ value = _value;
+ }
+
+ void generate_clear_arg(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // CLEAR_ARG_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "clear_given.h"
+
+void
+clear_given_gen_class::generate_clear_given(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ generate_string (arg_struct, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << "_given = 0 ;";
+ if (group)
+ {
+ indent = 1;
+ stream << " ";
+ generate_string (arg_struct, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << "_group = 0 ;";
+ }
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CLEAR_GIVEN_GEN_CLASS_H
+#define CLEAR_GIVEN_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class clear_given_gen_class
+{
+ protected:
+ string arg_struct;
+ bool group;
+ string var_arg;
+
+ public:
+ clear_given_gen_class() :
+ group (false)
+ {
+ }
+
+ clear_given_gen_class(const string &_arg_struct, bool _group, const string &_var_arg) :
+ arg_struct (_arg_struct), group (_group), var_arg (_var_arg)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_arg_struct(const string &_arg_struct)
+ {
+ arg_struct = _arg_struct;
+ }
+
+ void set_group(bool _group)
+ {
+ group = _group;
+ }
+
+ void set_var_arg(const string &_var_arg)
+ {
+ var_arg = _var_arg;
+ }
+
+ void generate_clear_given(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // CLEAR_GIVEN_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "copyright.h"
+
+void
+copyright_gen_class::generate_copyright(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "Copyright (C) ";
+ generate_string (year, stream, indent + indent_str.length ());
+ stream << " Free Software Foundation Inc.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "This program comes with ABSOLUTELY NO WARRANTY; for details";
+ stream << "\n";
+ stream << indent_str;
+ stream << "please see the file 'COPYING' supplied with the source code.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "This is free software, and you are welcome to redistribute it";
+ stream << "\n";
+ stream << indent_str;
+ stream << "under certain conditions; again, see 'COPYING' for details.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "This program is released under the GNU General Public License.";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef COPYRIGHT_GEN_CLASS_H
+#define COPYRIGHT_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class copyright_gen_class
+{
+ protected:
+ string year;
+
+ public:
+ copyright_gen_class()
+ {
+ }
+
+ copyright_gen_class(const string &_year) :
+ year (_year)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_year(const string &_year)
+ {
+ year = _year;
+ }
+
+ void generate_copyright(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // COPYRIGHT_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "custom_getopt_gen.h"
+
+void
+custom_getopt_gen_gen_class::generate_custom_getopt_gen(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Extracted from the glibc source tree, version 2.3.6";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Licensed under the GPL as per the whole glibc source tree.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * This file was modified so that getopt_long can be called";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * many times without risking previous memory to be spoiled.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Modified by Andre Noll and Lorenzo Bettini for use in";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * GNU gengetopt generated files.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * we must include anything we need since this file is not thought to be";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * inserted in a file already using getopt.h";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Lorenzo";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct option";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *name;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* has_arg can't be an enum because some compilers complain about";
+ stream << "\n";
+ stream << indent_str;
+ stream << " type mismatches in all the code that assumes it is an int. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int has_arg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int *flag;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int val;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* This version of `getopt' appears to the caller like standard Unix `getopt'";
+ stream << "\n";
+ stream << indent_str;
+ stream << " but it behaves differently for the user, since it allows the user";
+ stream << "\n";
+ stream << indent_str;
+ stream << " to intersperse the options with the other arguments.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " As `getopt' works, it permutes the elements of ARGV so that,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " when it is done, all the options precede everything else. Thus";
+ stream << "\n";
+ stream << indent_str;
+ stream << " all application programs are extended to handle flexible argument order.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "*/";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " If the field `flag' is not NULL, it points to a variable that is set";
+ stream << "\n";
+ stream << indent_str;
+ stream << " to the value given in the field `val' when the option is found, but";
+ stream << "\n";
+ stream << indent_str;
+ stream << " left unchanged if the option is not found.";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " To have a long-named option do something other than set an `int' to";
+ stream << "\n";
+ stream << indent_str;
+ stream << " a compiled-in constant, such as set a value from `custom_optarg', set the";
+ stream << "\n";
+ stream << indent_str;
+ stream << " option's `flag' field to zero and its `val' field to a nonzero";
+ stream << "\n";
+ stream << indent_str;
+ stream << " value (the equivalent single-letter option character, if there is";
+ stream << "\n";
+ stream << indent_str;
+ stream << " one). For long options that have a zero `flag' field, `getopt'";
+ stream << "\n";
+ stream << indent_str;
+ stream << " returns the contents of the `val' field. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* Names for the values of the `has_arg' field of `struct option'. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef no_argument";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define no_argument 0";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef required_argument";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define required_argument 1";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef optional_argument";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define optional_argument 2";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct custom_getopt_data {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * These have exactly the same meaning as the corresponding global variables,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * except that they are used for the reentrant versions of getopt.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int custom_opterr;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int custom_optopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *custom_optarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* True if the internal members have been initialized. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int initialized;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The next char to be scanned in the option-element in which the last option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * character we returned was found. This allows us to pick up the scan where";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * we left off. If this is zero, or a null string, it means resume the scan by";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * advancing to the next ARGV-element.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *nextchar;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Describe the part of ARGV that contains non-options that have been skipped.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * the index after the last of them.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int first_nonopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int last_nonopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "};";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * the variables optarg, optind, opterr and optopt are renamed with";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * the custom_ prefix so that they don't interfere with getopt ones.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Moreover they're static so they are visible only from within the";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * file where this very file will be included.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * option that takes an argument, the argument value is returned here.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static char *custom_optarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Index in ARGV of the next element to be scanned. This is used for";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * communication to and from the caller and for communication between";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * successive calls to `custom_getopt'.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * On entry to `custom_getopt', 1 means this is the first call; initialize.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * When `custom_getopt' returns -1, this is the index of the first of the non-option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * elements that the caller should itself scan.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * has been scanned so far.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * 1003.2 says this must be 1 before any call.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int custom_optind = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Callers store zero here to inhibit the error message for unrecognized";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * options.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int custom_opterr = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Set to an option character which was unrecognized. This must be initialized";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * on some systems to avoid linking in the system's own getopt implementation.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int custom_optopt = '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Exchange two adjacent subsequences of ARGV. One subsequence is elements";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * [first_nonopt,last_nonopt) which contains all the non-options that have been";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * skipped so far. The other is elements [last_nonopt,custom_optind), which contains";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * all the options processed since those non-options were skipped.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * `first_nonopt' and `last_nonopt' are relocated so that they describe the new";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * indices of the non-options in ARGV after they are moved.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void exchange(char **argv, struct custom_getopt_data *d)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int bottom = d->first_nonopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int middle = d->last_nonopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int top = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *tem;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Exchange the shorter segment with the far end of the longer segment.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * That puts the shorter segment into the right place. It leaves the";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * longer segment in the right place overall, but it consists of two";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * parts that need to be swapped next.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (top > middle && middle > bottom) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (top - middle > middle - bottom) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Bottom segment is the short one. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int len = middle - bottom;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Swap it with the top part of the top segment. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = 0; i < len; i++) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " tem = argv[bottom + i];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[bottom + i] =";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[top - (middle - bottom) + i];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[top - (middle - bottom) + i] = tem;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Exclude the moved bottom segment from further swapping. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " top -= len;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Top segment is the short one. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int len = top - middle;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int i;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Swap it with the bottom part of the bottom segment. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (i = 0; i < len; i++) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " tem = argv[bottom + i];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[bottom + i] = argv[middle + i];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[middle + i] = tem;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Exclude the moved top segment from further swapping. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " bottom += len;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Update records for the slots the non-options now occupy. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->first_nonopt += (d->custom_optind - d->last_nonopt);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->last_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* Initialize the internal data when the first call is made. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static void custom_getopt_initialize(struct custom_getopt_data *d)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Start processing options with ARGV-element 1 (since ARGV-element 0";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * is the program name); the sequence of previously skipped non-option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ARGV-elements is empty.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->first_nonopt = d->last_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->initialized = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\\0')";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* return: zero: continue, nonzero: return given value to user */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct custom_getopt_data *d)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * moved back by the user (who may also have changed the arguments).";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->last_nonopt > d->custom_optind)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->last_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->first_nonopt > d->custom_optind)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->first_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If we have just processed some options following some";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * non-options, exchange them so that the options come first.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->first_nonopt != d->last_nonopt &&";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->last_nonopt != d->custom_optind)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " exchange((char **) argv, d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else if (d->last_nonopt != d->custom_optind)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->first_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Skip any additional non-options and extend the range of";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * non-options previously skipped.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " while (d->custom_optind < argc && NONOPTION_P)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->last_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The special ARGV-element `--' means premature end of options. Skip";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * it like a null option, then exchange with previous non-options as if";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * it were an option, then skip everything else like a non-option.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], \"--\")) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->first_nonopt != d->last_nonopt";
+ stream << "\n";
+ stream << indent_str;
+ stream << " && d->last_nonopt != d->custom_optind)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " exchange((char **) argv, d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else if (d->first_nonopt == d->last_nonopt)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->first_nonopt = d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->last_nonopt = argc;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind = argc;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If we have done all the ARGV-elements, stop the scan and back over";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * any non-options that we skipped and permuted.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->custom_optind == argc) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Set the next-arg-index to point at the non-options that we";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * previously skipped, so the caller will digest them.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->first_nonopt != d->last_nonopt)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind = d->first_nonopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return -1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If we have come to a non-option and did not permute it, either stop";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * the scan or describe it to the caller and pass it by.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (NONOPTION_P) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = argv[d->custom_optind++];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * We have found another option-ARGV-element. Skip the initial";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * punctuation.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Check whether the ARGV-element is a long option.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If there's a long option \"fubar\" and the ARGV-element is \"-fu\", consider";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * that an abbreviation of the long option, just like \"--fu\", and not \"-f\" with";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * arg \"u\".";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * This distinction seems to be the most useful approach.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int check_long_opt(int argc, char *const *argv, const char *optstring,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const struct option *longopts, int *longind,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int print_errors, struct custom_getopt_data *d)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char *nameend;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const struct option *p;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const struct option *pfound = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int exact = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int ambig = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int indfound = -1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int option_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Do nothing. */ ;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Test all long options for either exact match or abbreviated matches */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " for (p = longopts, option_index = 0; p->name; p++, option_index++)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if ((unsigned int) (nameend - d->nextchar)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " == (unsigned int) strlen(p->name)) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Exact match found. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " pfound = p;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " indfound = option_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " exact = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else if (pfound == NULL) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* First nonexact match found. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " pfound = p;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " indfound = option_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else if (pfound->has_arg != p->has_arg";
+ stream << "\n";
+ stream << indent_str;
+ stream << " || pfound->flag != p->flag";
+ stream << "\n";
+ stream << indent_str;
+ stream << " || pfound->val != p->val)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Second or later nonexact match found. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ambig = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (ambig && !exact) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (print_errors) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s: option `%s' is ambiguous\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0], argv[d->custom_optind]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar += strlen(d->nextchar);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optopt = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (pfound) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " option_index = indfound;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*nameend) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (pfound->has_arg != no_argument)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = nameend + 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (print_errors) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (argv[d->custom_optind - 1][1] == '-') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* --option */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr, \"%s: option `--%s' doesn't allow an argument\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0], pfound->name);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* +option or -option */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr, \"%s: option `%c%s' doesn't allow an argument\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0], argv[d->custom_optind - 1][0], pfound->name);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar += strlen(d->nextchar);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optopt = pfound->val;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else if (pfound->has_arg == required_argument) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->custom_optind < argc)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = argv[d->custom_optind++];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (print_errors) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s: option `%s' requires an argument\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0],";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[d->custom_optind - 1]);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar += strlen(d->nextchar);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optopt = pfound->val;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return optstring[0] == ':' ? ':' : '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar += strlen(d->nextchar);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (longind != NULL)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *longind = option_index;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (pfound->flag) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *(pfound->flag) = pfound->val;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return pfound->val;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Can't find it as a long option. If this is not getopt_long_only, or";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * the option starts with '--' or is not a valid short option, then";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * it's an error. Otherwise interpret it as a short option.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (print_errors) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (argv[d->custom_optind][1] == '-') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* --option */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s: unrecognized option `--%s'\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0], d->nextchar);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* +option or -option */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s: unrecognized option `%c%s'\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0], argv[d->custom_optind][0],";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar = (char *) \"\";";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optopt = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int check_short_opt(int argc, char *const *argv, const char *optstring,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int print_errors, struct custom_getopt_data *d)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " char c = *d->nextchar++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *temp = strchr(optstring, c);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Increment `custom_optind' when we start to process its last character. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*d->nextchar == '\\0')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ++d->custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (!temp || c == ':') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (print_errors)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr, \"%s: invalid option -- %c\\n\", argv[0], c);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optopt = c;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (temp[1] == ':') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (temp[2] == ':') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* This is an option that accepts an argument optionally. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*d->nextchar != '\\0') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = d->nextchar;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* This is an option that requires an argument. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (*d->nextchar != '\\0') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = d->nextchar;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If we end this ARGV-element by taking the";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * rest as an arg, we must advance to the next";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * element now.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind++;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else if (d->custom_optind == argc) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (print_errors) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf(stderr,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"%s: option requires an argument -- %c\\n\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " argv[0], c);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optopt = c;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (optstring[0] == ':')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " c = ':';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " c = '?';";
+ stream << "\n";
+ stream << indent_str;
+ stream << " } else";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * We already incremented `custom_optind' once;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * increment it again when taking next ARGV-elt";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * as argument.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = argv[d->custom_optind++];";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->nextchar = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return c;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/*";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Scan elements of ARGV for option characters given in OPTSTRING.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If an element of ARGV starts with '-', and is not exactly \"-\" or \"--\",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * then it is an option element. The characters of this element";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * (aside from the initial '-') are option characters. If `getopt'";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * is called repeatedly, it returns successively each of the option characters";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * from each of the option elements.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If `getopt' finds another option character, it returns that character,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * updating `custom_optind' and `nextchar' so that the next call to `getopt' can";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * resume the scan with the following option character or ARGV-element.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If there are no more option characters, `getopt' returns -1.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Then `custom_optind' is the index in ARGV of the first ARGV-element";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * that is not an option. (The ARGV-elements have been permuted";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * so that those that are not options now come last.)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * OPTSTRING is a string containing the legitimate option characters.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If an option character is seen that is not listed in OPTSTRING,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * return '?' after printing an error message. If you set `custom_opterr' to";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * zero, the error message is suppressed but we still return '?'.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If a char in OPTSTRING is followed by a colon, that means it wants an arg,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * so the following text in the same ARGV-element, or the text of the following";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * wants an optional arg; if there is text in the current ARGV-element,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If OPTSTRING starts with `-' or `+', it requests different methods of";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * handling the non-option ARGV-elements.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Long-named options begin with `--' instead of `-'.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Their names may be abbreviated as long as the abbreviation is unique";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * or is an exact match for some defined option. If they have an";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * argument, it follows the option name in the same ARGV-element, separated";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * from the option name by a `=', or else the in next ARGV-element.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * When `getopt' finds a long-named option, it returns 0 if that option's";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * `flag' field is nonzero, the value of the option's `val' field";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * if the `flag' field is zero.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The elements of ARGV aren't really const, because we permute them.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * But we pretend they're const in the prototype to be compatible";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * with other systems.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * LONGOPTS is a vector of `struct option' terminated by an";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * element containing a name which is zero.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * LONGIND returns the index in LONGOPT of the long-named option found.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * It is only valid when a long-named option has been found by the most";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * recent call.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Return the option character from OPTS just read. Return -1 when there are";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * no more options. For unrecognized options, or options missing arguments,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * `custom_optopt' is set to the option letter, and '?' is returned.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The OPTS string is a list of characters which are recognized option letters,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * optionally followed by colons, specifying that that letter takes an";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * argument, to be placed in `custom_optarg'.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * If a letter in OPTS is followed by two colons, its argument is optional.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * This behavior is specific to the GNU `getopt'.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " *";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The argument `--' causes premature termination of argument scanning,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * explicitly telling `getopt' that there are no more options. If OPTS begins";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * with `--', then non-option arguments are treated as arguments to the option";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * '\\0'. This behavior is specific to the GNU `getopt'.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int getopt_internal_r(int argc, char *const *argv, const char *optstring,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const struct option *longopts, int *longind,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct custom_getopt_data *d)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int ret, print_errors = d->custom_opterr;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (optstring[0] == ':')";
+ stream << "\n";
+ stream << indent_str;
+ stream << " print_errors = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (argc < 1)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return -1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optarg = NULL;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * This is a big difference with GNU getopt, since optind == 0";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * means initialization while here 1 means first call.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->custom_optind == 0 || !d->initialized) {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->custom_optind == 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_getopt_initialize(d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (d->nextchar == NULL || *d->nextchar == '\\0') {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " ret = shuffle_argv(argc, argv, longopts, d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (ret)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return ret;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (longopts && (argv[d->custom_optind][1] == '-' ))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return check_long_opt(argc, argv, optstring, longopts,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " longind, print_errors, d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return check_short_opt(argc, argv, optstring, print_errors, d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const struct option *longopts, int *longind)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " /* Keep a global copy of all internal members of d */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " static struct custom_getopt_data d;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << " d.custom_optind = custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " d.custom_opterr = custom_opterr;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " result = getopt_internal_r(argc, argv, optstring, longopts,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " longind, &d);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_optind = d.custom_optind;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_optarg = d.custom_optarg;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " custom_optopt = d.custom_optopt;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return result;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "static int custom_getopt_long (int argc, char *const *argv, const char *options,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const struct option *long_options, int *opt_index)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return custom_getopt_internal(argc, argv, options, long_options,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " opt_index);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CUSTOM_GETOPT_GEN_GEN_CLASS_H
+#define CUSTOM_GETOPT_GEN_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class custom_getopt_gen_gen_class
+{
+ protected:
+
+ public:
+ custom_getopt_gen_gen_class()
+ {
+ }
+
+
+ void generate_custom_getopt_gen(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // CUSTOM_GETOPT_GEN_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "dependant_option.h"
+
+void
+dependant_option_gen_class::generate_dependant_option(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "if (args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given && ! args_info->";
+ generate_string (dep_option, stream, indent + indent_str.length ());
+ stream << "_given)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: ";
+ generate_string (option_descr, stream, indent + indent_str.length ());
+ stream << " option depends on option '";
+ generate_string (dep_option_descr, stream, indent + indent_str.length ());
+ stream << "'%s\\n\", ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef DEPENDANT_OPTION_GEN_CLASS_H
+#define DEPENDANT_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class dependant_option_gen_class
+{
+ protected:
+ string dep_option;
+ string dep_option_descr;
+ string option_descr;
+ string option_var_name;
+ string package_var_name;
+
+ public:
+ dependant_option_gen_class()
+ {
+ }
+
+ dependant_option_gen_class(const string &_dep_option, const string &_dep_option_descr, const string &_option_descr, const string &_option_var_name, const string &_package_var_name) :
+ dep_option (_dep_option), dep_option_descr (_dep_option_descr), option_descr (_option_descr), option_var_name (_option_var_name), package_var_name (_package_var_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_dep_option(const string &_dep_option)
+ {
+ dep_option = _dep_option;
+ }
+
+ void set_dep_option_descr(const string &_dep_option_descr)
+ {
+ dep_option_descr = _dep_option_descr;
+ }
+
+ void set_option_descr(const string &_option_descr)
+ {
+ option_descr = _option_descr;
+ }
+
+ void set_option_var_name(const string &_option_var_name)
+ {
+ option_var_name = _option_var_name;
+ }
+
+ void set_package_var_name(const string &_package_var_name)
+ {
+ package_var_name = _package_var_name;
+ }
+
+ void generate_dependant_option(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // DEPENDANT_OPTION_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "enum_decl.h"
+
+void
+enum_decl_gen_class::generate_enum_decl(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "enum enum_";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << " { ";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << "__NULL = -1";
+ generate_string (enum_values, stream, indent + indent_str.length ());
+ stream << " };";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef ENUM_DECL_GEN_CLASS_H
+#define ENUM_DECL_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class enum_decl_gen_class
+{
+ protected:
+ string enum_values;
+ string var_arg;
+
+ public:
+ enum_decl_gen_class()
+ {
+ }
+
+ enum_decl_gen_class(const string &_enum_values, const string &_var_arg) :
+ enum_values (_enum_values), var_arg (_var_arg)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_enum_values(const string &_enum_values)
+ {
+ enum_values = _enum_values;
+ }
+
+ void set_var_arg(const string &_var_arg)
+ {
+ var_arg = _var_arg;
+ }
+
+ void generate_enum_decl(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // ENUM_DECL_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "exit_failure.h"
+
+void
+exit_failure_gen_class::generate_exit_failure(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (handle_error)
+ {
+ stream << "if (result == EXIT_FAILURE)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 4;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_free (args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " exit (EXIT_FAILURE);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "return result;";
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef EXIT_FAILURE_GEN_CLASS_H
+#define EXIT_FAILURE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class exit_failure_gen_class
+{
+ protected:
+ bool handle_error;
+ string parser_name;
+
+ public:
+ exit_failure_gen_class() :
+ handle_error (false)
+ {
+ }
+
+ exit_failure_gen_class(bool _handle_error, const string &_parser_name) :
+ handle_error (_handle_error), parser_name (_parser_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_handle_error(bool _handle_error)
+ {
+ handle_error = _handle_error;
+ }
+
+ void set_parser_name(const string &_parser_name)
+ {
+ parser_name = _parser_name;
+ }
+
+ void generate_exit_failure(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // EXIT_FAILURE_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "file_save.h"
+
+void
+file_save_gen_class::generate_file_save(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "if (args_info->";
+ generate_string (given, stream, indent + indent_str.length ());
+ stream << ")";
+ stream << "\n";
+ stream << indent_str;
+ stream << " write_into_file(outfile, \"";
+ generate_string (opt_name, stream, indent + indent_str.length ());
+ stream << "\", ";
+ if (( arg == "" ))
+ {
+ stream << "0, 0 ";
+ }
+ else
+ {
+ stream << "args_info->";
+ generate_string (arg, stream, indent + indent_str.length ());
+ stream << ", ";
+ generate_string (values, stream, indent + indent_str.length ());
+ }
+ stream << ");";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FILE_SAVE_GEN_CLASS_H
+#define FILE_SAVE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class file_save_gen_class
+{
+ protected:
+ string arg;
+ string given;
+ string opt_name;
+ string values;
+
+ public:
+ file_save_gen_class()
+ {
+ }
+
+ file_save_gen_class(const string &_arg, const string &_given, const string &_opt_name, const string &_values) :
+ arg (_arg), given (_given), opt_name (_opt_name), values (_values)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_arg(const string &_arg)
+ {
+ arg = _arg;
+ }
+
+ void set_given(const string &_given)
+ {
+ given = _given;
+ }
+
+ void set_opt_name(const string &_opt_name)
+ {
+ opt_name = _opt_name;
+ }
+
+ void set_values(const string &_values)
+ {
+ values = _values;
+ }
+
+ void generate_file_save(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // FILE_SAVE_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "file_save_multiple.h"
+
+void
+file_save_multiple_gen_class::generate_file_save_multiple(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (has_arg)
+ {
+ stream << "write_multiple_into_file(outfile, args_info->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_given, \"";
+ generate_string (opt_name, stream, indent + indent_str.length ());
+ stream << "\", args_info->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_orig, ";
+ generate_string (values, stream, indent + indent_str.length ());
+ stream << ");";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "write_multiple_into_file(outfile, args_info->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_given, \"";
+ generate_string (opt_name, stream, indent + indent_str.length ());
+ stream << "\", 0, 0);";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FILE_SAVE_MULTIPLE_GEN_CLASS_H
+#define FILE_SAVE_MULTIPLE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class file_save_multiple_gen_class
+{
+ protected:
+ bool has_arg;
+ string opt_name;
+ string opt_var;
+ string values;
+
+ public:
+ file_save_multiple_gen_class() :
+ has_arg (false)
+ {
+ }
+
+ file_save_multiple_gen_class(bool _has_arg, const string &_opt_name, const string &_opt_var, const string &_values) :
+ has_arg (_has_arg), opt_name (_opt_name), opt_var (_opt_var), values (_values)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_has_arg(bool _has_arg)
+ {
+ has_arg = _has_arg;
+ }
+
+ void set_opt_name(const string &_opt_name)
+ {
+ opt_name = _opt_name;
+ }
+
+ void set_opt_var(const string &_opt_var)
+ {
+ opt_var = _opt_var;
+ }
+
+ void set_values(const string &_values)
+ {
+ values = _values;
+ }
+
+ void generate_file_save_multiple(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // FILE_SAVE_MULTIPLE_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "free_list.h"
+
+void
+free_list_gen_class::generate_free_list(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "free_list (";
+ generate_string (list_name, stream, indent + indent_str.length ());
+ stream << "_list, ";
+ if (string_list)
+ {
+ stream << "1 ";
+ }
+ else
+ {
+ stream << "0 ";
+ }
+ stream << ");";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FREE_LIST_GEN_CLASS_H
+#define FREE_LIST_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class free_list_gen_class
+{
+ protected:
+ string list_name;
+ bool string_list;
+
+ public:
+ free_list_gen_class() :
+ string_list (false)
+ {
+ }
+
+ free_list_gen_class(const string &_list_name, bool _string_list) :
+ list_name (_list_name), string_list (_string_list)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_list_name(const string &_list_name)
+ {
+ list_name = _list_name;
+ }
+
+ void set_string_list(bool _string_list)
+ {
+ string_list = _string_list;
+ }
+
+ void generate_free_list(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // FREE_LIST_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "free_multiple.h"
+
+void
+free_multiple_gen_class::generate_free_multiple(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (has_string_type)
+ {
+ stream << "free_multiple_string_field (";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_given, &(";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_arg), &(";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_orig));";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "free_multiple_field (";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_given, (void *)(";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_arg), &(";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_orig));";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_arg = 0;";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FREE_MULTIPLE_GEN_CLASS_H
+#define FREE_MULTIPLE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class free_multiple_gen_class
+{
+ protected:
+ bool has_string_type;
+ string opt_var;
+ string structure;
+
+ public:
+ free_multiple_gen_class() :
+ has_string_type (false)
+ {
+ }
+
+ free_multiple_gen_class(bool _has_string_type, const string &_opt_var, const string &_structure) :
+ has_string_type (_has_string_type), opt_var (_opt_var), structure (_structure)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_has_string_type(bool _has_string_type)
+ {
+ has_string_type = _has_string_type;
+ }
+
+ void set_opt_var(const string &_opt_var)
+ {
+ opt_var = _opt_var;
+ }
+
+ void set_structure(const string &_structure)
+ {
+ structure = _structure;
+ }
+
+ void generate_free_multiple(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // FREE_MULTIPLE_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "free_string.h"
+
+void
+free_string_gen_class::generate_free_string(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (has_string_type)
+ {
+ stream << "free_string_field (&(";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_arg));";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "free_string_field (&(";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << "->";
+ generate_string (opt_var, stream, indent + indent_str.length ());
+ stream << "_orig));";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FREE_STRING_GEN_CLASS_H
+#define FREE_STRING_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class free_string_gen_class
+{
+ protected:
+ bool has_string_type;
+ string opt_var;
+ string structure;
+
+ public:
+ free_string_gen_class() :
+ has_string_type (false)
+ {
+ }
+
+ free_string_gen_class(bool _has_string_type, const string &_opt_var, const string &_structure) :
+ has_string_type (_has_string_type), opt_var (_opt_var), structure (_structure)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_has_string_type(bool _has_string_type)
+ {
+ has_string_type = _has_string_type;
+ }
+
+ void set_opt_var(const string &_opt_var)
+ {
+ opt_var = _opt_var;
+ }
+
+ void set_structure(const string &_structure)
+ {
+ structure = _structure;
+ }
+
+ void generate_free_string(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // FREE_STRING_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "generic_option.h"
+
+void
+generic_option_gen_class::generate_generic_option(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (has_short_option)
+ {
+ stream << "case '";
+ generate_string (short_option, stream, indent + indent_str.length ());
+ stream << "': /* ";
+ generate_string (option_comment, stream, indent + indent_str.length ());
+ stream << ". */";
+ stream << "\n";
+ stream << indent_str;
+ if (( short_option == "?" ))
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (optopt) /* '?' represents an unrecognized option */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " goto failure;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ else
+ {
+ stream << "/* ";
+ generate_string (option_comment, stream, indent + indent_str.length ());
+ stream << ". */";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (gen_else, stream, indent + indent_str.length ());
+ stream << "if (strcmp (long_options[option_index].name, \"";
+ generate_string (long_option, stream, indent + indent_str.length ());
+ stream << "\") == 0)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (option_has_mode)
+ {
+ stream << " args_info->";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << "_mode_counter += 1;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (multiple)
+ {
+ if (option_has_type)
+ {
+ stream << " if (update_multiple_arg_temp(&";
+ generate_string (structure, stream, indent + indent_str.length ());
+ stream << ", ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " &(local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given), optarg, ";
+ generate_string (possible_values, stream, indent + indent_str.length ());
+ stream << ", ";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << ", ";
+ generate_string (arg_type, stream, indent + indent_str.length ());
+ stream << ",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"";
+ generate_string (long_option, stream, indent + indent_str.length ());
+ stream << "\", '";
+ generate_string (short_option, stream, indent + indent_str.length ());
+ stream << "',";
+ stream << "\n";
+ stream << indent_str;
+ stream << " additional_error))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " goto failure;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given++;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (option_has_group)
+ {
+ stream << " if (!args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_group)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_group = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << "_group_counter += 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ else
+ {
+ if (option_has_group)
+ {
+ stream << " if (args_info->";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << "_group_counter && override)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " reset_group_";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << " (args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << "_group_counter += 1;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ if (( arg_type == "ARG_FLAG" ))
+ {
+ stream << " if (update_arg((void *)&(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_flag), 0, &(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given),";
+ stream << "\n";
+ stream << indent_str;
+ stream << " &(local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given), optarg, 0, 0, ";
+ generate_string (arg_type, stream, indent + indent_str.length ());
+ stream << ",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " check_ambiguity, override, 1, 0, \"";
+ generate_string (long_option, stream, indent + indent_str.length ());
+ stream << "\", '";
+ generate_string (short_option, stream, indent + indent_str.length ());
+ stream << "',";
+ stream << "\n";
+ stream << indent_str;
+ stream << " additional_error))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " goto failure;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << " if (update_arg(";
+ if (( arg_type == "ARG_NO" ))
+ {
+ stream << " 0 ";
+ }
+ else
+ {
+ stream << " (void *)&(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_arg)";
+ }
+ stream << ", ";
+ stream << "\n";
+ stream << indent_str;
+ indent = 6;
+ stream << " ";
+ if (( arg_type == "ARG_NO" ))
+ {
+ stream << " 0 ";
+ }
+ else
+ {
+ stream << " &(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_orig)";
+ }
+ stream << ", &(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given),";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " &(local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given), optarg, ";
+ generate_string (possible_values, stream, indent + indent_str.length ());
+ stream << ", ";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << ", ";
+ generate_string (arg_type, stream, indent + indent_str.length ());
+ stream << ",";
+ stream << "\n";
+ stream << indent_str;
+ stream << " check_ambiguity, override, 0, 0,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " \"";
+ generate_string (long_option, stream, indent + indent_str.length ());
+ stream << "\", '";
+ generate_string (short_option, stream, indent + indent_str.length ());
+ stream << "',";
+ stream << "\n";
+ stream << indent_str;
+ stream << " additional_error))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " goto failure;";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (( final_instructions != "" ))
+ {
+ indent = 2;
+ stream << " ";
+ generate_string (final_instructions, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ if (has_short_option)
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << " break;";
+ }
+ else
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GENERIC_OPTION_GEN_CLASS_H
+#define GENERIC_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class generic_option_gen_class
+{
+ protected:
+ string arg_type;
+ string default_value;
+ string final_instructions;
+ string gen_else;
+ string group_var_name;
+ bool has_short_option;
+ string long_option;
+ bool multiple;
+ string option_comment;
+ bool option_has_group;
+ bool option_has_mode;
+ bool option_has_type;
+ string option_var_name;
+ string possible_values;
+ string short_option;
+ string structure;
+
+ public:
+ generic_option_gen_class() :
+ has_short_option (false), multiple (false), option_has_group (false), option_has_mode (false), option_has_type (false)
+ {
+ }
+
+ generic_option_gen_class(const string &_arg_type, const string &_default_value, const string &_final_instructions, const string &_gen_else, const string &_group_var_name, bool _has_short_option, const string &_long_option, bool _multiple, const string &_option_comment, bool _option_has_group, bool _option_has_mode, bool _option_has_type, const string &_option_var_name, const string &_possible_values, const string &_short_option, const string &_structure) :
+ arg_type (_arg_type), default_value (_default_value), final_instructions (_final_instructions), gen_else (_gen_else), group_var_name (_group_var_name), has_short_option (_has_short_option), long_option (_long_option), multiple (_multiple), option_comment (_option_comment), option_has_group (_option_has_group), option_has_mode (_option_has_mode), option_has_type (_option_has_type), option_var_name (_option_var_name), possible_values (_possible_values), short_option (_short_option), structure (_structure)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_arg_type(const string &_arg_type)
+ {
+ arg_type = _arg_type;
+ }
+
+ void set_default_value(const string &_default_value)
+ {
+ default_value = _default_value;
+ }
+
+ void set_final_instructions(const string &_final_instructions)
+ {
+ final_instructions = _final_instructions;
+ }
+
+ void set_gen_else(const string &_gen_else)
+ {
+ gen_else = _gen_else;
+ }
+
+ void set_group_var_name(const string &_group_var_name)
+ {
+ group_var_name = _group_var_name;
+ }
+
+ void set_has_short_option(bool _has_short_option)
+ {
+ has_short_option = _has_short_option;
+ }
+
+ void set_long_option(const string &_long_option)
+ {
+ long_option = _long_option;
+ }
+
+ void set_multiple(bool _multiple)
+ {
+ multiple = _multiple;
+ }
+
+ void set_option_comment(const string &_option_comment)
+ {
+ option_comment = _option_comment;
+ }
+
+ void set_option_has_group(bool _option_has_group)
+ {
+ option_has_group = _option_has_group;
+ }
+
+ void set_option_has_mode(bool _option_has_mode)
+ {
+ option_has_mode = _option_has_mode;
+ }
+
+ void set_option_has_type(bool _option_has_type)
+ {
+ option_has_type = _option_has_type;
+ }
+
+ void set_option_var_name(const string &_option_var_name)
+ {
+ option_var_name = _option_var_name;
+ }
+
+ void set_possible_values(const string &_possible_values)
+ {
+ possible_values = _possible_values;
+ }
+
+ void set_short_option(const string &_short_option)
+ {
+ short_option = _short_option;
+ }
+
+ void set_structure(const string &_structure)
+ {
+ structure = _structure;
+ }
+
+ void generate_generic_option(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // GENERIC_OPTION_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "given_field.h"
+
+void
+given_field_gen_class::generate_given_field(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "unsigned int ";
+ generate_string (arg_name, stream, indent + indent_str.length ());
+ stream << "_given ; /**< ";
+ stream << "@";
+ stream << "brief Whether ";
+ generate_string (long_opt, stream, indent + indent_str.length ());
+ stream << " was given. */";
+ stream << "\n";
+ stream << indent_str;
+ if (group)
+ {
+ stream << " int ";
+ generate_string (arg_name, stream, indent + indent_str.length ());
+ stream << "_group ; /**< ";
+ stream << "@";
+ stream << "brief Whether ";
+ generate_string (long_opt, stream, indent + indent_str.length ());
+ stream << "'s was updated. */";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GIVEN_FIELD_GEN_CLASS_H
+#define GIVEN_FIELD_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class given_field_gen_class
+{
+ protected:
+ string arg_name;
+ bool group;
+ string long_opt;
+
+ public:
+ given_field_gen_class() :
+ group (false)
+ {
+ }
+
+ given_field_gen_class(const string &_arg_name, bool _group, const string &_long_opt) :
+ arg_name (_arg_name), group (_group), long_opt (_long_opt)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_arg_name(const string &_arg_name)
+ {
+ arg_name = _arg_name;
+ }
+
+ void set_group(bool _group)
+ {
+ group = _group;
+ }
+
+ void set_long_opt(const string &_long_opt)
+ {
+ long_opt = _long_opt;
+ }
+
+ void generate_given_field(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // GIVEN_FIELD_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "group_counter.h"
+
+void
+group_counter_gen_class::generate_group_counter(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "int ";
+ generate_string (group_name, stream, indent + indent_str.length ());
+ stream << "_";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_counter; /**< ";
+ stream << "@";
+ stream << "brief Counter for ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (group_name, stream, indent + indent_str.length ());
+ stream << " */";
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GROUP_COUNTER_GEN_CLASS_H
+#define GROUP_COUNTER_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class group_counter_gen_class
+{
+ protected:
+ string group_name;
+ string name;
+
+ public:
+ group_counter_gen_class()
+ {
+ }
+
+ group_counter_gen_class(const string &_group_name, const string &_name) :
+ group_name (_group_name), name (_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_group_name(const string &_group_name)
+ {
+ group_name = _group_name;
+ }
+
+ void set_name(const string &_name)
+ {
+ name = _name;
+ }
+
+ void generate_group_counter(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // GROUP_COUNTER_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "group_option.h"
+
+void
+group_option_gen_class::generate_group_option(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "if (args_info->";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << "_group_counter ";
+ generate_string (Comparison_rule, stream, indent + indent_str.length ());
+ stream << ")";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: %d options of group ";
+ generate_string (group_name, stream, indent + indent_str.length ());
+ stream << " were given. ";
+ generate_string (number_required, stream, indent + indent_str.length ());
+ stream << " is required%s.\\n\", ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", args_info->";
+ generate_string (group_var_name, stream, indent + indent_str.length ());
+ stream << "_group_counter, (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GROUP_OPTION_GEN_CLASS_H
+#define GROUP_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class group_option_gen_class
+{
+ protected:
+ string Comparison_rule;
+ string group_name;
+ string group_var_name;
+ string number_required;
+ string package_var_name;
+
+ public:
+ group_option_gen_class()
+ {
+ }
+
+ group_option_gen_class(const string &_Comparison_rule, const string &_group_name, const string &_group_var_name, const string &_number_required, const string &_package_var_name) :
+ Comparison_rule (_Comparison_rule), group_name (_group_name), group_var_name (_group_var_name), number_required (_number_required), package_var_name (_package_var_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_Comparison_rule(const string &_Comparison_rule)
+ {
+ Comparison_rule = _Comparison_rule;
+ }
+
+ void set_group_name(const string &_group_name)
+ {
+ group_name = _group_name;
+ }
+
+ void set_group_var_name(const string &_group_var_name)
+ {
+ group_var_name = _group_var_name;
+ }
+
+ void set_number_required(const string &_number_required)
+ {
+ number_required = _number_required;
+ }
+
+ void set_package_var_name(const string &_package_var_name)
+ {
+ package_var_name = _package_var_name;
+ }
+
+ void generate_group_option(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // GROUP_OPTION_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "handle_help.h"
+
+void
+handle_help_gen_class::generate_handle_help(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (detailed_help)
+ {
+ stream << "if (strcmp (long_options[option_index].name, \"detailed-help\") == 0) {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_detailed_help ();";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ if (full_help)
+ {
+ stream << "if (strcmp (long_options[option_index].name, \"full-help\") == 0) {";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_full_help ();";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ if (short_opt)
+ {
+ stream << "case 'h': /* Print help and exit. */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "if (strcmp (long_options[option_index].name, \"help\") == 0) {";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_help ();";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_free (&local_args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << " exit (EXIT_SUCCESS);";
+ if (( full_help || ( ! short_opt ) ))
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef HANDLE_HELP_GEN_CLASS_H
+#define HANDLE_HELP_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class handle_help_gen_class
+{
+ protected:
+ bool detailed_help;
+ bool full_help;
+ string parser_name;
+ bool short_opt;
+
+ public:
+ handle_help_gen_class() :
+ detailed_help (false), full_help (false), short_opt (false)
+ {
+ }
+
+ handle_help_gen_class(bool _detailed_help, bool _full_help, const string &_parser_name, bool _short_opt) :
+ detailed_help (_detailed_help), full_help (_full_help), parser_name (_parser_name), short_opt (_short_opt)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_detailed_help(bool _detailed_help)
+ {
+ detailed_help = _detailed_help;
+ }
+
+ void set_full_help(bool _full_help)
+ {
+ full_help = _full_help;
+ }
+
+ void set_parser_name(const string &_parser_name)
+ {
+ parser_name = _parser_name;
+ }
+
+ void set_short_opt(bool _short_opt)
+ {
+ short_opt = _short_opt;
+ }
+
+ void generate_handle_help(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // HANDLE_HELP_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "handle_version.h"
+
+void
+handle_version_gen_class::generate_handle_version(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (short_opt)
+ {
+ stream << "case 'V': /* Print version and exit. */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "if (strcmp (long_options[option_index].name, \"version\") == 0) {";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_version ();";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_free (&local_args_info);";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " exit (EXIT_SUCCESS);";
+ if (( ! short_opt ))
+ {
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef HANDLE_VERSION_GEN_CLASS_H
+#define HANDLE_VERSION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class handle_version_gen_class
+{
+ protected:
+ string parser_name;
+ bool short_opt;
+
+ public:
+ handle_version_gen_class() :
+ short_opt (false)
+ {
+ }
+
+ handle_version_gen_class(const string &_parser_name, bool _short_opt) :
+ parser_name (_parser_name), short_opt (_short_opt)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_parser_name(const string &_parser_name)
+ {
+ parser_name = _parser_name;
+ }
+
+ void set_short_opt(bool _short_opt)
+ {
+ short_opt = _short_opt;
+ }
+
+ void generate_handle_version(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // HANDLE_VERSION_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "header.h"
+
+void
+header_gen_class::generate_header(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "/** ";
+ stream << "@";
+ stream << "file ";
+ generate_string (header_file_name, stream, indent + indent_str.length ());
+ stream << ".";
+ generate_string (header_file_ext, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "brief The header file for the command line option parser";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * generated by GNU Gengetopt ";
+ generate_string (generator_version, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << " * http://www.gnu.org/software/gengetopt.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * DO NOT modify this file, since it can be overwritten";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "author GNU Gengetopt by Lorenzo Bettini */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef ";
+ generate_string (ifndefname, stream, indent + indent_str.length ());
+ stream << "_H";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define ";
+ generate_string (ifndefname, stream, indent + indent_str.length ());
+ stream << "_H";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/* If we use autoconf. */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef HAVE_CONFIG_H";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include \"config.h\"";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#include <stdio.h> /* for FILE */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef __cplusplus";
+ stream << "\n";
+ stream << indent_str;
+ stream << "extern \"C\" {";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif /* __cplusplus */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief the program name (used for printing errors) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (package_var_val, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "_NAME";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief the complete program name (used for help and version) */";
+ stream << "\n";
+ stream << indent_str;
+ if (( package_var_val != "PACKAGE" ))
+ {
+ stream << "#define ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "_NAME ";
+ generate_string (package_var_val, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "#ifdef PACKAGE_NAME";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "_NAME PACKAGE_NAME";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << "_NAME PACKAGE";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifndef ";
+ generate_string (version_var_name, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief the program version */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#define ";
+ generate_string (version_var_name, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (version_var_val, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ if (enum_types.size () > 0)
+ generate_string (enum_types, stream, indent + indent_str.length ());
+ else
+ generate_enum_types (stream, indent + indent_str.length ());
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief Where the command line options are stored */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (option_arg.size () > 0)
+ generate_string (option_arg, stream, indent + indent_str.length ());
+ else
+ generate_option_arg (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ if (option_given.size () > 0)
+ generate_string (option_given, stream, indent + indent_str.length ());
+ else
+ generate_option_given (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ if (group_counters.size () > 0)
+ generate_string (group_counters, stream, indent + indent_str.length ());
+ else
+ generate_group_counters (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ indent = 2;
+ if (mode_counters.size () > 0)
+ generate_string (mode_counters, stream, indent + indent_str.length ());
+ else
+ generate_mode_counters (stream, indent + indent_str.length ());
+ indent = 0;
+ stream << indent_str;
+ stream << "} ;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief The additional parameters to pass to parser functions */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override; /**< ";
+ stream << "@";
+ stream << "brief whether to override possibly already present options (default 0) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int initialize; /**< ";
+ stream << "@";
+ stream << "brief whether to initialize the option structure ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " (default 1) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int check_required; /**< ";
+ stream << "@";
+ stream << "brief whether to check that all required options were provided (default 1) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int check_ambiguity; /**< ";
+ stream << "@";
+ stream << "brief whether to check for options already specified in the option structure ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " (default 0) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int print_errors; /**< ";
+ stream << "@";
+ stream << "brief whether getopt_long should print an error message for a bad option (default 1) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "} ;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief the purpose string of the program */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "extern const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_purpose;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief the usage string of the program */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "extern const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_usage;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/** ";
+ stream << "@";
+ stream << "brief all the lines making the help output */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "extern const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_help[];";
+ stream << "\n";
+ stream << indent_str;
+ if (has_hidden)
+ {
+ stream << "/** ";
+ stream << "@";
+ stream << "brief all the lines making the full help output (including hidden options) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "extern const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_full_help[];";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_details)
+ {
+ stream << "/** ";
+ stream << "@";
+ stream << "brief all the lines making the detailed help output (including hidden options and details) */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "extern const char *";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << "_detailed_help[];";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The command line parser";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param argc the number of command line options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param argv the command line options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << " (int argc, char **argv,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The command line parser (version with additional parameters - deprecated)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param argc the number of command line options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param argv the command line options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param override whether to override possibly already present options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param initialize whether to initialize the option structure my_args_info";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param check_required whether to check that all required options were provided";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "deprecated use ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_ext() instead";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "2 (int argc, char **argv,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override, int initialize, int check_required);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The command line parser (version with additional parameters)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param argc the number of command line options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param argv the command line options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param params additional parameters for the parser";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_ext (int argc, char **argv,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Save the contents of the option struct into an already open FILE stream.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param outfile the stream where to dump options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the option struct to dump";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_dump(FILE *outfile,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Save the contents of the option struct into a (text) file.";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * This file can be read by the config file parser (if generated by gengetopt)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param filename the file where to save";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the option struct to save";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_file_save(const char *filename,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Print the help";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_help(void);";
+ stream << "\n";
+ stream << indent_str;
+ if (has_hidden)
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Print the full help (including hidden options)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_full_help(void);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (has_details)
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Print the detailed help (including hidden options and details)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_detailed_help(void);";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Print the version";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_print_version(void);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Initializes all the fields a ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params structure ";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * to their default values";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param params the structure to initialize";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params_init(struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Allocates dynamically a ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params structure and initializes";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * all its fields to their default values";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return the created and initialized ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params structure";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params_create(void);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Initializes the passed ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " structure's fields";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * (also set default values for options that have a default)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure to initialize";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_init (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Deallocates the string fields of the ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " structure";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * (but does not deallocate the structure itself)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure to deallocate";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "void ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_free (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (generate_config_parser)
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The config file parser (deprecated version)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param filename the name of the config file";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param override whether to override possibly already present options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param initialize whether to initialize the option structure my_args_info";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param check_required whether to check that all required options were provided";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "deprecated use ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_config_file() instead";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_configfile (const char *filename,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override, int initialize, int check_required);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The config file parser";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param filename the name of the config file";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param params additional parameters for the parser";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_config_file (const char *filename,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ if (generate_string_parser)
+ {
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The string parser (interprets the passed string as a command line)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param cmdline the command line stirng";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param prog_name the name of the program that will be used to print";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * possible errors";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string (const char *cmdline, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *prog_name);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The string parser (version with additional parameters - deprecated)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param cmdline the command line stirng";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param prog_name the name of the program that will be used to print";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * possible errors";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param override whether to override possibly already present options";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param initialize whether to initialize the option structure my_args_info";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param check_required whether to check that all required options were provided";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "deprecated use ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string_ext() instead";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string2 (const char *cmdline, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *prog_name,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " int override, int initialize, int check_required);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * The string parser (version with additional parameters)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param cmdline the command line stirng";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure where option information will be stored";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param prog_name the name of the program that will be used to print";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * possible errors";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param params additional parameters for the parser";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return 0 if everything went fine, NON 0 if an error took place";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_string_ext (const char *cmdline, struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *prog_name,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " struct ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_params *params);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "/**";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * Checks that all the required options were specified";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param args_info the structure to check";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "param prog_name the name of the program that will be used to print";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * possible errors";
+ stream << "\n";
+ stream << indent_str;
+ stream << " * ";
+ stream << "@";
+ stream << "return";
+ stream << "\n";
+ stream << indent_str;
+ stream << " */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "int ";
+ generate_string (parser_name, stream, indent + indent_str.length ());
+ stream << "_required (struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " const char *prog_name);";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ if (option_values_decl.size () > 0)
+ generate_string (option_values_decl, stream, indent + indent_str.length ());
+ else
+ generate_option_values_decl (stream, indent + indent_str.length ());
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ stream << "#ifdef __cplusplus";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif /* __cplusplus */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif /* ";
+ generate_string (ifndefname, stream, indent + indent_str.length ());
+ stream << "_H */";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.4 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef HEADER_GEN_CLASS_H
+#define HEADER_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class header_gen_class
+{
+ protected:
+ string args_info;
+ string enum_types;
+ bool generate_config_parser;
+ bool generate_string_parser;
+ string generator_version;
+ string group_counters;
+ bool has_details;
+ bool has_hidden;
+ string header_file_ext;
+ string header_file_name;
+ string ifndefname;
+ string mode_counters;
+ string option_arg;
+ string option_given;
+ string option_values_decl;
+ string package_var_name;
+ string package_var_val;
+ string parser_name;
+ string version_var_name;
+ string version_var_val;
+
+ public:
+ header_gen_class() :
+ generate_config_parser (false), generate_string_parser (false), has_details (false), has_hidden (false)
+ {
+ }
+
+ header_gen_class(const string &_args_info, const string &_enum_types, bool _generate_config_parser, bool _generate_string_parser, const string &_generator_version, const string &_group_counters, bool _has_details, bool _has_hidden, const string &_header_file_ext, const string &_header_file_name, const string &_ifndefname, const string &_mode_counters, const string &_option_arg, const string &_option_given, const string &_option_values_decl, const string &_package_var_name, const string &_package_var_val, const string &_parser_name, const string &_version_var_name, const string &_version_var_val) :
+ args_info (_args_info), enum_types (_enum_types), generate_config_parser (_generate_config_parser), generate_string_parser (_generate_string_parser), generator_version (_generator_version), group_counters (_group_counters), has_details (_has_details), has_hidden (_has_hidden), header_file_ext (_header_file_ext), header_file_name (_header_file_name), ifndefname (_ifndefname), mode_counters (_mode_counters), option_arg (_option_arg), option_given (_option_given), option_values_decl (_option_values_decl), package_var_name (_package_var_name), package_var_val (_package_var_val), parser_name (_parser_name), version_var_name (_version_var_name), version_var_val (_version_var_val)
+ {
+ }
+
+ virtual ~header_gen_class()
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_args_info(const string &_args_info)
+ {
+ args_info = _args_info;
+ }
+
+ virtual void generate_enum_types(ostream &stream, unsigned int indent) = 0;
+
+ void set_enum_types(const string &_enum_types)
+ {
+ enum_types = _enum_types;
+ }
+
+ void set_generate_config_parser(bool _generate_config_parser)
+ {
+ generate_config_parser = _generate_config_parser;
+ }
+
+ void set_generate_string_parser(bool _generate_string_parser)
+ {
+ generate_string_parser = _generate_string_parser;
+ }
+
+ void set_generator_version(const string &_generator_version)
+ {
+ generator_version = _generator_version;
+ }
+
+ virtual void generate_group_counters(ostream &stream, unsigned int indent) = 0;
+
+ void set_group_counters(const string &_group_counters)
+ {
+ group_counters = _group_counters;
+ }
+
+ void set_has_details(bool _has_details)
+ {
+ has_details = _has_details;
+ }
+
+ void set_has_hidden(bool _has_hidden)
+ {
+ has_hidden = _has_hidden;
+ }
+
+ void set_header_file_ext(const string &_header_file_ext)
+ {
+ header_file_ext = _header_file_ext;
+ }
+
+ void set_header_file_name(const string &_header_file_name)
+ {
+ header_file_name = _header_file_name;
+ }
+
+ void set_ifndefname(const string &_ifndefname)
+ {
+ ifndefname = _ifndefname;
+ }
+
+ virtual void generate_mode_counters(ostream &stream, unsigned int indent) = 0;
+
+ void set_mode_counters(const string &_mode_counters)
+ {
+ mode_counters = _mode_counters;
+ }
+
+ virtual void generate_option_arg(ostream &stream, unsigned int indent) = 0;
+
+ void set_option_arg(const string &_option_arg)
+ {
+ option_arg = _option_arg;
+ }
+
+ virtual void generate_option_given(ostream &stream, unsigned int indent) = 0;
+
+ void set_option_given(const string &_option_given)
+ {
+ option_given = _option_given;
+ }
+
+ virtual void generate_option_values_decl(ostream &stream, unsigned int indent) = 0;
+
+ void set_option_values_decl(const string &_option_values_decl)
+ {
+ option_values_decl = _option_values_decl;
+ }
+
+ void set_package_var_name(const string &_package_var_name)
+ {
+ package_var_name = _package_var_name;
+ }
+
+ void set_package_var_val(const string &_package_var_val)
+ {
+ package_var_val = _package_var_val;
+ }
+
+ void set_parser_name(const string &_parser_name)
+ {
+ parser_name = _parser_name;
+ }
+
+ void set_version_var_name(const string &_version_var_name)
+ {
+ version_var_name = _version_var_name;
+ }
+
+ void set_version_var_val(const string &_version_var_val)
+ {
+ version_var_val = _version_var_val;
+ }
+
+ void generate_header(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // HEADER_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "init_args_info.h"
+
+void
+init_args_info_gen_class::generate_init_args_info(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "args_info->";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << "_help = ";
+ generate_string (help_strings, stream, indent + indent_str.length ());
+ stream << "[";
+ generate_string (num, stream, indent + indent_str.length ());
+ stream << "] ;";
+ stream << "\n";
+ stream << indent_str;
+ if (multiple)
+ {
+ stream << "args_info->";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << "_min = ";
+ generate_string (min, stream, indent + indent_str.length ());
+ stream << ";";
+ stream << "\n";
+ stream << indent_str;
+ stream << "args_info->";
+ generate_string (var_arg, stream, indent + indent_str.length ());
+ stream << "_max = ";
+ generate_string (max, stream, indent + indent_str.length ());
+ stream << ";";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef INIT_ARGS_INFO_GEN_CLASS_H
+#define INIT_ARGS_INFO_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class init_args_info_gen_class
+{
+ protected:
+ string help_strings;
+ string max;
+ string min;
+ bool multiple;
+ string num;
+ string var_arg;
+
+ public:
+ init_args_info_gen_class() :
+ multiple (false)
+ {
+ }
+
+ init_args_info_gen_class(const string &_help_strings, const string &_max, const string &_min, bool _multiple, const string &_num, const string &_var_arg) :
+ help_strings (_help_strings), max (_max), min (_min), multiple (_multiple), num (_num), var_arg (_var_arg)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_help_strings(const string &_help_strings)
+ {
+ help_strings = _help_strings;
+ }
+
+ void set_max(const string &_max)
+ {
+ max = _max;
+ }
+
+ void set_min(const string &_min)
+ {
+ min = _min;
+ }
+
+ void set_multiple(bool _multiple)
+ {
+ multiple = _multiple;
+ }
+
+ void set_num(const string &_num)
+ {
+ num = _num;
+ }
+
+ void set_var_arg(const string &_var_arg)
+ {
+ var_arg = _var_arg;
+ }
+
+ void generate_init_args_info(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // INIT_ARGS_INFO_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "multiple_fill_array.h"
+
+void
+multiple_fill_array_gen_class::generate_multiple_fill_array(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (( default_value != "0" ))
+ {
+ stream << "multiple_default_value.";
+ if (( arg_type == "ARG_STRING" ))
+ {
+ stream << "default_";
+ }
+ generate_string (type, stream, indent + indent_str.length ());
+ stream << "_arg = ";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << ";";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "update_multiple_arg((void *)&(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_arg),";
+ stream << "\n";
+ stream << indent_str;
+ stream << " &(args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_orig), args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given,";
+ stream << "\n";
+ stream << indent_str;
+ stream << " local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given, ";
+ if (( default_value != "0" ))
+ {
+ stream << "&multiple_default_value";
+ }
+ else
+ {
+ stream << "0";
+ }
+ stream << ",";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (arg_type, stream, indent + indent_str.length ());
+ stream << ", ";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_list);";
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef MULTIPLE_FILL_ARRAY_GEN_CLASS_H
+#define MULTIPLE_FILL_ARRAY_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class multiple_fill_array_gen_class
+{
+ protected:
+ string arg_type;
+ string default_value;
+ string option_var_name;
+ string type;
+
+ public:
+ multiple_fill_array_gen_class()
+ {
+ }
+
+ multiple_fill_array_gen_class(const string &_arg_type, const string &_default_value, const string &_option_var_name, const string &_type) :
+ arg_type (_arg_type), default_value (_default_value), option_var_name (_option_var_name), type (_type)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_arg_type(const string &_arg_type)
+ {
+ arg_type = _arg_type;
+ }
+
+ void set_default_value(const string &_default_value)
+ {
+ default_value = _default_value;
+ }
+
+ void set_option_var_name(const string &_option_var_name)
+ {
+ option_var_name = _option_var_name;
+ }
+
+ void set_type(const string &_type)
+ {
+ type = _type;
+ }
+
+ void generate_multiple_fill_array(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // MULTIPLE_FILL_ARRAY_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "multiple_opt_list.h"
+
+void
+multiple_opt_list_gen_class::generate_multiple_opt_list(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "struct generic_list * ";
+ generate_string (arg_name, stream, indent + indent_str.length ());
+ stream << "_list = NULL;";
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef MULTIPLE_OPT_LIST_GEN_CLASS_H
+#define MULTIPLE_OPT_LIST_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class multiple_opt_list_gen_class
+{
+ protected:
+ string arg_name;
+
+ public:
+ multiple_opt_list_gen_class()
+ {
+ }
+
+ multiple_opt_list_gen_class(const string &_arg_name) :
+ arg_name (_arg_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_arg_name(const string &_arg_name)
+ {
+ arg_name = _arg_name;
+ }
+
+ void generate_multiple_opt_list(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // MULTIPLE_OPT_LIST_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "option_arg.h"
+
+void
+option_arg_gen_class::generate_option_arg(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (long_long_arg)
+ {
+ stream << "#ifdef HAVE_LONG_LONG";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (type, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_arg; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ if (has_default)
+ {
+ stream << " (default=";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << ")";
+ }
+ stream << ". */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#else";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (longtype, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_arg; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ if (has_default)
+ {
+ stream << " (default=";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << ")";
+ }
+ stream << ". */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "#endif";
+ stream << "\n";
+ stream << indent_str;
+ generate_string (origtype, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_orig; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ stream << " original value given at command line. */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ if (flag_arg)
+ {
+ generate_string (type, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_flag; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ stream << " (default=";
+ if (default_on)
+ {
+ stream << "on";
+ }
+ else
+ {
+ stream << "off";
+ }
+ stream << "). */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ if (has_arg)
+ {
+ if (has_enum)
+ {
+ stream << "enum enum_";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << " ";
+ if (multiple)
+ {
+ stream << "*";
+ }
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_arg; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ if (has_default)
+ {
+ stream << " (default='";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << "')";
+ }
+ stream << ". */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ generate_string (type, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_arg; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ if (has_default)
+ {
+ stream << " (default='";
+ generate_string (default_value, stream, indent + indent_str.length ());
+ stream << "')";
+ }
+ stream << ". */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ generate_string (origtype, stream, indent + indent_str.length ());
+ stream << " ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_orig; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ stream << " original value given at command line. */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ }
+ }
+ if (multiple)
+ {
+ stream << "unsigned int ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_min; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ stream << "'s minimum occurreces */";
+ stream << "\n";
+ stream << indent_str;
+ stream << "unsigned int ";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_max; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ stream << "'s maximum occurreces */";
+ stream << "\n";
+ stream << indent_str;
+ }
+ stream << "const char *";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_help; /**< ";
+ stream << "@";
+ stream << "brief ";
+ generate_string (desc, stream, indent + indent_str.length ());
+ stream << " help description. */";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef OPTION_ARG_GEN_CLASS_H
+#define OPTION_ARG_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class option_arg_gen_class
+{
+ protected:
+ bool default_on;
+ string default_value;
+ string desc;
+ bool flag_arg;
+ bool has_arg;
+ bool has_default;
+ bool has_enum;
+ bool long_long_arg;
+ string longtype;
+ bool multiple;
+ string name;
+ string origtype;
+ string type;
+
+ public:
+ option_arg_gen_class() :
+ default_on (false), flag_arg (false), has_arg (false), has_default (false), has_enum (false), long_long_arg (false), multiple (false)
+ {
+ }
+
+ option_arg_gen_class(bool _default_on, const string &_default_value, const string &_desc, bool _flag_arg, bool _has_arg, bool _has_default, bool _has_enum, bool _long_long_arg, const string &_longtype, bool _multiple, const string &_name, const string &_origtype, const string &_type) :
+ default_on (_default_on), default_value (_default_value), desc (_desc), flag_arg (_flag_arg), has_arg (_has_arg), has_default (_has_default), has_enum (_has_enum), long_long_arg (_long_long_arg), longtype (_longtype), multiple (_multiple), name (_name), origtype (_origtype), type (_type)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_default_on(bool _default_on)
+ {
+ default_on = _default_on;
+ }
+
+ void set_default_value(const string &_default_value)
+ {
+ default_value = _default_value;
+ }
+
+ void set_desc(const string &_desc)
+ {
+ desc = _desc;
+ }
+
+ void set_flag_arg(bool _flag_arg)
+ {
+ flag_arg = _flag_arg;
+ }
+
+ void set_has_arg(bool _has_arg)
+ {
+ has_arg = _has_arg;
+ }
+
+ void set_has_default(bool _has_default)
+ {
+ has_default = _has_default;
+ }
+
+ void set_has_enum(bool _has_enum)
+ {
+ has_enum = _has_enum;
+ }
+
+ void set_long_long_arg(bool _long_long_arg)
+ {
+ long_long_arg = _long_long_arg;
+ }
+
+ void set_longtype(const string &_longtype)
+ {
+ longtype = _longtype;
+ }
+
+ void set_multiple(bool _multiple)
+ {
+ multiple = _multiple;
+ }
+
+ void set_name(const string &_name)
+ {
+ name = _name;
+ }
+
+ void set_origtype(const string &_origtype)
+ {
+ origtype = _origtype;
+ }
+
+ void set_type(const string &_type)
+ {
+ type = _type;
+ }
+
+ void generate_option_arg(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // OPTION_ARG_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "print_help_string.h"
+
+void
+print_help_string_gen_class::generate_print_help_string(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (shared)
+ {
+ generate_string (target, stream, indent + indent_str.length ());
+ stream << "[";
+ generate_string (index, stream, indent + indent_str.length ());
+ stream << "] = ";
+ if (last)
+ {
+ stream << "0; ";
+ }
+ else
+ {
+ generate_string (from, stream, indent + indent_str.length ());
+ stream << "[";
+ generate_string (full_index, stream, indent + indent_str.length ());
+ stream << "];";
+ }
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "\"";
+ generate_string (helpstring, stream, indent + indent_str.length ());
+ stream << "\",";
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef PRINT_HELP_STRING_GEN_CLASS_H
+#define PRINT_HELP_STRING_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class print_help_string_gen_class
+{
+ protected:
+ string from;
+ string full_index;
+ string helpstring;
+ string index;
+ bool last;
+ bool shared;
+ string target;
+
+ public:
+ print_help_string_gen_class() :
+ last (false), shared (false)
+ {
+ }
+
+ print_help_string_gen_class(const string &_from, const string &_full_index, const string &_helpstring, const string &_index, bool _last, bool _shared, const string &_target) :
+ from (_from), full_index (_full_index), helpstring (_helpstring), index (_index), last (_last), shared (_shared), target (_target)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_from(const string &_from)
+ {
+ from = _from;
+ }
+
+ void set_full_index(const string &_full_index)
+ {
+ full_index = _full_index;
+ }
+
+ void set_helpstring(const string &_helpstring)
+ {
+ helpstring = _helpstring;
+ }
+
+ void set_index(const string &_index)
+ {
+ index = _index;
+ }
+
+ void set_last(bool _last)
+ {
+ last = _last;
+ }
+
+ void set_shared(bool _shared)
+ {
+ shared = _shared;
+ }
+
+ void set_target(const string &_target)
+ {
+ target = _target;
+ }
+
+ void generate_print_help_string(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // PRINT_HELP_STRING_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "required_option.h"
+
+void
+required_option_gen_class::generate_required_option(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ if (checkrange)
+ {
+ stream << "if (";
+ generate_string (mode_condition, stream, indent + indent_str.length ());
+ stream << "check_multiple_option_occurrences(";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given, args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_min, args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_max, \"";
+ generate_string (option_descr, stream, indent + indent_str.length ());
+ stream << "\"))";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+ else
+ {
+ stream << "if (";
+ generate_string (mode_condition, stream, indent + indent_str.length ());
+ stream << "! args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " {";
+ stream << "\n";
+ stream << indent_str;
+ stream << " fprintf (stderr, \"%s: ";
+ generate_string (option_descr, stream, indent + indent_str.length ());
+ stream << " option required%s\\n\", ";
+ generate_string (package_var_name, stream, indent + indent_str.length ());
+ stream << ", (additional_error ? additional_error : \"\"));";
+ stream << "\n";
+ stream << indent_str;
+ stream << " error = 1;";
+ stream << "\n";
+ stream << indent_str;
+ stream << " }";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+ }
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef REQUIRED_OPTION_GEN_CLASS_H
+#define REQUIRED_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class required_option_gen_class
+{
+ protected:
+ bool checkrange;
+ string mode_condition;
+ string option_descr;
+ string option_var_name;
+ string package_var_name;
+
+ public:
+ required_option_gen_class() :
+ checkrange (false)
+ {
+ }
+
+ required_option_gen_class(bool _checkrange, const string &_mode_condition, const string &_option_descr, const string &_option_var_name, const string &_package_var_name) :
+ checkrange (_checkrange), mode_condition (_mode_condition), option_descr (_option_descr), option_var_name (_option_var_name), package_var_name (_package_var_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_checkrange(bool _checkrange)
+ {
+ checkrange = _checkrange;
+ }
+
+ void set_mode_condition(const string &_mode_condition)
+ {
+ mode_condition = _mode_condition;
+ }
+
+ void set_option_descr(const string &_option_descr)
+ {
+ option_descr = _option_descr;
+ }
+
+ void set_option_var_name(const string &_option_var_name)
+ {
+ option_var_name = _option_var_name;
+ }
+
+ void set_package_var_name(const string &_package_var_name)
+ {
+ package_var_name = _package_var_name;
+ }
+
+ void generate_required_option(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // REQUIRED_OPTION_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "reset_group.h"
+
+void
+reset_group_gen_class::generate_reset_group(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "static void";
+ stream << "\n";
+ stream << indent_str;
+ stream << "reset_group_";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "(struct ";
+ generate_string (args_info, stream, indent + indent_str.length ());
+ stream << " *args_info)";
+ stream << "\n";
+ stream << indent_str;
+ stream << "{";
+ stream << "\n";
+ stream << indent_str;
+ stream << " if (! args_info->";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_group_counter)";
+ stream << "\n";
+ stream << indent_str;
+ stream << " return;";
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ indent = 2;
+ stream << " ";
+ generate_string (body, stream, indent + indent_str.length ());
+ indent = 0;
+ stream << "\n";
+ stream << indent_str;
+ stream << " args_info->";
+ generate_string (name, stream, indent + indent_str.length ());
+ stream << "_group_counter = 0;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "}";
+ stream << "\n";
+ stream << indent_str;
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef RESET_GROUP_GEN_CLASS_H
+#define RESET_GROUP_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class reset_group_gen_class
+{
+ protected:
+ string args_info;
+ string body;
+ string name;
+
+ public:
+ reset_group_gen_class()
+ {
+ }
+
+ reset_group_gen_class(const string &_args_info, const string &_body, const string &_name) :
+ args_info (_args_info), body (_body), name (_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_args_info(const string &_args_info)
+ {
+ args_info = _args_info;
+ }
+
+ void set_body(const string &_body)
+ {
+ body = _body;
+ }
+
+ void set_name(const string &_name)
+ {
+ name = _name;
+ }
+
+ void generate_reset_group(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // RESET_GROUP_GEN_CLASS_H
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "update_given.h"
+
+void
+update_given_gen_class::generate_update_given(ostream &stream, unsigned int indent)
+{
+ string indent_str (indent, ' ');
+ indent = 0;
+
+ stream << "args_info->";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given += local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given;";
+ stream << "\n";
+ stream << indent_str;
+ stream << "local_args_info.";
+ generate_string (option_var_name, stream, indent + indent_str.length ());
+ stream << "_given = 0;";
+ stream << "\n";
+ stream << indent_str;
+}
--- /dev/null
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef UPDATE_GIVEN_GEN_CLASS_H
+#define UPDATE_GIVEN_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class update_given_gen_class
+{
+ protected:
+ string option_var_name;
+
+ public:
+ update_given_gen_class()
+ {
+ }
+
+ update_given_gen_class(const string &_option_var_name) :
+ option_var_name (_option_var_name)
+ {
+ }
+
+ static void
+ generate_string(const string &s, ostream &stream, unsigned int indent)
+ {
+ if (!indent || s.find('\n') == string::npos)
+ {
+ stream << s;
+ return;
+ }
+
+ string::size_type pos;
+ string::size_type start = 0;
+ string ind (indent, ' ');
+ while ( (pos=s.find('\n', start)) != string::npos)
+ {
+ stream << s.substr (start, (pos+1)-start);
+ start = pos+1;
+ if (start+1 <= s.size ())
+ stream << ind;
+ }
+ if (start+1 <= s.size ())
+ stream << s.substr (start);
+ }
+
+ void set_option_var_name(const string &_option_var_name)
+ {
+ option_var_name = _option_var_name;
+ }
+
+ void generate_update_given(ostream &stream, unsigned int indent = 0);
+
+};
+
+#endif // UPDATE_GIVEN_GEN_CLASS_H
--- /dev/null
+/*
+This file is licensed to you under the license specified in the included file
+`LICENSE'. Look there for further details.
+*/
+
+
+/*
+ Called by yyparse on error.
+ */
+
+#include "yyerror.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+extern int tokenpos;
+extern char linebuf[];
+extern char *yytext;
+
+using namespace std;
+
+void
+yyerror (const char *s)
+{
+ const char *source =
+ (gengetopt_input_filename ? gengetopt_input_filename : "gengetopt");
+
+ fprintf (stderr, "%s:%d: %s %s\n", source, gengetopt_count_line, s, yytext);
+
+ if (/*!linebuf || */!strlen(linebuf))
+ return;
+
+ fprintf (stderr, "%s:%d: %s\n", source, gengetopt_count_line, linebuf);
+ fprintf (stderr, "%s:%d: %*s\n", source, gengetopt_count_line,
+ tokenpos + 1, "^");
+}
+
+void
+yyerror (gengetopt_option *opt, const char *s)
+{
+ const char *source =
+ (opt->filename ? opt->filename : "gengetopt");
+
+ cerr << source << ":" << opt->linenum << ": " << s << endl;
+}
--- /dev/null
+#ifndef YYERROR_H_
+#define YYERROR_H_
+
+#include "ggos.h"
+
+void
+yyerror (const char *s);
+
+void
+yyerror (gengetopt_option *opt, const char *s);
+
+#endif /*YYERROR_H_*/
--- /dev/null
+/*
+This file is licensed to you under the license specified in the included file
+`LICENSE'. Look there for further details.
+*/
+
+
+/*
+ This function is called when found EOF.
+ */
+#include <stdio.h>
+
+int
+yywrap ()
+{
+ /* fprintf (stderr, "yywrap() called.\n"); */
+ return 1;
+}
+
#ADD_LIBRARY(clitkCommonShared SHARED ${clitkCommon_SRC})
#SET_TARGET_PROPERTIES(clitkCommonShared PROPERTIES COMPILE_FLAGS -fPIC)
+
is >> c;
if (is.eof()) return;
}
- is.unget();
+ if (!(is.fail()) && c != '\n')
+ is.unget();
} ////
//------------------------------------------------------------------
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
#ifndef clitk_configuration_h
#define clitk_configuration_h
//This file is interpreted by cmake, to define macros based on the cmake configuration options
#cmakedefine01 CLITK_EXPERIMENTAL
#cmakedefine01 CLITK_MEMORY_INFO
+// Global environment variables
+#define OS_NAME "@CMAKE_SYSTEM@"
+#define ARCHITECTURE "@CMAKE_SYSTEM_PROCESSOR@"
+
#endif
#define clitkDD_h
#include <iostream>
-
+#ifdef WIN32
+# include <windows.h>
+#endif
// David's debug
-#define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();
+#ifdef WIN32
+# define DD(a) { \
+ std::ostringstream ossDD; \
+ ossDD << #a " = [ " << a << " ]" << std::endl; \
+ OutputDebugString(ossDD.str().c_str()); \
+ }
+#else
+# define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();
+#endif
#define DDV(a,n) { std::cout << #a " = [ "; for(unsigned int _i_=0; _i_<n; _i_++) { std::cout << a[_i_] << " "; }; std::cout << " ]" << std::endl;std::cout.flush();}
template<class T>
void _print_container(T const& a)
const gdcm::DataElement & contourdata = nestedds2.GetDataElement( tcontourdata );
at.SetFromDataElement( contourdata );
const double* points = at.GetValues();
- unsigned int npts = at.GetNumberOfValues() / 3;
assert(at.GetNumberOfValues() == static_cast<unsigned int>(mNbOfPoints)*3);
mMeshIsUpToDate = false;
mBackgroundValue = 0;
mForegroundValue = 1;
- mZDelta = 0;
}
//--------------------------------------------------------------------
gdcm::Tag tcsq(0x3006,0x0040);
if( !nestedds.FindDataElement( tcsq ) )
{
+ std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl;
+ return;
}
const gdcm::DataElement& csq = nestedds.GetDataElement( tcsq );
gdcm::SmartPointer<gdcm::SequenceOfItems> sqi2 = csq.GetValueAsSQ();
}
unsigned int nitems = sqi2->GetNumberOfItems();
- bool contour_processed=false;
- bool delta_computed=false;
- double last_z=0;
for(unsigned int i = 0; i < nitems; ++i)
{
- const gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1
- DicomRT_Contour::Pointer c = DicomRT_Contour::New();
- bool b = c->Read(j);
- if (b) {
- mListOfContours.push_back(c);
- if (contour_processed) {
- double delta=c->GetZ() - last_z;
- if (delta_computed)
- assert(mZDelta == delta);
- else
- mZDelta = delta;
- } else
- contour_processed=true;
- last_z=c->GetZ();
+ const gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1
+ DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+ bool b = c->Read(j);
+ if (b) {
+ mListOfContours.push_back(c);
+ }
}
- }
-
}
#else
void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item)
// Read contours [Contour Sequence]
gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040);
- bool contour_processed=false;
- bool delta_computed=false;
- double last_z=0;
- for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) {
- DicomRT_Contour::Pointer c = DicomRT_Contour::New();
- bool b = c->Read(j);
- if (b) {
- mListOfContours.push_back(c);
- if (contour_processed) {
- double delta=c->GetZ() - last_z;
- if (delta_computed)
- assert(mZDelta == delta);
- else
- mZDelta = delta;
- } else
- contour_processed=true;
- last_z=c->GetZ();
+ if (contours) {
+ int i=0;
+ for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) {
+ DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+ bool b = c->Read(j);
+ if (b) {
+ mListOfContours.push_back(c);
+ }
+ ++i;
}
}
+ else {
+ std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl;
+ }
}
#endif
//--------------------------------------------------------------------
//--------------------------------------------------------------------
void clitk::DicomRT_ROI::SetFromBinaryImage(vvImage * image, int n,
- std::string name,
- std::vector<double> color,
- std::string filename)
+ std::string name,
+ std::vector<double> color,
+ std::string filename)
{
// ROI number [Referenced ROI Number]
void SetImage(vvImage * im);
DicomRT_Contour* GetContour(int n);
- double GetContourSpacing() const {return mZDelta;}
+ // double GetContourSpacing() const {return mZDelta;}
protected:
void ComputeMesh();
double mBackgroundValue;
double mForegroundValue;
///Spacing between two contours
- double mZDelta;
+ // double mZDelta;
private:
DicomRT_ROI();
#include <iterator>
#include <algorithm>
+
+// clitk
#include "clitkDicomRT_ROI_ConvertToImageFilter.h"
+#include "clitkImageCommon.h"
+
+// vtk
#include <vtkPolyDataToImageStencil.h>
#include <vtkSmartPointer.h>
#include <vtkImageStencil.h>
#include <vtkLinearExtrusionFilter.h>
-#include "clitkImageCommon.h"
+#include <vtkMetaImageWriter.h>
+
//--------------------------------------------------------------------
clitk::DicomRT_ROI_ConvertToImageFilter::DicomRT_ROI_ConvertToImageFilter()
std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
exit(0);
}
- // DD("Update");
// Get Mesh
vtkPolyData * mesh = mROI->GetMesh();
- DD(mesh->GetNumberOfCells());
// Get bounds
double *bounds=mesh->GetBounds();
// Extrude
vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
extrude->SetInput(mesh);
- extrude->SetVector(0, 0, mROI->GetContourSpacing());
+ ///We extrude in the -slice_spacing direction to respect the FOCAL convention (NEEDED !)
+ extrude->SetVector(0, 0, -mSpacing[2]);
// Binarization
vtkSmartPointer<vtkPolyDataToImageStencil> sts=vtkSmartPointer<vtkPolyDataToImageStencil>::New();
stencil->SetInput(mBinaryImage);
stencil->ReverseStencilOn();
stencil->Update();
+
+ /*
+ vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
+ w->SetInput(stencil->GetOutput());
+ w->SetFileName("binary2.mhd");
+ w->Write();
+ */
+
mBinaryImage->ShallowCopy(stencil->GetOutput());
if (mWriteOutput) {
mStudyTime = reader.GetValEntry(0x008,0x0020)->GetValue();
mStudyDate = reader.GetValEntry(0x008,0x0030)->GetValue();
mLabel = reader.GetValEntry(0x3006,0x002)->GetValue();
- mName = reader.GetValEntry(0x3006,0x004)->GetValue();
+ if (!reader.GetValEntry(0x3006,0x004)) {
+ mName = "Anonymous";
+ }
+ else {
+ mName = reader.GetValEntry(0x3006,0x004)->GetValue();
+ }
mTime = reader.GetValEntry(0x3006,0x009)->GetValue();
//----------------------------------
/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
- Authors belong to:
+ Authors belong to:
- University of LYON http://www.universite-lyon.fr/
- Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"
-namespace clitk {
-
- //--------------------------------------------------------------------
- // New Image creation (no allocation)
- template<class PixelType>
- typename itk::Image<PixelType,1>::Pointer NewImage1D(int size, double spacing=1.0);
- template<class PixelType>
- typename itk::Image<PixelType,2>::Pointer NewImage2D(int sx, int sy, double dx=1.0, double dy=1.0);
- template<class PixelType>
- typename itk::Image<PixelType,3>::Pointer NewImage3D(int sx, int sy, int sz, double dx=1.0, double dy=1.0, double dz=1.0);
- template<class PixelType>
- typename itk::Image<PixelType,4>::Pointer NewImage4D(int sx, int sy, int sz, int st, double dx=1.0, double dy=1.0, double dz=1.0, double dt=1.0);
-
- template<class ImageType>
- typename ImageType::Pointer NewImageLike(const typename ImageType::Pointer input, bool allocate=true);
-
- template<class ImageType>
- void CopyValues(const typename ImageType::Pointer input, typename ImageType::Pointer output);
- //--------------------------------------------------------------------
- // New Image creation (with allocation)
-
- //--------------------------------------------------------------------
- // Read an Write image
- // template<class ImageType>
- // typename ImageType::Pointer ReadImage(const std::string & filename, const bool verbose=false);
- template<typename ImageType>
- typename ImageType::Pointer readImage(const std::string & filename, const bool verbose=false);
- template<typename ImageType>
- typename ImageType::Pointer readImage(const std::vector<std::string> & filenames, const bool verbose=false);
- template<class ImageType>
- void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose=false);
-// template<class ImageType>
+namespace clitk
+{
+
+//--------------------------------------------------------------------
+// New Image creation (no allocation)
+template<class PixelType>
+typename itk::Image<PixelType,1>::Pointer NewImage1D(int size, double spacing=1.0);
+template<class PixelType>
+typename itk::Image<PixelType,2>::Pointer NewImage2D(int sx, int sy, double dx=1.0, double dy=1.0);
+template<class PixelType>
+typename itk::Image<PixelType,3>::Pointer NewImage3D(int sx, int sy, int sz, double dx=1.0, double dy=1.0, double dz=1.0);
+template<class PixelType>
+typename itk::Image<PixelType,4>::Pointer NewImage4D(int sx, int sy, int sz, int st, double dx=1.0, double dy=1.0, double dz=1.0, double dt=1.0);
+
+template<class ImageType>
+typename ImageType::Pointer NewImageLike(const typename ImageType::Pointer input, bool allocate=true);
+
+template<class ImageType>
+void CopyValues(const typename ImageType::Pointer input, typename ImageType::Pointer output);
+//--------------------------------------------------------------------
+// New Image creation (with allocation)
+
+//--------------------------------------------------------------------
+// Read an Write image
+// template<class ImageType>
+// typename ImageType::Pointer ReadImage(const std::string & filename, const bool verbose=false);
+template<typename ImageType>
+typename ImageType::Pointer readImage(const std::string & filename, const bool verbose=false);
+template<typename ImageType>
+typename ImageType::Pointer readImage(const std::vector<std::string> & filenames, const bool verbose=false);
+template<class ImageType>
+void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose=false, const bool compression=false);
+// template<class ImageType>
// void writeConstImage(const typename ImageType::ConstPointer image, const std::string & filename, const bool verbose=false);
- template<class ImageType>
- void writeImage(const ImageType* image, const std::string & filename, const bool verbose=false);
-
- //--------------------------------------------------------------------
- // Read/print image header
- itk::ImageIOBase::Pointer readImageHeader(const std::string & filename,bool exit_on_error=true);
- void printImageHeader(itk::ImageIOBase::Pointer header, std::ostream & os, const int level=0);
-
- //--------------------------------------------------------------------
- // Determine pixetype and dimension of an image file
- void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType);
-
- //--------------------------------------------------------------------
- // Determine pixetype, dimension and number of pixel components of an image file
- void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType, int & components);
-
- //--------------------------------------------------------------------
- template<class ImageType>
- int ComputeHowManyDifferentIntensity(const typename ImageType::Pointer & image,
- std::vector<typename ImageType::PixelType> & listOfIntensities);
- template<class InputImageType, class MaskImageType>
- void ComputeWeightsOfEachClasses(const typename InputImageType::Pointer & input,
- const typename MaskImageType::Pointer & mask,
- const std::vector<typename MaskImageType::PixelType> & listOfIntensities,
- std::map<typename MaskImageType::PixelType,
- std::map<typename InputImageType::PixelType, double> > & mapOfLabelsAndWeights);
-
- //--------------------------------------------------------------------
- template<class ImageType1, class ImageType2>
- bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
- typename ImageType2::ConstPointer B);
-
- template<class ImageType1, class ImageType2>
- bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
- typename ImageType2::Pointer B);
-
- //--------------------------------------------------------------------
- template<class ImageType1, class ImageType2>
- bool HaveSameSpacing(typename ImageType1::ConstPointer A,
- typename ImageType2::ConstPointer B);
-
- template<class ImageType1, class ImageType2>
- bool HaveSameSpacing(typename ImageType1::Pointer A,
- typename ImageType2::Pointer B);
+template<class ImageType>
+void writeImage(const ImageType* image, const std::string & filename, const bool verbose=false, const bool compression=false);
+
+//--------------------------------------------------------------------
+// Read/print image header
+itk::ImageIOBase::Pointer readImageHeader(const std::string & filename,bool exit_on_error=true);
+void printImageHeader(itk::ImageIOBase::Pointer header, std::ostream & os, const int level=0);
+
+//--------------------------------------------------------------------
+// Determine pixetype and dimension of an image file
+void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType);
+
+//--------------------------------------------------------------------
+// Determine pixetype, dimension and number of pixel components of an image file
+void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType, int & components);
+
+//--------------------------------------------------------------------
+template<class ImageType>
+int ComputeHowManyDifferentIntensity(const typename ImageType::Pointer & image,
+ std::vector<typename ImageType::PixelType> & listOfIntensities);
+template<class InputImageType, class MaskImageType>
+void ComputeWeightsOfEachClasses(const typename InputImageType::Pointer & input,
+ const typename MaskImageType::Pointer & mask,
+ const std::vector<typename MaskImageType::PixelType> & listOfIntensities,
+ std::map<typename MaskImageType::PixelType,
+ std::map<typename InputImageType::PixelType, double> > & mapOfLabelsAndWeights);
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSpacing(typename ImageType1::ConstPointer A,
+ typename ImageType2::ConstPointer B);
+
+template<class ImageType1, class ImageType2>
+bool HaveSameSpacing(typename ImageType1::Pointer A,
+ typename ImageType2::Pointer B);
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSize(typename ImageType1::ConstPointer A,
+ typename ImageType2::ConstPointer B);
+
+template<class ImageType1, class ImageType2>
+bool HaveSameSize(typename ImageType1::Pointer A,
+ typename ImageType2::Pointer B);
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
+ typename ImageType2::ConstPointer B);
+
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
+ typename ImageType2::Pointer B);
#include "clitkImageCommon.txx"
//--------------------------------------------------------------------
template<class PixelType>
-typename itk::Image<PixelType,1>::Pointer
+typename itk::Image<PixelType,1>::Pointer
NewImage1D(int vsize, double vspacing)
{
typedef itk::Image<PixelType,1> ImageType;
//--------------------------------------------------------------------
template<class PixelType>
-typename itk::Image<PixelType,2>::Pointer
+typename itk::Image<PixelType,2>::Pointer
NewImage2D(int sx, int sy, double dx, double dy)
{
typedef itk::Image<PixelType,2> ImageType;
//--------------------------------------------------------------------
template<class PixelType>
-typename itk::Image<PixelType,3>::Pointer
+typename itk::Image<PixelType,3>::Pointer
NewImage3D(int sx, int sy, int sz, double dx, double dy, double dz)
{
typedef itk::Image<PixelType,3> ImageType;
//--------------------------------------------------------------------
template<class ImageType>
-void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose)
+void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose, const bool compression)
{
- typedef itk::ImageFileWriter<ImageType> WriterType;
- typename WriterType::Pointer writer = WriterType::New();
- writer->SetFileName(filename.c_str());
- writer->SetInput(image);
- if (verbose) {
- std::cout << "Writing [" << filename << "] ... " << std::endl;
- }
- try {
- writer->Update();
- } catch( itk::ExceptionObject & err ) {
- std::cerr << "Exception while writing image [" << filename << "]" << std::endl;
- std::cerr << err << std::endl;
- exit(-1);
- }
+ return writeImage(image.GetPointer(), filename, verbose, compression);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
template<class ImageType>
-void writeImage(const ImageType* image, const std::string & filename, const bool verbose)
+void writeImage(const ImageType* image, const std::string & filename, const bool verbose, const bool compression)
{
typedef itk::ImageFileWriter<ImageType> WriterType;
typename WriterType::Pointer writer = WriterType::New();
writer->SetFileName(filename.c_str());
writer->SetInput(image);
+ writer->SetUseCompression(compression);
if (verbose) {
std::cout << "Writing [" << filename << "] ... " << std::endl;
}
//--------------------------------------------------------------------
template<class ImageType1, class ImageType2>
-bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
- typename ImageType2::ConstPointer B)
+bool HaveSameSpacing(typename ImageType1::ConstPointer A,
+ typename ImageType2::ConstPointer B)
{
if (A->GetImageDimension() != B->GetImageDimension()) return false;
for(unsigned int i=0; i<A->GetImageDimension(); i++) {
if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
- if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
}
return true;
}
//--------------------------------------------------------------------
template<class ImageType1, class ImageType2>
-bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
- typename ImageType2::Pointer B)
+bool HaveSameSpacing(typename ImageType1::Pointer A,
+ typename ImageType2::Pointer B)
{
if (A->GetImageDimension() != B->GetImageDimension()) return false;
for(unsigned int i=0; i<A->GetImageDimension(); i++) {
if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
- if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
}
return true;
}
//--------------------------------------------------------------------
template<class ImageType1, class ImageType2>
-bool HaveSameSpacing(typename ImageType1::ConstPointer A,
- typename ImageType2::ConstPointer B)
+bool HaveSameSize(typename ImageType1::ConstPointer A,
+ typename ImageType2::ConstPointer B)
{
if (A->GetImageDimension() != B->GetImageDimension()) return false;
for(unsigned int i=0; i<A->GetImageDimension(); i++) {
- if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
+ if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
}
return true;
}
//--------------------------------------------------------------------
template<class ImageType1, class ImageType2>
-bool HaveSameSpacing(typename ImageType1::Pointer A,
- typename ImageType2::Pointer B)
+bool HaveSameSize(typename ImageType1::Pointer A,
+ typename ImageType2::Pointer B)
{
if (A->GetImageDimension() != B->GetImageDimension()) return false;
for(unsigned int i=0; i<A->GetImageDimension(); i++) {
- if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
+ if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
}
return true;
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
+ typename ImageType2::ConstPointer B)
+{
+ return ( HaveSameSize<ImageType1, ImageType2>(A, B) &&
+ HaveSameSpacing<ImageType1, ImageType2>(A, B) );
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
+ typename ImageType2::Pointer B)
+{
+ return ( HaveSameSize<ImageType1, ImageType2>(A, B) &&
+ HaveSameSpacing<ImageType1, ImageType2>(A, B) );
+}
+//--------------------------------------------------------------------
+
#endif /* end #define CLITKIMAGECOMMON_TXX */
m_FailOnImageTypeError = true;
m_ReadOnDisk = true;
m_WriteOnDisk = true;
+ m_WriteCompression = false;
// m_LastError = "";
// StopOnErrorOn();
SetFilterBase(NULL);
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+void clitk::ImageToImageGenericFilterBase::EnableWriteCompression(bool b)
+{
+ m_WriteCompression = b;
+}
+//--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
void clitk::ImageToImageGenericFilterBase::SetInputFilename(const std::string & filename)
{
void clitk::ImageToImageGenericFilterBase::SetNextOutput(typename ImageType::Pointer output)
{
if (m_WriteOnDisk && m_OutputFilenames.size()) {
- clitk::writeImage<ImageType>(output, m_OutputFilenames.front(), m_IOVerbose);
+ clitk::writeImage<ImageType>(output, m_OutputFilenames.front(), m_IOVerbose, m_WriteCompression);
m_OutputFilenames.pop_front();
}
if (m_InputVVImages.size()) //We assume that if a vv image is set as input, we want one as the output
void SetInputFilenames(const std::vector<std::string> & filenames);
void EnableReadOnDisk(bool b);
void EnableWriteOnDisk(bool b);
+ void EnableWriteCompression(bool b);
void SetOutputFilename(const std::string & filename);
void AddOutputFilename(const std::string filename);
void SetOutputFilenames(const std::vector<std::string> & filenames);
protected:
bool m_ReadOnDisk;
bool m_WriteOnDisk;
+ bool m_WriteCompression;
+
/// Call this function to dispatch an output towards the correct sink
template<class ImageType>
void SetNextOutput(typename ImageType::Pointer output);
SetOrigin(i,10*p[0]);
//Test if rectilinear image is actually uniform (tolerance 0.1 mm)
- for (j=0; j<GetDimensions(i)-1; j++) {
- if (fabs((p[j+1]-p[j])*10-GetSpacing(i))>0.1) {
- free(points);
- fclose(fstream);
- return ER_NOT_HANDLED;
+ if(i<3) { // Only for first 3 dimensions because spacing is barely used in other dims
+ for (j=0; j<GetDimensions(i)-1; j++) {
+ if (fabs((p[j+1]-p[j])*10-GetSpacing(i))>0.1) {
+ free(points);
+ fclose(fstream);
+ return ER_NOT_HANDLED;
+ }
}
}
p += (int)GetDimensions(i);
/**Converts the itk image to vv, handling the 4D problem
* The time_sequence boolean specifies that the image is to be interpreted as a time sequence,
* even if its dim is < 4. */
-template<unsigned int Dim, class PixelType> vvImage::Pointer vvImageFromITK(typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
+
+template<unsigned int Dim, class PixelType>
+static inline void ReadTimeSequence (vvImage::Pointer& vv_image, typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
{
- assert(Dim < 5 && Dim > 0); // We don't handle anything higher than 4-dimensional (for the moment :-p)
- vvImage::Pointer vv_image=vvImage::New();
- typedef itk::Image< PixelType, Dim > InputImageType;
+ typedef itk::Image< PixelType, Dim > InputImageType;
+ typedef itk::Image< PixelType, Dim - 1 > ItkImageType;
+ typedef itk::ExtractImageFilter<InputImageType, ItkImageType> FilterType;
+
+ //extract the 3D slices and put them in a std::vector<vtkImageData*>
+ input->UpdateOutputInformation();
+ typename InputImageType::RegionType inputRegion = input->GetLargestPossibleRegion();
+ typename InputImageType::SizeType inputSize = inputRegion.GetSize();
+ typename InputImageType::IndexType start = inputRegion.GetIndex();
+ typename InputImageType::SizeType extractedRegionSize = inputSize;
+ typename InputImageType::RegionType extractedRegion;
+ extractedRegionSize[Dim - 1] = 0;
+ extractedRegion.SetSize(extractedRegionSize);
- if (Dim == 4 || time_sequence) //The time sequence case: create a series of VTK images
- {
- typedef itk::Image< PixelType, Dim - 1 > ItkImageType;
- typedef itk::ExtractImageFilter<InputImageType, ItkImageType> FilterType;
-
- //extract the 3D slices and put them in a std::vector<vtkImageData*>
- input->UpdateOutputInformation();
- typename InputImageType::RegionType inputRegion = input->GetLargestPossibleRegion();
- typename InputImageType::SizeType inputSize = inputRegion.GetSize();
- typename InputImageType::IndexType start = inputRegion.GetIndex();
- typename InputImageType::SizeType extractedRegionSize = inputSize;
- typename InputImageType::RegionType extractedRegion;
- extractedRegionSize[Dim - 1] = 0;
- extractedRegion.SetSize(extractedRegionSize);
-
- for (unsigned int i = 0; i < inputSize[Dim - 1]; i++) {
- start[Dim - 1] = i;
- extractedRegion.SetIndex(start);
-
- typename FilterType::Pointer filter = FilterType::New();
+ for (unsigned int i = 0; i < inputSize[Dim - 1]; i++) {
+ start[Dim - 1] = i;
+ extractedRegion.SetIndex(start);
+
+ typename FilterType::Pointer filter = FilterType::New();
#if ITK_VERSION_MAJOR == 4
- filter->SetDirectionCollapseToSubmatrix();
+ filter->SetDirectionCollapseToSubmatrix();
#endif
- filter->SetExtractionRegion(extractedRegion);
- filter->SetInput(input);
- filter->ReleaseDataFlagOn();
- vv_image->AddItkImage<ItkImageType>(filter->GetOutput());
- }
- vv_image->SetTimeSpacing(input->GetSpacing()[Dim-1]);
- vv_image->SetTimeOrigin(input->GetOrigin()[Dim-1]);
- }
+ filter->SetExtractionRegion(extractedRegion);
+ filter->SetInput(input);
+ filter->ReleaseDataFlagOn();
+ vv_image->AddItkImage<ItkImageType>(filter->GetOutput());
+ }
+ vv_image->SetTimeSpacing(input->GetSpacing()[Dim-1]);
+ vv_image->SetTimeOrigin(input->GetOrigin()[Dim-1]);
+}
+
+template<unsigned int Dim, class PixelType>
+struct vvImageFromITK_Impl
+{
+ static vvImage::Pointer Do (typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
+ {
+ vvImage::Pointer vv_image=vvImage::New();
+ typedef itk::Image< PixelType, Dim > InputImageType;
+
+ if (time_sequence) //The time sequence case: create a series of VTK images
+ ReadTimeSequence<Dim,PixelType>(vv_image, input, time_sequence);
else //Dim == 1,2,3 and not time_sequence
- {
- vv_image->AddItkImage<InputImageType>(input);
- }
+ vv_image->AddItkImage<InputImageType>(input);
+
+ return vv_image;
+ }
+};
+
+template<class PixelType>
+struct vvImageFromITK_Impl<4u, PixelType>
+{
+ static vvImage::Pointer Do (typename itk::Image<PixelType,4u>::Pointer input, bool time_sequence=false)
+ {
+ vvImage::Pointer vv_image = vvImage::New();
+ ReadTimeSequence<4u,PixelType>(vv_image, input, time_sequence);
return vv_image;
+ }
+};
+
+template<unsigned int Dim, class PixelType> vvImage::Pointer vvImageFromITK(typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
+{
+ assert(Dim < 5 && Dim > 0); // We don't handle anything higher than 4-dimensional (for the moment :-p)
+ return vvImageFromITK_Impl<Dim, PixelType>::Do(input, time_sequence);
}
//------------------------------------------------------------------------------
input->Update();
// Convert from ITK object to VTK object
- mImageDimension = TItkImageType::ImageDimension;
+ mImageDimension = TItkImageType::ImageDimension;
typedef itk::ImageToVTKImageFilter <TItkImageType> ConverterType;
typename ConverterType::Pointer converter = ConverterType::New();
mItkToVtkConverters.push_back(dynamic_cast< itk::ProcessObject *>(converter.GetPointer()));
converter->SetInput(input);
converter->Update();
mVtkImages.push_back( converter->GetOutput() );
-
+
// Account for direction in transform. The offset is already accounted for
// in the VTK image coordinates, no need to put it in the transform.
vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
matrix->Identity();
- for(unsigned int j=0; j<input->GetImageDimension(); j++)
- for(unsigned int i=0; i<input->GetImageDimension(); i++)
+ for(unsigned int i=0; i<input->GetImageDimension(); i++) {
+ for(unsigned int j=0; j<input->GetImageDimension(); j++) {
(*matrix)[i][j] = input->GetDirection()[i][j];
+ // Direction is used around the image origin in ITK
+ (*matrix)[i][3] -= (*matrix)[i][j] * input->GetOrigin()[j];
+ }
+ (*matrix)[i][3] += input->GetOrigin()[i];
+ }
+
+ // GetDirection provides the forward transform, vtkImageReslice wants the inverse
+ matrix->Invert();
+
mTransform->SetMatrix(matrix);
}
//--------------------------------------------------------------------
//Read transformation in ASCII format
void vvImageReader::ReadMatImageTransform()
{
- std::string filename(mInputFilenames[0]+".mat");
+ std::string filename(itksys::SystemTools::GetFilenameWithoutExtension(mInputFilenames[0]));
+ filename += ".mat";
+
std::ifstream f(filename.c_str());
if(f.is_open()) {
f.close();
-
+
itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(filename);
-
+
vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
matrix->Identity();
for(int j=0; j<4; j++)
// file is inverted wrt the transformation given in the MAT file.
// We don't really know where the inversion takes place inside
// VTK or ITK. For what we could see in VV, the transformation
- // given in the MHD file seems "more correct" than that given in
+ // given in the MHD file seems "more correct" than that given in
// the MAT file. For this reason, we invert the matrix read from
// the MAT file before concatenating it to the current transformation.
// Still, it would be nice to find out what happens exactly between
// VTK and ITK...
//
- vtkSmartPointer<vtkMatrix4x4> inv_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
+ // SR: 23/06/2011
+ // We actually use vtkImageReslice which takes the inverse transform
+ // as input. So it seems more correct to inverse the matrix given by
+ // itk::ImageBase< VImageDimension >::GetDirection() than the matrix
+ // in .mat which is indeed the inverse optimized by a typical
+ // affine registration algorithm.
+ // Validated using clitkAffineTransform --transform_grid
if (matrix->Determinant() == 0)
{
vtkGenericWarningMacro("Matrix in " << filename.c_str() << " cannot be inverted (determinant = 0)");
}
- else
- matrix->Invert(*matrix, *inv_matrix);
-
+
mImage->GetTransform()->PostMultiply();
- mImage->GetTransform()->Concatenate(inv_matrix);
+ mImage->GetTransform()->Concatenate(matrix);
mImage->GetTransform()->Update();
}
}
IMAGEWITHTIME,
MERGEDWITHTIME,
VECTORFIELD,
+ VECTORFIELDWITHTIME,
UNDEFINEDIMAGETYPE
} LoadedImageType;
typedef itk::SmartPointer<Self> Pointer;
itkNewMacro(Self);
+ const std::vector<std::string>& GetInputFilenames(){return mInputFilenames;}
+
void SetInputFilename(const std::string & filename);
void SetInputFilenames(const std::vector<std::string> & filenames);
template<unsigned int VImageDimension>
void vvImageReader::UpdateWithDim(std::string InputPixelType)
{
- if (mType == VECTORFIELD)
+ if (mType == VECTORFIELD || mType == VECTORFIELDWITHTIME)
UpdateWithDimAndInputPixelType<itk::Vector<float,3>,VImageDimension>();
else if (InputPixelType == "short")
UpdateWithDimAndInputPixelType<short,VImageDimension>();
template<class InputPixelType, unsigned int VImageDimension>
void vvImageReader::UpdateWithDimAndInputPixelType()
{
- itk::AnalyzeImageIO *analyzeImageIO;
+ itk::AnalyzeImageIO *analyzeImageIO = NULL;
if (mType == MERGEDWITHTIME) // In this case we can load the images
// one at the time to avoid excessive
filter->SetExtractionRegion(extractedRegion);
filter->SetInput(reader->GetOutput());
filter->ReleaseDataFlagOn();
+#if ITK_VERSION_MAJOR == 4
+ filter->SetDirectionCollapseToSubmatrix();
+#endif
try {
mImage->AddItkImage<SlicedImageType>(filter->GetOutput());
} catch ( itk::ExceptionObject & err ) {
try {
if (mType == IMAGEWITHTIME)
- mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput(),true);
+ {
+ std::cerr << "We should never come here:" << std::endl
+ << " Calling vvImageReader with multiple images and IMAGEWITHTIME is undefined." << std::endl
+ << " You are probably looking for MERGEDWITHTIME Type." << std::endl;
+ return;
+ }
else
mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput());
} catch ( itk::ExceptionObject & err ) {
reader->ReleaseDataFlagOn();
try {
- if (mType == IMAGEWITHTIME)
+ if (mType == IMAGEWITHTIME || mType == VECTORFIELDWITHTIME)
mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput(),true);
else
mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput());
*
* This filter is implemented using the propagation algorithm
*/
-
+
+#if ITK_VERSION_MAJOR == 4
+ template <class TInputImage, class TOutputImage, class TtNorm=Functor::Minimum<
+ typename TOutputImage::PixelType,
+ typename TOutputImage::PixelType,
+ typename TOutputImage::PixelType> >
+#else
template <class TInputImage, class TOutputImage, class TtNorm=Function::Minimum<
typename TOutputImage::PixelType,
typename TOutputImage::PixelType,
typename TOutputImage::PixelType> >
+#endif
class ITK_EXPORT RelativePositionPropImageFilter :
public ImageToImageFilter< TInputImage, TOutputImage >
{
#include <itkBinaryErodeImageFilter.h>
#include <itkBinaryBallStructuringElement.h>
#include <itkAddImageFilter.h>
-#include <itkDivideByConstantImageFilter.h>
+#if ITK_VERSION_MAJOR >= 4
+ #include <itkDivideImageFilter.h>
+#else
+ #include <itkDivideByConstantImageFilter.h>
+#endif
// itk [Bloch et al]
#include "RelativePositionPropImageFilter.h"
// Divide by the number of relpos
if (GetNumberOfAngles() != 1) {
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::DivideImageFilter<FloatImageType, FloatImageType, FloatImageType> DivideFilter;
+ typename DivideFilter::Pointer divideFilter = DivideFilter::New();
+ divideFilter->SetConstant2(GetNumberOfAngles());
+#else
typedef itk::DivideByConstantImageFilter<FloatImageType, float, FloatImageType> DivideFilter;
typename DivideFilter::Pointer divideFilter = DivideFilter::New();
- divideFilter->SetInput(m_FuzzyMap);
divideFilter->SetConstant(GetNumberOfAngles());
+#endif
+ divideFilter->SetInput(m_FuzzyMap);
divideFilter->Update();
m_FuzzyMap = divideFilter->GetOutput();
}
AutoCropFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
this->SetNumberOfRequiredInputs(1);
m_BackgroundValue = 0;
- UseBorderOn();
+ UseBorderOff();
}
//--------------------------------------------------------------------
autoCropFilter->SetInput(imageToLabelFilter->GetOutput());
// autoCropFilter->ReleaseDataFlagOff();
if (GetUseBorder()) {
+ DD("UseBorder seems buggy ?");
+ exit(0);
typename ImageType::SizeType s;
for(uint i=0; i<ImageType::ImageDimension; i++) s[i] = 1;
autoCropFilter->SetCropBorder(s);
}
}
+ void SetPanelShift(double x, double y)
+ {
+ m_PanelShift[0] = x;
+ m_PanelShift[1] = y;
+ }
// itkSetMacro(IsoCenter, OutputPointType);
// itkGetConstReferenceMacro(IsoCenter, OutputPointType)
// itkSetMacro( SourceToScreen, double );
double m_SourceToAxis;
OutputPixelType m_EdgePaddingValue;
double m_ProjectionAngle;
+ double m_PanelShift[2];
// Output image info
OutputSizeType m_OutputSize; // Size of the output image
#include "clitkBackProjectImageFilter.h"
#include "itkContinuousIndex.h"
#include "vnl/vnl_math.h"
+#include "itkLinearInterpolateImageFunction.h"
namespace clitk
{
this->m_SourceToAxis = 1000.0;
this->m_EdgePaddingValue = itk::NumericTraits<OutputPixelType>::Zero;//density images
this->m_RigidTransformMatrix.SetIdentity();
+ this->m_PanelShift[0] = 0.;
+ this->m_PanelShift[1] = 0.;
//Parameters for output
this->m_OutputSpacing.Fill(1);
{
//Projection pointer
InputImageConstPointer inputPtr=this->GetInput();
- InputPixelType * beginPtr=const_cast<InputPixelType *>(this->GetInput()->GetBufferPointer());
- InputPixelType * pp;
//Volume pointer
OutputImagePointer outputPTr= this->GetOutput();
OutputIndexType oIndex;
ContinuousInputIndexType iIndex;
InputSizeType inputSize=inputPtr->GetLargestPossibleRegion().GetSize();
- double dx,dy,dxm,dym;
- int lx, ly;
//Get the first output coordinate
oIndex=iterator.GetIndex();//costly but only once a thread
//Compute the first input coordinate (invert Y/X)
homInputPoint= (m_ProjectionMatrix * homOutputPoint);
- iPoint[0]=-homInputPoint[0]/homInputPoint[2];
- iPoint[1]=homInputPoint[1]/homInputPoint[2];
-
+ iPoint[0]=-homInputPoint[0]/homInputPoint[2] + m_PanelShift[0];
+ iPoint[1]=homInputPoint[1]/homInputPoint[2] + m_PanelShift[1];
+
+ typedef itk::LinearInterpolateImageFunction< InputImageType, double > InterpolatorType;
+ typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+ interpolator->SetInputImage(this->GetInput());
+
//Run over all output voxels
for (unsigned int i=0; i<outputSizeForThread[2]; i++)
{
{
for (unsigned int k=0; k<outputSizeForThread[0]; k++)
{
- iPoint[0]=homInputPoint[0]/homInputPoint[2];
- iPoint[1]=homInputPoint[1]/homInputPoint[2];
+ iPoint[0]=-homInputPoint[0]/homInputPoint[2] + m_PanelShift[0];
+ iPoint[1]=homInputPoint[1]/homInputPoint[2] + m_PanelShift[1];
//Check wether inside, convert to index (use modified with correct origin)
- if( m_ModifiedInput->TransformPhysicalPointToContinuousIndex(iPoint, iIndex) )
- {
- //Own (fast bilinear) interpolation
- lx = (int)floor(iIndex[0]); dx = iIndex[0]-lx; dxm = 1.-dx;
- ly = (int)floor(iIndex[1]); dy = iIndex[1]-ly; dym = 1.-dy;
- pp = beginPtr + ly*inputSize[0]+lx;
- value =static_cast<OutputPixelType>( ( dxm * dym*(double)(*pp)
- + dx * dym*(double)(*(pp+1))
- + dxm* dy *(double)(*(pp + inputSize[0]))
- + dx * dy *(double)(*(pp + inputSize[0]+1))) );
-
- }
+ if (m_ModifiedInput->TransformPhysicalPointToContinuousIndex(iPoint, iIndex) && interpolator->IsInsideBuffer(iIndex))
+ value = interpolator->EvaluateAtContinuousIndex(iIndex);
//Outside: padding value
- else value=m_EdgePaddingValue;
-
+ else
+ value=m_EdgePaddingValue;
//Set it
iterator.Set(value);
// get neighbor index and overlap fraction
- for( dim = 0; dim < 3; dim++ )
+ for( dim = 0; dim < ImageDimension; dim++ )
{
if ( upper & 1 )
{
IndexType idx = tmpRegIndexIt.GetIndex() + *itIdx;
if( outputRegion.IsInside( idx ) )
{
- // JV output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) ); }
- if (input->GetPixel(idx)==backgroundValue)
- output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) );
+ // JV output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) ); }
+ if (input->GetPixel(idx)==backgroundValue)
+ output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) );
}
}
--- /dev/null
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile: itkGrayscaleDilateImageFilter.h,v $
+ Language: C++
+ Date: $Date: 2009-04-28 14:36:20 $
+ Version: $Revision: 1.19 $
+
+ Copyright (c) Insight Software Consortium. All rights reserved.
+ See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef __clitkGrayscaleDilateImageFilter_h
+#define __clitkGrayscaleDilateImageFilter_h
+
+// First make sure that the configuration is available.
+// This line can be removed once the optimized versions
+// gets integrated into the main directories.
+#include "itkConfigure.h"
+
+#ifdef ITK_USE_CONSOLIDATED_MORPHOLOGY
+#include "itkOptGrayscaleDilateImageFilter.h"
+#else
+
+
+#include "itkMorphologyImageFilter.h"
+
+namespace itk {
+
+/**
+ * \class ConditionalGrayscaleDilateImageFilter
+ * \brief gray scale dilation of an image
+ *
+ * Dilate an image using grayscale morphology. Dilation takes the
+ * maximum of all the pixels identified by the structuring element.
+ *
+ * The structuring element is assumed to be composed of binary
+ * values (zero or one). Only elements of the structuring element
+ * having values > 0 are candidates for affecting the center pixel.
+ *
+ * For the each input image pixel,
+ * - NeighborhoodIterator gives neighbors of the pixel.
+ * - Evaluate() member function returns the maximum value among
+ * the image neighbors where the kernel has elements > 0.
+ * - Replace the original value with the max value
+ *
+ * \sa MorphologyImageFilter, GrayscaleFunctionDilateImageFilter, BinaryDilateImageFilter
+ * \ingroup ImageEnhancement MathematicalMorphologyImageFilters
+ */
+
+template<class TInputImage, class TOutputImage, class TKernel>
+class ITK_EXPORT ConditionalGrayscaleDilateImageFilter :
+ public MorphologyImageFilter<TInputImage, TOutputImage, TKernel>
+{
+public:
+ /** Standard class typedefs. */
+ typedef ConditionalGrayscaleDilateImageFilter Self;
+ typedef MorphologyImageFilter<TInputImage, TOutputImage, TKernel>
+ Superclass;
+ typedef SmartPointer<Self> Pointer;
+ typedef SmartPointer<const Self> ConstPointer;
+
+ /** Standard New method. */
+ itkNewMacro(Self);
+
+ /** Runtime information support. */
+ itkTypeMacro(ConditionalGrayscaleDilateImageFilter,
+ MorphologyImageFilter);
+
+ /** Declaration of pixel type. */
+ typedef typename Superclass::PixelType PixelType;
+
+ /** Kernel (structuring element) iterator. */
+ typedef typename Superclass::KernelIteratorType KernelIteratorType;
+
+ /** Neighborhood iterator type. */
+ typedef typename Superclass::NeighborhoodIteratorType NeighborhoodIteratorType;
+
+ /** Kernel typedef. */
+ typedef typename Superclass::KernelType KernelType;
+
+ /** Default boundary condition type */
+ typedef typename Superclass::DefaultBoundaryConditionType DefaultBoundaryConditionType;
+
+ /** ImageDimension constants */
+ itkStaticConstMacro(InputImageDimension, unsigned int,
+ TInputImage::ImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int,
+ TOutputImage::ImageDimension);
+ itkStaticConstMacro(KernelDimension, unsigned int,
+ TKernel::NeighborhoodDimension);
+
+ /** Type of the pixels in the Kernel. */
+ typedef typename TKernel::PixelType KernelPixelType;
+
+#ifdef ITK_USE_CONCEPT_CHECKING
+ /** Begin concept checking */
+ itkConceptMacro(InputConvertibleToOutputCheck,
+ (Concept::Convertible<PixelType, typename TOutputImage::PixelType>));
+ itkConceptMacro(SameDimensionCheck1,
+ (Concept::SameDimension<InputImageDimension, OutputImageDimension>));
+ itkConceptMacro(SameDimensionCheck2,
+ (Concept::SameDimension<InputImageDimension, KernelDimension>));
+ itkConceptMacro(InputGreaterThanComparableCheck,
+ (Concept::GreaterThanComparable<PixelType>));
+ itkConceptMacro(KernelGreaterThanComparableCheck,
+ (Concept::GreaterThanComparable<KernelPixelType>));
+ /** End concept checking */
+#endif
+
+protected:
+ ConditionalGrayscaleDilateImageFilter();
+ ~ConditionalGrayscaleDilateImageFilter() {};
+
+ /** Evaluate image neighborhood with kernel to find the new value
+ * for the center pixel value
+ *
+ * It will return the maximum value of the image pixels whose corresponding
+ * element in the structuring element is positive. This version of
+ * Evaluate is used for non-boundary pixels. */
+ PixelType Evaluate(const NeighborhoodIteratorType &nit,
+ const KernelIteratorType kernelBegin,
+ const KernelIteratorType kernelEnd);
+
+private:
+ ConditionalGrayscaleDilateImageFilter(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+
+ // Default boundary condition for dilation filter, defaults to
+ // NumericTraits<PixelType>::NonpositiveMin()
+ DefaultBoundaryConditionType m_DilateBoundaryCondition;
+
+}; // end of class
+
+} // end namespace itk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkConditionalGrayscaleDilateImageFilter.txx"
+#endif
+
+#endif
+
+#endif
--- /dev/null
+/*=========================================================================
+
+ Program: Insight Segmentation & Registration Toolkit
+ Module: $RCSfile: itkConditionalGrayscaleDilateImageFilter.txx,v $
+ Language: C++
+ Date: $Date: 2009-04-28 14:36:20 $
+ Version: $Revision: 1.17 $
+
+ Copyright (c) Insight Software Consortium. All rights reserved.
+ See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __clitkConditionalGrayscaleDilateImageFilter_txx
+#define __clitkConditionalGrayscaleDilateImageFilter_txx
+
+// First make sure that the configuration is available.
+// This line can be removed once the optimized versions
+// gets integrated into the main directories.
+#include "itkConfigure.h"
+
+#ifdef ITK_USE_CONSOLIDATED_MORPHOLOGY
+#include "itkOptGrayscaleDilateImageFilter.txx"
+#else
+
+
+#include "clitkConditionalGrayscaleDilateImageFilter.h"
+
+namespace itk {
+
+template<class TInputImage, class TOutputImage, class TKernel>
+ConditionalGrayscaleDilateImageFilter<TInputImage, TOutputImage, TKernel>
+::ConditionalGrayscaleDilateImageFilter()
+{
+ m_DilateBoundaryCondition.SetConstant( NumericTraits<PixelType>::NonpositiveMin() );
+ this->OverrideBoundaryCondition( &m_DilateBoundaryCondition );
+}
+
+template<class TInputImage, class TOutputImage, class TKernel>
+typename ConditionalGrayscaleDilateImageFilter<TInputImage, TOutputImage, TKernel>::PixelType
+ConditionalGrayscaleDilateImageFilter<TInputImage, TOutputImage, TKernel>
+::Evaluate(const NeighborhoodIteratorType &nit,
+ const KernelIteratorType kernelBegin,
+ const KernelIteratorType kernelEnd)
+{
+ unsigned int i;
+ PixelType max = NumericTraits<PixelType>::NonpositiveMin();
+ PixelType temp;
+
+ KernelIteratorType kernel_it;
+
+ PixelType center = nit.GetCenterPixel ();
+ // if (center != NumericTraits<KernelPixelType>::Zero) {
+ // DD((int)center);
+ // }
+
+ if (center > NumericTraits<KernelPixelType>::Zero) return center;
+
+ for( i=0, kernel_it=kernelBegin; kernel_it<kernelEnd; ++kernel_it, ++i )
+ {
+ // if structuring element is positive, use the pixel under that element
+ // in the image
+ if( *kernel_it > NumericTraits<KernelPixelType>::Zero )
+ {
+ // note we use GetPixel() on the SmartNeighborhoodIterator to
+ // respect boundary conditions
+ temp = nit.GetPixel(i);
+
+ if( temp > max )
+ {
+ max = temp;
+ }
+ }
+ }
+
+ return max;
+}
+
+
+}// end namespace itk
+#endif
+
+#endif
<< ") of 'like' is " << likeSpacing[i] << ".");
}
}
+
+ // Check that we must crop along each dimension. If not, we use the
+ // size of the input image
+ for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
+ if (m_CropAlongThisDimension[i] == false) {
+ likeStart[i] = input->GetLargestPossibleRegion().GetIndex()[i];
+ likeSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
+ }
+ }
+
// Define output region
m_OutputRegion.SetIndex(likeStart);
m_OutputRegion.SetSize(likeSize);
itkGetConstMacro( Outside, InternalPixelType);
itkSetMacro( ErosionPaddingValue, OutputPixelType);
itkGetConstMacro( ErosionPaddingValue, OutputPixelType);
- void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+ void SetRadius ( const SizeType& s) { m_Radius=s; this->Modified();}
SizeType GetRadius(void){return m_Radius;}
+ void SetRadius(const int r) { for(uint i=0; i<InputImageDimension; i++) m_Radius[i] = r; SetRadius(m_Radius); }
itkSetMacro( NumberOfNewLabels, unsigned int);
itkGetConstMacro( NumberOfNewLabels, unsigned int);
itkSetMacro( MinimumObjectSize, unsigned int);
m_index[GetDirection()] = start + i;
m_region.SetIndex(m_index);
extract->SetExtractionRegion(m_region);
+#if ITK_VERSION_MAJOR == 4
+ extract->SetDirectionCollapseToSubmatrix();
+#endif
extract->Update();
SetNthOutput(i, extract->GetOutput());
}
//define some temp variables
signed long baseIndex[ImageDimension];
double distance[ImageDimension];
+ for(uint i=0; i<ImageDimension; i++) distance[i] = 0.0; // to avoid warning
unsigned int dim, counter, upper;
double overlap, totalOverlap;
typename OutputImageType::IndexType neighIndex;
upper = counter; // each bit indicates upper/lower neighbour
// get neighbor index and overlap fraction
- for( dim = 0; dim < 3; dim++ ) {
+ for( dim = 0; dim < ImageDimension; dim++ ) {
if ( upper & 1 ) {
neighIndex[dim] = baseIndex[dim] + 1;
overlap *= distance[dim];
#include "itkConnectedComponentImageFilter.h"
#include "itkStatisticsImageFilter.h"
#include "itkCastImageFilter.h"
-#include "itkDifferenceImageFilter.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkTestingComparisonImageFilter.h"
+#else
+ #include "itkDifferenceImageFilter.h"
+#endif
#include "itkThresholdImageFilter.h"
namespace clitk
itkSetMacro( Verbose, bool);
itkGetConstReferenceMacro( Verbose, bool);
void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+ void SetRadius(const int r) { for(uint i=0; i<InputImageDimension; i++) m_Radius[i] = r; SetRadius(m_Radius); }
SizeType GetRadius(void){return m_Radius;}
itkSetMacro( ErosionPaddingValue, OutputPixelType);
itkGetConstMacro( ErosionPaddingValue, OutputPixelType)
typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
typedef itk::BinaryBallStructuringElement<InternalPixelType,InputImageDimension > KernelType;
typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> ConditionalBinaryDilateImageFilterType;
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::Testing::ComparisonImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
+#else
typedef itk::DifferenceImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
+#endif
typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+
+#ifndef clitkReconstructWithConditionalGrayscaleDilateImageFilter_h
+#define clitkReconstructWithConditionalGrayscaleDilateImageFilter_h
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkConditionalGrayscaleDilateImageFilter.h"
+
+namespace clitk
+{
+ /*
+ This filter takes as input a multilabel image (and a bg value).
+ It performs several greyscale dilatation of radius 1, but only in
+ the bg pixels. It means that when two objects (with different
+ labels) will dilate inside each other (collistion), the dilatation
+ is stopped.
+ */
+
+ template <class ImageType>
+ class ITK_EXPORT ReconstructWithConditionalGrayscaleDilateImageFilter :
+ public itk::ImageToImageFilter<ImageType, ImageType>
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef ReconstructWithConditionalGrayscaleDilateImageFilter Self;
+ typedef itk::ImageToImageFilter<ImageType, ImageType> Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ // Method for creation through the object factory
+ itkNewMacro(Self);
+
+ // Run-time type information (and related methods)
+ itkTypeMacro( ReconstructWithConditionalGrayscaleDilateImageFilter, ImageToImageFilter);
+
+ /** Dimension of the domain space. */
+ itkStaticConstMacro(ImageDimension, unsigned int, Superclass::InputImageDimension);
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef typename ImageType::PixelType PixelType;
+ typedef typename ImageType::SizeType SizeType;
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ itkBooleanMacro(Verbose);
+ itkSetMacro( Verbose, bool);
+ itkGetConstReferenceMacro( Verbose, bool);
+
+ itkSetMacro(IterationNumber, int);
+ itkGetConstMacro(IterationNumber, int);
+
+ itkSetMacro(BackgroundValue, PixelType);
+ itkGetConstMacro(BackgroundValue, PixelType);
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ ReconstructWithConditionalGrayscaleDilateImageFilter();
+ ~ReconstructWithConditionalGrayscaleDilateImageFilter() {};
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ // Generate Data
+ void GenerateData(void);
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ PixelType m_BackgroundValue;
+ int m_IterationNumber;
+ };
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkReconstructWithConditionalGrayscaleDilateImageFilter.txx"
+#endif
+
+#endif // #define clitkReconstructWithConditionalGrayscaleDilateImageFilter_h
+
+
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+
+#ifndef clitkReconstructWithConditionalGrayscaleDilateImageFilter_txx
+#define clitkReconstructWithConditionalGrayscaleDilateImageFilter_txx
+
+#include <itkGrayscaleDilateImageFilter.h>
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ template<class ImageType>
+ ReconstructWithConditionalGrayscaleDilateImageFilter<ImageType>::ReconstructWithConditionalGrayscaleDilateImageFilter()
+ {
+ m_Verbose=false;
+ m_BackgroundValue=0;
+ m_IterationNumber = 5;
+ }
+ //-------------------------------------------------------------------
+
+ //-------------------------------------------------------------------
+ template<class ImageType>
+ void
+ ReconstructWithConditionalGrayscaleDilateImageFilter<ImageType>::GenerateData()
+ {
+ // Get input image
+ typename ImageType::ConstPointer input = this->GetInput();
+
+ // Main loop
+ typename ImageType::Pointer output;
+ for(int r=0; r<GetIterationNumber(); r++) {
+
+ // Create kernel for GrayscaleDilateImageFilter
+ typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension > KernelType;
+ KernelType k;
+ k.SetRadius(1);
+ k.CreateStructuringElement();
+
+ // Check that BG is 0, because ConditionalGrayscaleDilateImageFilter consider BG is 0
+ if (GetBackgroundValue() !=0) {
+ FATAL("FATAL -> BG is not 0, check ReconstructWithConditionalGrayscaleDilateImageFilter");
+ // TODO -> replace 0 with new label, replace BG with 0 ; reverse at the end
+ }
+
+ // ConditionalGrayscaleDilateImageFilter -> Dilate only BG value
+ typedef itk::ConditionalGrayscaleDilateImageFilter<ImageType, ImageType, KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetKernel(k);
+ if (r==0) {
+ m->SetInput(input); // First time
+ }
+ else m->SetInput(output);
+ m->Update();
+ output = m->GetOutput();
+ }
+
+ //---------------------------------
+ this->SetNthOutput(0, output);
+ }
+
+}//end clitk
+
+#endif //#define clitkReconstructWithConditionalGrayscaleDilateImageFilter_txx
// floor() is used to intentionally reduce the number of slices
// because, from a clinical point of view, it's better to
// remove data than to add data that privously didn't exist.
+ if(inputSpacing[i]*m_OutputSpacing[i]<0)
+ itkExceptionMacro( << "Input and output spacings don't have the same signs, can't cope with that" );
m_OutputSize[i] = (int)floor(inputSize[i]*inputSpacing[i]/m_OutputSpacing[i]);
}
} else {
if (m_OutputSpacing[0] != -1) { // apply spacing, compute size
for(unsigned int i=0; i<dim; i++) {
+ if(inputSpacing[i]*m_OutputSpacing[i]<0)
+ itkExceptionMacro( << "Input and output spacings don't have the same signs, can't cope with that" );
// see comment above for the use of floor()
m_OutputSize[i] = (int)floor(inputSize[i]*inputSpacing[i]/m_OutputSpacing[i]);
}
m_OutputSize[l] = inputSize[l];
m_OutputSpacing[l] = inputSpacing[l];
}
-
+
// Set Size/Spacing
OutputImagePointer outputImage = this->GetOutput(0);
// OutputImageRegionType region;
#include "clitkCommon.h"
#include "clitkAutoCropFilter.h"
#include "clitkLabelizeParameters.h"
+#include "clitkExtractSliceFilter.h"
// itk
#include <itkBoundingBox.h>
typename ImageType::PixelType BG=0);
template<class ImageType>
typename ImageType::Pointer
- CropImageAbove(const ImageType * image,
- int dim, double min, bool autoCrop = false,
- typename ImageType::PixelType BG=0);
+ CropImageRemoveGreaterThan(const ImageType * image,
+ int dim, double min, bool autoCrop = false,
+ typename ImageType::PixelType BG=0);
template<class ImageType>
typename ImageType::Pointer
- CropImageBelow(const ImageType * image,
- int dim, double max,bool autoCrop = false,
- typename ImageType::PixelType BG=0);
+ CropImageRemoveLowerThan(const ImageType * image,
+ int dim, double max,bool autoCrop = false,
+ typename ImageType::PixelType BG=0);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
+ template<class ImageType, class LabelType>
+ typename itk::LabelMap< itk::ShapeLabelObject<LabelType, ImageType::ImageDimension> >::Pointer
+ ComputeLabelMap(const ImageType * image,
+ typename ImageType::PixelType BG,
+ bool computePerimeterFlag=false);
template<class ImageType>
void
ComputeCentroids(const ImageType * image,
//--------------------------------------------------------------------
template<class ImageType>
void
- ExtractSlices(const ImageType * image, int dim,
- std::vector< typename itk::Image<typename ImageType::PixelType,
- ImageType::ImageDimension-1>::Pointer > & slices);
+ ExtractSlices(const ImageType * image, int direction,
+ std::vector<typename itk::Image<typename ImageType::PixelType,
+ ImageType::ImageDimension-1>::Pointer > & slices)
+ {
+ typedef ExtractSliceFilter<ImageType> ExtractSliceFilterType;
+ typedef typename ExtractSliceFilterType::SliceType SliceType;
+ typename ExtractSliceFilterType::Pointer
+ extractSliceFilter = ExtractSliceFilterType::New();
+ extractSliceFilter->SetInput(image);
+ extractSliceFilter->SetDirection(direction);
+ extractSliceFilter->Update();
+ extractSliceFilter->GetOutputSlices(slices);
+ }
//--------------------------------------------------------------------
bool extendSupport);
//--------------------------------------------------------------------
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ Opening(const ImageType * image, typename ImageType::SizeType radius,
+ typename ImageType::PixelType BG, typename ImageType::PixelType FG);
+ //--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
template<class ValueType, class VectorType>
void ConvertOption(std::string optionName, uint given,
void AndNot(ImageType * input,
const ImageType * object,
typename ImageType::PixelType BG=0);
+ template<class ImageType>
+ void And(ImageType * input,
+ const ImageType * object,
+ typename ImageType::PixelType BG=0);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceKeepMainCCL(const ImageType * input,
+ typename ImageType::PixelType BG,
+ typename ImageType::PixelType FG);
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ Clone(const ImageType * input);
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceSetBackgroundFromSingleLine(const ImageType * input,
+ typename ImageType::PixelType BG,
+ typename ImageType::PointType & A,
+ typename ImageType::PointType & B,
+ int dim1, int dim2, bool removeLowerPartFlag);
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceSetBackgroundFromPoints(const ImageType * input,
+ typename ImageType::PixelType BG,
+ int sliceDim,
+ std::vector<typename ImageType::PointType> & A,
+ bool removeGreaterThanXFlag,
+ bool removeGreaterThanYFlag);
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ FillRegionWithValue(ImageType * input, typename ImageType::PixelType value,
+ typename ImageType::RegionType & region);
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ GetMinMaxBoundary(ImageType * input, typename ImageType::PointType & min,
+ typename ImageType::PointType & max);
+ //--------------------------------------------------------------------
+
}
#include "clitkSegmentationUtils.txx"
#include <itkBinaryDilateImageFilter.h>
#include <itkConstantPadImageFilter.h>
#include <itkImageSliceIteratorWithIndex.h>
+#include <itkBinaryMorphologicalOpeningImageFilter.h>
+#include <itkImageDuplicator.h>
namespace clitk {
sliceRelPosFilter->SetIntermediateSpacingFlag((spacing != -1));
sliceRelPosFilter->SetIntermediateSpacing(spacing);
sliceRelPosFilter->SetUniqueConnectedComponentBySlice(uniqueConnectedComponent);
+ sliceRelPosFilter->CCLSelectionFlagOff();
sliceRelPosFilter->SetUseASingleObjectConnectedComponentBySliceFlag(singleObjectCCL);
// sliceRelPosFilter->SetInverseOrientationFlag(inverseflag);
sliceRelPosFilter->SetAutoCropFlag(autocropFlag);
//--------------------------------------------------------------------
template<class ImageType>
typename ImageType::Pointer
- CropImageAbove(const ImageType * image,
+ CropImageRemoveGreaterThan(const ImageType * image,
int dim, double min, bool autoCrop,
typename ImageType::PixelType BG)
{
//--------------------------------------------------------------------
template<class ImageType>
typename ImageType::Pointer
- CropImageBelow(const ImageType * image,
+ CropImageRemoveLowerThan(const ImageType * image,
int dim, double max, bool autoCrop,
typename ImageType::PixelType BG)
{
p[dim] = max;
typename ImageType::IndexType end;
image->TransformPhysicalPointToIndex(p, end);
- size[dim] = fabs(end[dim]-start[dim]);
+ size[dim] = abs(end[dim]-start[dim]);
region.SetIndex(start);
region.SetSize(size);
centroids.clear();
typename ImageType::PointType dummy;
- centroids.push_back(dummy); // label 0 -> no centroid, use dummy point
- for(uint i=1; i<labelMap->GetNumberOfLabelObjects()+1; i++) {
- centroids.push_back(labelMap->GetLabelObject(i)->GetCentroid());
+ centroids.push_back(dummy); // label 0 -> no centroid, use dummy point for BG
+ //DS FIXME (not useful ! to change ..)
+ for(uint i=0; i<labelMap->GetNumberOfLabelObjects(); i++) {
+ int label = labelMap->GetLabels()[i];
+ centroids.push_back(labelMap->GetLabelObject(label)->GetCentroid());
}
}
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ template<class ImageType, class LabelType>
+ typename itk::LabelMap< itk::ShapeLabelObject<LabelType, ImageType::ImageDimension> >::Pointer
+ ComputeLabelMap(const ImageType * image,
+ typename ImageType::PixelType BG,
+ bool computePerimeterFlag)
+ {
+ static const unsigned int Dim = ImageType::ImageDimension;
+ typedef itk::ShapeLabelObject< LabelType, Dim > LabelObjectType;
+ typedef itk::LabelMap< LabelObjectType > LabelMapType;
+ typedef itk::LabelImageToLabelMapFilter<ImageType, LabelMapType> ImageToMapFilterType;
+ typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New();
+ typedef itk::ShapeLabelMapFilter<LabelMapType, ImageType> ShapeFilterType;
+ typename ShapeFilterType::Pointer statFilter = ShapeFilterType::New();
+ imageToLabelFilter->SetBackgroundValue(BG);
+ imageToLabelFilter->SetInput(image);
+ statFilter->SetInput(imageToLabelFilter->GetOutput());
+ statFilter->SetComputePerimeter(computePerimeterFlag);
+ statFilter->Update();
+ return statFilter->GetOutput();
+ }
+ //--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
template<class ImageType>
void
//--------------------------------------------------------------------
- //--------------------------------------------------------------------
- template<class ImageType>
- void
- ExtractSlices(const ImageType * image, int direction,
- std::vector<typename itk::Image<typename ImageType::PixelType,
- ImageType::ImageDimension-1>::Pointer > & slices)
- {
- typedef ExtractSliceFilter<ImageType> ExtractSliceFilterType;
- typedef typename ExtractSliceFilterType::SliceType SliceType;
- typename ExtractSliceFilterType::Pointer
- extractSliceFilter = ExtractSliceFilterType::New();
- extractSliceFilter->SetInput(image);
- extractSliceFilter->SetDirection(direction);
- extractSliceFilter->Update();
- extractSliceFilter->GetOutputSlices(slices);
- }
- //--------------------------------------------------------------------
-
-
//--------------------------------------------------------------------
template<class ImageType>
void
dilateFilter->SetForegroundValue(FG);
dilateFilter->SetBoundaryToForeground(false);
dilateFilter->SetKernel(structuringElement);
- dilateFilter->SetInput(output);
+ if (extendSupport) dilateFilter->SetInput(output);
+ else dilateFilter->SetInput(image);
dilateFilter->Update();
return dilateFilter->GetOutput();
}
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ Opening(const ImageType * image, typename ImageType::SizeType radius,
+ typename ImageType::PixelType BG,
+ typename ImageType::PixelType FG)
+ {
+ // Kernel
+ typedef itk::BinaryBallStructuringElement<typename ImageType::PixelType,
+ ImageType::ImageDimension> KernelType;
+ KernelType structuringElement;
+ structuringElement.SetRadius(radius);
+ structuringElement.CreateStructuringElement();
+
+ // Filter
+ typedef itk::BinaryMorphologicalOpeningImageFilter<ImageType, ImageType , KernelType> OpeningFilterType;
+ typename OpeningFilterType::Pointer open = OpeningFilterType::New();
+ open->SetInput(image);
+ open->SetBackgroundValue(BG);
+ open->SetForegroundValue(FG);
+ open->SetKernel(structuringElement);
+ open->Update();
+ return open->GetOutput();
+ }
+ //--------------------------------------------------------------------
+
+
+
//--------------------------------------------------------------------
template<class ValueType, class VectorType>
void ConvertOption(std::string optionName, uint given,
while ((i<lA.size()) && (!siter.IsAtEnd())) {
// Check that the current slice correspond to the current point
input->TransformIndexToPhysicalPoint(siter.GetIndex(), C);
- // DD(C);
- // DD(i);
- // DD(lA[i]);
if ((fabs(C[2] - lA[i][2]))>0.01) { // is !equal with a tolerance of 0.01 mm
}
else {
A = lA[i];
B = lB[i];
C = A;
- // DD(A);
- // DD(B);
- // DD(C);
// Check that the line is not a point (A=B)
bool p = (A[0] == B[0]) && (A[1] == B[1]);
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
template<class ImageType>
void
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ And(ImageType * input,
+ const ImageType * object,
+ typename ImageType::PixelType BG)
+ {
+ typename ImageType::Pointer o;
+ bool resized=false;
+ if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(input, object)) {
+ o = clitk::ResizeImageLike<ImageType>(object, input, BG);
+ resized = true;
+ }
+
+ typedef clitk::BooleanOperatorLabelImageFilter<ImageType> BoolFilterType;
+ typename BoolFilterType::Pointer boolFilter = BoolFilterType::New();
+ boolFilter->InPlaceOn();
+ boolFilter->SetInput1(input);
+ if (resized) boolFilter->SetInput2(o);
+ else boolFilter->SetInput2(object);
+ boolFilter->SetBackgroundValue1(BG);
+ boolFilter->SetBackgroundValue2(BG);
+ boolFilter->SetOperationType(BoolFilterType::And);
+ boolFilter->Update();
+ }
+ //--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
template<class ImageType>
typename ImageType::Pointer
typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> BinaryThresholdFilterType;
typename BinaryThresholdFilterType::Pointer binarizeFilter = BinaryThresholdFilterType::New();
binarizeFilter->SetInput(input);
+ binarizeFilter->InPlaceOff();
binarizeFilter->SetLowerThreshold(lower);
binarizeFilter->SetUpperThreshold(upper);
binarizeFilter->SetInsideValue(FG);
extremaDirection, extremaOppositeFlag, p);
if (found) {
position2D[i] = p;
- }
+ }
}
// Convert 2D points in slice into 3D points
p[lineDirection] += 10;
B.push_back(p);
// Margins ?
- A[i][1] += margin;
- B[i][1] += margin;
+ A[i][extremaDirection] += margin;
+ B[i][extremaDirection] += margin;
+ }
+
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceKeepMainCCL(const ImageType * input,
+ typename ImageType::PixelType BG,
+ typename ImageType::PixelType FG) {
+
+ // Extract slices
+ const int d = ImageType::ImageDimension-1;
+ typedef typename itk::Image<typename ImageType::PixelType, d> SliceType;
+ std::vector<typename SliceType::Pointer> slices;
+ clitk::ExtractSlices<ImageType>(input, d, slices);
+
+ // Labelize and keep the main one
+ std::vector<typename SliceType::Pointer> o;
+ for(uint i=0; i<slices.size(); i++) {
+ o.push_back(clitk::Labelize<SliceType>(slices[i], BG, false, 1));
+ o[i] = clitk::KeepLabels<SliceType>(o[i], BG, FG, 1, 1, true);
+ }
+
+ // Join slices
+ typename ImageType::Pointer output;
+ output = clitk::JoinSlices<ImageType>(o, input, d);
+ return output;
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ typename ImageType::Pointer
+ Clone(const ImageType * input) {
+ typedef itk::ImageDuplicator<ImageType> DuplicatorType;
+ typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
+ duplicator->SetInputImage(input);
+ duplicator->Update();
+ return duplicator->GetOutput();
+ }
+ //--------------------------------------------------------------------
+
+
+ //--------------------------------------------------------------------
+ /* Consider an input object, start at A, for each slice (dim1):
+ - compute the intersection between the AB line and the current slice
+ - remove what is at lower or greater according to dim2 of this point
+ - stop at B
+ */
+ template<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceSetBackgroundFromSingleLine(const ImageType * input,
+ typename ImageType::PixelType BG,
+ typename ImageType::PointType & A,
+ typename ImageType::PointType & B,
+ int dim1, int dim2, bool removeLowerPartFlag)
+
+ {
+ // Extract slices
+ typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+ typedef typename SliceType::Pointer SlicePointer;
+ std::vector<SlicePointer> slices;
+ clitk::ExtractSlices<ImageType>(input, dim1, slices);
+
+ // Start at slice that contains A, and stop at B
+ typename ImageType::IndexType Ap;
+ typename ImageType::IndexType Bp;
+ input->TransformPhysicalPointToIndex(A, Ap);
+ input->TransformPhysicalPointToIndex(B, Bp);
+
+ // Determine slice largest region
+ typename SliceType::RegionType region = slices[0]->GetLargestPossibleRegion();
+ typename SliceType::SizeType size = region.GetSize();
+ typename SliceType::IndexType index = region.GetIndex();
+
+ // Line slope
+ double a = (Bp[dim2]-Ap[dim2])/(Bp[dim1]-Ap[dim1]);
+ double b = Ap[dim2];
+
+ // Loop from slice A to slice B
+ for(uint i=0; i<(Bp[dim1]-Ap[dim1]); i++) {
+ // Compute intersection between line AB and current slice for the dim2
+ double p = a*i+b;
+ // Change region (lower than dim2)
+ if (removeLowerPartFlag) {
+ size[dim2] = p-Ap[dim2];
+ }
+ else {
+ size[dim2] = slices[0]->GetLargestPossibleRegion().GetSize()[dim2]-p;
+ index[dim2] = p;
+ }
+ region.SetSize(size);
+ region.SetIndex(index);
+ // Fill region with BG (simple region iterator)
+ FillRegionWithValue<SliceType>(slices[i+Ap[dim1]], BG, region);
+ /*
+ typedef itk::ImageRegionIterator<SliceType> IteratorType;
+ IteratorType iter(slices[i+Ap[dim1]], region);
+ iter.GoToBegin();
+ while (!iter.IsAtEnd()) {
+ iter.Set(BG);
+ ++iter;
+ }
+ */
+ // Loop
+ }
+
+ // Merge slices
+ typename ImageType::Pointer output;
+ output = clitk::JoinSlices<ImageType>(slices, input, dim1);
+ return output;
+ }
+ //--------------------------------------------------------------------
+
+ //--------------------------------------------------------------------
+ /* Consider an input object, slice by slice, use the point A and set
+ pixel to BG according to their position relatively to A
+ */
+ template<class ImageType>
+ typename ImageType::Pointer
+ SliceBySliceSetBackgroundFromPoints(const ImageType * input,
+ typename ImageType::PixelType BG,
+ int sliceDim,
+ std::vector<typename ImageType::PointType> & A,
+ bool removeGreaterThanXFlag,
+ bool removeGreaterThanYFlag)
+
+ {
+ // Extract slices
+ typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+ typedef typename SliceType::Pointer SlicePointer;
+ std::vector<SlicePointer> slices;
+ clitk::ExtractSlices<ImageType>(input, sliceDim, slices);
+
+ // Start at slice that contains A
+ typename ImageType::IndexType Ap;
+
+ // Determine slice largest region
+ typename SliceType::RegionType region = slices[0]->GetLargestPossibleRegion();
+ typename SliceType::SizeType size = region.GetSize();
+ typename SliceType::IndexType index = region.GetIndex();
+
+ // Loop from slice A to slice B
+ for(uint i=0; i<A.size(); i++) {
+ input->TransformPhysicalPointToIndex(A[i], Ap);
+ uint sliceIndex = Ap[2] - input->GetLargestPossibleRegion().GetIndex()[2];
+ if ((sliceIndex < 0) || (sliceIndex >= slices.size())) {
+ continue; // do not consider this slice
+ }
+
+ // Compute region for BG
+ if (removeGreaterThanXFlag) {
+ index[0] = Ap[0];
+ size[0] = region.GetSize()[0]-(index[0]-region.GetIndex()[0]);
+ }
+ else {
+ index[0] = region.GetIndex()[0];
+ size[0] = Ap[0] - index[0];
+ }
+
+ if (removeGreaterThanYFlag) {
+ index[1] = Ap[1];
+ size[1] = region.GetSize()[1]-(index[1]-region.GetIndex()[1]);
+ }
+ else {
+ index[1] = region.GetIndex()[1];
+ size[1] = Ap[1] - index[1];
+ }
+
+ // Set region
+ region.SetSize(size);
+ region.SetIndex(index);
+
+ // Fill region with BG (simple region iterator)
+ FillRegionWithValue<SliceType>(slices[sliceIndex], BG, region);
+ // Loop
}
+
+ // Merge slices
+ typename ImageType::Pointer output;
+ output = clitk::JoinSlices<ImageType>(slices, input, sliceDim);
+ return output;
+ }
+ //--------------------------------------------------------------------
+
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ FillRegionWithValue(ImageType * input, typename ImageType::PixelType value, typename ImageType::RegionType & region)
+ {
+ typedef itk::ImageRegionIterator<ImageType> IteratorType;
+ IteratorType iter(input, region);
+ iter.GoToBegin();
+ while (!iter.IsAtEnd()) {
+ iter.Set(value);
+ ++iter;
+ }
}
//--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+ template<class ImageType>
+ void
+ GetMinMaxBoundary(ImageType * input, typename ImageType::PointType & min,
+ typename ImageType::PointType & max)
+ {
+ typedef typename ImageType::PointType PointType;
+ typedef typename ImageType::IndexType IndexType;
+ IndexType min_i, max_i;
+ min_i = input->GetLargestPossibleRegion().GetIndex();
+ for(uint i=0; i<ImageType::ImageDimension; i++)
+ max_i[i] = input->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
+ input->TransformIndexToPhysicalPoint(min_i, min);
+ input->TransformIndexToPhysicalPoint(max_i, max);
+ }
+ //--------------------------------------------------------------------
+
} // end of namespace
this->VerboseStepFlagOff();
this->WriteStepFlagOff();
this->SetCombineWithOrFlag(false);
- CCLSelectionFlagOn();
+ CCLSelectionFlagOff();
SetCCLSelectionDimension(0);
SetCCLSelectionDirection(1);
CCLSelectionIgnoreSingleCCLFlagOff();
true);
}
}
- }
+ } // end GetCCLSelectionFlag = true
// Relative position
typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
-/*=========================================================================
+/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
Authors belong to:
#include "itkRayCastInterpolateImageFunctionWithOrigin.h"
#include "vnl/vnl_math.h"
-
+#include "clitkCommon.h"
// Put the helper class in an anonymous namespace so that it is not
// exposed to the user
{
double maxInterDist, interDist;
double cornerVect[4][3];
+ for(clitk::uint i=0; i<4; i++)
+ for(clitk::uint j=0; j<3; j++)
+ cornerVect[i][j] = 0.0; // to avoid warning
int cross[4][3], noInterFlag[6];
int nSidesCrossed, crossFlag, c[4];
double ax, ay, az, bx, by, bz;
- BSD See included LICENSE.txt file
- CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
+==========================================================================*/
+++ /dev/null
-
-* GIT emacs command
-C-x v d
-.gitignore -> contains ignored files
-commit (local)
-push (repository)
-pull
-
-* Test in temp
-git clone http://www.creatis.insa-lyon.fr/~dsarrut/clitk3.pub.git clitk3
-need itk4 (git) ?
-
############################## registration algorithms
ADD_EXECUTABLE(clitkAffineRegistration clitkAffineRegistration.cxx)
TARGET_LINK_LIBRARIES(clitkAffineRegistration clitkAffineRegistrationLib clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL clitkAffineRegistration)
WRAP_GGO(clitkDemonsDeformableRegistration_GGO_C clitkDemonsDeformableRegistration.ggo)
ADD_EXECUTABLE(clitkDemonsDeformableRegistration clitkDemonsDeformableRegistration.cxx ${clitkDemonsDeformableRegistration_GGO_C} clitkDemonsDeformableRegistrationGenericFilter.cxx)
TARGET_LINK_LIBRARIES(clitkDemonsDeformableRegistration ${ITK_LIBRARIES} clitkCommon)
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkDemonsDeformableRegistration)
WRAP_GGO(clitkBLUTDIR_GGO_C clitkBLUTDIR.ggo)
ADD_EXECUTABLE(clitkBLUTDIR clitkBLUTDIR.cxx clitkBLUTDIRGenericFilter.cxx ${clitkBLUTDIR_GGO_C} clitkLBFGSBOptimizer.cxx )
TARGET_LINK_LIBRARIES(clitkBLUTDIR clitkCommon ${ITK_LIBRARIES} )
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkBLUTDIR)
WRAP_GGO(clitkShapedBLUTSpatioTemporalDIR_GGO_C clitkShapedBLUTSpatioTemporalDIR.ggo)
ADD_EXECUTABLE(clitkShapedBLUTSpatioTemporalDIR clitkShapedBLUTSpatioTemporalDIR.cxx clitkShapedBLUTSpatioTemporalDIRGenericFilter.cxx ${clitkShapedBLUTSpatioTemporalDIR_GGO_C} clitkLBFGSBOptimizer.cxx)
TARGET_LINK_LIBRARIES(clitkShapedBLUTSpatioTemporalDIR clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkShapedBLUTSpatioTemporalDIR)
WRAP_GGO(clitkBSplineDeformableRegistration_GGO_C clitkBSplineDeformableRegistration.ggo)
ADD_EXECUTABLE(clitkBSplineDeformableRegistration clitkBSplineDeformableRegistration.cxx clitkBSplineDeformableRegistrationGenericFilter.cxx ${clitkBSplineDeformableRegistration_GGO_C} clitkLBFGSBOptimizer.cxx)
TARGET_LINK_LIBRARIES(clitkBSplineDeformableRegistration clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkBSplineDeformableRegistration)
############################## registration-related tools to process points, bsplines, vf and image pyramids
WRAP_GGO(clitkConvertPointList_GGO_C clitkConvertPointList.ggo)
ADD_EXECUTABLE(clitkConvertPointList clitkConvertPointList.cxx ${clitkConvertPointList_GGO_C})
TARGET_LINK_LIBRARIES(clitkConvertPointList ${ITK_LIBRARIES} clitkCommon )
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkConvertPointList)
WRAP_GGO(clitkSelectPoints_GGO_C clitkSelectPoints.ggo)
ADD_EXECUTABLE(clitkSelectPoints clitkSelectPoints.cxx clitkSelectPointsGenericFilter.cxx ${clitkSelectPoints_GGO_C})
TARGET_LINK_LIBRARIES(clitkSelectPoints clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkSelectPoints)
WRAP_GGO(clitkPointTrajectory_GGO_C clitkPointTrajectory.ggo)
ADD_EXECUTABLE(clitkPointTrajectory clitkPointTrajectory.cxx clitkPointTrajectoryGenericFilter.cxx ${clitkPointTrajectory_GGO_C})
TARGET_LINK_LIBRARIES(clitkPointTrajectory clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkPointTrajectory)
WRAP_GGO(clitkCalculateTRE_GGO_C clitkCalculateTRE.ggo)
ADD_EXECUTABLE(clitkCalculateTRE clitkCalculateTRE.cxx clitkCalculateTREGenericFilter.cxx ${clitkCalculateTRE_GGO_C})
TARGET_LINK_LIBRARIES(clitkCalculateTRE clitkCommon ${ITK_LIBRARIES} )
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkCalculateTRE)
WRAP_GGO(clitkMatrixTransformToVF_GGO_C clitkMatrixTransformToVF.ggo)
ADD_EXECUTABLE(clitkMatrixTransformToVF clitkMatrixTransformToVF.cxx clitkMatrixTransformToVFGenericFilter.cxx ${clitkMatrixTransformToVF_GGO_C})
TARGET_LINK_LIBRARIES(clitkMatrixTransformToVF ${ITK_LIBRARIES} clitkCommon)
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkMatrixTransformToVF)
WRAP_GGO(clitkConvertBSplineDeformableTransformToVF_GGO_C clitkConvertBSplineDeformableTransformToVF.ggo)
ADD_EXECUTABLE(clitkConvertBSplineDeformableTransformToVF clitkConvertBSplineDeformableTransformToVF.cxx clitkConvertBSplineDeformableTransformToVFGenericFilter.cxx ${clitkConvertBSplineDeformableTransformToVF_GGO_C})
TARGET_LINK_LIBRARIES(clitkConvertBSplineDeformableTransformToVF clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkConvertBSplineDeformableTransformToVF)
WRAP_GGO(clitkMultiResolutionPyramid_GGO_C clitkMultiResolutionPyramid.ggo)
ADD_EXECUTABLE(clitkMultiResolutionPyramid clitkMultiResolutionPyramid.cxx clitkMultiResolutionPyramidGenericFilter.cxx ${clitkMultiResolutionPyramid_GGO_C})
TARGET_LINK_LIBRARIES(clitkMultiResolutionPyramid clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkMultiResolutionPyramid)
WRAP_GGO(clitkBSplinePyramid_GGO_C clitkBSplinePyramid.ggo)
ADD_EXECUTABLE(clitkBSplinePyramid clitkBSplinePyramid.cxx clitkBSplinePyramidGenericFilter.cxx ${clitkBSplinePyramid_GGO_C})
TARGET_LINK_LIBRARIES(clitkBSplinePyramid clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkBSplinePyramid)
WRAP_GGO(clitkResampleBSplineDeformableTransform_GGO_C clitkResampleBSplineDeformableTransform.ggo)
ADD_EXECUTABLE(clitkResampleBSplineDeformableTransform clitkResampleBSplineDeformableTransform.cxx clitkResampleBSplineDeformableTransformGenericFilter.cxx ${clitkResampleBSplineDeformableTransform_GGO_C})
TARGET_LINK_LIBRARIES(clitkResampleBSplineDeformableTransform clitkCommon ${ITK_LIBRARIES})
+ SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkResampleBSplineDeformableTransform)
+
+ SET_TARGET_PROPERTIES(${REGISTRATION_INSTALL} PROPERTIES INSTALL_RPATH "${VTK_DIR}:${ITK_DIR}" )
+ INSTALL (TARGETS ${REGISTRATION_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
+
ENDIF(CLITK_BUILD_REGISTRATION)
// Compute the DVF (only deformable transform)
//=======================================================
typedef itk::Vector< float, SpaceDimension > DisplacementType;
- typedef itk::Image< DisplacementType, InputImageType::ImageDimension > DeformationFieldType;
- typedef itk::TransformToDeformationFieldSource<DeformationFieldType, double> ConvertorType;
+ typedef itk::Image< DisplacementType, InputImageType::ImageDimension > DisplacementFieldType;
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::TransformToDisplacementFieldSource<DisplacementFieldType, double> ConvertorType;
+#else
+ typedef itk::TransformToDeformationFieldSource<DisplacementFieldType, double> ConvertorType;
+#endif
typename ConvertorType::Pointer filter= ConvertorType::New();
filter->SetNumberOfThreads(1);
transform->SetBulkTransform(NULL);
filter->SetTransform(transform);
filter->SetOutputParametersFromImage(fixedImage);
filter->Update();
- typename DeformationFieldType::Pointer field = filter->GetOutput();
+ typename DisplacementFieldType::Pointer field = filter->GetOutput();
//=======================================================
// Write the DVF
//=======================================================
- typedef itk::ImageFileWriter< DeformationFieldType > FieldWriterType;
+ typedef itk::ImageFileWriter< DisplacementFieldType > FieldWriterType;
typename FieldWriterType::Pointer fieldWriter = FieldWriterType::New();
fieldWriter->SetFileName( m_ArgsInfo.vf_arg );
fieldWriter->SetInput( field );
#include "itkLabelGeometryImageFilter.h"
#include "itkImageDuplicator.h"
#include "itkExtractImageFilter.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkTransformToDisplacementFieldSource.h"
+#else
+ #include "itkTransformToDeformationFieldSource.h"
+#endif
namespace clitk
{
-/*=========================================================================
+/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
Authors belong to:
for(unsigned int r=0; r<ImageDimension; r++)
{
chosenSpacing[r]= m_ArgsInfo.spacing_arg[r];
- gridSizeOnImage[r] = ceil( (double) transformRegion.GetSize()[r] / ( round(chosenSpacing[r]/fixedImageSpacing[r]) ) );
- adaptedSpacing[r]= ( round(chosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+ gridSizeOnImage[r] = ceil( (double) transformRegion.GetSize()[r] / ( itk::Math::Round<double>(chosenSpacing[r]/fixedImageSpacing[r]) ) );
+ adaptedSpacing[r]= ( itk::Math::Round<double>(chosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
}
if (m_Verbose) std::cout<<"The chosen control point spacing "<<chosenSpacing<<"..."<<std::endl;
if (m_Verbose) std::cout<<"The control points spacing was adapted to "<<adaptedSpacing<<"..."<<std::endl;
}
/** Compute the Jacobian Matrix of the transformation at one point */
+#if ITK_VERSION_MAJOR >= 4
+ virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const;
+ virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( "ComputeJacobianWithRespectToPosition not yet implemented for " << this->GetNameOfClass() );
+ }
+#else
virtual const JacobianType& GetJacobian(const InputPointType &point ) const;
+#endif
/** Return the number of parameters that completely define the Transfom */
virtual unsigned int GetNumberOfParameters(void) const;
// VD Add MultipleBSplineDeformableTransform as friend to facilitate wrapping
friend class MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>;
+#if ITK_VERSION_MAJOR >= 4
+ mutable JacobianType m_SharedDataBSplineJacobian;
+#endif
}; //class BSplineDeformableTransform
// Constructor with default arguments
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
BSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+ ::BSplineDeformableTransform():Superclass(0)
+#else
::BSplineDeformableTransform():Superclass(OutputDimension,0)
+#endif
{
unsigned int i;
m_CoefficientImage = m_WrappedImage;
//JV Wrap jacobian into OutputDimension X Vectorial images
+#if ITK_VERSION_MAJOR >= 4
+ this->m_SharedDataBSplineJacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#else
this->m_Jacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#endif
// Use memset to set the memory
+#if ITK_VERSION_MAJOR >= 4
+ JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
+#else
JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
+#endif
memset(jacobianDataPointer, 0, OutputDimension*numberOfPixels*sizeof(JacobianPixelType));
m_LastJacobianIndex = m_ValidRegion.GetIndex();
m_NeedResetJacobian = false;
// JV weights are identical as for transformpoint, could be done simultaneously in metric!!!!
// Compute the Jacobian in one position
+#if ITK_VERSION_MAJOR >= 4
+ template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
+ void
+ BSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+ ::ComputeJacobianWithRespectToParameters(const InputPointType & point, JacobianType & jacobian) const
+ {
+ if (m_NeedResetJacobian)
+ ResetJacobian();
+
+ //========================================================
+ // For each dimension, copy the weight to the support region
+ //========================================================
+
+ // Check if inside mask
+ if (m_Mask && !(m_Mask->IsInside(point) ) )
+ {
+ // Outside: no (deformable) displacement
+ jacobian = m_SharedDataBSplineJacobian;
+ return;
+ }
+
+ //Get index
+ this->TransformPointToContinuousIndex( point, m_Index );
+
+ // NOTE: if the support region does not lie totally within the grid
+ // we assume zero displacement and return the input point
+ if ( !this->InsideValidRegion( m_Index ) )
+ {
+ jacobian = m_SharedDataBSplineJacobian;
+ return;
+ }
+
+ //Compute interpolation weights
+ const WeightsDataType *weights = NULL;
+ m_VectorInterpolator->EvaluateWeightsAtContinuousIndex( m_Index, &weights, m_LastJacobianIndex);
+ m_SupportRegion.SetIndex( m_LastJacobianIndex );
+
+ //Reset the iterators
+ unsigned int j = 0;
+ for ( j = 0; j < OutputDimension; j++ )
+ m_Iterator[j] = IteratorType( m_JacobianImage[j], m_SupportRegion);
+
+ // For each dimension, copy the weight to the support region
+ while ( ! (m_Iterator[0]).IsAtEnd() )
+ {
+ //copy weight to jacobian image
+ for ( j = 0; j < OutputDimension; j++ )
+ {
+ m_ZeroVector[j]=*weights;
+ (m_Iterator[j]).Set( m_ZeroVector);
+ m_ZeroVector[j]=itk::NumericTraits<JacobianValueType>::Zero;
+ ++(m_Iterator[j]);
+ }
+ // go to next coefficient in the support region
+ weights++;
+ }
+ m_NeedResetJacobian = true;
+
+ // Return the result
+ jacobian = m_SharedDataBSplineJacobian;
+
+ }
+#else
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
const
typename BSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
return this->m_Jacobian;
}
+#endif
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
-/*=========================================================================
+/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
Authors belong to:
#ifndef __clitkBSplineDeformableTransformInitializer_txx
#define __clitkBSplineDeformableTransformInitializer_txx
#include "clitkBSplineDeformableTransformInitializer.h"
+#include "itkMath.h"
namespace clitk
{
{
// JV
m_ChosenSpacing[r]= m_ControlPointSpacing[r];
- m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+ m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
if ( ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
== ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
// -----------------------------------------------
// Filter
// -----------------------------------------------
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::TransformToDisplacementFieldSource<OutputImageType, double> ConvertorType;
+#else
typedef itk::TransformToDeformationFieldSource<OutputImageType, double> ConvertorType;
+#endif
ConvertorType::Pointer filter= ConvertorType::New();
//Output image info
//itk include
#include "itkLightObject.h"
#include "itkImageMaskSpatialObject.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkTransformToDisplacementFieldSource.h"
+#else
+ #include "itkTransformToDeformationFieldSource.h"
+#endif
namespace clitk
if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint , jacobian);
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
+#endif
const RealType fixedValue = ti.Value();
if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
+#endif
const RealType fixedValue = ti.Value();
return OutputCovariantVectorType();
}
+#if ITK_VERSION_MAJOR >= 4
+ virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( << "DeformationFieldTransform doesn't declare ComputeJacobianWithRespectToParameters" );
+ }
+ virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( << "DeformationFieldTransform doesn't declare ComputeJacobianWithRespectToPosition" );
+ }
+#else
virtual const JacobianType& GetJacobian(const InputPointType &point ) const
{
itkExceptionMacro( << "DeformationFieldTransform doesn't declare GetJacobian" );
return this->m_Jacobian;
}
+#endif
protected:
DeformationFieldTransform();
// Constructor
template<class TScalarType, unsigned int InputDimension, unsigned int OutputDimension, unsigned int SpaceDimension>
DeformationFieldTransform<TScalarType, InputDimension, OutputDimension, SpaceDimension>
+#if ITK_VERSION_MAJOR >= 4
+ ::DeformationFieldTransform():Superclass(1)
+#else
::DeformationFieldTransform():Superclass(OutputDimension,1)
+#endif
{
m_DeformationField=NULL;
m_Interpolator=DefaultInterpolatorType::New();
//find the multiresolution filter
// typedef typename RegistrationFilterType::FixedImageType InternalImageType;
// typedef typename RegistrationFilterType::MovingImageType MovingImageType;
- typedef typename RegistrationFilterType::DeformationFieldType DeformationFieldType;
- typedef clitk::MultiResolutionPDEDeformableRegistration<FixedImageType, MovingImageType, DeformationFieldType> MultiResolutionRegistrationType;
+#if ITK_VERSION_MAJOR >= 4
+ typedef typename RegistrationFilterType::DisplacementFieldType DisplacementFieldType;
+#else
+ typedef typename RegistrationFilterType::DeformationFieldType DisplacementFieldType;
+#endif
+ typedef clitk::MultiResolutionPDEDeformableRegistration<FixedImageType, MovingImageType, DisplacementFieldType> MultiResolutionRegistrationType;
typedef CommandResolutionLevelUpdate<MultiResolutionRegistrationType> LevelObserver;
protected:
//JV TODO
// pdeFilter->SetMaximumError(m_ArgsInfo.maxError_arg);
// pdeFilter->SetMaximumKernelWidth(m_ArgsInfo.maxError_arg);
+#if ITK_VERSION_MAJOR >= 4
+ pdeFilter->SetSmoothDisplacementField(!m_ArgsInfo.fluid_flag);
+#else
pdeFilter->SetSmoothDeformationField(!m_ArgsInfo.fluid_flag);
+#endif
pdeFilter->SetSmoothUpdateField(m_ArgsInfo.fluid_flag);
pdeFilter->SetUseImageSpacing( m_ArgsInfo.spacing_flag );
typedef itk::WarpImageFilter< MovingImageType, FixedImageType, DeformationFieldType > WarpFilterType;
typename WarpFilterType::Pointer warp = WarpFilterType::New();
+#if ITK_VERSION_MAJOR >= 4
+ warp->SetDisplacementField( deformationField );
+#else
warp->SetDeformationField( deformationField );
+#endif
warp->SetInput( movingImageReader->GetOutput() );
warp->SetOutputOrigin( fixedImage->GetOrigin() );
warp->SetOutputSpacing( fixedImage->GetSpacing() );
m_Maximize=false;
m_Verbose=false;
m_FixedImageRegionGiven=false;
-#ifdef ITK_USE_OPTIMISED_REGISTRATION_METHODS
+#ifdef ITK_USE_OPTIMIZED_REGISTRATION_METHODS
m_FixedImageSamplesIntensityThreshold=0;
m_UseFixedImageSamplesIntensityThreshold=false;
#endif
}
- //typedef itk::ImageMaskSpatialObject<itkGetStaticConstMacro(FixedImageDimension)> ImageMaskSpatialObjectType;
- //typename ImageMaskSpatialObjectType::ConstPointer mask = dynamic_cast<const ImageMaskSpatialObjectType*>(m_FixedImageMask.GetPointer());
+ typedef itk::ImageMaskSpatialObject<itkGetStaticConstMacro(FixedImageDimension)> ImageMaskSpatialObjectType;
+ typename ImageMaskSpatialObjectType::ConstPointer mask = NULL;
+ if (m_FixedImageMask.IsNotNull())
+ mask = dynamic_cast<const ImageMaskSpatialObjectType*>(m_FixedImageMask.GetPointer());
- //typedef typename ImageMaskSpatialObjectType::RegionType ImageMaskRegionType;
- //ImageMaskRegionType mask_region = mask->GetAxisAlignedBoundingBoxRegion();
+ typedef typename ImageMaskSpatialObjectType::RegionType ImageMaskRegionType;
+ ImageMaskRegionType mask_region;
+ if (mask.IsNotNull())
+ mask_region = mask->GetAxisAlignedBoundingBoxRegion();
// Common properties
if( m_FixedImageMask.IsNotNull() )
// Calculate the number
const unsigned int totalNumberOfPixels = m_FixedImageRegion.GetNumberOfPixels();
- //const unsigned int totalNumberOfPixels = mask_region.GetNumberOfPixels();
+ const unsigned int totalNumberOfMaskPixels = mask_region.GetNumberOfPixels();
const unsigned int numberOfDemandedPixels = static_cast< unsigned int >( (double) totalNumberOfPixels *m_ArgsInfo.samples_arg );
// --------------------------------------------------
}
// Intensity?
+ /*
if( m_UseFixedImageSamplesIntensityThreshold &&
( regionIter.Get() < m_FixedImageSamplesIntensityThreshold) ) {
++regionIter; // jump to next pixel
continue;
}
+ */
// Add point to the numbers
fiic.push_back(index);
//RandomIterator randIter( m_FixedImage, mask_region );
if (m_Verbose) std::cout << "Search region " << m_FixedImageRegion << std::endl;
- //if (m_Verbose) std::cout << "Mask search region " << mask_region << std::endl;
+ if (m_Verbose) std::cout << "Mask search region " << mask_region << std::endl;
// Randomly sample the image
short att = 1;
}
// Intensity?
- if( m_UseFixedImageSamplesIntensityThreshold &&
- randIter.Get() < m_FixedImageSamplesIntensityThreshold ) {
- ++randIter;
- //if (m_Verbose) std::cout << "not in threshold" << std::endl;
- count_not_thres++;
- continue;
- }
+// if( m_UseFixedImageSamplesIntensityThreshold &&
+// randIter.Get() < m_FixedImageSamplesIntensityThreshold ) {
+// ++randIter;
+// //if (m_Verbose) std::cout << "not in threshold" << std::endl;
+// count_not_thres++;
+// continue;
+// }
// Add point to the numbers
fiic.push_back(index);
if (m_Verbose) std::cout<<"A fraction of "<<m_ArgsInfo.samples_arg<<" spatial samples was requested..."<<std::endl;
double fraction=(double)numberOfValidPixels/ (double) totalNumberOfPixels;
if (m_Verbose) std::cout<<"Found "<<numberOfValidPixels <<" valid pixels for a total of "<<totalNumberOfPixels<<" (a fraction of "<<fraction<<")..."<<std::endl;
+ if (m_Verbose) std::cout<<"number of mask pixels "<<totalNumberOfMaskPixels<<std::endl;
}
//itk include
#include "itkLightObject.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkTransformToDisplacementFieldSource.h"
+#else
+ #include "itkTransformToDeformationFieldSource.h"
+#endif
#include "itkAffineTransform.h"
namespace clitk
typedef itk::Image<Displacement, Dimension> OutputImageType;
// Filter
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::TransformToDisplacementFieldSource<OutputImageType, double> ConvertorType;
+#else
typedef itk::TransformToDeformationFieldSource<OutputImageType, double> ConvertorType;
+#endif
typename ConvertorType::Pointer filter= ConvertorType::New();
// Output image info
if( tempField.IsNull() )
{
+#if ITK_VERSION_MAJOR >= 4
+ m_RegistrationFilter->SetInitialDisplacementField( NULL );
+#else
m_RegistrationFilter->SetInitialDeformationField( NULL );
+#endif
}
else
{
tempField = m_FieldExpander->GetOutput();
tempField->DisconnectPipeline();
+#if ITK_VERSION_MAJOR >= 4
+ m_RegistrationFilter->SetInitialDisplacementField( tempField );
+#else
m_RegistrationFilter->SetInitialDeformationField( tempField );
+#endif
}
}
/** Compute the Jacobian Matrix of the transformation at one point */
+#if ITK_VERSION_MAJOR >= 4
+ virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const;
+ virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( "ComputeJacobianWithRespectToPosition not yet implemented for " << this->GetNameOfClass() );
+ }
+#else
virtual const JacobianType& GetJacobian(const InputPointType &point ) const;
+#endif
/** Return the number of parameters that completely define the Transfom */
virtual unsigned int GetNumberOfParameters(void) const;
std::vector<ParametersType> m_parameters;
mutable std::vector<CoefficientImagePointer> m_CoefficientImages;
mutable int m_LastJacobian;
+#if ITK_VERSION_MAJOR >= 4
+ mutable JacobianType m_SharedDataBSplineJacobian;
+#endif
void InitJacobian();
// FIXME it seems not used
// Constructor with default arguments
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+ ::MultipleBSplineDeformableTransform() : Superclass(0)
+#else
::MultipleBSplineDeformableTransform() : Superclass(OutputDimension, 0)
+#endif
{
m_nLabels = 1;
m_labels = 0;
return m_trans[lidx]->DeformablyTransformPoint(inputPoint);
}
+#if ITK_VERSION_MAJOR >= 4
+ template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
+ inline void
+ MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+ ::ComputeJacobianWithRespectToParameters (const InputPointType &point, JacobianType &jacobian) const
+ {
+ if (m_LastJacobian != -1)
+ m_trans[m_LastJacobian]->ResetJacobian();
+
+ int lidx = 0;
+ if (m_labels)
+ lidx = m_labelInterpolator->Evaluate(point) - 1;
+ if (lidx == -1)
+ {
+ m_LastJacobian = lidx;
+ jacobian = this->m_SharedDataBSplineJacobian;
+ return;
+ }
+
+ JacobianType unused;
+ m_trans[lidx]->ComputeJacobianWithRespectToParameters(point, unused);
+ m_LastJacobian = lidx;
+
+ jacobian = this->m_SharedDataBSplineJacobian;
+ }
+
+#else
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::JacobianType &
MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
::GetJacobian( const InputPointType & point ) const
{
- /*
- for (unsigned i = 0; i < m_nLabels; ++i)
- m_trans[i]->ResetJacobian();
- */
if (m_LastJacobian != -1)
m_trans[m_LastJacobian]->ResetJacobian();
return this->m_Jacobian;
}
+#endif
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
inline void
MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>::InitJacobian()
{
unsigned numberOfParameters = this->GetNumberOfParameters();
+#if ITK_VERSION_MAJOR >= 4
+ this->m_SharedDataBSplineJacobian.set_size(OutputDimension, numberOfParameters);
+ JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
+#else
this->m_Jacobian.set_size(OutputDimension, numberOfParameters);
JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
+#endif
memset(jacobianDataPointer, 0, numberOfParameters * sizeof (JacobianPixelType));
unsigned tot = 0;
-/*=========================================================================
+/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
Authors belong to:
{
// JV
m_ChosenSpacing[r]= m_ControlPointSpacing[r];
- m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+ m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
if ( ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
== ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
const RealType fixedValue = ti.Get();
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
+#endif
// Get the gradient by NearestNeighboorInterpolation:
// which is equivalent to round up the point components.
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
const RealType fixedValue = ti.Get();
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
+#endif
// Get the gradient by NearestNeighboorInterpolation:
// which is equivalent to round up the point components.
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
const RealType fixedValue = ti.Get();
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
+#endif
// Get the gradient by NearestNeighboorInterpolation:
// which is equivalent to round up the point components.
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
const RealType fixedValue = ti.Get();
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
+#endif
// Get the gradient by NearestNeighboorInterpolation:
// which is equivalent to round up the point components.
return OutputCovariantVectorType();
}
+#if ITK_VERSION_MAJOR >= 4
+ virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( << "PointListTransform doesn't declare ComputeJacobianWithRespectToParameters" );
+ }
+ virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( << "PointListTransform doesn't declare ComputeJacobianWithRespectToPosition" );
+ }
+#else
virtual const JacobianType& GetJacobian(const InputPointType &point ) const
{
itkExceptionMacro( << "PointListTransform doesn't declare GetJacobian" );
return this->m_Jacobian;
}
+#endif
protected:
PointListTransform();
// Constructor
template<class TScalarType, unsigned int NDimensions, unsigned int NOutputDimensions>
PointListTransform<TScalarType, NDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+ ::PointListTransform():Superclass(1)
+#else
::PointListTransform():Superclass(NOutputDimensions,1)
+#endif
{
m_PointLists.resize(0);
m_PointList.resize(1);
typedef itk::WarpImageFilter< MovingImageType, FixedImageType, DeformationField4DType > WarpFilterType;
typename WarpFilterType::Pointer warp = WarpFilterType::New();
+#if ITK_VERSION_MAJOR >= 4
+ warp->SetDisplacementField( field4D );
+#else
warp->SetDeformationField( field4D );
+#endif
warp->SetInput( movingImageReader->GetOutput() );
warp->SetOutputOrigin( fixedImage->GetOrigin() );
warp->SetOutputSpacing( fixedImage->GetSpacing() );
#include "itkImageRegion.h"
#include "itkSpatialObject.h"
#include "itkPasteImageFilter.h"
-#include "itkMultiplyByConstantImageFilter.h"
namespace clitk
{
}
/** Compute the Jacobian Matrix of the transformation at one point */
+#if ITK_VERSION_MAJOR >= 4
+ virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const;
+ virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+ {
+ itkExceptionMacro( "ComputeJacobianWithRespectToPosition not yet implemented for " << this->GetNameOfClass() );
+ }
+#else
virtual const JacobianType& GetJacobian(const InputPointType &point ) const;
+#endif
/** Return the number of parameters that completely define the Transfom */
virtual unsigned int GetNumberOfParameters(void) const;
// JV Shape
unsigned int m_TransformShape;
+#if ITK_VERSION_MAJOR >= 4
+ mutable JacobianType m_SharedDataBSplineJacobian;
+#endif
}; //class ShapedBLUTSpatioTemporalDeformableTransform
// Constructor with default arguments
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+ ::ShapedBLUTSpatioTemporalDeformableTransform():Superclass(0)
+#else
::ShapedBLUTSpatioTemporalDeformableTransform():Superclass(OutputDimension,0)
+#endif
{
unsigned int i;
//=====================================
//JV Wrap jacobian into OutputDimension X Vectorial images
//=====================================
+#if ITK_VERSION_MAJOR >= 4
+ this->m_SharedDataBSplineJacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#else
this->m_Jacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#endif
// Use memset to set the memory
// JV four rows of three comps of parameters
+#if ITK_VERSION_MAJOR >= 4
+ JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
+#else
JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
+#endif
memset(jacobianDataPointer, 0, OutputDimension*numberOfPixels*sizeof(JacobianPixelType));
for (unsigned int j=0; j<OutputDimension; j++)
typedef itk::PasteImageFilter<CoefficientImageType, CoefficientImageType, CoefficientImageType> PasteImageFilterType;
typedef clitk::ExtractImageFilter<CoefficientImageType, CoefficientImageType> ExtractImageFilterType;
typedef clitk::LinearCombinationImageFilter<CoefficientImageType, CoefficientImageType> LinearCombinationFilterType;
- typedef itk::MultiplyByConstantImageFilter<CoefficientImageType, double, CoefficientImageType> MultiplicationFilterType;
// Regions
typename CoefficientImageType::RegionType sourceRegion=m_PaddedCoefficientImage->GetLargestPossibleRegion();
// JV weights are identical as for transformpoint, could be done simultaneously in metric!!!!
// Compute the Jacobian in one position
template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+ void
+ ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+ ::ComputeJacobianWithRespectToParameters( const InputPointType & point, JacobianType & jacobian) const
+#else
const
typename ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
::JacobianType &
ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
::GetJacobian( const InputPointType & point ) const
+#endif
{
//========================================================
if(m_Mask && !(m_Mask->IsInside(point) ) )
{
// Outside: no (deformable) displacement
+#if ITK_VERSION_MAJOR >= 4
+ jacobian = m_SharedDataBSplineJacobian;
+ return;
+#else
return this->m_Jacobian;
+#endif
}
// Get index
// we assume zero displacement and return the input point
if ( !this->InsideValidRegion( m_Index ) )
{
+#if ITK_VERSION_MAJOR >= 4
+ jacobian = m_SharedDataBSplineJacobian;
+ return;
+#else
return this->m_Jacobian;
+#endif
}
// Compute interpolation weights
}
// Return the result
+#if ITK_VERSION_MAJOR >= 4
+ jacobian = m_SharedDataBSplineJacobian;
+#else
return this->m_Jacobian;
+#endif
}
-/*=========================================================================
+/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
Authors belong to:
{
// JV
m_ChosenSpacing[r]= m_ControlPointSpacing[r];
- m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+ m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
if ( ( ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
== ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
#include "itkBSplineDerivativeKernelFunction.h"
#include "itkCentralDifferenceImageFunction.h"
#include "itkBSplineInterpolateImageFunction.h"
-#include "itkBSplineDeformableTransform.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkBSplineTransform.h"
+#else
+ #include "itkBSplineDeformableTransform.h"
+#endif
#include "itkArray2D.h"
namespace itk
/**
* Typedefs for the BSplineDeformableTransform.
*/
+#if ITK_VERSION_MAJOR >= 4
+ typedef BSplineTransform<
+ CoordinateRepresentationType,
+ ::itk::GetImageDimension<FixedImageType>::ImageDimension,
+ DeformationSplineOrder> BSplineTransformType;
+#else
typedef BSplineDeformableTransform<
CoordinateRepresentationType,
::itk::GetImageDimension<FixedImageType>::ImageDimension,
DeformationSplineOrder> BSplineTransformType;
+#endif
typedef typename BSplineTransformType::WeightsType
BSplineTransformWeightsType;
typedef typename BSplineTransformType::ParameterIndexArrayType
#include "itkImageRegionIterator.h"
#include "itkImageIterator.h"
#include "vnl/vnl_math.h"
-#include "itkBSplineDeformableTransform.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkBSplineTransform.h"
+#else
+ #include "itkBSplineDeformableTransform.h"
+#endif
namespace itk
{
// Compute the transform Jacobian.
typedef typename TransformType::JacobianType JacobianType;
- const JacobianType& jacobian =
- this->m_Transform->GetJacobian(
- m_FixedImageSamples[sampleNumber].FixedImagePointValue );
+#if ITK_VERSION_MAJOR >= 4
+ JacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( m_FixedImageSamples[sampleNumber].FixedImagePointValue, jacobian );
+#else
+ const JacobianType & jacobian =
+ this->m_Transform->GetJacobian( m_FixedImageSamples[sampleNumber].FixedImagePointValue );
+#endif
for ( unsigned int mu = 0; mu < m_NumberOfParameters; mu++ ) {
double innerProduct = 0.0;
weights = m_BSplineTransformWeightsArray[sampleNumber];
indices = m_BSplineTransformIndicesArray[sampleNumber];
} else {
+#if ITK_VERSION_MAJOR >= 4
+ m_BSplineTransform->ComputeJacobianFromBSplineWeightsWithRespectToPosition(
+ m_FixedImageSamples[sampleNumber].FixedImagePointValue, m_Weights, m_Indices );
+#else
m_BSplineTransform->GetJacobian(
m_FixedImageSamples[sampleNumber].FixedImagePointValue, m_Weights, m_Indices );
+#endif
}
for( unsigned int dim = 0; dim < FixedImageDimension; dim++ ) {
if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
-
+#endif
const RealType fixedValue = ti.Value();
this->m_NumberOfPixelsCounted++;
if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
const RealType movingValue = this->m_Interpolator->Evaluate( transformedPoint );
+#if ITK_VERSION_MAJOR >= 4
+ TransformJacobianType jacobian;
+ this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
const TransformJacobianType & jacobian =
this->m_Transform->GetJacobian( inputPoint );
-
+#endif
const RealType fixedValue = ti.Value();
this->m_NumberOfPixelsCounted++;
--- /dev/null
+#!/bin/sh
+
+
+#################################################################################
+# create_mhd_3D argument : {image data} raw_image nom_fichier_de_sortie #
+#################################################################################
+if [ $# -lt 1 ]
+then
+ echo "Usage: create_mhd_3D.sh dimx dimy dimz spcx spcy spcz offx offy offz pixel_type raw_image_file output_file"
+ echo "dim*: dimensions of the image"
+ echo "spc*: pixel spacing along each dimension"
+ echo "off*: offset along each dimension"
+ echo "pixel_type: CHAR, UCHAR, SHORT, USHORT, FLOAT"
+ echo "raw_image_file: image to be referenced by the mhd file created"
+ echo "output_file: mhd to be created"
+ exit 1
+fi
+
+# can point to existing raw files
+n=`ls ${11} | wc -l`
+if [ $n -eq 0 ]
+then
+ echo "${11} does not exist. Cannot create mhd file."
+ exit
+fi
+
+# check if the raw file has the "raw" extension
+n=`ls ${11} | grep .raw | wc -l`
+if [ $n -eq 0 ]
+then
+ # change extension to raw
+ raw_base=`echo ${11} | cut -d . -f 1`;
+ raw_file=$raw_base".raw";
+ mv ${11} $raw_file
+else
+ raw_file=${11}
+fi
+
+# create file (with some default values...)
+echo "NDims = 3" > ${12}
+echo "TransformMatrix = 1 0 0 0 1 0 0 0 1" >> ${12}
+echo "Offset = " $7 $8 $9 >> ${12}
+echo "CenterOfRotation = 0 0 0" >> ${12}
+echo "AnatomicalOrientation = RAI" >> ${12}
+echo "ElementSpacing = " $4 $5 $6 >> ${12}
+echo "DimSize = " $1 $2 $3 >> ${12}
+echo "ElementType = MET_"${10} >> ${12}
+echo "ElementDataFile = " $raw_file >> ${12}
+
+
--- /dev/null
+#!/bin/sh +x
+
+
+write_mhd_4D()
+{
+ cat $orig | sed "s/NDims = .*/NDims = 4/
+ s/TransformMatrix = .*/TransformMatrix = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/
+ /Offset/ s/.*/& 0/
+ /CenterOfRotation/ s/.*/& 0/
+ s/AnatomicalOrientation = .*/AnatomicalOrientation = ????/
+ /ElementSpacing/ s/.*/& 1/
+ /DimSize/ s/.*/& $nbph/
+ s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D"
+
+ for ph in $listph
+ do
+ phase=`basename $ph`
+ echo "$phase" >> "$1/$file_name_4D"
+ done
+}
+
+#################################################
+# create_mhd_4D argument : repertoire #
+#################################################
+if [ $# -lt 1 ]
+then
+ echo "Usage: create_mhd_4D.sh DIRECTORY"
+ exit 1
+fi
+
+dirname=`dirname $1`
+pattern=`basename $1`
+
+list_phase_file=`ls -1 $1*[0-9].mhd`
+nb_phase_file=`ls -1 $1*[0-9].mhd | wc -l`
+if [ $nb_phase_file = 0 ]
+then
+ echo "Error: no phase found"
+ exit 1
+fi
+
+nbph=$nb_phase_file
+orig=`echo $list_phase_file | cut -f 1 -d ' '`
+listph=`echo $list_phase_file | sed 's:\.mhd:\.raw:g'`
+
+file_name_4D=`echo "${pattern}4D.mhd"`
+
+write_mhd_4D $dirname
+echo "$dirname/$file_name_4D"
exit 1
fi
-nb_phase_file=`find $1 -iname "*[0-9].mhd" -o -iname "*[0-9]*\]*.mhd" | wc -l`
+nb_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*.mhd" -o -iname "*[0-9]*\]*.mhd" | wc -l`
if [ $nb_phase_file = 0 ]
then
echo "Error: no phase found"
########## CT #########
list_pattern=""
-list_phase_file=`find $1 -iname "*[0-9].mhd"`
+list_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*.mhd"`
for phase_file in $list_phase_file
do
phase_file_name=`basename $phase_file`
pattern=""
fi
- nbph=`find $1 -iname "${pattern}*[0-9].mhd" | wc -l`
- orig=`find $1 -iname "${pattern}*[0-9].mhd" | sort | head -n 1`
- listph=`find $1 -iname "${pattern}*[0-9].raw" | sort`
+ nbph=`find $1 -maxdepth 1 -iname "${pattern}*[0-9]*.mhd" | wc -l`
+ orig=`find $1 -maxdepth 1 -iname "${pattern}*[0-9]*.mhd" | sort | head -n 1`
+ listph=`find $1 -maxdepth 1 -iname "${pattern}*[0-9]*.raw" | sort`
file_name_4D="${pattern}_4D.mhd"
+ echo $file_name_4D
write_mhd_4D $1
############ PET ###########
list_pattern=""
-list_phase_file=`find $1 -iname "*[0-9]*\]*.mhd"`
+list_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*\]*.mhd"`
for phase_file in $list_phase_file
do
phase_file_name=`basename $phase_file`
pattern=""
fi
- nbph=`find $1 -iname "*[0-9]${pattern}\]*.mhd" | wc -l`
- orig=`find $1 -iname "*[0-9]${pattern}\]*.mhd" | sort | head -n 1`
- listph=`find $1 -iname "*[0-9]${pattern}\]*.raw" | sort`
+ nbph=`find $1 -maxdepth 1 -iname "*[0-9]${pattern}\]*.mhd" | wc -l`
+ orig=`find $1 -maxdepth 1 -iname "*[0-9]${pattern}\]*.mhd" | sort | head -n 1`
+ listph=`find $1 -maxdepth 1 -iname "*[0-9]${pattern}\]*.raw" | sort`
file_name_4D=`basename "$orig" | sed "s/[0-9]${pattern}\]/${pattern}\]/;s/_.mhd/_4D.mhd/"`
--- /dev/null
+#!/bin/sh +x
+
+###############################################################################
+#
+# FILE: create_mhd_pattern.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Similar to create_mhd_4D.sh, but receives a pattern as input.
+#
+# Example:
+# create_mhd_pattern.sh "<path>/all_my_phases_start_like_this_"
+#
+###############################################################################
+
+write_mhd_4D()
+{
+ cat $orig | sed "s/NDims = .*/NDims = 4/
+ s/TransformMatrix = .*/TransformMatrix = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/
+ /Offset/ s/.*/& 0/
+ /CenterOfRotation/ s/.*/& 0/
+ s/AnatomicalOrientation = .*/AnatomicalOrientation = ????/
+ /ElementSpacing/ s/.*/& 1/
+ /DimSize/ s/.*/& $nbph/
+ s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D"
+
+ for ph in $listph
+ do
+ phase=`basename $ph`
+ echo "$phase" >> "$1/$file_name_4D"
+ done
+}
+
+#################################################
+# create_mhd_4D argument : repertoire #
+#################################################
+if [ $# -lt 1 ]
+then
+ echo "Usage: $0 PATTERN"
+ exit 1
+fi
+
+dirname=`dirname $1`
+pattern=`basename $1`
+
+list_phase_file=`ls -1 $1*[0-9].mhd`
+nb_phase_file=`ls -1 $1*[0-9].mhd | wc -l`
+if [ $nb_phase_file = 0 ]
+then
+ echo "Error: no phase found"
+ exit 1
+fi
+
+nbph=$nb_phase_file
+orig=`echo $list_phase_file | cut -f 1 -d ' '`
+listph=`echo $list_phase_file | sed 's:\.mhd:\.raw:g'`
+
+file_name_4D=`echo "${pattern}4D.mhd"`
+
+write_mhd_4D $dirname
+echo "$dirname/$file_name_4D"
--- /dev/null
+#!/bin/sh -x
+
+###############################################################################
+#
+# FILE: create_midP-2.0.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Version 2.0 of the create_midP.sh script. The most relevant changes are:
+# * receives a .conf file as input, with variables related to the registration
+# parameters and to paramters of the script itself (see accompanying midp_template.conf)
+# for details.
+# * separates execution steps: it's now possible to choose which operation to execute
+# (mask, registration, midp, or all).
+# * some steps are now in different modules, to facilitate re-use (see "includes" section).
+# * minor modifications on output file names.
+# * attempt to simplify the code a bit.
+#
+###############################################################################
+
+######################### includes
+
+source `dirname $0`/create_midP_masks-2.0.sh using-as-lib 2 nn
+source `dirname $0`/registration.sh
+source `dirname $0`/midp_common.sh
+
+registration()
+{
+ echo
+ echo "----------- Registration ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+
+ mkdir -p $vf_dir
+ mkdir -p $output_dir
+
+ # banded images may be created as separate files,
+ # with the specified preffix, which is interesting for debugging.
+ # if blank, it means that the original images (those without bands)
+ # will be used (see create_midP_masks-2.0.sh for details).
+ banded="banded_"
+
+ # params read from conf file
+ params="$nb_iter $nb_samples $sampling_algo $nb_hist_bins $nb_levels $bspline_spacing $metric $optimizer $interpolator"
+
+ # register all phases to the reference
+ for i in $( seq 0 $((${#phase_files[@]} - 1))); do
+ phase_file=${phase_files[$i]}
+ phase_nb=${phase_nbs[$i]}
+
+ if [ "$phase_nb" != "$ref_phase_nb" ]; then
+ # inside params
+ reference_in=$mask_dir/${banded}inside_$ref_phase_nb.mhd
+ target_in=$mask_dir/${banded}inside_$phase_nb.mhd
+ mask_ref_in=$mask_dir/mask_inside_$ref_phase_nb.mhd
+ mask_targ_in=$mask_dir/mask_inside_$phase_nb.mhd
+ vf_in=$vf_dir/vf_inside_${ref_phase_nb}_$phase_nb.mhd
+ result_in=$output_dir/result_inside_${ref_phase_nb}_$phase_nb.mhd
+ log_in=$log_dir/log_inside_${ref_phase_nb}_$phase_nb.log
+
+ # outside params
+ reference_out=$mask_dir/${banded}outside_$ref_phase_nb.mhd
+ target_out=$mask_dir/${banded}outside_$phase_nb.mhd
+ mask_ref_out=$mask_dir/mask_outside_$ref_phase_nb.mhd
+ mask_targ_out=$mask_dir/mask_outside_$phase_nb.mhd
+ vf_out=$vf_dir/vf_outside_$ref_phase_nb\_$phase_nb.mhd
+ result_out=$output_dir/result_outside_$ref_phase_nb\_$phase_nb.mhd
+ log_out=$log_dir/log_outside_${ref_phase_nb}_$phase_nb.log
+
+ # registration
+ if [ "$method" == "blutdir" ]; then
+ registration_blutdir $reference_in $target_in $mask_ref_in $mask_targ_in $vf_in $result_in $params $log_in
+ registration_blutdir $reference_out $target_out $mask_ref_out $mask_targ_out $vf_out $result_out $params $log_out
+ elif [ "$method" == "elastix" ]; then
+ registration_elastix $reference_in $target_in $mask_ref_in $mask_targ_in $vf_in $result_in $params $log_in
+ registration_elastix $reference_out $target_out $mask_ref_out $mask_targ_out $vf_out $result_out $params $log_out
+ fi
+
+ # combine in and out vf
+ motion_mask=$mask_dir/mm_$phase_nb.mhd
+ vf_result=$vf_dir/vf_${ref_phase_nb}_$phase_nb.mhd
+ clitkCombineImage -i $vf_in -j $vf_out -m $motion_mask -o $vf_result
+ clitkZeroVF -i $vf_in -o vf_zero.mhd
+ clitkCombineImage -i $vf_result -j vf_zero.mhd -m $patient_mask -o $vf_result
+ rm vf_zero.*
+
+ # save for later...
+ vf_ref=$vf_in
+ fi
+ done
+
+ # create (zero) vf from reference to reference
+ clitkZeroVF -i $vf_ref -o $vf_dir/vf_${ref_phase_nb}_${ref_phase_nb}.mhd
+
+ # create 4D vf
+ create_mhd_4D_pattern.sh $vf_dir/vf_${ref_phase_nb}_
+
+ echo
+ echo "-------- Registration done ! --------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+midp()
+{
+ echo
+ echo "----------- Mid-position ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+
+ mkdir -p $midp_dir
+
+ ########### calculate the midp wrt the reference phase
+ phase_nb=$ref_phase_nb
+ echo "Calculating midp_$phase_nb.mhd..."
+ vf_midp=$midp_dir/vf_$phase_nb\_midp.mhd
+ midp=$midp_dir/midp_$phase_nb.mhd
+ # average the vf's from reference phase to phase
+ clitkAverageTemporalDimension -i $vf_dir/vf_${ref_phase_nb}_4D.mhd -o $vf_midp
+ # invert the vf (why?)
+ clitkInvertVF -i $vf_midp -o $vf_midp
+ # create the midp by warping the reference phase with the reference vf
+ clitkWarpImage -i $ref_phase_file -o $midp --vf=$vf_midp -s 1
+
+ ref_vf_midp=$vf_midp
+ ref_midp=$midp
+ clitkImageConvert -i $ref_midp -o $ref_midp -t float
+
+ ########### calculate the midp wrt the other phases
+ for i in $( seq 0 $((${#phase_files[@]} - 1))); do
+ phase_file=${phase_files[$i]}
+ phase_nb=${phase_nbs[$i]}
+ vf_midp=$midp_dir/vf_$phase_nb\_midp.mhd
+ midp=$midp_dir/midp_$phase_nb.mhd
+
+ if [ "$phase_nb" != "$ref_phase_nb" ]; then
+ echo "Calculating midp_$phase_nb.mhd..."
+ # calculate vf from phase to midp, using the vf from reference phase to midp (-i)
+ # and the vf from reference phase to phase (-j)
+ clitkComposeVF -i $ref_vf_midp -j $vf_dir/vf_$ref_phase_nb\_$phase_nb.mhd -o $vf_midp
+ clitkWarpImage -i $phase_file -o $midp --vf=$vf_midp -s 1
+ clitkImageConvert -i $midp -o $midp -t float
+ fi
+ done
+
+ create_mhd_4D_pattern.sh $midp_dir/midp_
+ echo "Calculating midp_avg.mhd..."
+ clitkAverageTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_avg.mhd
+ echo "Calculating midp_med.mhd..."
+ clitkMedianTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_med.mhd
+
+ # clean-up
+ rm $midp_dir/vf_*
+
+ echo
+ echo "-------- Mid-position done ! --------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+
+
+######################### main
+
+if [ $# != 3 ]; then
+ echo "Usage: create_midP-2.0.sh CT_4D REF_PHASE CONF_FILE"
+ exit -1
+fi
+
+echo
+echo "--------------- START ---------------"
+begining=`date --rfc-3339=seconds`
+# echo "beginning: $begining"
+echo
+
+# variable declarations
+mhd4d=$1
+ref_phase=$2
+conf=$3
+source $conf
+
+mkdir -p $log_dir
+mask_dir="MASK-${mask_interpolation_spacing}mm-$mask_interpolation_algorithm"
+
+extract_4d_phases_ref $mhd4d $ref_phase
+
+if [ "$step" == "mask" -o "$step" == "all" ]; then
+ motion_mask $mhd4d $mask_interpolation_spacing $mask_interpolation_algorithm
+fi
+
+if [ "$step" == "registration" -o "$step" == "all" ]; then
+ registration
+fi
+
+if [ "$step" == "midp" -o "$step" == "all" ]; then
+ midp
+fi
+
+echo
+echo "---------------- END ----------------"
+terminating=`date --rfc-3339=seconds`
+echo "beginning: $begining"
+echo "terminating: $terminating"
+echo
--- /dev/null
+#!/bin/sh -x
+
+#################################################################
+# create_MidP arguments : CT_4D.mhd ref_phase spacing #
+#################################################################
+source `dirname $0`/midp_common.sh
+
+extract_patient()
+{
+ echo "$image_name -> Extracting patient..."
+ $CLITK/clitkExtractPatient -i $image_name -o MASK/patient_$image_name --noAutoCrop
+ $CLITK/clitkBinarizeImage -i MASK/patient_$image_name -o MASK/patient_$image_name -l 1 -u 1 --mode=BG
+ $CLITK/clitkSetBackground -i $image_name -o MASK/patient_only_$image_name --mask MASK/patient_$image_name --outsideValue -1000
+}
+
+extract_bones()
+{
+ echo "$image_name -> Extracting bones..."
+ $CLITK/clitkImageConvert -i $image_name -o MASK/float_$image_name -t float
+ $CLITK/clitkExtractBones -i MASK/float_$image_name -o MASK/bones_$image_name --lower1 120 --upper1 2000 --lower2 70 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+ $CLITK/clitkMorphoMath -i MASK/bones_$image_name -o MASK/bones_$image_name --type 2 --radius 4,4,2
+}
+
+resample()
+{
+ echo "$image_name -> Resampling..."
+ $CLITK/clitkResampleImage -i MASK/patient_$image_name -o MASK/patient_$image_name --spacing $spacing
+ $CLITK/clitkResampleImage -i MASK/patient_only_$image_name -o MASK/patient_only_$image_name --spacing $spacing
+ #$CLITK/clitkResampleImage -i MASK/bones_$image_name -o MASK/bones_$image_name --like MASK/patient_only_$image_name
+}
+
+compute_motion_mask()
+{
+# $CLITK/clitkMotionMask -i MASK/patient_only_$image_name -o MASK/mm_$image_name --featureBones=MASK/bones_$image_name --upperThresholdLungs -400 --fillingLevel 94 --offsetDetect 0,-5,0 --pad --writeFeature=MASK/feature_$image_name --writeEllips=MASK/inital_ellipse_$image_name --writeGrownEllips=MASK/growing_ellipse_$image_name;
+$CLITK/clitkMotionMask -i MASK/patient_only_$image_name -o MASK/mm_$image_name --upperThresholdLungs -400 --fillingLevel 94 --offsetDetect 0,-5,0 --pad --writeFeature=MASK/feature_$image_name --writeEllips=MASK/inital_ellipse_$image_name --writeGrownEllips=MASK/growing_ellipse_$image_name;
+}
+
+set_background()
+{
+ echo "$image_name -> Setting Background..."
+ $CLITK/clitkSetBackground -i MASK/patient_only_$image_name -o MASK/inside_$image_name --mask MASK/mm_$image_name --outsideValue -1200
+ $CLITK/clitkSetBackground -i MASK/patient_only_$image_name -o MASK/outside_$image_name --mask MASK/mm_$image_name --outsideValue -1200 --fg
+}
+
+create_registration_masks()
+{
+ echo "$image_name -> Creating registration masks..."
+ $CLITK/clitkMorphoMath -i MASK/mm_$image_name -o MASK/regmask_in_$image_name --type 1 --radius 8
+ $CLITK/clitkExtractPatient -i MASK/outside_$image_name -o MASK/regmask_out_$image_name --noAutoCrop
+ $CLITK/clitkMorphoMath -i MASK/regmask_out_$image_name -o MASK/regmask_out_$image_name --type 1 --radius 8
+}
+
+remove_files()
+{
+ echo "Removing temporary files..."
+ image_name_base=`echo $image_name | sed 's/mhd//'`
+ case $1 in
+ 1)
+ rm MASK/float_$image_name_base*;;
+ 2)
+ rm MASK/bones_$image_name_base*;;
+ 3)
+ rm MASK/patient_only_$image_name_base*;;
+ 4)
+ #rm MASK/patient_$image_name_base*
+ #rm MASK/mm_$image_name_base*
+ rm -f $vf_dir/vf_tmp_in_${ref}_${phase}.*
+ rm -f $vf_dir/vf_tmp_out_${ref}_${phase}.*
+ #rm MASK/regmask_in_$image_name_base*
+ #rm MASK/regmask_out_$image_name_base*
+ ;;
+ 5)
+# rm -f coeff_*
+ #rm $vf_dir/vf_in_*
+ #rm $vf_dir/vf_out_*
+# rm MASK/regmask_*
+# rm MASK/mm_*
+ ;;
+ 6)
+ ;;
+ #rm -f $vf_dir/_4D.*
+ #rm -f $vf_dir/vf_MIDP_${ref}.*
+ #rm -f $vf_dir/vf_${ref}_MIDP.*;;
+ 7)
+ ;; #rm $vf_dir/vf_MIDP_${phase}.*;;
+ 8)
+ rm $vf_dir/*.txt
+ rm $vf_dir/*.log
+ esac
+}
+
+mm_preprocessing()
+{
+ extract_patient
+ #extract_bones
+ remove_files 1
+ resample
+}
+
+mm_postprocessing()
+{
+ remove_files 2
+ set_background
+ remove_files 3
+ create_registration_masks
+}
+
+# mm_workflow()
+# {
+# extract_patient
+# extract_bones
+# remove_files 1
+# resample
+# echo "$image_name -> Computing motion mask..."
+# compute_motion_mask >> LOG/motion_mask_$image_name.log
+# remove_files 2
+# set_background
+# remove_files 3
+# create_registration_masks
+# }
+
+motion_mask()
+{
+ echo
+ echo "------------ Motion mask ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+ mkdir -p "MASK"
+ rm -f "LOG/motion_mask*.log"
+ regmask_in_list=""
+ regmask_out_list=""
+ reg_in_list=""
+ reg_out_list=""
+
+ # multi-threaded pre-processing for motion mask calcs
+ for phase in $phase_list
+ do
+ image_name=`echo $phase | sed 's/raw/mhd/'`
+ check_threads $MAX_THREADS
+ #mm_preprocessing &
+ done
+
+ # single-threaded motion mask calc
+ check_threads 1
+ for phase in $phase_list
+ do
+ image_name=`echo $phase | sed 's/raw/mhd/'`
+
+ echo "$image_name -> Computing motion mask..."
+ #compute_motion_mask >> LOG/motion_mask_$image_name.log
+ done
+
+ # multi-threaded post-processing of motion mask calcs
+ for phase in $phase_list
+ do
+ image_name=`echo $phase | sed 's/raw/mhd/'`
+ check_threads $MAX_THREADS
+ #mm_postprocessing &
+ regmask_in_list="$regmask_in_list regmask_in_$image_name"
+ regmask_out_list="$regmask_out_list regmask_out_$image_name"
+ reg_in_list="$reg_in_list inside_$image_name"
+ reg_out_list="$reg_out_list outside_$image_name"
+ done
+
+ wait
+ echo
+ echo "-------- Motion mask done ! ---------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+compute_BLUTDIR()
+{
+ ########## register in ##########
+ for reg_in in $reg_in_list
+ do
+ if [ ! -z `echo $reg_in | grep "$phase"` ]
+ then
+ target_in=$reg_in
+ fi
+ done
+ echo "Computing BLUTDIR $reference_in -> $target_in ..."
+ #$CLITK/clitkBLUTDIR --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --referenceMask="MASK/$reference_mask_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" $coeff_in_ini --coeff="$coeff_dir/coeff_in_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+ $CLITK/clitkBLUTDIR --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --referenceMask="MASK/$reference_mask_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" --coeff="$coeff_dir/coeff_in_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+ coeff_in_ini="--initCoeff=$coeff_dir/coeff_in_${ref}_${phase}.mhd"
+ ########## register out ##########
+ for reg_out in $reg_out_list
+ do
+ if [ ! -z `echo $reg_out | grep "$phase"` ]
+ then
+ target_out=$reg_out
+ fi
+ done
+ echo "Computing BLUTDIR $reference_out -> $target_out ..."
+ #$CLITK/clitkBLUTDIR --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --referenceMask="MASK/$reference_mask_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" $coeff_out_ini --coeff="$coeff_dir/coeff_out_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+ $CLITK/clitkBLUTDIR --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --referenceMask="MASK/$reference_mask_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" --coeff="$coeff_dir/coeff_out_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+ coeff_out_ini="--initCoeff=$coeff_dir/coeff_out_${ref}_${phase}.mhd"
+ ##################################
+ $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+ $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd
+ $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+ remove_files 4
+}
+
+compute_DEMONSDIR()
+{
+ ########## register in ##########
+ for reg_in in $reg_in_list
+ do
+ if [ ! -z `echo $reg_in | grep "_$phase"` ]
+ then
+ target_in=$reg_in
+ fi
+ done
+ echo "Computing DEMONSDIR $reference_in -> $target_in ..."
+ $CLITK/clitkDemonsDeformableRegistration --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" $vf_in_ini $registration_parameters_DEMONSDIR #&>> LOG/registration_${ref}_${phase}.log
+ vf_in_ini="--init=$vf_dir/vf_in_${ref}_${phase}.mhd"
+ ########## register out ##########
+ for reg_out in $reg_out_list
+ do
+ if [ ! -z `echo $reg_out | grep "_$phase"` ]
+ then
+ target_out=$reg_out
+ fi
+ done
+ echo "Computing DEMONSDIR $reference_out -> $target_out ..."
+ $CLITK/clitkDemonsDeformableRegistration --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" $vf_out_ini $registration_parameters_DEMONSDIR #&>> LOG/registration_${ref}_${phase}.log
+ vf_out_ini="--init=$vf_dir/vf_out_${ref}_${phase}.mhd"
+ ##################################
+ $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+ $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd
+ $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+ remove_files 4
+}
+
+compute_ELASTIX()
+{
+ ########## register in ##########
+ for reg_in in $reg_in_list
+ do
+ if [ ! -z `echo $reg_in | grep "_$phase"` ]
+ then
+ target_in=$reg_in
+ fi
+ done
+ echo "Computing ELASTIX $reference_in -> $target_in ..."
+ exec_dir=`which elastix`
+ exec_dir=`dirname $exec_dir`
+ cat $exec_dir/params_BSpline.txt | sed -e "s+<NbIterations>+500+" \
+ -e "s+<LabelsFile>++" \
+ -e "s+<HistBins>+25+" \
+ -e "s+<Levels>+3+" \
+ -e "s+<NbSamples>+2000+" \
+ -e "s+<SamplerType>+Random+" \
+ -e "s+<Spacing>+32+" > params_BSpline.txt
+ elastix -f "MASK/$reference_in" -m "MASK/$target_in" -fMask "MASK/$reference_mask_in" -out $vf_dir -p params_BSpline.txt > /dev/null
+ transformix -tp $vf_dir/TransformParameters.0.txt -out $vf_dir -def all > /dev/null
+ mv $vf_dir/deformationField.mhd $vf_dir/vf_in_${ref}_${phase}.mhd
+ mv $vf_dir/deformationField.raw $vf_dir/vf_in_${ref}_${phase}.raw
+ sed -i "s:deformationField:vf_in_${ref}_${phase}:" $vf_dir/vf_in_${ref}_${phase}.mhd
+ mv $vf_dir/result.0.mhd MASK/reg_$target_in
+ targetraw=`echo reg_$target_in | sed 's:mhd:raw:'`
+ sed -i "s:result.0.mhd:$targetraw" MASK/reg_$target_in
+ mv $vf_dir/result.0.raw MASK/$targetraw
+ remove_files 8
+
+ ########## register out ##########
+ for reg_out in $reg_out_list
+ do
+ if [ ! -z `echo $reg_out | grep "_$phase"` ]
+ then
+ target_out=$reg_out
+ fi
+ done
+ echo "Computing ELASTIX $reference_out -> $target_out ..."
+ elastix -f "MASK/$reference_out" -m "MASK/$target_out" -fMask "MASK/$reference_mask_out" -out $vf_dir -p params_BSpline.txt > /dev/null
+ transformix -tp $vf_dir/TransformParameters.0.txt -out $vf_dir -def all > /dev/null
+ mv $vf_dir/deformationField.mhd $vf_dir/vf_out_${ref}_${phase}.mhd
+ mv $vf_dir/deformationField.raw $vf_dir/vf_out_${ref}_${phase}.raw
+ sed -i "s:deformationField:vf_out_${ref}_${phase}:" $vf_dir/vf_out_${ref}_${phase}.mhd
+ mv $vf_dir/result.0.mhd MASK/reg_$target_out
+ targetraw=`echo reg_$target_out | sed 's:mhd:raw:'`
+ sed -i "s:result.0.mhd:$targetraw" MASK/reg_$target_out
+ mv $vf_dir/result.0.raw MASK/$targetraw
+ remove_files 8
+
+ ##################################
+ $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+ $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd
+ $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+ remove_files 4
+}
+
+registration()
+{
+ echo
+ echo "----------- Registration ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+
+ rm -f "LOG/registration*.log"
+
+ # wait any unfinished threads
+ check_threads 1
+
+ for reg_in in $reg_in_list
+ do
+ if [ ! -z `echo $reg_in | grep "$ref"` ]
+ then
+ reference_in=$reg_in
+ fi
+ done
+ for reg_out in $reg_out_list
+ do
+ if [ ! -z `echo $reg_out | grep "$ref"` ]
+ then
+ reference_out=$reg_out
+ fi
+ done
+ for regmask_in in $regmask_in_list
+ do
+ if [ ! -z `echo $regmask_in | grep "$ref"` ]
+ then
+ reference_mask_in=$regmask_in
+ fi
+ done
+ for regmask_out in $regmask_out_list
+ do
+ if [ ! -z `echo $regmask_out | grep "$ref"` ]
+ then
+ reference_mask_out=$regmask_out
+ fi
+ done
+
+ registration_parameters_BLUTDIR="--spacing=32,32,32 --interp=2 --metric=11 --bins=25 --samples=1 --levels=3 --verbose " #--coeffEveryN 5"
+ registration_parameters_DEMONSDIR="--demons=3 --levels=1"
+ registration_parameters_ELASTIX="--demons=3 --levels=1"
+
+ coeff_in_ini=""
+ coeff_out_ini=""
+ vf_in_ini=""
+ vf_out_ini=""
+
+ for phase in $list_phases
+ do
+ for img in $phase_list
+ do
+ if [ ! -z `echo $img | grep "$phase" | grep -v "[0-9]$phase"` ]
+ then
+ image_name=`echo $img | sed 's/raw/mhd/'`
+ fi
+ done
+ if [ $method = 1 ]
+ then
+ compute_BLUTDIR
+ elif [ $method = 2 ]
+ then
+ compute_DEMONSDIR
+ elif [ $method = 3 ]
+ then
+ compute_ELASTIX
+ fi
+ done
+ remove_files 5
+
+ echo
+ echo "-------- Registration done ! --------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+calculate_vf_MIDP_REF()
+{
+ echo "Calculating vf_REF_MIDP.mhd..."
+ remove_files 6
+ create_mhd_4D.sh $vf_dir #"vf_4D.mhd"
+ $CLITK/clitkAverageTemporalDimension -i $vf_dir/_4D.mhd -o $vf_dir/vf_${ref}_MIDP.mhd
+ $CLITK/clitkInvertVF -i $vf_dir/vf_${ref}_MIDP.mhd -o $vf_dir/vf_MIDP_${ref}.mhd
+}
+
+calculate_CT_MIDP_REF()
+{
+ reference=`ls *.mhd | grep $ref #| grep -v "[0-9]$ref.mhd"`
+ echo "Calculating CT_MIDP_REF.mhd '$reference'..."
+ $CLITK/clitkWarpImage -i $reference -o CT_MIDP_REF.mhd --vf=$vf_dir/vf_MIDP_${ref}.mhd -s 1
+}
+
+calculate_CT_MIDP_PHASE()
+{
+ echo "Calculating CT_MIDP_${phase}.mhd..."
+ $CLITK/clitkComposeVF -i $vf_dir/vf_MIDP_${ref}.mhd -j $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_MIDP_${phase}.mhd
+ phase_img=`ls *.mhd | grep "${phase}" # | grep -v "[0-9]$ref.mhd"`
+ $CLITK/clitkWarpImage -i $phase_img -o MIDP/CT_MIDP_${phase}.mhd --vf=$vf_dir/vf_MIDP_${phase}.mhd -s 1
+ $CLITK/clitkImageConvert -i MIDP/CT_MIDP_${phase}.mhd -o MIDP/CT_MIDP_${phase}.mhd -t float
+ remove_files 7
+}
+
+prepare_MIDP_images()
+{
+ echo "Preparing MIDP images..."
+ cp CT_MIDP_REF.mhd MIDP/CT_MIDP_${ref}.mhd
+ cp CT_MIDP_REF.raw MIDP/CT_MIDP_${ref}.raw
+ cat MIDP/CT_MIDP_${ref}.mhd | sed "s/ElementDataFile = .*/ElementDataFile = CT\_MIDP\_${ref}\.raw/" > MIDP/CT_MIDP_${ref}_tmp.mhd
+ rm MIDP/CT_MIDP_${ref}.mhd
+ mv MIDP/CT_MIDP_${ref}_tmp.mhd MIDP/CT_MIDP_${ref}.mhd
+ $CLITK/clitkImageConvert -i MIDP/CT_MIDP_${ref}.mhd -o MIDP/CT_MIDP_${ref}.mhd -t float
+ create_mhd_4D.sh MIDP #"CT_MIDP_4D.mhd"
+}
+
+calculate_CT_MIDP_MOY()
+{
+ echo "Calculating CT_MIDP_MOY.mhd..."
+ $CLITK/clitkAverageTemporalDimension -i MIDP/_4D.mhd -o CT_MIDP_MOY.mhd
+}
+
+calculate_CT_MIDP_MED()
+{
+ echo "Calculating CT_MIDP_MED.mhd..."
+ $CLITK/clitkMedianTemporalDimension -i MIDP/_4D.mhd -o CT_MIDP_MED.mhd
+}
+
+calculate_CT_MIDP_MIP()
+{
+ echo "Calculating CT_MIDP_MIP.mhd..."
+ $CLITK/clitkMIP -i MIDP/_4D.mhd -o CT_MIDP_MIP.mhd -d 3
+}
+
+mid_position()
+{
+ echo
+ echo "----------- Mid-position ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+
+ mkdir -p "MIDP"
+
+ calculate_vf_MIDP_REF
+ calculate_CT_MIDP_REF
+ for phase in $list_phases
+ do
+ check_threads $MAX_THREADS
+ calculate_CT_MIDP_PHASE &
+ done
+ wait
+ prepare_MIDP_images
+ calculate_CT_MIDP_MED &
+ calculate_CT_MIDP_MIP &
+ calculate_CT_MIDP_MOY &
+ wait
+
+ echo
+ echo "-------- Mid-position done ! --------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+#################
+# main #
+#################
+
+if [ $# -lt 1 ]
+then
+ echo "Usage: create_midP.sh CT_4D.mhd ref_phase computation_spacing(mm) method(1:BSPLINE, 2:DEMONS)"
+ exit 1
+fi
+CLITK=~/creatis/clitk3/build/bin
+CT_4D_path=$1
+CT_4D=`basename $CT_4D_path`
+work_dir=`dirname $CT_4D_path`
+cd $work_dir
+ref=$2
+spacing=$3
+method=$4
+
+vf_dir="VF"
+coeff_dir="$vf_dir/coeff"
+
+mkdir -p $vf_dir
+mkdir -p $coeff_dir
+
+echo
+echo "--------------- START ---------------"
+begining=`date`
+echo "start: $begining"
+echo
+
+mkdir -p "LOG"
+phase_list=`grep ".raw" $CT_4D`
+echo "phases -> " $phase_list
+nb_phases=`grep ".raw" $CT_4D | wc -l`
+gt_ref=""
+lt_ref=""
+
+phase_files=( `cat $CT_4D | grep ".raw" | sed 's:.raw:.mhd:'` )
+echo "Phase files are ${phase_files[@]}"
+
+phase_nbs=( `echo ${phase_files[@]} | grep -o '[[:alpha:][:punct:]][0-9]\{1,2\}[[:punct:]]' | grep -o '[0-9]\{1,2\}'` )
+#phase_nbs=( `echo ${phase_files[@]} | grep -o '[0-9]\{1,2\}'` )
+echo "Phase numbers are ${phase_nbs[@]}"
+
+
+for ph in $phase_list
+do
+ #ph_nb=`echo $ph | grep -o "[0-9][0-9]*\.raw" | sed -e 's/\.raw//'`
+ ph_nb=`echo $ph | grep -o "[0-9][0-9]"`
+ if [ $ph_nb -gt $ref ]
+ then
+ gt_ref="$gt_ref $ph_nb"
+ elif [ $ph_nb -lt $ref ]
+ then
+ lt_ref="$lt_ref $ph_nb"
+ fi
+done
+list_phases="$gt_ref $lt_ref"
+echo list_phases $list_phases
+
+motion_mask
+registration
+mid_position
+
+echo
+echo "---------------- END ----------------"
+terminating=`date`
+echo "start: $begining"
+echo "end: $terminating"
+echo
--- /dev/null
+#! /bin/bash -x
+
+###############################################################################
+#
+# FILE: create_midP-2.0.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Version 2.0 of the create_midP_masks.sh script. The most relevant changes are:
+# * creation of bands around input and output image regions to try to improve
+# the registration along lung boundaries (naturally, it depends on the quality
+# of motion mask generation).
+# * some steps are now in different modules, to facilitate re-use (see "includes" section).
+# * minor modifications on output file names.
+# * attempt to simplify the code a bit.
+#
+###############################################################################
+
+source `dirname $0`/midp_common.sh
+
+extract_patient()
+{
+ echo "$phase_file -> Extracting patient..."
+ clitkExtractPatient -i $phase_file -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --noAutoCrop -a $afdb_file $ExtractPatientExtra
+ clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000
+}
+
+extract_bones()
+{
+ if [ x = x$ExtractBonesLower1 ]; then
+ ExtractBonesLower1=120
+ fi
+ if [ x = x$ExtractBonesLower2 ]; then
+ ExtractBonesLower2=80
+ fi
+ echo "$phase_file -> Extracting bones..."
+ clitkImageConvert -i $phase_file -o $mask_dir_tmp/float_$phase_nb.mhd -t float
+ clitkExtractBones -i $mask_dir_tmp/float_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd -a $afdb_file --lower1 $ExtractBonesLower1 --upper1 2000 --lower2 $ExtractBonesLower2 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+}
+
+extract_lungs()
+{
+ echo "$phase_file -> Extracting lungs..."
+ clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop
+}
+
+resample()
+{
+ echo "$phase_file -> Resampling..."
+ clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
+
+ clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+}
+
+compute_motion_mask()
+{
+ if [ x = x$MotionMaskOffsetDetect ]; then
+ MotionMaskOffsetDetect="0,-5,0"
+ fi
+ if [ x = x$FillingLevel ]; then
+ FillingLevel=94
+ fi
+
+ clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra
+ #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
+}
+
+create_banded_mask()
+{
+ input=$1
+ input_mask=$2
+ output=$3
+ output_mask=$4
+ radius=$5
+
+ input_dir=`dirname $input`
+ input_base=`basename $input`
+
+ # first band
+ clitkMorphoMath -i $input_mask -o $input_dir/extra1_$input_base --type 1 --radius $radius
+ clitkImageArithm -i $input_dir/extra1_$input_base -j $input_mask -o $input_dir/band1_$input_base -t 7
+ clitkBinarizeImage -i $input_dir/band1_$input_base -o $input_dir/band1_$input_base -l 1 -u 1 --fg 100 --mode both
+ clitkImageConvert -i $input_dir/band1_$input_base -o $input_dir/short_band1_$input_base -t short
+
+ # second band
+ clitkMorphoMath -i $input_dir/extra1_$input_base -o $input_dir/extra2_$input_base --type 1 --radius $radius
+ clitkImageArithm -i $input_dir/extra2_$input_base -j $input_dir/extra1_$input_base -o $input_dir/band2_$input_base -t 7
+ clitkBinarizeImage -i $input_dir/band2_$input_base -o $input_dir/band2_$input_base -l 1 -u 1 --fg 200 --mode both
+ clitkImageConvert -i $input_dir/band2_$input_base -o $input_dir/short_band2_$input_base -t short
+
+ # combine bands with masks
+ clitkImageArithm -i $input_mask -j $input_dir/band1_$input_base -o $output_mask -t 0
+ clitkImageArithm -i $output_mask -j $input_dir/band2_$input_base -o $output_mask -t 0
+ # combine bands with image
+ clitkCombineImage -i $input_dir/short_band1_$input_base -j $input -m $input_dir/band1_$input_base -o $output
+ clitkCombineImage -i $input_dir/short_band2_$input_base -j $output -m $input_dir/band2_$input_base -o $output
+
+ # clean-up
+ rm `echo $input_dir/extra?_$input_base | sed 's:.mhd:.*:g'`
+ rm `echo $input_dir/band?_$input_base | sed 's:.mhd:.*:g'`
+ rm `echo $input_dir/short_band?_$input_base | sed 's:.mhd:.*:g'`
+}
+
+create_registration_masks()
+{
+ # extract inside and outside lung regions from the patient image,
+ # using the motion mask computed previously
+ echo "$phase_file -> Setting Background..."
+ clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200
+ clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200 --fg
+
+ # the registration masks for inside (and outside) region correspond
+ # to the motion mask (and its complement) plus extra grey value bands,
+ # obtained with morphological dilations.
+ #
+ echo "$phase_file -> Creating registration masks..."
+ # inside
+ create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/mm_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/mask_inside_$phase_nb.mhd 4
+ # outside
+ clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
+ create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/mm_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/mask_outside_$phase_nb.mhd 4
+}
+
+mm_preprocessing()
+{
+ extract_patient
+ # extract_bones
+ extract_lungs
+ # remove_tmp_masks 1
+ resample
+}
+
+mm_postprocessing()
+{
+ # remove_tmp_masks 2
+ # remove_tmp_masks 3
+ create_registration_masks
+}
+
+motion_mask()
+{
+ #set cmd line variables
+ mhd4d=$1
+ resample_spacing=$2
+ resample_algo=$3
+
+ dir=`dirname $1`
+ cd $dir
+
+ # import variables specific to each patient
+ source ./variables
+
+ #set other global variables
+ mask_dir="MASK-${resample_spacing}mm-$resample_algo"
+ mask_dir_tmp="tmp.$mask_dir"
+ extract_4d_phases $mhd4d
+
+ echo
+ echo "------------ Motion mask from create_midP_masks.sh ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+
+ # the motion masks are first created in a tmp directory. this directory is
+ # later going to be renamed to the final motion mask directory. concurrent
+ # executions trying to create the same set of masks will be blocked until
+ # the first execution finishes. naturally, these other executions will not
+ # recreate the masks. so first we try to create the tmp directory.
+ # if the creation fails, it means that another execution is
+ # already creating the masks, so this execution will be blocked. the
+ # execution is unblocked only when the creation of masks is finished and
+ # the mask directory is renamed.
+ #
+ # ATTENTION: RP - 08/02/2011
+ # robustness issue: tmp directory may exist but may be empty or
+ # incomplete. the solution is to check per file, but I'll leave it like
+ # this for the moment.
+ do_mm=0
+ if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
+ mkdir $mask_dir_tmp 2> /dev/null
+ return_mkdir=$?
+ if [ $return_mkdir == 0 ]; then
+ do_mm=1
+ else
+ while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
+ echo "waiting creation of motion masks..."
+ sleep 2
+ done
+ echo "finished waiting"
+ fi
+ fi
+
+# do_mm=1
+# mask_dir_tmp=$mask_dir
+ if [ $do_mm == 1 ]; then
+ mask_log_dir=$mask_dir_tmp/LOG
+ mkdir -p $mask_log_dir
+
+ # multi-threaded pre-processing for motion mask calcs
+ for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+ phase_nb=${phase_nbs[$i]}
+ phase_file=${phase_files[$i]}
+ afdb_file=`echo $phase_file | sed 's/mhd/afdb/'`
+
+ check_threads $MAX_THREADS
+ mm_preprocessing &
+ done
+
+ # single-threaded motion mask calc
+ for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+ phase_nb=${phase_nbs[$i]}
+ phase_file=${phase_files[$i]}
+
+ check_threads 1
+ echo "$phase_file -> Computing motion mask..."
+ compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log
+ done
+
+ # multi-threaded post-processing of motion mask calcs
+ for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+ phase_nb=${phase_nbs[$i]}
+ phase_file=${phase_files[$i]}
+
+ check_threads $MAX_THREADS
+ mm_postprocessing &
+ done
+
+ # rename tmp mask directory after mask creation
+ check_threads 1
+ mv -f $mask_dir_tmp $mask_dir
+ fi
+
+ echo
+ echo "-------- Motion mask done ! ---------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+
+#################
+# main #
+#################
+
+if [ $# != 3 ]; then
+ echo "Usage: $0 CT_4D RESAMPLE_SPACING RESAMPLE_ALGORITHM"
+ exit -1
+fi
+
+#
+# variables exported in this scope
+#
+# mask_dir: directory where all masks are kept
+#
+
+if [ $1 != "using-as-lib" ]; then
+ motion_mask $1 $2 $3
+fi
--- /dev/null
+#! /bin/bash -x
+
+source `dirname $0`/midp_common.sh
+
+extract_patient()
+{
+ echo "$image_name -> Extracting patient..."
+ clitkExtractPatient -i $image_name -o $mask_dir_tmp/patient_$image_name --noAutoCrop -a $afdb_name $ExtractPatientExtra
+ clitkBinarizeImage -i $mask_dir_tmp/patient_$image_name -o $mask_dir_tmp/patient_$image_name -l 1 -u 1 --mode=BG
+ clitkSetBackground -i $image_name -o $mask_dir_tmp/patient_only_$image_name --mask $mask_dir_tmp/patient_$image_name --outsideValue -1000
+}
+
+extract_bones()
+{
+ if [ x = x$ExtractBonesLower1 ]; then
+ ExtractBonesLower1=120
+ fi
+ if [ x = x$ExtractBonesLower2 ]; then
+ ExtractBonesLower2=80
+ fi
+ echo "$image_name -> Extracting bones..."
+ clitkImageConvert -i $image_name -o $mask_dir_tmp/float_$image_name -t float
+ #clitkExtractBones -i $mask_dir_tmp/float_$image_name -o $mask_dir_tmp/bones_$image_name --lower1 120 --upper1 2000 --lower2 70 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+ clitkExtractBones -i $mask_dir_tmp/float_$image_name -o $mask_dir_tmp/bones_$image_name -a $afdb_name --lower1 $ExtractBonesLower1 --upper1 2000 --lower2 $ExtractBonesLower2 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+ #clitkMorphoMath -i $mask_dir_tmp/bones_$image_name -o $mask_dir_tmp/bones_$image_name --type 2 --radius 4,4,2
+}
+
+extract_lungs()
+{
+ echo "$image_name -> Extracting lungs..."
+ clitkExtractLung -i $image_name -o $mask_dir_tmp/lungs_$image_name -a $afdb_name --noAutoCrop
+}
+
+resample()
+{
+ echo "$image_name -> Resampling..."
+ clitkResampleImage -i $mask_dir_tmp/patient_$image_name -o $mask_dir_tmp/patient_$image_name --spacing $resample_spacing --interp $resample_algo
+ clitkResampleImage -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/patient_only_$image_name --spacing $resample_spacing --interp $resample_algo
+ clitkResampleImage -i $mask_dir_tmp/bones_$image_name -o $mask_dir_tmp/bones_$image_name --like $mask_dir_tmp/patient_only_$image_name --interp $resample_algo
+ clitkResampleImage -i $mask_dir_tmp/lungs_$image_name -o $mask_dir_tmp/lungs_$image_name --like $mask_dir_tmp/patient_only_$image_name
+}
+
+compute_motion_mask()
+{
+ if [ x = x$MotionMaskOffsetDetect ]; then
+ MotionMaskOffsetDetect="0,-5,0"
+ fi
+ if [ x = x$FillingLevel ]; then
+ FillingLevel=94
+ fi
+ clitkMotionMask -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/mm_$image_name --featureBones=$mask_dir_tmp/bones_$image_name --featureLungs=$mask_dir_tmp/lungs_$image_name --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect 0,-5,0 --pad --writeFeature=$mask_dir_tmp/feature_$image_name $MotionMaskExtra --monitor=$mask_dir_tmp/monitor_$image_name
+}
+
+set_background()
+{
+ echo "$image_name -> Setting Background..."
+ clitkSetBackground -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/inside_$image_name --mask $mask_dir_tmp/mm_$image_name --outsideValue -1200
+ clitkSetBackground -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/outside_$image_name --mask $mask_dir_tmp/mm_$image_name --outsideValue -1200 --fg
+}
+
+create_registration_masks()
+{
+ echo "$image_name -> Creating registration masks..."
+ clitkMorphoMath -i $mask_dir_tmp/mm_$image_name -o $mask_dir_tmp/regmask_in_$image_name --type 1 --radius 8
+ clitkExtractPatient -i $mask_dir_tmp/outside_$image_name -o $mask_dir_tmp/regmask_out_$image_name --noAutoCrop
+ clitkMorphoMath -i $mask_dir_tmp/regmask_out_$image_name -o $mask_dir_tmp/regmask_out_$image_name --type 1 --radius 8
+}
+
+remove_tmp_masks()
+{
+ echo "Removing temporary files..."
+ image_name_base=`echo $image_name | sed 's/mhd//'`
+ case $1 in
+ 1)
+ #rm $mask_dir_tmp/float_$image_name_base*
+ ;;
+ 2)
+ #rm $mask_dir_tmp/bones_$image_name_base*
+ ;;
+ 3)
+ #rm $mask_dir_tmp/patient_only_$image_name_base*
+ ;;
+ esac
+}
+
+mm_preprocessing()
+{
+ extract_patient
+ extract_bones
+ extract_lungs
+ remove_tmp_masks 1
+ resample
+}
+
+mm_postprocessing()
+{
+ remove_tmp_masks 2
+ set_background
+ remove_tmp_masks 3
+ create_registration_masks
+}
+
+mm_workflow()
+{
+ extract_patient
+ extract_bones
+ remove_tmp_masks 1
+ resample
+ echo "$image_name -> Computing motion mask..."
+ compute_motion_mask >> $mask_log_dir/motion_mask_$image_name.log
+ remove_tmp_masks 2
+ set_background
+ remove_tmp_masks 3
+ create_registration_masks
+}
+
+motion_mask()
+{
+ #set cmd line variables
+ echo "4D CT -> "$1
+ phases=`grep ".raw" $1`
+ echo "mask phases -> " $phases
+
+ dir=`dirname $1`
+ cd $dir
+
+ # import variables specific to each patient
+ source variables
+
+ resample_spacing=$2
+ resample_algo=$3
+
+
+ #set other global variables
+ mask_dir="MASK-$resample_spacing""mm""-$resample_algo"
+ mask_dir_tmp="tmp."$mask_dir
+
+ echo
+ echo "------------ Motion mask from create_midP_masks.sh ------------"
+ start=`date`
+ echo "start: $start"
+ echo
+
+ # the motion masks are first created in a tmp directory. this directory is
+ # later going to be renamed to the final motion mask directory. concurrent
+ # executions trying to create the same set of masks will be blocked until
+ # the first execution finishes. naturally, these other executions will not
+ # recreate the masks. so first we try to create the tmp directory.
+ # if the creation fails, it means that another execution is
+ # already creating the masks, so this execution will be blocked. the
+ # execution is unblocked only when the creation of masks is finished and
+ # the mask directory is renamed.
+ #
+ # ATTENTION: RP - 08/02/2011
+ # robustness issue: tmp directory may exist but may be empty or
+ # incomplete. the solution is to check per file, but I'll leave it like
+ # this for the moment.
+ do_mm=0
+ if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
+ mkdir $mask_dir_tmp 2> /dev/null
+ return_mkdir=$?
+ if [ $return_mkdir == 0 ]; then
+ do_mm=1
+ else
+ while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
+ echo "waiting creation of motion masks..."
+ sleep 2
+ done
+ echo "finished waiting"
+ fi
+ fi
+
+ regmask_in_list=""
+ regmask_out_list=""
+ reg_in_list=""
+ reg_out_list=""
+
+ # multi-threaded pre-processing for motion mask calcs
+ if [ $do_mm == 1 ]; then
+ mask_log_dir=$mask_dir_tmp/LOG
+ mkdir -p $mask_log_dir
+
+ for phase in $phases
+ do
+ image_name=`echo $phase | sed 's/raw/mhd/'`
+ afdb_name=`echo $phase | sed 's/raw/afdb/'`
+ check_threads $MAX_THREADS
+ mm_preprocessing &
+ done
+
+ # single-threaded motion mask calc
+ for phase in $phases
+ do
+ image_name=`echo $phase | sed 's/raw/mhd/'`
+
+ check_threads 1
+ echo "$image_name -> Computing motion mask..."
+ compute_motion_mask >> $mask_log_dir/motion_mask_$image_name.log
+ done
+ fi
+
+ # multi-threaded post-processing of motion mask calcs
+ for phase in $phases
+ do
+ image_name=`echo $phase | sed 's/raw/mhd/'`
+ if [ $do_mm = 1 ]; then
+ check_threads $MAX_THREADS
+ mm_postprocessing &
+ fi
+
+ regmask_in_list="$regmask_in_list regmask_in_$image_name"
+ regmask_out_list="$regmask_out_list regmask_out_$image_name"
+ reg_in_list="$reg_in_list inside_$image_name"
+ reg_out_list="$reg_out_list outside_$image_name"
+ done
+
+ # rename tmp mask directory after mask creation
+ check_threads 1
+ mv $mask_dir_tmp $mask_dir
+
+ wait
+
+ echo
+ echo "-------- Motion mask done ! ---------"
+ end=`date`
+ echo "start: $start"
+ echo "end: $end"
+ echo
+}
+
+
+#################
+# main #
+#################
+
+if [ $# != 3 ]; then
+ echo "Usage: create_midP_masks.sh 4D_CT.mhd resample_spacing resample_algorithm"
+ exit -1
+fi
+
+#
+# variables exported in this scope
+#
+# mask_dir: directory where all masks are kept
+# regmask_in_list: list of registration mask files (inside lungs)
+# regmask_out_list: list of registration mask files (outised lungs)
+# reg_in_list: list of registration image files (inside lungs)
+# reg_out_list: list of registration image files (outside lungs)
+#
+
+if [ $1 != "using-as-lib" ]; then
+ motion_mask $1 $2 $3
+fi
find "$i" -iname "*.dcm" | clitkDicom2Image --focal_origin -o "$filename" --std_input
done
-create_mhd_4D.sh . "CT_4D.mhd"
+create_mhd_4D.sh .
--- /dev/null
+#! /bin/sh +x
+
+###############################################################################
+#
+# FILE: midp_common.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Helper file with many functions used in the midP scripts.
+#
+###############################################################################
+
+
+# block execution untill the number of threads (jobs) launched by the
+# current process is below the given number of threads.
+MAX_THREADS=2
+check_threads()
+{
+ nbth=$1
+ while [[ $(jobs -p | wc -l) -ge $nbth ]]; do
+ jobs
+ sleep 10
+ done
+}
+
+#
+# receive a 4D file and and extract the corresponding phase numbers
+# export the variables containing each of the extracted data
+#
+extract_4d_phase_numbers()
+{
+ mhd4d=$1
+
+ nb_phases=${#phase_files[@]}
+
+ # get everything except numbers and punctuation
+ cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt
+
+ # find which patterns have the phases connected to it
+ patterns=`cat /tmp/patterns.txt`
+ if [ -z "$patterns" ]; then
+ phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` )
+ else
+ for i in $patterns; do
+
+ # check if the pattern appears before the phase number
+ nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l`
+ if [ $nb_phases_found == $nb_phases ]; then
+ # keep only what identifies the phase number
+ phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` )
+ break
+ fi
+
+ # check if the pattern appears after the phase number
+ nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l`
+ if [ $nb_phases_found == $nb_phases ]; then
+ # keep only what identifies the phase number
+ phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` )
+ break
+ fi
+
+ done
+ fi
+
+ echo "Phase numbers are ${phase_nbs[@]}"
+ rm /tmp/patterns.txt
+}
+
+#
+# receive a 4D file and extract the corresponding phase files,
+# and phase numbers.
+# export the variables containing each of the extracted data
+#
+extract_4d_phases()
+{
+ mhd4d=$1
+
+ echo "4D file is $mhd4d"
+
+ # array of phase files
+ phase_files=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:'` )
+ echo "Phase files are ${phase_files[@]}"
+
+ extract_4d_phase_numbers $mhd4d
+}
+
+
+#
+# receive a 4D file and the reference phase number as input
+# and extract the corresponding phase files, phase numbers,
+# and reference phase file.
+#
+# export the variables containing each of the extracted data
+#
+extract_4d_phases_ref()
+{
+ extract_4d_phases $1
+
+ # reference phase file
+ ref_phase_file=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | grep $2`
+ echo "Reference phase is $ref_phase_file"
+
+ # reference phase number
+ for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+ ref_phase_nb=`echo ${phase_nbs[$i]} | grep $2`
+ if [ -n "$ref_phase_nb" ]; then
+ echo "Reference phase number is $ref_phase_nb"
+ break
+ fi
+ done
+}
--- /dev/null
+###############################################################################
+#
+# FILE: midp_template.conf
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Template configuration file for create_midP-2.0.sh. Values between <> must be
+# changed according to the methods.
+#
+###############################################################################
+
+# output directories
+vf_dir="<VFDIR>"
+midp_dir="<MIDPDIR>"
+output_dir="<OUTDIR>"
+log_dir="<LOGDIR>"
+
+# script step to be executed (mask, registration, midp, all)
+# midp depends on registration, which depends on mask
+step="all"
+
+# mask parameters
+#
+# interpolation algorithm for resampling (see clitkResampleImage)
+mask_interpolation_algorithm="<MASK_INTERPOLATION_ALGORITHM>"
+# interpolation spacing (in mm)
+mask_interpolation_spacing=<MASK_INTERPOLATION_SPACING>
+
+# registration method (blut, elastix)
+method="<METHOD>"
+
+# registration parameters (depend on registration method - see descriptions)
+#
+
+# b-spline spacing (blut, elastix)
+bspline_spacing=<BSPLINE_SPACING>
+
+# multi-resolution levels
+nb_levels=<NB_LEVELS>
+
+# number of histogram bins (blut, elastix)
+nb_hist_bins=<NB_HIST_BINS>
+
+# number of points (samples) to calculate metric
+# (blut: percentage of image size; elastix: absolute number)
+nb_samples=<NBSAMPLES>
+
+# algorithm used to sample points for the metric
+# (elastix: see docs)
+sampling_algo="<SAMPLING_ALGO>"
+
+# number of iterations (blut, elastix)
+nb_iter=<NB_ITER>
+
+# tolerance (stop condition for the metric) (blut)
+tolerance=<TOLERANCE>
+
+# metric used in the registration
+# (blut: see clitkBLUTDIR; elastix: see docs)
+metric="<METRIC>"
+
+# interpolation type
+# (blut: see clitkBLUTDIR; elastix: see docs)
+interpolator="<INTERPOLATOR>"
+
+# optmizer
+# (blut: see clitkBLUTDIR; elastix: see docs)
+optimizer="<OPTIMIZER>"
--- /dev/null
+#! /bin/sh
+
+###############################################################################
+#
+# FILE: pts_to_landmarks
+# AUTHOR: Vivien Delmon
+#
+# Conversion from landmarks in the format used in clitkCalculateTRE (.pts)
+# to the format used in VV (.txt).
+#
+###############################################################################
+
+if [ $# -ne 2 ]; then
+ echo "Usage: $0 input.pts output.txt" 1>&2
+fi
+
+to_append=/tmp/$RANDOM
+to_prepend=/tmp/$RANDOM
+
+for i in $(seq 0 $((`cat $1 | wc -l` - 1)));
+do
+ echo 0' '0 >> $to_append
+ echo $i >> $to_prepend
+done
+
+echo "LANDMARKS1" > $2
+paste -d ' ' $to_prepend $1 $to_append >> $2
--- /dev/null
+#! /bin/sh
+
+###############################################################################
+#
+# FILE: registration.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Helper file with registration functions using different methods.
+# Each function receives a set of parameters that overall apply to any
+# registration algorithm, as follows:
+#
+# reference=$1 : reference (fixed) image
+# target=$2 : target (moving) image
+# mask_ref=$3 : mask for the reference image
+# mask_targ=$4 : mask for the moving image
+# vf=$5 : output vector field representing the registration
+# result=$6 : result image after applying the vector field
+# nb_iter=$7 : maximum number of iterations
+# nb_samples=$8 : number of image samples used in the metric calulcation
+# sampling_algo=$9 : algorithm used in the selection of image samples
+# hist_bins=${10} : number of histogram bins used in the metric calculation
+# nb_levels=${11} : number of image resolutions
+# spacing=${12} : spacing of the b-spline grid of the fines resolution
+# metric=${13} : metric algorithm
+# optimizer=${14} : optimizer
+# interpolator=${15} : image interpolator
+# log=${16} : log file
+#
+# New registration functions may be added to this file at any moment,
+# respecting the interface defined above.
+#
+###############################################################################
+
+
+################# BLUTDIR #####################
+registration_blutdir()
+{
+ reference=$1
+ target=$2
+ mask_ref=$3
+ mask_targ=$4
+ vf=$5
+ result=$6
+ nb_iter=$7
+ nb_samples=$8
+ sampling_algo=$9
+ hist_bins=${10}
+ nb_levels=${11}
+ spacing=${12}
+ metric=${13}
+ optimizer=${14}
+ interpolator=${15}
+ log=${16}
+
+ echo "Computing BLUTDIR $reference -> $target ..."
+ blutdir_params="--levels $nb_levels --metric $metric --optimizer $optimizer --samples $nb_samples --spacing $spacing,$spacing,$spacing --bins $hist_bins --maxIt $nb_iter --interp $interpolator --verbose"
+ cmd="clitkBLUTDIR -r $reference -t $target -m $mask_ref --targetMask $mask_targ --vf $vf -o $result $blutdir_params"
+ $cmd > $log
+}
+
+################# ELASTIX #####################
+registration_elastix()
+{
+ reference=$1
+ target=$2
+ mask_ref=$3
+ mask_targ=$4
+ vf=$5
+ result=$6
+ nb_iter=$7
+ nb_samples=$8
+ sampling_algo=$9
+ hist_bins=${10}
+ nb_levels=${11}
+ spacing=${12}
+ metric=${13}
+ optimizer=${14}
+ interpolator=${15}
+
+ ########## register in ##########
+ for reg_in in $reg_in_list
+ do
+ if [ ! -z `echo $reg_in | grep "_$phase"` ]
+ then
+ target_in=$reg_in
+ fi
+ done
+ echo "Computing ELASTIX $reference -> $target ..."
+ exec_dir=`which elastix`
+ exec_dir=`dirname $exec_dir`
+ suffix=${nb_samples}_${nb_iter}_${nb_levels}
+ cat $exec_dir/params_BSpline.txt | sed -e "s+<NbIterations>+$nb_iter+" \
+ -e "s+<LabelsFile>++" \
+ -e "s+<HistBins>+$hist_bins+" \
+ -e "s+<Levels>+$nb_levels+" \
+ -e "s+<NbSamples>+$nb_samples+" \
+ -e "s+<SamplerType>+$sampling_algo+" \
+ -e "s+<Spacing>+$spacing+" > params_BSpline_${suffix}.txt
+
+ vf_dir=`dirname $vf`
+ vf_base=`basename $vf .mhd`
+ result_dir=`dirname $result`
+ result_base=`basename $result .mhd`
+
+ # image registration
+ cmd="elastix -f $reference -m $target -fMask $mask_ref -mMask $mask_targ -out $result_dir -p params_BSpline_${suffix}.txt"
+ $cmd > /dev/null
+
+ # generate vector field
+ cmd="transformix -tp $result_dir/TransformParameters.0.txt -out $vf_dir -def all"
+ $cmd > /dev/null
+
+ # post-processing
+ mv $vf_dir/deformationField.mhd $vf
+ mv $vf_dir/deformationField.raw `echo $vf | sed 's/mhd/raw/'`
+ sed -i "s+deformationField+$vf_base+" $vf
+
+ mv $result_dir/result.0.mhd $result
+ mv $result_dir/result.0.raw `echo $result | sed 's/mhd/raw/'`
+ sed -i "s+result.0+$result_base+" $result
+
+ mv $result_dir/elasitx.log $log
+ mv $result_dir/TransformParameters.0.txt $result_dir/${result_base}_TransformParameters.0.txt
+}
\ No newline at end of file
+++ /dev/null
-/clitkTestFilter.cxx
WRAP_GGO(clitkConnectedComponentLabeling_GGO_C clitkConnectedComponentLabeling.ggo)
ADD_EXECUTABLE(clitkConnectedComponentLabeling clitkConnectedComponentLabeling.cxx ${clitkConnectedComponentLabeling_GGO_C})
TARGET_LINK_LIBRARIES(clitkConnectedComponentLabeling clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL clitkConnectedComponentLabeling)
WRAP_GGO(clitkFillMask_GGO_C clitkFillMask.ggo)
ADD_EXECUTABLE(clitkFillMask clitkFillMask.cxx ${clitkFillMask_GGO_C})
TARGET_LINK_LIBRARIES(clitkFillMask clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkFillMask)
ADD_EXECUTABLE(clitkExtractPatient clitkExtractPatient.cxx ${clitkExtractPatient_GGO_C})
TARGET_LINK_LIBRARIES(clitkExtractPatient clitkCommon ${ITK_LIBRARIES} clitkSegmentationGgoLib)
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractPatient)
ADD_EXECUTABLE(clitkExtractLung clitkExtractLung.cxx ${clitkExtractLung_GGO_C})
TARGET_LINK_LIBRARIES(clitkExtractLung clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractLung)
# WRAP_GGO(clitkExtractAirwaysTreeInfo_GGO_C clitkExtractAirwaysTreeInfo.ggo)
# ADD_EXECUTABLE(clitkExtractAirwaysTreeInfo clitkExtractAirwaysTreeInfo.cxx ${clitkExtractAirwaysTreeInfo_GGO_C})
# TARGET_LINK_LIBRARIES(clitkExtractAirwaysTreeInfo clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES})
+ # SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractAirwaysTreeInfo)
WRAP_GGO(clitkExtractBones_GGO_C clitkExtractBones.ggo)
ADD_EXECUTABLE(clitkExtractBones clitkExtractBones.cxx ${clitkExtractBones_GGO_C})
TARGET_LINK_LIBRARIES(clitkExtractBones clitkCommon ${ITK_LIBRARIES} clitkSegmentationGgoLib)
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractBones)
+
+ WRAP_GGO(clitkBool_GGO_C clitkBool.ggo)
+ ADD_EXECUTABLE(clitkBool clitkBool.cxx ${clitkBool_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkBool clitkCommon ${ITK_LIBRARIES} clitkSegmentationGgoLib)
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkBool)
WRAP_GGO(clitkExtractMediastinum_GGO_C clitkExtractMediastinum.ggo)
ADD_EXECUTABLE(clitkExtractMediastinum clitkExtractMediastinum.cxx ${clitkExtractMediastinum_GGO_C})
TARGET_LINK_LIBRARIES(clitkExtractMediastinum clitkCommon clitkSegmentationGgoLib ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractMediastinum)
+
+ WRAP_GGO(clitkExtractLymphStations_GGO_C clitkExtractLymphStations.ggo)
+ ADD_EXECUTABLE(clitkExtractLymphStations clitkExtractLymphStations.cxx clitkFilterWithAnatomicalFeatureDatabaseManagement.cxx ${clitkExtractLymphStations_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkExtractLymphStations clitkSegmentationGgoLib clitkCommon vtkHybrid)
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractLymphStations)
- # WRAP_GGO(clitkExtractLymphStations_GGO_C clitkExtractLymphStations.ggo)
- # ADD_EXECUTABLE(clitkExtractLymphStations clitkExtractLymphStations.cxx clitkFilterWithAnatomicalFeatureDatabaseManagement.cxx ${clitkExtractLymphStations_GGO_C})
- # TARGET_LINK_LIBRARIES(clitkExtractLymphStations clitkSegmentationGgoLib clitkCommon ITKIO ITKStatistics vtkHybrid)
+ WRAP_GGO(clitkExtractMediastinalVessels_GGO_C clitkExtractMediastinalVessels.ggo)
+ ADD_EXECUTABLE(clitkExtractMediastinalVessels clitkExtractMediastinalVessels.cxx clitkFilterWithAnatomicalFeatureDatabaseManagement.cxx ${clitkExtractMediastinalVessels_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkExtractMediastinalVessels clitkSegmentationGgoLib clitkCommon vtkHybrid)
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractMediastinalVessels)
WRAP_GGO(clitkMorphoMath_GGO_C clitkMorphoMath.ggo)
ADD_EXECUTABLE(clitkMorphoMath clitkMorphoMath.cxx ${clitkMorphoMath_GGO_C})
TARGET_LINK_LIBRARIES(clitkMorphoMath clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkMorphoMath)
WRAP_GGO(clitkMorphoReconstruction_GGO_C clitkMorphoReconstruction.ggo)
ADD_EXECUTABLE(clitkMorphoReconstruction clitkMorphoReconstruction.cxx clitkMorphoReconstructionGenericFilter.cxx ${clitkMorphoReconstruction_GGO_C})
TARGET_LINK_LIBRARIES(clitkMorphoReconstruction clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkMorphoReconstruction)
WRAP_GGO(clitkCalculateDistanceMap_GGO_C clitkCalculateDistanceMap.ggo)
ADD_EXECUTABLE(clitkCalculateDistanceMap clitkCalculateDistanceMap.cxx clitkCalculateDistanceMapGenericFilter.cxx ${clitkCalculateDistanceMap_GGO_C})
TARGET_LINK_LIBRARIES(clitkCalculateDistanceMap clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkCalculateDistanceMap)
WRAP_GGO(clitkLevelSetSegmentation_GGO_C clitkLevelSetSegmentation.ggo)
ADD_EXECUTABLE(clitkLevelSetSegmentation clitkLevelSetSegmentation.cxx clitkLevelSetSegmentationGenericFilter.cxx ${clitkLevelSetSegmentation_GGO_C})
TARGET_LINK_LIBRARIES(clitkLevelSetSegmentation clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkLevelSetSegmentation)
WRAP_GGO(clitkAnd_GGO_C clitkAnd.ggo)
ADD_EXECUTABLE(clitkAnd clitkAnd.cxx clitkAndGenericFilter.cxx ${clitkAnd_GGO_C})
TARGET_LINK_LIBRARIES(clitkAnd clitkCommon ${ITK_LIBRARIES} )
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkAnd)
WRAP_GGO(clitkRegionGrowing_GGO_C clitkRegionGrowing.ggo)
ADD_EXECUTABLE(clitkRegionGrowing clitkRegionGrowing.cxx clitkRegionGrowingGenericFilter.cxx ${clitkRegionGrowing_GGO_C})
TARGET_LINK_LIBRARIES(clitkRegionGrowing clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkRegionGrowing)
WRAP_GGO(clitkDecomposeAndReconstruct_GGO_C clitkDecomposeAndReconstruct.ggo)
ADD_EXECUTABLE(clitkDecomposeAndReconstruct clitkDecomposeAndReconstruct.cxx clitkDecomposeAndReconstructGenericFilter.cxx ${clitkDecomposeAndReconstruct_GGO_C})
TARGET_LINK_LIBRARIES(clitkDecomposeAndReconstruct clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkDecomposeAndReconstruct)
WRAP_GGO(clitkMotionMask_GGO_C clitkMotionMask.ggo)
ADD_EXECUTABLE(clitkMotionMask clitkMotionMask.cxx clitkMotionMaskGenericFilter.cxx ${clitkMotionMask_GGO_C})
TARGET_LINK_LIBRARIES(clitkMotionMask clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkMotionMask)
WRAP_GGO(clitkFillImageRegion_GGO_C clitkFillImageRegion.ggo)
ADD_EXECUTABLE(clitkFillImageRegion clitkFillImageRegion.cxx clitkFillImageRegionGenericFilter.cxx ${clitkFillImageRegion_GGO_C})
TARGET_LINK_LIBRARIES(clitkFillImageRegion clitkCommon ${ITK_LIBRARIES})
+ SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkFillImageRegion)
# WRAP_GGO(clitkTestFilter_GGO_C clitkTestFilter.ggo)
# ADD_EXECUTABLE(clitkTestFilter clitkTestFilter.cxx ${clitkTestFilter_GGO_C})
- # TARGET_LINK_LIBRARIES(clitkTestFilter clitkSegmentationGgoLib clitkCommon vtkHybrid ITKIO)
+ # TARGET_LINK_LIBRARIES(clitkTestFilter clitkSegmentationGgoLib clitkCommon vtkHybrid)
+ # SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkTestFilter)
+
+ SET_TARGET_PROPERTIES(${SEGMENTATION_INSTALL} PROPERTIES INSTALL_RPATH "${VTK_DIR}:${ITK_DIR}" )
+ INSTALL (TARGETS ${SEGMENTATION_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
ENDIF(CLITK_BUILD_SEGMENTATION)
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
void clitk::AnatomicalFeatureDatabase::SetDouble(std::string tag, double value)
{
}
//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
double clitk::AnatomicalFeatureDatabase::GetDouble(std::string tag)
{
return a;
}
//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void clitk::AnatomicalFeatureDatabase::RemoveTag(TagType tag)
+{
+ if (TagExist(tag)) {
+ m_MapOfTag.erase(m_MapOfTag.find(tag));
+ }
+}
+//--------------------------------------------------------------------
// Set Get Double
void SetDouble(TagType tag, double d);
double GetDouble(TagType tag);
+
+ // Remove Tag
+ void RemoveTag(TagType tag);
protected:
std::string m_Filename;
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+// clitk
+#include "clitkBool_ggo.h"
+#include "clitkBooleanOperatorLabelImageGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+
+ // Init command line
+ GGO(clitkBool, args_info);
+ CLITK_INIT;
+
+ // Filter
+ typedef clitk::BooleanOperatorLabelImageGenericFilter<args_info_clitkBool> FilterType;
+ FilterType::Pointer filter = FilterType::New();
+
+ filter->SetArgsInfo(args_info);
+
+ try {
+ filter->Update();
+ } catch(std::runtime_error e) {
+ std::cout << e.what() << std::endl;
+ }
+
+ return EXIT_SUCCESS;
+} // This is the end, my friend
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkExtractMediastinalVessels.ggo
+package "clitkExtractMediastinalVessels"
+version "1.0"
+purpose "Extract MediastinalVessels"
+
+option "config" - "Config file" string no
+option "imagetypes" - "Display allowed image types" flag off
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input mask 1" string yes
+option "input2" j "Input mask 2" string yes
+option "output" o "Output filename" string yes
+
+option "type" t "Bool type : " int default="1" no
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+#ifndef CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_H
+#define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_H
+
+#include "clitkIO.h"
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkBooleanOperatorLabelImageFilter.h"
+
+//--------------------------------------------------------------------
+namespace clitk
+{
+
+ template<class ArgsInfoType>
+ class ITK_EXPORT BooleanOperatorLabelImageGenericFilter:
+ public ImageToImageGenericFilter<BooleanOperatorLabelImageGenericFilter<ArgsInfoType> >
+ {
+
+ public:
+ //--------------------------------------------------------------------
+ BooleanOperatorLabelImageGenericFilter();
+
+ //--------------------------------------------------------------------
+ typedef ImageToImageGenericFilter<BooleanOperatorLabelImageGenericFilter<ArgsInfoType> > Superclass;
+ typedef BooleanOperatorLabelImageGenericFilter Self;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ //--------------------------------------------------------------------
+ itkNewMacro(Self);
+ itkTypeMacro(BooleanOperatorLabelImageGenericFilter, LightObject);
+
+ //--------------------------------------------------------------------
+ // Options for the GenericFilter
+ void SetArgsInfo(const ArgsInfoType & a);
+
+ //--------------------------------------------------------------------
+ // Options for the Filter
+ template<class FilterType>
+ void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
+
+ //--------------------------------------------------------------------
+ // Main function called each time the filter is updated
+ template<class ImageType>
+ void UpdateWithInputImageType();
+
+ protected:
+ template<unsigned int Dim> void InitializeImageType();
+ ArgsInfoType mArgsInfo;
+
+ private:
+ BooleanOperatorLabelImageGenericFilter(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+
+ }; // end class
+ //--------------------------------------------------------------------
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkBooleanOperatorLabelImageGenericFilter.txx"
+#endif
+
+#endif // #define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_H
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ ======================================================================-====*/
+
+#ifndef CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_TXX
+#define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_TXX
+
+#include "clitkImageCommon.h"
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::BooleanOperatorLabelImageGenericFilter():
+ ImageToImageGenericFilter<Self>("BooleanOperatorLabelImage")
+{
+ // Default values
+ cmdline_parser_clitkBool_init(&mArgsInfo);
+ InitializeImageType<3>(); // Only for 3D images
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<unsigned int Dim>
+void clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::InitializeImageType()
+{
+ ADD_IMAGE_TYPE(Dim, uchar); // Can add float later
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+void clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a)
+{
+ mArgsInfo=a;
+ SetIOVerbose(mArgsInfo.verbose_flag);
+ if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+ if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
+ if (mArgsInfo.input2_given) AddInputFilename(mArgsInfo.input2_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void
+clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f)
+{
+ // Operation type
+ f->SetOperationType(typename FilterType::OperationTypeEnumeration(mArgsInfo.type_arg));
+
+ // Output filename
+ this->AddOutputFilename(mArgsInfo.output_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class ImageType>
+void clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
+{
+ // Reading input
+ typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
+ typename ImageType::Pointer input2 = this->template GetInput<ImageType>(1);
+
+ // Create filter
+ typedef clitk::BooleanOperatorLabelImageFilter<ImageType> FilterType;
+ typename FilterType::Pointer filter = FilterType::New();
+
+ // Set global Options
+ filter->SetInput1(input1);
+ filter->SetInput2(input2);
+ SetOptionsFromArgsInfoToFilter<FilterType>(filter);
+
+ // Go !
+ filter->Update();
+
+ // Write/Save results
+ typename ImageType::Pointer output = filter->GetOutput();
+ this->template SetNextOutput<ImageType>(output);
+}
+//--------------------------------------------------------------------
+
+#endif //#define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_TXX
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeAndReconstructImageFilter_h
-#define clitkDecomposeAndReconstructImageFilter_h
-
-/* =================================================
- * @file clitkDecomposeAndReconstructImageFilter.h
- * @author
- * @date
- *
- * @brief
- *
- ===================================================*/
-
-
-// clitk include
-#include "clitkIO.h"
-#include "clitkCommon.h"
-#include "clitkDecomposeThroughErosionImageFilter.h"
-#include "clitkReconstructThroughDilationImageFilter.h"
-
-//itk include
-#include "itkImageToImageFilter.h"
-#include "itkRelabelComponentImageFilter.h"
-
-
-namespace clitk
-{
-
- template <class InputImageType, class OutputImageType>
- class ITK_EXPORT DecomposeAndReconstructImageFilter :
- public itk::ImageToImageFilter<InputImageType, OutputImageType>
- {
- public:
- //----------------------------------------
- // ITK
- //----------------------------------------
- typedef DecomposeAndReconstructImageFilter Self;
- typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- // Method for creation through the object factory
- itkNewMacro(Self);
-
- // Run-time type information (and related methods)
- itkTypeMacro( DecomposeAndReconstructImageFilter, ImageToImageFilter );
-
- /** Dimension of the domain space. */
- itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
- itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
-
- //----------------------------------------
- // Typedefs
- //----------------------------------------
- typedef typename OutputImageType::RegionType OutputImageRegionType;
- typedef int InternalPixelType;
- typedef typename InputImageType::PixelType InputPixelType;
- typedef typename OutputImageType::PixelType OutputPixelType;
- typedef typename InputImageType::SizeType SizeType;
-
-
- //----------------------------------------
- // Set & Get
- //----------------------------------------
- itkBooleanMacro(Verbose);
- itkSetMacro( Verbose, bool);
- itkGetConstReferenceMacro( Verbose, bool);
- itkBooleanMacro(FullyConnected);
- itkSetMacro( FullyConnected, bool);
- itkGetConstReferenceMacro( FullyConnected, bool);
- void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
- SizeType GetRadius(void){return m_Radius;}
- itkSetMacro( MaximumNumberOfLabels, unsigned int);
- itkGetConstMacro( MaximumNumberOfLabels, unsigned int);
- itkSetMacro( BackgroundValue, InternalPixelType);
- itkGetConstMacro( BackgroundValue, InternalPixelType);
- itkSetMacro( ForegroundValue, InternalPixelType);
- itkGetConstMacro( ForegroundValue, InternalPixelType);
- itkSetMacro( NumberOfNewLabels, unsigned int);
- itkGetConstMacro( NumberOfNewLabels, unsigned int);
- itkSetMacro( MinimumObjectSize, unsigned int);
- itkGetConstMacro( MinimumObjectSize, unsigned int);
- itkSetMacro( MinimumNumberOfIterations, unsigned int);
- itkGetConstMacro( MinimumNumberOfIterations, unsigned int);
- // // Convenience macro's: Built-in
- // itkBooleanMacro (flag); //FlagOn FlagOff
- // itkGetMacro(name, type);
- // itkSetMacro(name, type);
- // itkSetConstMacro( name, type);
- // itkGetConstMacro( name, type);
- // itkSetConstReferenceMacro(name, type);
- // itkGetConstReferenceMacro(name, type);
- // // Convenience macro's: Smartpointers
- // itkSetObjectMacro(name, type);
- // itkGetObjectMacro(name, type);
- // itkSetConstObjectMacro(name, type);
- // itkGetConstObjectMacro(name, type);
- // itkSetConstReferenceObjectMacro(name, type);
- // itkSetConstReference(name, type);
-
-
- protected:
-
- //----------------------------------------
- // Constructor & Destructor
- //----------------------------------------
- DecomposeAndReconstructImageFilter();
- ~DecomposeAndReconstructImageFilter() {};
-
- //----------------------------------------
- // Update
- //----------------------------------------
- // Generate Data
- void GenerateData(void);
-
- // // Threaded Generate Data
- // void BeforeThreadedGenerateData(void );
- // void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
- // void AfterThreadedGenerateData(void );
- // // Override defaults
- // virtual void GenerateInputRequestedRegion();
- // virtual void GenerateOutputInformation (void);
- // virtual void EnlargeOutputRequestedRegion(DataObject *data);
- void AllocateOutputs(){;}
- //----------------------------------------
- // Data members
- //----------------------------------------
- bool m_Verbose;
- SizeType m_Radius;
- unsigned int m_NumberOfNewLabels;
- bool m_FullyConnected;
- InputPixelType m_BackgroundValue;
- InputPixelType m_ForegroundValue;
- unsigned int m_MaximumNumberOfLabels;
- unsigned int m_MinimumObjectSize;
- unsigned int m_MinimumNumberOfIterations;
- };
-
-
-} // end namespace clitk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkDecomposeAndReconstructImageFilter.txx"
-#endif
-
-#endif // #define clitkDecomposeAndReconstructImageFilter_h
-
-
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeAndReconstructImageFilter_txx
-#define clitkDecomposeAndReconstructImageFilter_txx
-
-namespace clitk
-{
-
- //-------------------------------------------------------------------
- // Update with the number of dimensions
- //-------------------------------------------------------------------
- template<class InputImageType, class OutputImageType>
- DecomposeAndReconstructImageFilter<InputImageType, OutputImageType>::DecomposeAndReconstructImageFilter()
- {
- m_Verbose=false;
- for (unsigned int i=0; i<InputImageDimension; i++)
- m_Radius[i]=1;
- m_NumberOfNewLabels=1;
- m_FullyConnected=true;
- m_BackgroundValue=0;
- m_ForegroundValue=1;
- m_MaximumNumberOfLabels=10;
- m_MinimumObjectSize=10;
- m_MinimumNumberOfIterations=1;
-
- }
-
-
- //-------------------------------------------------------------------
- // Update with the number of dimensions and the pixeltype
- //-------------------------------------------------------------------
- template <class InputImageType, class OutputImageType>
- void
- DecomposeAndReconstructImageFilter<InputImageType, OutputImageType>::GenerateData()
- {
-
-
- // Internal type
- typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
-
- // Filters used
- typedef clitk::DecomposeThroughErosionImageFilter<InputImageType, InternalImageType> DecomposeThroughErosionImageFilterType;
- typedef clitk::ReconstructThroughDilationImageFilter<InternalImageType, InputImageType> ReconstructThroughDilationImageFilterType;
-
- // Erode
- typename DecomposeThroughErosionImageFilterType::Pointer erosionFilter=DecomposeThroughErosionImageFilterType::New();
- erosionFilter->SetInput(this->GetInput());
- erosionFilter->SetVerbose(m_Verbose);
- erosionFilter->SetFullyConnected(m_FullyConnected);
- erosionFilter->SetRadius(m_Radius);
- erosionFilter->SetNumberOfNewLabels(m_NumberOfNewLabels);
- erosionFilter->SetMinimumObjectSize(m_MinimumObjectSize);
- erosionFilter->SetMinimumNumberOfIterations(m_MinimumNumberOfIterations);
- erosionFilter->Update();
-
- // Reconstruct
- typename ReconstructThroughDilationImageFilterType::Pointer reconstructionFilter =ReconstructThroughDilationImageFilterType::New();
- reconstructionFilter->SetInput(erosionFilter->GetOutput());
- reconstructionFilter->SetVerbose(m_Verbose);
- reconstructionFilter->SetRadius(m_Radius);
- reconstructionFilter->SetMaximumNumberOfLabels(m_MaximumNumberOfLabels);
- reconstructionFilter->SetBackgroundValue(m_BackgroundValue);
- reconstructionFilter->SetForegroundValue(m_ForegroundValue);
- reconstructionFilter->Update();
-
- // Output
- this->SetNthOutput(0,reconstructionFilter->GetOutput());
- }
-
-
-}//end clitk
-
-#endif //#define clitkDecomposeAndReconstructImageFilter_txx
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeThroughErosionImageFilter_h
-#define clitkDecomposeThroughErosionImageFilter_h
-
-/* =================================================
- * @file clitkDecomposeThroughErosionImageFilter.h
- * @author
- * @date
- *
- * @brief
- *
- ===================================================*/
-
-
-// clitk include
-#include "clitkIO.h"
-#include "clitkCommon.h"
-#include "clitkSetBackgroundImageFilter.h"
-
-//itk include
-#include "itkImageToImageFilter.h"
-#include "itkBinaryThresholdImageFilter.h"
-#include "itkBinaryErodeImageFilter.h"
-#include "itkStatisticsImageFilter.h"
-#include "itkConnectedComponentImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "itkBinaryBallStructuringElement.h"
-#include "itkRelabelComponentImageFilter.h"
-
-namespace clitk
-{
-
- template <class InputImageType, class OutputImageType>
- class ITK_EXPORT DecomposeThroughErosionImageFilter :
- public itk::ImageToImageFilter<InputImageType, OutputImageType>
- {
- public:
- //----------------------------------------
- // ITK
- //----------------------------------------
- typedef DecomposeThroughErosionImageFilter Self;
- typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- // Method for creation through the object factory
- itkNewMacro(Self);
-
- // Run-time type information (and related methods)
- itkTypeMacro( DecomposeThroughErosionImageFilter, ImageToImageFilter );
-
- /** Dimension of the domain space. */
- itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
- itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
-
- //----------------------------------------
- // Typedefs
- //----------------------------------------
- typedef typename OutputImageType::RegionType OutputImageRegionType;
- typedef int InternalPixelType;
- typedef typename InputImageType::PixelType InputPixelType;
- typedef typename OutputImageType::PixelType OutputPixelType;
- typedef typename InputImageType::SizeType SizeType;
-
- //----------------------------------------
- // Set & Get
- //----------------------------------------
- itkBooleanMacro(Verbose);
- itkSetMacro( Verbose, bool);
- itkGetConstReferenceMacro( Verbose, bool);
- itkBooleanMacro(FullyConnected);
- itkSetMacro( FullyConnected, bool);
- itkGetConstReferenceMacro( FullyConnected, bool);
- itkSetMacro( Lower, InputPixelType);
- itkGetConstMacro( Lower, InputPixelType);
- itkSetMacro( Upper, InputPixelType);
- itkGetConstMacro( Upper, InputPixelType);
- itkSetMacro( Inside, InternalPixelType);
- itkGetConstMacro( Inside, InternalPixelType);
- itkSetMacro( Outside, InternalPixelType);
- itkGetConstMacro( Outside, InternalPixelType);
- itkSetMacro( ErosionPaddingValue, OutputPixelType);
- itkGetConstMacro( ErosionPaddingValue, OutputPixelType);
- void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
- SizeType GetRadius(void){return m_Radius;}
- itkSetMacro( NumberOfNewLabels, unsigned int);
- itkGetConstMacro( NumberOfNewLabels, unsigned int);
- itkSetMacro( MinimumObjectSize, unsigned int);
- itkGetConstMacro( MinimumObjectSize, unsigned int);
- itkSetMacro( MinimumNumberOfIterations, unsigned int);
- itkGetConstMacro( MinimumNumberOfIterations, unsigned int);
-
- protected:
-
- //----------------------------------------
- // Constructor & Destructor
- //----------------------------------------
- DecomposeThroughErosionImageFilter();
- ~DecomposeThroughErosionImageFilter() {};
-
- //----------------------------------------
- // Update
- //----------------------------------------
- // Generate Data
- void GenerateData(void);
- void AllocateOutput(){;}
-
- // // Threaded Generate Data
- // void BeforeThreadedGenerateData(void );
- // void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
- // void AfterThreadedGenerateData(void );
- // // Override defaults
- // virtual void GenerateInputRequestedRegion();
- // virtual void GenerateOutputInformation (void);
- // virtual void EnlargeOutputRequestedRegion(DataObject *data);
- // void AllocateOutputs();
- //----------------------------------------
- // Data members
- //----------------------------------------
- bool m_Verbose;
- bool m_FullyConnected;
- InputPixelType m_Lower;
- InputPixelType m_Upper;
- OutputPixelType m_ErosionPaddingValue;
- InputPixelType m_Inside;
- InputPixelType m_Outside;
- SizeType m_Radius;
- unsigned int m_NumberOfNewLabels;
- unsigned int m_MinimumObjectSize;
- unsigned int m_MinimumNumberOfIterations;
-
- };
-
-
-} // end namespace clitk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkDecomposeThroughErosionImageFilter.txx"
-#endif
-
-#endif // #define clitkDecomposeThroughErosionImageFilter_h
-
-
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeThroughErosionImageFilter_txx
-#define clitkDecomposeThroughErosionImageFilter_txx
-
-/* =================================================
- * @file clitkDecomposeThroughErosionImageFilter.txx
- * @author
- * @date
- *
- * @brief
- *
- ===================================================*/
-
-
-namespace clitk
-{
-
- //-------------------------------------------------------------------
- // Update with the number of dimensions
- //-------------------------------------------------------------------
- template<class InputImageType, class OutputImageType>
- DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::DecomposeThroughErosionImageFilter()
- {
- m_Verbose=false;
- m_Lower =1;
- m_Upper=1;
- m_Inside=1;
- m_Outside=0;
- m_ErosionPaddingValue=static_cast<OutputPixelType>(-1);
- for (unsigned int i=0; i<InputImageDimension; i++)
- m_Radius[i]=1;
- m_NumberOfNewLabels=1;
- m_FullyConnected=true;
- m_MinimumObjectSize=10;
- m_MinimumNumberOfIterations=1;
- }
-
-
- //-------------------------------------------------------------------
- // Update with the number of dimensions and the pixeltype
- //-------------------------------------------------------------------
- template<class InputImageType, class OutputImageType>
- void
- DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::GenerateData()
- {
-
- //---------------------------------
- // Typedefs
- //---------------------------------
-
- // Internal type
- typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
-
- // Filters used
- typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinaryThresholdImageFilter;
- typedef itk::BinaryBallStructuringElement<InputPixelType,InputImageDimension > KernelType;
- typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> BinaryErodeImageFilterType;
- typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinaryThresholdImageFilterType;
- typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
- typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
- typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelImageFilterType;
- typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
-
- //---------------------------------
- // Binarize input
- //---------------------------------
- typename InputBinaryThresholdImageFilter::Pointer inputBinarizer=InputBinaryThresholdImageFilter::New();
- inputBinarizer->SetInput(this->GetInput());
- inputBinarizer->SetLowerThreshold(m_Lower);
- inputBinarizer->SetUpperThreshold(m_Upper);
- inputBinarizer ->SetInsideValue(m_Inside);
- inputBinarizer ->SetOutsideValue(m_Outside);
- if(m_Verbose) std::cout<<"Binarizing the input..."<<std::endl;
- inputBinarizer->Update();
-
- //---------------------------------
- // Label the input
- //---------------------------------
- typename ConnectFilterType::Pointer inputConnectFilter=ConnectFilterType::New();
- inputConnectFilter->SetInput(inputBinarizer->GetOutput());
- inputConnectFilter->SetBackgroundValue(0);
- inputConnectFilter->SetFullyConnected(m_FullyConnected);
- if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
- // inputConnectFilter->Update();
-
- //---------------------------------
- // Count the initial labels
- //---------------------------------
- typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
- inputStatisticsImageFilter->SetInput(inputConnectFilter->GetOutput());
- if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
- inputStatisticsImageFilter->Update();
- unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
- if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
- if(m_Verbose) std::cout<<"Performing erosions till at least "<<initialNumberOfLabels+m_NumberOfNewLabels<<" distinctive labels are counted..."<<std::endl;
-
- //---------------------------------
- // Structuring element
- //---------------------------------
- KernelType structuringElement;
- structuringElement.SetRadius(m_Radius);
- structuringElement.CreateStructuringElement();
-
- //---------------------------------
- // Repeat while not decomposed
- //---------------------------------
- typename InternalImageType::Pointer current=inputBinarizer->GetOutput();
- typename InternalImageType::Pointer output=inputBinarizer->GetOutput();
- unsigned int iteration=0;
- unsigned int max =initialNumberOfLabels;
-
- while ( (iteration < m_MinimumNumberOfIterations) || ( (max< initialNumberOfLabels + m_NumberOfNewLabels ) && (iteration<100 ) ) )
- {
-
-
- if(m_Verbose) std::cout<<"Eroding image (iteration "<<iteration<<")..."<<std::endl;
-
- //---------------------------------
- // Erode
- //---------------------------------
- typename BinaryErodeImageFilterType::Pointer erosionFilter=BinaryErodeImageFilterType::New();
- erosionFilter->SetInput (current);
- erosionFilter->SetForegroundValue (1);
- erosionFilter->SetBackgroundValue (-1);
- erosionFilter->SetBoundaryToForeground(false);
- erosionFilter->SetKernel(structuringElement);
- erosionFilter->Update();
- current=erosionFilter->GetOutput();
-
- //---------------------------------
- // Binarize (remove -1)
- //---------------------------------
- typename BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
- binarizer->SetInput(erosionFilter->GetOutput());
- binarizer->SetLowerThreshold(1);
- binarizer->SetUpperThreshold(1);
- binarizer ->SetInsideValue(1);
- binarizer ->SetOutsideValue(0);
- if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
- //binarizer->Update();
-
-
- //---------------------------------
- // ReLabel the connected components
- //---------------------------------
- typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
- connectFilter->SetInput(binarizer->GetOutput());
- connectFilter->SetBackgroundValue(0);
- connectFilter->SetFullyConnected(m_FullyConnected);
- if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
- //connectFilter->Update();
-
- //---------------------------------
- // Sort
- //---------------------------------
- typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
- relabelFilter->SetInput(connectFilter->GetOutput());
- relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize);
- //relabelFilter->Update();
-
-
- //---------------------------------
- // Count the labels
- //---------------------------------
- typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
- statisticsImageFilter->SetInput(relabelFilter->GetOutput());
- statisticsImageFilter->Update();
- max= statisticsImageFilter->GetMaximum();
- if(m_Verbose) std::cout<<"Counted "<<max<<" label (s) larger then "<<m_MinimumObjectSize<<" voxels..."<<std::endl;
- output=statisticsImageFilter->GetOutput();
-
- // Next iteration
- iteration++;
- }
-
-
- //---------------------------------
- // Binarize current (remove -1)
- //---------------------------------
- typename BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
- binarizer->SetInput(current);
- binarizer->SetLowerThreshold(1);
- binarizer->SetUpperThreshold(1);
- binarizer ->SetInsideValue(1);
- binarizer ->SetOutsideValue(0);
- if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
- //binarizer->Update();
-
- //---------------------------------
- // ReLabel the connected components
- //---------------------------------
- typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
- connectFilter->SetInput(binarizer->GetOutput());
- connectFilter->SetBackgroundValue(0);
- connectFilter->SetFullyConnected(m_FullyConnected);
- if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
- connectFilter->Update();
-
- //---------------------------------
- // Sort
- //---------------------------------
- typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
- relabelFilter->SetInput(connectFilter->GetOutput());
- //relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize); // Preserve all intensities
- //relabelFilter->Update();
-
- //---------------------------------
- // Set -1 to padding value
- //---------------------------------
- typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
- setBackgroundFilter->SetInput(relabelFilter->GetOutput());
- setBackgroundFilter->SetInput2(current);
- setBackgroundFilter->SetMaskValue(-1);
- setBackgroundFilter->SetOutsideValue(m_ErosionPaddingValue);
- if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
-
- //---------------------------------
- // Cast
- //---------------------------------
- typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
- typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
- caster->SetInput(setBackgroundFilter->GetOutput());
- caster->Update();
-
- //---------------------------------
- // SetOutput
- //---------------------------------
- this->SetNthOutput(0, caster->GetOutput());
- }
-
-
-}//end clitk
-
-#endif //#define clitkDecomposeThroughErosionImageFilter_txx
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
-#ifndef __clitkExtractImageFilter_h
-#define __clitkExtractImageFilter_h
-
-#include "itkImageToImageFilter.h"
-#include "itkSmartPointer.h"
-#include "itkExtractImageFilterRegionCopier.h"
-
-namespace clitk
-{
-
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ExtractImageFilter:
- public itk::ImageToImageFilter<TInputImage,TOutputImage>
-{
-public:
- /** Standard class typedefs. */
- typedef ExtractImageFilter Self;
- typedef itk::ImageToImageFilter<TInputImage,TOutputImage> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- /** Method for creation through the object factory. */
- itkNewMacro(Self);
-
- /** Run-time type information (and related methods). */
- itkTypeMacro(ExtractImageFilter, ImageToImageFilter);
-
- /** Image type information. */
- typedef TInputImage InputImageType;
- typedef TOutputImage OutputImageType;
-
- /** Typedef to describe the output and input image region types. */
- typedef typename TOutputImage::RegionType OutputImageRegionType;
- typedef typename TInputImage::RegionType InputImageRegionType;
-
- /** Typedef to describe the type of pixel. */
- typedef typename TOutputImage::PixelType OutputImagePixelType;
- typedef typename TInputImage::PixelType InputImagePixelType;
-
- /** Typedef to describe the output and input image index and size types. */
- typedef typename TOutputImage::IndexType OutputImageIndexType;
- typedef typename TInputImage::IndexType InputImageIndexType;
- typedef typename TOutputImage::SizeType OutputImageSizeType;
- typedef typename TInputImage::SizeType InputImageSizeType;
-
- /** ImageDimension enumeration */
- itkStaticConstMacro(InputImageDimension, unsigned int,
- TInputImage::ImageDimension);
- itkStaticConstMacro(OutputImageDimension, unsigned int,
- TOutputImage::ImageDimension);
-
- typedef itk::ImageToImageFilterDetail::ExtractImageFilterRegionCopier<
- itkGetStaticConstMacro(InputImageDimension),
- itkGetStaticConstMacro(OutputImageDimension)> ExtractImageFilterRegionCopierType;
-
- void SetExtractionRegion(InputImageRegionType extractRegion);
- itkGetMacro(ExtractionRegion, InputImageRegionType);
-
-#ifdef ITK_USE_CONCEPT_CHECKING
- /** Begin concept checking */
- itkConceptMacro(InputCovertibleToOutputCheck,
- (itk::Concept::Convertible<InputImagePixelType, OutputImagePixelType>));
- /** End concept checking */
-#endif
-
-protected:
- ExtractImageFilter();
- ~ExtractImageFilter() {};
- void PrintSelf(std::ostream& os, itk::Indent indent) const;
-
-
- virtual void GenerateOutputInformation();
-
-
- virtual void CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
- const OutputImageRegionType &srcRegion);
-
-
- void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
- int threadId );
- InputImageRegionType m_ExtractionRegion;
- OutputImageRegionType m_OutputImageRegion;
-
-private:
- ExtractImageFilter(const Self&); //purposely not implemented
- void operator=(const Self&); //purposely not implemented
-
-};
-
-
-} // end namespace itk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkExtractImageFilter.txx"
-#endif
-
-#endif
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
-#ifndef _clitkExtractImageFilter_txx
-#define _clitkExtractImageFilter_txx
-
-#include "clitkExtractImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkObjectFactory.h"
-#include "itkExtractImageFilterRegionCopier.h"
-#include "itkProgressReporter.h"
-
-
-namespace clitk
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-ExtractImageFilter<TInputImage,TOutputImage>
-::ExtractImageFilter()
-{
-}
-
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
- Superclass::PrintSelf(os,indent);
-
- os << indent << "ExtractionRegion: " << m_ExtractionRegion << std::endl;
- os << indent << "OutputImageRegion: " << m_OutputImageRegion << std::endl;
-}
-
-
-template<class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
- const OutputImageRegionType &srcRegion)
-{
- ExtractImageFilterRegionCopierType extractImageRegionCopier;
- extractImageRegionCopier(destRegion, srcRegion, m_ExtractionRegion);
-}
-
-
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::SetExtractionRegion(InputImageRegionType extractRegion)
-{
- m_ExtractionRegion = extractRegion;
-
- unsigned int nonzeroSizeCount = 0;
- InputImageSizeType inputSize = extractRegion.GetSize();
- OutputImageSizeType outputSize;
- OutputImageIndexType outputIndex;
-
- /**
- * check to see if the number of non-zero entries in the extraction region
- * matches the number of dimensions in the output image.
- **/
- for (unsigned int i = 0; i < InputImageDimension; ++i)
- {
- if (inputSize[i])
- {
- outputSize[nonzeroSizeCount] = inputSize[i];
- outputIndex[nonzeroSizeCount] = extractRegion.GetIndex()[i];
- nonzeroSizeCount++;
- }
- }
-
- if (nonzeroSizeCount != OutputImageDimension)
- {
- itkExceptionMacro("Extraction Region not consistent with output image");
- }
-
- m_OutputImageRegion.SetSize(outputSize);
- m_OutputImageRegion.SetIndex(outputIndex);
- this->Modified();
-}
-
-
-
-/**
- * ExtractImageFilter can produce an image which is a different resolution
- * than its input image. As such, ExtractImageFilter needs to provide an
- * implementation for GenerateOutputInformation() in order to inform
- * the pipeline execution model. The original documentation of this
- * method is below.
- *
- * \sa ProcessObject::GenerateOutputInformaton()
- */
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::GenerateOutputInformation()
-{
- // do not call the superclass' implementation of this method since
- // this filter allows the input and the output to be of different dimensions
-
- // get pointers to the input and output
- typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
- typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
-
- if ( !outputPtr || !inputPtr)
- {
- return;
- }
-
- // Set the output image size to the same value as the extraction region.
- outputPtr->SetLargestPossibleRegion( m_OutputImageRegion );
-
- // Set the output spacing and origin
- const itk::ImageBase<InputImageDimension> *phyData;
-
- phyData
- = dynamic_cast<const itk::ImageBase<InputImageDimension>*>(this->GetInput());
-
- if (phyData)
- {
- // Copy what we can from the image from spacing and origin of the input
- // This logic needs to be augmented with logic that select which
- // dimensions to copy
-
- unsigned int i;
- const typename InputImageType::SpacingType&
- inputSpacing = inputPtr->GetSpacing();
- const typename InputImageType::DirectionType&
- inputDirection = inputPtr->GetDirection();
- const typename InputImageType::PointType&
- inputOrigin = inputPtr->GetOrigin();
-
- typename OutputImageType::SpacingType outputSpacing;
- typename OutputImageType::DirectionType outputDirection;
- typename OutputImageType::PointType outputOrigin;
-
- if ( static_cast<unsigned int>(OutputImageDimension) >
- static_cast<unsigned int>(InputImageDimension ) )
- {
- // copy the input to the output and fill the rest of the
- // output with zeros.
- for (i=0; i < InputImageDimension; ++i)
- {
- outputSpacing[i] = inputSpacing[i];
- outputOrigin[i] = inputOrigin[i];
- for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
- {
- outputDirection[i][dim] = inputDirection[i][dim];
- }
- }
- for (; i < OutputImageDimension; ++i)
- {
- outputSpacing[i] = 1.0;
- outputOrigin[i] = 0.0;
- for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
- {
- outputDirection[i][dim] = 0.0;
- }
- outputDirection[i][i] = 1.0;
- }
- }
- else
- {
- // copy the non-collapsed part of the input spacing and origing to the output
- int nonZeroCount = 0;
- for (i=0; i < InputImageDimension; ++i)
- {
- if (m_ExtractionRegion.GetSize()[i])
- {
- outputSpacing[nonZeroCount] = inputSpacing[i];
- outputOrigin[nonZeroCount] = inputOrigin[i];
- int nonZeroCount2 = 0;
- for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
- {
- if (m_ExtractionRegion.GetSize()[dim])
- {
- outputDirection[nonZeroCount][nonZeroCount2] =
- inputDirection[i][dim];
- ++nonZeroCount2;
- }
- }
- nonZeroCount++;
- }
- }
- }
-
- // set the spacing and origin
- outputPtr->SetSpacing( outputSpacing );
- outputPtr->SetDirection( outputDirection );
- outputPtr->SetOrigin( outputOrigin );
- outputPtr->SetNumberOfComponentsPerPixel(inputPtr->GetNumberOfComponentsPerPixel() );
- }
- else
- {
- // pointer could not be cast back down
- itkExceptionMacro(<< "itk::ExtractImageFilter::GenerateOutputInformation "
- << "cannot cast input to "
- << typeid(itk::ImageBase<InputImageDimension>*).name() );
- }
-}
-
-/**
- * ExtractImageFilter can be implemented as a multithreaded filter.
- * Therefore, this implementation provides a ThreadedGenerateData()
- * routine which is called for each processing thread. The output
- * image data is allocated automatically by the superclass prior to
- * calling ThreadedGenerateData(). ThreadedGenerateData can only
- * write to the portion of the output image specified by the
- * parameter "outputRegionForThread"
- *
- * \sa ImageToImageFilter::ThreadedGenerateData(),
- * ImageToImageFilter::GenerateData()
- */
-template <class TInputImage, class TOutputImage>
-void
-ExtractImageFilter<TInputImage,TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
- int threadId)
-{
- itkDebugMacro(<<"Actually executing");
-
- // Get the input and output pointers
- typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
- typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
-
- // support progress methods/callbacks
- itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-
- // Define the portion of the input to walk for this thread
- InputImageRegionType inputRegionForThread;
- this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
-
- // Define the iterators.
- typedef itk::ImageRegionIterator<TOutputImage> OutputIterator;
- typedef itk::ImageRegionConstIterator<TInputImage> InputIterator;
-
- OutputIterator outIt(outputPtr, outputRegionForThread);
- InputIterator inIt(inputPtr, inputRegionForThread);
-
- // walk the output region, and sample the input image
- while( !outIt.IsAtEnd() )
- {
- // copy the input pixel to the output
- outIt.Set( static_cast<OutputImagePixelType>(inIt.Get()));
- ++outIt;
- ++inIt;
- progress.CompletedPixel();
- }
-}
-
-} // end namespace clitk
-
-#endif
option "doNotFillHoles" - "Do not fill holes if set" flag on
option "dir" d "Directions (axes) to perform filling (defaults to 2,1,0)" int multiple no
+option "noAutoCrop" - "If set : do no crop final mask to BoundingBox" flag off
itkGetConstMacro(FillHolesFlag, bool);
itkBooleanMacro(FillHolesFlag);
+ // Step Auto Crop
+ itkSetMacro(AutoCrop, bool);
+ itkGetConstMacro(AutoCrop, bool);
+ itkBooleanMacro(AutoCrop);
+
protected:
ExtractLungFilter();
virtual ~ExtractLungFilter() {}
MaskImagePixelType m_BackgroundValue;
MaskImagePixelType m_ForegroundValue;
int m_MinimalComponentSize;
+ bool m_AutoCrop;
// Step 1
InputImagePixelType m_UpperThreshold;
#include "itkImageIteratorWithIndex.h"
#include "itkBinaryMorphologicalOpeningImageFilter.h"
#include "itkBinaryMorphologicalClosingImageFilter.h"
+#include "itkConstantPadImageFilter.h"
//--------------------------------------------------------------------
template <class ImageType>
// Step 6
FillHolesFlagOn();
+ AutoCropOn();
}
//--------------------------------------------------------------------
StartNewStep("Set background to initial image");
working_input = SetBackground<ImageType, MaskImageType>
(working_input, patient, GetPatientMaskBackgroundValue(), -1000, true);
+
+ // Pad images with air to prevent patient touching the image border
+ static const unsigned int Dim = ImageType::ImageDimension;
+ typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
+ typename PadFilterType::Pointer padFilter = PadFilterType::New();
+ padFilter->SetInput(working_input);
+ padFilter->SetConstant(-1000);
+ typename ImageType::SizeType bounds;
+ for (unsigned i = 0; i < Dim - 1; ++i)
+ bounds[i] = 1;
+ bounds[Dim - 1] = 0;
+ padFilter->SetPadLowerBound(bounds);
+ padFilter->SetPadUpperBound(bounds);
+ padFilter->Update();
+ working_input = padFilter->GetOutput();
+
StopCurrentStep<ImageType>(working_input);
PrintMemory(GetVerboseMemoryFlag(), "After set bg"); // OK, additional mem = 0
//--------------------------------------------------------------------
PrintMemory(GetVerboseMemoryFlag(), "before autocropfilter");
if (m_Seeds.size() != 0) { // if ==0 ->no trachea found
- trachea = clitk::AutoCrop<MaskImageType>(trachea, GetBackgroundValue());
+ if (GetAutoCrop())
+ trachea = clitk::AutoCrop<MaskImageType>(trachea, GetBackgroundValue());
+ else
+ {
+ // Remove Padding region
+ typedef itk::CropImageFilter<MaskImageType, MaskImageType> CropFilterType;
+ typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ cropFilter->SetInput(trachea);
+ cropFilter->SetLowerBoundaryCropSize(bounds);
+ cropFilter->SetUpperBoundaryCropSize(bounds);
+ cropFilter->Update();
+ trachea = cropFilter->GetOutput();
+ }
StopCurrentStep<MaskImageType>(trachea);
PrintMemory(GetVerboseMemoryFlag(), "after delete trachea");
}
//--------------------------------------------------------------------
StartNewStep("Cropping lung");
PrintMemory(GetVerboseMemoryFlag(), "Before Autocropfilter");
- working_mask = clitk::AutoCrop<MaskImageType>(working_mask, GetBackgroundValue());
+ if (GetAutoCrop())
+ working_mask = clitk::AutoCrop<MaskImageType>(working_mask, GetBackgroundValue());
+ else
+ {
+ // Remove Padding region
+ typedef itk::CropImageFilter<MaskImageType, MaskImageType> CropFilterType;
+ typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ cropFilter->SetInput(working_mask);
+ cropFilter->SetLowerBoundaryCropSize(bounds);
+ cropFilter->SetUpperBoundaryCropSize(bounds);
+ cropFilter->Update();
+ working_mask = cropFilter->GetOutput();
+ }
StopCurrentStep<MaskImageType>(working_mask);
//--------------------------------------------------------------------
PrintMemory(GetVerboseMemoryFlag(), "After count label");
// Decompose the first label
- static const unsigned int Dim = ImageType::ImageDimension;
if (initialNumberOfLabels<2) {
// Structuring element radius
typename ImageType::SizeType radius;
//--------------------------------------------------------------------
template <class ImageType>
-void
+void
clitk::ExtractLungFilter<ImageType>::
SearchForTrachea()
{
double volume = 0.0;
int skip = GetNumberOfSlicesToSkipBeforeSearchingSeed();
while (!stop) {
- stop = SearchForTracheaSeed(skip);
- if (stop) {
+ stop = true;
+ if (SearchForTracheaSeed(skip)) {
TracheaRegionGrowing();
volume = ComputeTracheaVolume()/1000; // assume mm3, so divide by 1000 to get cc
if (GetWriteStepFlag()) {
if (GetVerboseStepFlag()) {
std::cout << "\t Found trachea with volume " << volume << " cc." << std::endl;
}
- stop = true;
}
else {
if (GetVerboseStepFlag()) {
// empty the list of seed
m_Seeds.clear();
}
+ if (skip > 0.5 * working_input->GetLargestPossibleRegion().GetSize()[2]) {
+ // we want to skip more than a half of the image, it is probably a bug
+ std::cerr << "2 : Number of slices to skip to find trachea too high = " << skip << std::endl;
+ stop = true;
+ }
}
else {
stop = true;
f->SetOpenCloseFlag(mArgsInfo.openclose_flag);
f->SetOpenCloseRadius(mArgsInfo.opencloseRadius_arg);
+ f->SetAutoCrop(!mArgsInfo.noAutoCrop_flag);
if (mArgsInfo.doNotFillHoles_given)
f->SetFillHolesFlag(false);
std::vector<itk::Point<double, Dim-1> > previous;
HypercubeCorners<Dim-1>(previous);
out.resize(previous.size()*2);
- for(uint i=0; i<out.size(); i++) {
+ for(unsigned int i=0; i<out.size(); i++) {
itk::Point<double, Dim> p;
if (i<previous.size()) p[0] = 0;
else p[0] = 1;
std::vector<typename ImageType::PointType> & bounds)
{
// Get image max/min coordinates
- const uint dim=ImageType::ImageDimension;
+ const unsigned int dim=ImageType::ImageDimension;
typedef typename ImageType::PointType PointType;
typedef typename ImageType::IndexType IndexType;
PointType min_c, max_c;
IndexType min_i, max_i;
min_i = image->GetLargestPossibleRegion().GetIndex();
- for(uint i=0; i<dim; i++) max_i[i] = image->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
+ for(unsigned int i=0; i<dim; i++)
+ max_i[i] = image->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
image->TransformIndexToPhysicalPoint(min_i, min_c);
image->TransformIndexToPhysicalPoint(max_i, max_c);
// Get corners coordinates
HypercubeCorners<ImageType::ImageDimension>(bounds);
- for(uint i=0; i<bounds.size(); i++) {
- for(uint j=0; j<dim; j++) {
+ for(unsigned int i=0; i<bounds.size(); i++) {
+ for(unsigned int j=0; j<dim; j++) {
if (bounds[i][j] == 0) bounds[i][j] = min_c[j];
if (bounds[i][j] == 1) bounds[i][j] = max_c[j];
}
ExtractStation_2RL_SetDefaultValues()
{
SetFuzzyThreshold("2RL", "CommonCarotidArtery", 0.7);
- SetFuzzyThreshold("2RL", "BrachioCephalicTrunk", 0.7);
+ SetFuzzyThreshold("2RL", "BrachioCephalicArtery", 0.7);
SetFuzzyThreshold("2RL", "BrachioCephalicVein", 0.3);
SetFuzzyThreshold("2RL", "Aorta", 0.7);
SetFuzzyThreshold("2RL", "SubclavianArteryRight", 0.5);
// -----------------------------------------------------
// Remove Ant to H line from the Ant most part of the
// CommonCarotidArtery until we reach the first slice of
- // BrachioCephalicTrunk
+ // BrachioCephalicArtery
StartNewStep("[Station 2RL] Ant limits with CommonCarotidArtery, H line");
- // First, find the first slice of BrachioCephalicTrunk
- MaskImagePointer BrachioCephalicTrunk = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicTrunk");
- MaskImagePointType p = BrachioCephalicTrunk->GetOrigin(); // initialise to avoid warning
- clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicTrunk, GetBackgroundValue(), 2, false, p);
- double TopOfBrachioCephalicTrunkZ=p[2] + BrachioCephalicTrunk->GetSpacing()[2]; // Add one slice
+ // First, find the first slice of BrachioCephalicArtery
+ MaskImagePointer BrachioCephalicArtery = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicArtery");
+ MaskImagePointType p = BrachioCephalicArtery->GetOrigin(); // initialise to avoid warning
+ clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicArtery, GetBackgroundValue(), 2, false, p);
+ double TopOfBrachioCephalicArteryZ=p[2] + BrachioCephalicArtery->GetSpacing()[2]; // Add one slice
// Remove CommonCarotidArtery below this point
- CommonCarotidArtery = clitk::CropImageBelow<MaskImageType>(CommonCarotidArtery, 2, TopOfBrachioCephalicTrunkZ, true, GetBackgroundValue());
+ CommonCarotidArtery = clitk::CropImageRemoveLowerThan<MaskImageType>(CommonCarotidArtery, 2, TopOfBrachioCephalicArteryZ, true, GetBackgroundValue());
// Find most Ant points
std::vector<MaskImagePointType> ccaAntPositionA;
m_ListOfStations["2L"] = m_Working_Support;
// -----------------------------------------------------
- // Ant limit with the BrachioCephalicTrunk
- StartNewStep("[Station 2RL] Ant limits with BrachioCephalicTrunk line");
+ // Ant limit with the BrachioCephalicArtery
+ StartNewStep("[Station 2RL] Ant limits with BrachioCephalicArtery line");
- // Remove Ant to BrachioCephalicTrunk
+ // Remove Ant to BrachioCephalicArtery
m_Working_Support =
- clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, BrachioCephalicTrunk, 2,
- GetFuzzyThreshold("2RL", "BrachioCephalicTrunk"), "NotAntTo", false, 2, true, false);
+ clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, BrachioCephalicArtery, 2,
+ GetFuzzyThreshold("2RL", "BrachioCephalicArtery"), "NotAntTo", false, 2, true, false);
// End
StopCurrentStep<MaskImageType>(m_Working_Support);
m_ListOfStations["2R"] = m_Working_Support;
m_ListOfStations["2L"] = m_Working_Support;
// -----------------------------------------------------
- // Ant limit with the BrachioCephalicTrunk H line
- StartNewStep("[Station 2RL] Ant limits with BrachioCephalicTrunk, Horizontal line");
+ // Ant limit with the BrachioCephalicArtery H line
+ StartNewStep("[Station 2RL] Ant limits with BrachioCephalicArtery, Horizontal line");
// Find most Ant points
std::vector<MaskImagePointType> bctAntPositionA;
std::vector<MaskImagePointType> bctAntPositionB;
- clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(BrachioCephalicTrunk,
+ clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(BrachioCephalicArtery,
GetBackgroundValue(), 2,
1, true, // Ant
0, // Horizontal line
/* Here, we consider the vessels form a kind of anterior barrier. We
link all vessels centroids and remove what is post to it.
- select the list of structure
- vessel1 = BrachioCephalicTrunk
+ vessel1 = BrachioCephalicArtery
vessel2 = BrachioCephalicVein (warning several CCL, keep most at Right)
vessel3 = CommonCarotidArtery
vessel4 = SubclavianArtery
*/
// Read structures
- MaskImagePointer BrachioCephalicTrunk = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicTrunk");
+ MaskImagePointer BrachioCephalicArtery = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicArtery");
MaskImagePointer BrachioCephalicVein = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicVein");
MaskImagePointer CommonCarotidArtery = GetAFDB()->template GetImage<MaskImageType>("CommonCarotidArtery");
MaskImagePointer SubclavianArtery = GetAFDB()->template GetImage<MaskImageType>("SubclavianArtery");
MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
// Resize all structures like support
- BrachioCephalicTrunk =
- clitk::ResizeImageLike<MaskImageType>(BrachioCephalicTrunk, m_Working_Support, GetBackgroundValue());
+ BrachioCephalicArtery =
+ clitk::ResizeImageLike<MaskImageType>(BrachioCephalicArtery, m_Working_Support, GetBackgroundValue());
CommonCarotidArtery =
clitk::ResizeImageLike<MaskImageType>(CommonCarotidArtery, m_Working_Support, GetBackgroundValue());
SubclavianArtery =
clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
// Extract slices
- std::vector<MaskSlicePointer> slices_BrachioCephalicTrunk;
- clitk::ExtractSlices<MaskImageType>(BrachioCephalicTrunk, 2, slices_BrachioCephalicTrunk);
+ std::vector<MaskSlicePointer> slices_BrachioCephalicArtery;
+ clitk::ExtractSlices<MaskImageType>(BrachioCephalicArtery, 2, slices_BrachioCephalicArtery);
std::vector<MaskSlicePointer> slices_BrachioCephalicVein;
clitk::ExtractSlices<MaskImageType>(BrachioCephalicVein, 2, slices_BrachioCephalicVein);
std::vector<MaskSlicePointer> slices_CommonCarotidArtery;
clitk::ExtractSlices<MaskImageType>(Aorta, 2, slices_Aorta);
std::vector<MaskSlicePointer> slices_Trachea;
clitk::ExtractSlices<MaskImageType>(Trachea, 2, slices_Trachea);
- uint n= slices_BrachioCephalicTrunk.size();
+ unsigned int n= slices_BrachioCephalicArtery.size();
// Get the boundaries of one slice
std::vector<MaskSlicePointType> bounds;
- ComputeImageBoundariesCoordinates<MaskSliceType>(slices_BrachioCephalicTrunk[0], bounds);
+ ComputeImageBoundariesCoordinates<MaskSliceType>(slices_BrachioCephalicArtery[0], bounds);
// For all slices, for all structures, find the centroid and build the contour
// List of 3D points (for debug)
std::vector<MaskImagePointType> p3D;
vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::New();
- for(uint i=0; i<n; i++) {
+ for(unsigned int i=0; i<n; i++) {
// Labelize the slices
slices_CommonCarotidArtery[i] = Labelize<MaskSliceType>(slices_CommonCarotidArtery[i],
GetBackgroundValue(), true, 1);
slices_SubclavianArtery[i] = Labelize<MaskSliceType>(slices_SubclavianArtery[i],
GetBackgroundValue(), true, 1);
- slices_BrachioCephalicTrunk[i] = Labelize<MaskSliceType>(slices_BrachioCephalicTrunk[i],
+ slices_BrachioCephalicArtery[i] = Labelize<MaskSliceType>(slices_BrachioCephalicArtery[i],
GetBackgroundValue(), true, 1);
slices_BrachioCephalicVein[i] = Labelize<MaskSliceType>(slices_BrachioCephalicVein[i],
GetBackgroundValue(), true, 1);
std::vector<MaskSlicePointType> centroids6;
ComputeCentroids<MaskSliceType>(slices_CommonCarotidArtery[i], GetBackgroundValue(), centroids1);
ComputeCentroids<MaskSliceType>(slices_SubclavianArtery[i], GetBackgroundValue(), centroids2);
- ComputeCentroids<MaskSliceType>(slices_BrachioCephalicTrunk[i], GetBackgroundValue(), centroids3);
+ ComputeCentroids<MaskSliceType>(slices_BrachioCephalicArtery[i], GetBackgroundValue(), centroids3);
ComputeCentroids<MaskSliceType>(slices_Thyroid[i], GetBackgroundValue(), centroids4);
ComputeCentroids<MaskSliceType>(slices_Aorta[i], GetBackgroundValue(), centroids5);
ComputeCentroids<MaskSliceType>(slices_BrachioCephalicVein[i], GetBackgroundValue(), centroids6);
}
// BrachioCephalicVein -> when SubclavianArtery has 2 CCL
- // (BrachioCephalicTrunk is divided) -> forget BrachioCephalicVein
+ // (BrachioCephalicArtery is divided) -> forget BrachioCephalicVein
if ((centroids3.size() ==1) && (centroids2.size() > 2)) {
centroids6.clear();
}
- for(uint j=1; j<centroids1.size(); j++) points2D.push_back(centroids1[j]);
- for(uint j=1; j<centroids2.size(); j++) points2D.push_back(centroids2[j]);
- for(uint j=1; j<centroids3.size(); j++) points2D.push_back(centroids3[j]);
- for(uint j=1; j<centroids4.size(); j++) points2D.push_back(centroids4[j]);
- for(uint j=1; j<centroids5.size(); j++) points2D.push_back(centroids5[j]);
- for(uint j=1; j<centroids6.size(); j++) points2D.push_back(centroids6[j]);
+ for(unsigned int j=1; j<centroids1.size(); j++) points2D.push_back(centroids1[j]);
+ for(unsigned int j=1; j<centroids2.size(); j++) points2D.push_back(centroids2[j]);
+ for(unsigned int j=1; j<centroids3.size(); j++) points2D.push_back(centroids3[j]);
+ for(unsigned int j=1; j<centroids4.size(); j++) points2D.push_back(centroids4[j]);
+ for(unsigned int j=1; j<centroids5.size(); j++) points2D.push_back(centroids5[j]);
+ for(unsigned int j=1; j<centroids6.size(); j++) points2D.push_back(centroids6[j]);
// Sort by angle according to trachea centroid and vertical line,
// in polar coordinates :
ComputeCentroids<MaskSliceType>(slices_Trachea[i], GetBackgroundValue(), centroids_trachea);
typedef std::pair<MaskSlicePointType, double> PointAngleType;
std::vector<PointAngleType> angles;
- for(uint j=0; j<points2D.size(); j++) {
+ for(unsigned int j=0; j<points2D.size(); j++) {
//double r = centroids_trachea[1].EuclideanDistanceTo(points2D[j]);
double x = (points2D[j][0]-centroids_trachea[1][0]); // X : Right to Left
double y = (centroids_trachea[1][1]-points2D[j][1]); // Y : Post to Ant
// Sort points2D according to polar angles
std::sort(angles.begin(), angles.end(), comparePointsWithAngle<PointAngleType>());
- for(uint j=0; j<angles.size(); j++) {
+ for(unsigned int j=0; j<angles.size(); j++) {
points2D[j] = angles[j].first;
}
// DDV(points2D, points2D.size());
low, add one point
*/
std::vector<MaskSlicePointType> toadd;
- uint index = 0;
+ unsigned int index = 0;
double dmax = 5;
while (index<points2D.size()-1) {
MaskSlicePointType a = points2D[index];
// Build 3D points from the 2D points
std::vector<ImagePointType> points3D;
clitk::PointsUtils<MaskImageType>::Convert2DListTo3DList(points2D, i, m_Working_Support, points3D);
- for(uint x=0; x<points3D.size(); x++) p3D.push_back(points3D[x]);
+ for(unsigned int x=0; x<points3D.size(); x++) p3D.push_back(points3D[x]);
// Build the mesh from the contour's points
vtkSmartPointer<vtkPolyData> mesh = Build3DMeshFrom2DContour(points3D);
SetFuzzyThreshold("7", "RightPulmonaryArtery", 0.3);
SetFuzzyThreshold("7", "LeftPulmonaryArtery", 0.5);
SetFuzzyThreshold("7", "SVC", 0.2);
+ SetS7_UseMostInferiorPartOnlyFlag(false);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_7() {
+ if (CheckForStation("7")) {
+ ExtractStation_7_SI_Limits();
+ ExtractStation_7_RL_Interior_Limits();
+
+ // ExtractStation_7_Posterior_Limits();
+ ExtractStation_8_Single_CCL_Limits();
+ ExtractStation_7_Remove_Structures();
+ // Store image filenames into AFDB
+ writeImage<MaskImageType>(m_ListOfStations["7"], "seg/Station7.mhd");
+ GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd");
+ WriteAFDB();
+ }
}
//--------------------------------------------------------------------
clitk::ExtractLymphStationsFilter<TImageType>::
ExtractStation_7_SI_Limits()
{
- StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus");
+ StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLL-RMLBronchus");
// Get Inputs
MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");
+
+ // Create line from A to B with
+ // A = upper border of LLL at left
+ // B = lower border of bronchus intermedius (BI) or RightMiddleLobeBronchus
+ ImagePointType A;
+ ImagePointType B;
+ FindLineForS7S8Separation(A, B);
+
+ // // if option -> replace A[0] with B[0]
+ // if (GetS7_UseMostInferiorPartOnlyFlag()) {
+ // A[0] = B[0];
+ // }
+
+ // Use line to remove the inferior part
+ m_Working_Support =
+ SliceBySliceSetBackgroundFromSingleLine<MaskImageType>(m_Working_Support, GetBackgroundValue(),
+ A, B, 2, 0, false);
+
+ // Get the CarinaZ position
+ m_CarinaZ = FindCarinaSlicePosition();
- // We suppoe that CarinaZ was already computed (S8)
- double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ");
+ // Crop support
+ m_Working_Support =
+ clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2,
+ A[2], m_CarinaZ, true,
+ GetBackgroundValue());
+ // Crop trachea
+ m_Working_Trachea =
+ clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2,
+ A[2], m_CarinaZ, true,
+ GetBackgroundValue());
- // double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2);
- // DD(m_OriginOfRightMiddleLobeBronchusZ);
- MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage<MaskImageType>("UpperBorderOfLLLBronchus");
+ StopCurrentStep<MaskImageType>(m_Working_Support);
+ m_ListOfStations["7"] = m_Working_Support;
+}
+//--------------------------------------------------------------------
- // Search most inf point (WHY ? IS IT THE RIGHT STRUCTURE ??)
- MaskImagePointType ps = UpperBorderOfLLLBronchus->GetOrigin(); // initialise to avoid warning
- clitk::FindExtremaPointInAGivenDirection<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), 2, true, ps);
- double m_UpperBorderOfLLLBronchusZ = ps[2];
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_7_RL_Interior_Limits()
+{
+ // ----------------------------------------------------------------
+ StartNewStep("[Station7] RL limits with bronchi");
+
/*
- std::vector<MaskImagePointType> centroids;
- clitk::ComputeCentroids<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids);
- double m_UpperBorderOfLLLBronchusZ = centroids[1][2];
- DD(m_UpperBorderOfLLLBronchusZ)
+ Slice by Slice, consider most Left point of the Right
+ bronchus. Remove the Ant/Right corner
*/
- /* Crop support */
+ // First consider bronchi
+ FindLeftAndRightBronchi();
+ m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
+ m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
+
+ // Resize like m_Working_Support
+ m_LeftBronchus =
+ clitk::ResizeImageLike<MaskImageType>(m_LeftBronchus, m_Working_Support, GetBackgroundValue());
+ m_RightBronchus =
+ clitk::ResizeImageLike<MaskImageType>(m_RightBronchus, m_Working_Support, GetBackgroundValue());
+
+ // Extract slices, Label, compute centroid, keep most central connected component
+ std::vector<MaskSlicePointer> slices_leftbronchus;
+ std::vector<MaskSlicePointer> slices_rightbronchus;
+ std::vector<MaskSlicePointer> slices_support;
+ clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
+ clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
+ clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices_support);
+
+ // Keep only the CCL of the bronchus with the closest to the center
+ // Loop on slices for left bronchus
+ for(uint i=0; i<slices_leftbronchus.size(); i++) {
+ slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
+ std::vector<typename MaskSliceType::PointType> c;
+ clitk::ComputeCentroids<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), c);
+ if (c.size() > 1) {
+ double most_at_left = c[1][0];
+ int most_at_left_index=1;
+ for(uint j=1; j<c.size(); j++) {
+ if (c[j][0] < most_at_left) {
+ most_at_left = c[j][0];
+ most_at_left_index = j;
+ }
+ }
+ // Put all other CCL to Background
+ slices_leftbronchus[i] =
+ clitk::Binarize<MaskSliceType>(slices_leftbronchus[i], most_at_left_index,
+ most_at_left_index, GetBackgroundValue(), GetForegroundValue());
+ } // end c.size
+ }
+
+ // Loop on slices for right bronchus
+ for(uint i=0; i<slices_rightbronchus.size(); i++) {
+ slices_rightbronchus[i] = Labelize<MaskSliceType>(slices_rightbronchus[i], 0, false, 10);
+ std::vector<typename MaskSliceType::PointType> c;
+ clitk::ComputeCentroids<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), c);
+ if (c.size() > 1) {
+ double most_at_right = c[1][0];
+ int most_at_right_index=1;
+ for(uint j=1; j<c.size(); j++) {
+ if (c[j][0] > most_at_right) {
+ most_at_right = c[j][0];
+ most_at_right_index = j;
+ }
+ }
+ // Put all other CCL to Background
+ slices_rightbronchus[i] =
+ clitk::Binarize<MaskSliceType>(slices_rightbronchus[i], most_at_right_index,
+ most_at_right_index, GetBackgroundValue(), GetForegroundValue());
+ } // end c.size
+ }
+
+ // Joint slices
+ m_LeftBronchus = clitk::JoinSlices<MaskImageType>(slices_leftbronchus, m_LeftBronchus, 2);
+ m_RightBronchus = clitk::JoinSlices<MaskImageType>(slices_rightbronchus, m_RightBronchus, 2);
+
+ // For Right bronchus, Find most Left point. Remove corner Ant/Right corner
+ for(uint i=0; i<slices_rightbronchus.size(); i++) {
+ // Find most point most at left
+ MaskSlicePointType p_left;
+ MaskSlicePointType p_post;
+ bool b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 0, false, p_left);
+ if (b) {
+ b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 1, false, p_post);
+ }
+ if (b) {
+ MaskSlicePointType p = p_left;
+ p[1] = p_post[1];
+ MaskSliceIndexType pi;
+ slices_rightbronchus[i]->TransformPhysicalPointToIndex(p, pi);
+
+ // Build region to remove
+ MaskSliceRegionType region = slices_rightbronchus[i]->GetLargestPossibleRegion();
+ MaskSliceIndexType index = region.GetIndex();
+ MaskSliceSizeType size = region.GetSize();
+ size[0] = pi[0] - index[0];
+ size[1] = pi[1] - index[1];
+ region.SetSize(size);
+
+ // Fill region with Background value
+ clitk::FillRegionWithValue<MaskSliceType>(slices_support[i], GetBackgroundValue(), region);
+ }
+ }
+
+ // For Left bronchus, Find most Right point. Remove corner Ant/Left corner
+ for(uint i=0; i<slices_leftbronchus.size(); i++) {
+ // Find most point most at right
+ MaskSlicePointType p_right;
+ MaskSlicePointType p_post;
+ bool b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), 0, true, p_right);
+ if (b) {
+ b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 1, false, p_post);
+ }
+ if (b) {
+ MaskSlicePointType p = p_right;
+ p[1] = p_post[1];
+ MaskSliceIndexType pi;
+ slices_leftbronchus[i]->TransformPhysicalPointToIndex(p, pi);
+
+ /* typedef itk::ImageRegionIterator<ImageType> IteratorType;
+ IteratorType iter(input, region);
+ iter.GoToBegin();
+ while (!iter.IsAtEnd()) {
+ MaskSliceIndexType index = iter.GetIndex();
+ if (index[0] > pi[0]) && (index[1] > pi[1]) iter.Set(GetBackgroundValue());
+
+ ++iter;
+ }
+ */
+
+
+ // Build region to remove
+ MaskSliceRegionType region = slices_leftbronchus[i]->GetLargestPossibleRegion();
+ MaskSliceIndexType index = region.GetIndex();
+ MaskSliceSizeType size = region.GetSize();
+ index[0] = pi[0];
+ size[0] = slices_leftbronchus[i]->GetLargestPossibleRegion().GetSize()[0] - pi[0];
+ size[1] = pi[1] - index[1];
+ region.SetSize(size);
+ region.SetIndex(index);
+
+ // Fill region with Background value
+ clitk::FillRegionWithValue<MaskSliceType>(slices_support[i], GetBackgroundValue(), region);
+ }
+ }
+
+ m_Working_Support = clitk::JoinSlices<MaskImageType>(slices_support, m_Working_Support, 2);
+
+ // Also remove what is at right of the Right bronchus (left respectively)
m_Working_Support =
- clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2,
- m_UpperBorderOfLLLBronchusZ,
- m_CarinaZ, true,
- GetBackgroundValue());
- /* Crop trachea */
- m_Working_Trachea =
- clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2,
- m_UpperBorderOfLLLBronchusZ,
- m_CarinaZ, true,
- GetBackgroundValue());
+ clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_LeftBronchus, 2,
+ GetFuzzyThreshold("7", "Bronchi"), "NotLeftTo",
+ false, 3, false);
+ m_Working_Support =
+ clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_RightBronchus, 2,
+ GetFuzzyThreshold("7", "Bronchi"), "NotRightTo",
+ false, 3, false);
+
+ // SECOND PART
StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["7"] = m_Working_Support;
}
//--------------------------------------------------------------------
template <class TImageType>
void
clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_7_RL_Limits()
+ExtractStation_7_RL_Limits_OLD()
{
// ----------------------------------------------------------------
StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus");
clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
+ // Version #1 with limit = centroid of the bronchus (OUTDATED)
+ // Step1 = keep only the CCL of the bronchus with the closest to the center
+ // Step2 = SliceBySlice Rel pos to both bronchi
+
// Loop on slices
for(uint i=0; i<slices_leftbronchus.size(); i++) {
slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
Remove_Structures("7", "AzygousVein");
Remove_Structures("7", "Aorta");
- Remove_Structures("7", "Esophagus");
Remove_Structures("7", "RightPulmonaryArtery");
Remove_Structures("7", "LeftPulmonaryArtery");
Remove_Structures("7", "LeftSuperiorPulmonaryVein");
Remove_Structures("7", "PulmonaryTrunk");
Remove_Structures("7", "VertebralBody");
+ // Keep only one CCL by slice (before removing Esophagus)
+ // DD("SliceBySliceKeepMainCCL");
+
+ // TODO -> replace by keep the one that contains point at the middle of the line between the bronchus
+ // -> new function "keep/select" the ccl that contains this point (2D)
+
+ //m_Working_Support = clitk::SliceBySliceKeepMainCCL<MaskImageType>(m_Working_Support, GetBackgroundValue(), GetForegroundValue());
+
+ Remove_Structures("7", "Esophagus");
+
// END
StopCurrentStep<MaskImageType>(m_Working_Support);
m_ListOfStations["7"] = m_Working_Support;
clitk::ExtractLymphStationsFilter<ImageType>::
ExtractStation_8_SetDefaultValues()
{
- SetDistanceMaxToAnteriorPartOfTheSpine(10);
MaskImagePointType p;
p[0] = 15; p[1] = 2; p[2] = 1;
SetEsophagusDiltationForAnt(p);
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_8()
+{
+ if (CheckForStation("8")) {
+ ExtractStation_8_SI_Limits(); // OK, validated
+ ExtractStation_8_Ant_Limits(); // OK, validated
+ ExtractStation_8_Left_Sup_Limits(); // OK, validated
+ ExtractStation_8_Left_Inf_Limits(); // OK, validated
+ ExtractStation_8_Single_CCL_Limits(); // OK, validated
+ ExtractStation_8_Remove_Structures(); // OK, validated
+
+ // Store image filenames into AFDB
+ writeImage<MaskImageType>(m_ListOfStations["8"], "seg/Station8.mhd");
+ GetAFDB()->SetImageFilename("Station8", "seg/Station8.mhd");
+ WriteAFDB();
+ }
+}
+//--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
template <class ImageType>
void
left; the lower border of the bronchus intermedius on the right"
*/
- StartNewStep("[Station8] Inf/Sup mediastinum limits with carina/diaphragm junction");
-
- // Get Carina Z position
- MaskImagePointer Carina = GetAFDB()->template GetImage<MaskImageType>("Carina");
+ StartNewStep("[Station8] Sup/Inf limits with LeftLower/RightMiddle Lobe and diaphragm");
- std::vector<MaskImagePointType> centroids;
- clitk::ComputeCentroids<MaskImageType>(Carina, GetBackgroundValue(), centroids);
- m_CarinaZ = centroids[1][2];
- // DD(m_CarinaZ);
- // add one slice to include carina ?
- m_CarinaZ += m_Mediastinum->GetSpacing()[2];
- // We dont need Carina structure from now
- Carina->Delete();
- GetAFDB()->SetDouble("CarinaZ", m_CarinaZ);
+ /* -----------------------------------------------
+ NEW SUPERIOR LIMIT = LeftLowerLobeBronchus /
+ RightMiddleLobeBronchus See FindLineForS7S8Separation
+ -----------------------------------------------
+ */
+ ImagePointType A;
+ ImagePointType B;
+ FindLineForS7S8Separation(A, B);
+
+ // add one slice to be adjacent to Station7
+ B[2] += m_Working_Support->GetSpacing()[2];
+ A[2] += m_Working_Support->GetSpacing()[2];
+
+ // Use the line to remove the inferior part
+ m_Working_Support =
+ SliceBySliceSetBackgroundFromSingleLine<MaskImageType>(m_Working_Support,
+ GetBackgroundValue(), A, B, 2, 0, true);
+ /* -----------------------------------------------
+ INFERIOR LIMIT = Diaphragm
+ -----------------------------------------------
+ */
+
// Found most inferior part of the lung
MaskImagePointer Lungs = GetAFDB()->template GetImage<MaskImageType>("Lungs");
// It should be already croped, so I took the origin and add 10mm above
m_DiaphragmInferiorLimit = Lungs->GetOrigin()[2]+10;
- // Lungs->Delete(); // we don't need it, release memory -> it we want to release, also free in AFDB
- clitk::PrintMemory(GetVerboseMemoryFlag(), "after reading lungs");
GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
- clitk::PrintMemory(GetVerboseMemoryFlag(), "after release lungs");
- /* Crop support :
- Superior limit = carina
- Inferior limit = DiaphragmInferiorLimit (old=Gastroesphogeal junction) */
m_Working_Support =
clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2,
- m_DiaphragmInferiorLimit, //GOjunctionZ,
- m_CarinaZ, true,
+ m_DiaphragmInferiorLimit,
+ B[2], true,
GetBackgroundValue());
-
- // Remove some structures that we know are excluded
- MaskImagePointer VertebralBody =
- GetAFDB()->template GetImage <MaskImageType>("VertebralBody");
- MaskImagePointer Aorta =
- GetAFDB()->template GetImage <MaskImageType>("Aorta");
-
- typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
- typename BoolFilterType::Pointer boolFilter = BoolFilterType::New();
- boolFilter->InPlaceOn();
- boolFilter->SetInput1(m_Working_Support);
- boolFilter->SetInput2(VertebralBody);
- boolFilter->SetOperationType(BoolFilterType::AndNot);
- boolFilter->Update();
- /*
-
- DO NOT REMOVE AORTA YET (LATER)
-
- boolFilter->SetInput1(boolFilter->GetOutput());
- boolFilter->SetInput2(Aorta);
- boolFilter->SetOperationType(BoolFilterType::AndNot);
- boolFilter->Update();
- */
- m_Working_Support = boolFilter->GetOutput();
-
// Done.
StopCurrentStep<MaskImageType>(m_Working_Support);
m_ListOfStations["8"] = m_Working_Support;
template <class ImageType>
void
clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Post_Limits()
-{
- /*
- Station 8: paraeosphageal nodes
-
- Anteriorly, it is in contact with Station 7 and the
- left main stem bronchus in its superior aspect (Fig. 3C–H) and
- with the heart more inferiorly. Posteriorly, Station 8 abuts the
- descending aorta and the anterior aspect of the vertebral body
- until an imaginary horizontal line running 1 cm posterior to the
- anterior border of the vertebral body (Fig. 3C).
-
- New classification IASCL 2009 :
-
- "Nodes lying adjacent to the wall of the esophagus and to the
- right or left of the midline, excluding subcarinal nodes (S7)
- Upper"
-
- */
-
- StartNewStep("[Station8] Post limits with vertebral body");
- MaskImagePointer VertebralBody =
- GetAFDB()->template GetImage <MaskImageType>("VertebralBody");
-
- // Consider vertebral body slice by slice
- typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
- typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
- typedef typename ExtractSliceFilterType::SliceType SliceType;
- std::vector<typename SliceType::Pointer> vertebralSlices;
- extractSliceFilter->SetInput(VertebralBody);
- extractSliceFilter->SetDirection(2);
- extractSliceFilter->Update();
- extractSliceFilter->GetOutputSlices(vertebralSlices);
-
- // For each slice, compute the most anterior point
- std::map<int, typename SliceType::PointType> vertebralAntPositionBySlice;
- for(uint i=0; i<vertebralSlices.size(); i++) {
- typename SliceType::PointType p;
- bool found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vertebralSlices[i],
- GetBackgroundValue(),
- 1, true, p);
- if (found) {
- vertebralAntPositionBySlice[i] = p;
- }
- else {
- // no Foreground in this slice (it appends generally at the
- // beginning and the end of the volume). Do nothing in this
- // case.
- }
- }
-
- // Convert 2D points in slice into 3D points
- std::vector<MaskImagePointType> vertebralAntPositions;
- clitk::PointsUtils<MaskImageType>::Convert2DMapTo3DList(vertebralAntPositionBySlice,
- VertebralBody,
- vertebralAntPositions);
-
- // DEBUG : write list of points
- clitk::WriteListOfLandmarks<MaskImageType>(vertebralAntPositions,
- "S8-vertebralMostAntPositions-points.txt");
-
- // Cut support posteriorly 1cm the most anterior point of the
- // VertebralBody. Do nothing below and above the VertebralBody. To
- // do that compute several region, slice by slice and fill.
- MaskImageRegionType region;
- MaskImageSizeType size;
- MaskImageIndexType start;
- size[2] = 1; // a single slice
- start[0] = m_Working_Support->GetLargestPossibleRegion().GetIndex()[0];
- size[0] = m_Working_Support->GetLargestPossibleRegion().GetSize()[0];
- for(uint i=0; i<vertebralAntPositions.size(); i++) {
- typedef typename itk::ImageRegionIterator<MaskImageType> IteratorType;
- IteratorType iter =
- IteratorType(m_Working_Support, m_Working_Support->GetLargestPossibleRegion());
- MaskImageIndexType index;
- // Consider some cm posterior to most anterior positions (usually
- // 1 cm).
- vertebralAntPositions[i][1] += GetDistanceMaxToAnteriorPartOfTheSpine();
- // Get index of this point
- m_Working_Support->TransformPhysicalPointToIndex(vertebralAntPositions[i], index);
- // Compute region (a single slice)
- start[2] = index[2];
- start[1] = m_Working_Support->GetLargestPossibleRegion().GetIndex()[1]+index[1];
- size[1] = m_Working_Support->GetLargestPossibleRegion().GetSize()[1]-start[1];
- region.SetSize(size);
- region.SetIndex(start);
- // Fill region
- if (m_Working_Support->GetLargestPossibleRegion().IsInside(start)) {
- itk::ImageRegionIterator<MaskImageType> it(m_Working_Support, region);
- it.GoToBegin();
- while (!it.IsAtEnd()) {
- it.Set(GetBackgroundValue());
- ++it;
- }
- }
- }
-
- StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Ant_Sup_Limits()
+ExtractStation_8_Ant_Limits()
{
- //--------------------------------------------------------------------
- StartNewStep("[Station8] Ant limits with S7 above Carina");
- /*
- Anteriorly, it is in contact with Station 7 and the
- left main stem bronchus in its superior aspect (Fig. 3C–H) and
- with the heart more inferiorly.
-
- 1) line post wall bronchi (S7), till originRMLB
- - LUL bronchus : to detect in trachea. But not needed here ??
- 2) heart ! -> not delineated.
- ==> below S7, crop CT not to far away (ant), then try with threshold
-
- 1) ==> how to share with S7 ? Prepare both support at the same time !
- NEED vector of initial support for each station ? No -> map if it exist before, take it !!
-
- */
-
- // Ant limit from carina (start) to end of S7 = originRMLB
- // Get Trachea
- MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
-
- MaskImagePointer m_Working_Trachea =
- clitk::CropImageAbove<MaskImageType>(Trachea, 2, m_CarinaZ, true, // AutoCrop
- GetBackgroundValue());
-
- // Seprate into two main bronchi
- MaskImagePointer RightBronchus;
- MaskImagePointer LeftBronchus;
-
- // Labelize and consider the two first (main) labels
- m_Working_Trachea = Labelize<MaskImageType>(m_Working_Trachea, 0, true, 1);
-
- // Carina position must at the first slice that separate the two
- // main bronchus (not superiorly). We thus first check that the
- // upper slice is composed of at least two labels
- typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
- SliceIteratorType iter(m_Working_Trachea, m_Working_Trachea->GetLargestPossibleRegion());
- iter.SetFirstDirection(0);
- iter.SetSecondDirection(1);
- iter.GoToReverseBegin(); // Start from the end (because image is IS not SI)
- int maxLabel=0;
- while (!iter.IsAtReverseEndOfSlice()) {
- while (!iter.IsAtReverseEndOfLine()) {
- if (iter.Get() > maxLabel) maxLabel = iter.Get();
- --iter;
- }
- iter.PreviousLine();
- }
- if (maxLabel < 2) {
- clitkExceptionMacro("First slice form Carina does not seems to seperate the two main bronchus. Abort");
- }
-
- // Compute 3D centroids of both parts to identify the left from the
- // right bronchus
- std::vector<ImagePointType> c;
- clitk::ComputeCentroids<MaskImageType>(m_Working_Trachea, GetBackgroundValue(), c);
- ImagePointType C1 = c[1];
- ImagePointType C2 = c[2];
-
- ImagePixelType rightLabel;
- ImagePixelType leftLabel;
- if (C1[0] < C2[0]) { rightLabel = 1; leftLabel = 2; }
- else { rightLabel = 2; leftLabel = 1; }
-
- // Select LeftLabel (set one label to Backgroundvalue)
- RightBronchus =
- clitk::Binarize<MaskImageType>(m_Working_Trachea, rightLabel, rightLabel,
- GetBackgroundValue(), GetForegroundValue());
- /*
- SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea,
- leftLabel, GetBackgroundValue(), false);
- */
- LeftBronchus = clitk::Binarize<MaskImageType>(m_Working_Trachea, leftLabel, leftLabel,
- GetBackgroundValue(), GetForegroundValue());
- /*
- SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea,
- rightLabel, GetBackgroundValue(), false);
- */
-
- // Crop images
- RightBronchus = clitk::AutoCrop<MaskImageType>(RightBronchus, GetBackgroundValue());
- LeftBronchus = clitk::AutoCrop<MaskImageType>(LeftBronchus, GetBackgroundValue());
-
- // Insert int AFDB if need after
- GetAFDB()->template SetImage <MaskImageType>("RightBronchus", "seg/rightBronchus.mhd",
- RightBronchus, true);
- GetAFDB()->template SetImage <MaskImageType>("LeftBronchus", "seg/leftBronchus.mhd",
- LeftBronchus, true);
-
- // Now crop below OriginOfRightMiddleLobeBronchusZ
- // It is not done before to keep entire bronchi.
-
- MaskImagePointer OriginOfRightMiddleLobeBronchus =
- GetAFDB()->template GetImage<MaskImageType>("OriginOfRightMiddleLobeBronchus");
- std::vector<MaskImagePointType> centroids;
- clitk::ComputeCentroids<MaskImageType>(OriginOfRightMiddleLobeBronchus, GetBackgroundValue(), centroids);
- m_OriginOfRightMiddleLobeBronchusZ = centroids[1][2];
- // add one slice to include carina ?
- m_OriginOfRightMiddleLobeBronchusZ += RightBronchus->GetSpacing()[2];
- // We dont need Carina structure from now
- OriginOfRightMiddleLobeBronchus->Delete();
-
- RightBronchus =
- clitk::CropImageBelow<MaskImageType>(RightBronchus, 2,
- m_OriginOfRightMiddleLobeBronchusZ,
- true, // AutoCrop
- GetBackgroundValue());
- LeftBronchus =
- clitk::CropImageBelow<MaskImageType>(LeftBronchus, 2,
- m_OriginOfRightMiddleLobeBronchusZ,
- true, // AutoCrop
- GetBackgroundValue());
-
- // Search for points that are the most left/post/ant and most
- // right/post/ant of the left and right bronchus
- // 15 = not 15 mm more distance than the middle point.
- FindExtremaPointsInBronchus(RightBronchus, 0, 10, m_LeftMostInRightBronchus,
- m_AntMostInRightBronchus, m_PostMostInRightBronchus);
-
- FindExtremaPointsInBronchus(LeftBronchus, 1, 10, m_RightMostInLeftBronchus,
- m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
-
- // DEBUG : write the list of points
- ListOfPointsType v;
- v.reserve(m_LeftMostInRightBronchus.size()+m_AntMostInRightBronchus.size()+
- m_PostMostInRightBronchus.size());
- v.insert(v.end(), m_LeftMostInRightBronchus.begin(), m_LeftMostInRightBronchus.end() );
- v.insert(v.end(), m_AntMostInRightBronchus.begin(), m_AntMostInRightBronchus.end() );
- v.insert(v.end(), m_PostMostInRightBronchus.begin(), m_PostMostInRightBronchus.end() );
- clitk::WriteListOfLandmarks<MaskImageType>(v, "S8-RightBronchus-points.txt");
-
- v.clear();
- v.reserve(m_RightMostInLeftBronchus.size()+m_AntMostInLeftBronchus.size()+
- m_PostMostInLeftBronchus.size());
- v.insert(v.end(), m_RightMostInLeftBronchus.begin(), m_RightMostInLeftBronchus.end() );
- v.insert(v.end(), m_AntMostInLeftBronchus.begin(), m_AntMostInLeftBronchus.end() );
- v.insert(v.end(), m_PostMostInLeftBronchus.begin(), m_PostMostInLeftBronchus.end() );
- clitk::WriteListOfLandmarks<MaskImageType>(v, "S8-LeftBronchus-points.txt");
-
- v.clear();
- v.reserve(m_PostMostInLeftBronchus.size()+m_PostMostInRightBronchus.size());
- v.insert(v.end(), m_PostMostInLeftBronchus.begin(), m_PostMostInLeftBronchus.end() );
- v.insert(v.end(), m_PostMostInRightBronchus.begin(), m_PostMostInRightBronchus.end() );
- clitk::WriteListOfLandmarks<MaskImageType>(v, "S8-RightLeftBronchus-points.txt");
-
-
- // Now uses these points to limit, slice by slice
- // line is mainly horizontal, so mainDirection=1
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- m_PostMostInRightBronchus,
- m_PostMostInLeftBronchus,
- GetBackgroundValue(), 1, 10);
-
- // Keep main 3D CCL :
- m_Working_Support = Labelize<MaskImageType>(m_Working_Support, 0, false, 10);
- m_Working_Support = KeepLabels<MaskImageType>(m_Working_Support,
- GetBackgroundValue(),
- GetForegroundValue(), 1, 1, true);
-
- // Autocrop
- m_Working_Support = clitk::AutoCrop<MaskImageType>(m_Working_Support, GetBackgroundValue());
-
- // End of step
- StopCurrentStep<MaskImageType>(m_Working_Support);
- // m_ListOfStations["8"] = m_Working_Support;
-
-}
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Ant_Inf_Limits()
-{
-
//--------------------------------------------------------------------
StartNewStep("[Station8] Ant part: not post to Esophagus");
/*
// Get Esophagus
m_Esophagus = GetAFDB()->template GetImage<MaskImageType>("Esophagus");
- clitk::PrintMemory(GetVerboseMemoryFlag(), "after read Esophagus");
// In images from the original article, Atlas – UM, the oesophagus
//was included in nodal stations 3p and 8. Having said that, in the
//prospective, the oesophagus should be excluded from these nodal
//stations.
- /* NOT YET !! DO IT LATER
-
- typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
- typename BoolFilterType::Pointer boolFilter = BoolFilterType::New();
- boolFilter->InPlaceOn();
- boolFilter->SetInput1(m_Working_Support);
- boolFilter->SetInput2(m_Esophagus);
- boolFilter->SetOperationType(BoolFilterType::AndNot);
- boolFilter->Update();
- m_Working_Support = boolFilter->GetOutput();
-
- */
-
- // Crop Esophagus : keep only below the OriginOfRightMiddleLobeBronchusZ
+ // Resize Esophagus like current support
m_Esophagus =
- clitk::CropImageAbove<MaskImageType>(m_Esophagus, 2,
- m_OriginOfRightMiddleLobeBronchusZ,
- true, // AutoCrop
- GetBackgroundValue());
+ clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue()); // Needed ?
// Dilate to keep only not Anterior positions
MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
-
- // m_Esophagus = EnlargeEsophagusDilatationRadiusInferiorly(m_Esophagus);
-
m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus,
radiusInMM,
GetBackgroundValue(),
GetForegroundValue(), true);
-
- // Remove Anterior part according to this dilatated esophagus. Note:
- // because we crop Esophagus with ORML, the support will also be
- // croped in the same way. Here it is a desired feature. If we dont
- // want, use SetIgnoreEmptySliceObject(true)
-
- // In the new IASCL definition, it is not clear if sup limits is
- // around carina or On the right, it is “the lower border of the
- // bronchus intermedius”, indicated on the image set as a point
- // (“lower border of the bronchus intermedius”)
-
+ // Keep what is Posterior to Esophagus
typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> RelPosFilterType;
typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
relPosFilter->VerboseStepFlagOff();
template <class ImageType>
void
clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Ant_Injected_Limits()
+ExtractStation_8_Left_Sup_Limits()
{
-
//--------------------------------------------------------------------
- StartNewStep("[Station8] Ant part (remove high density, injected part)");
-
- // Consider initial image, crop to current support
- ImagePointer working_input =
- clitk::ResizeImageLike<ImageType>(m_Input,
- m_Working_Support,
- (short)GetBackgroundValue());
-
- // Threshold
- typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> BinarizeFilterType;
- typename BinarizeFilterType::Pointer binarizeFilter = BinarizeFilterType::New();
- binarizeFilter->SetInput(working_input);
- binarizeFilter->SetLowerThreshold(GetInjectedThresholdForS8());
- binarizeFilter->SetInsideValue(GetForegroundValue());
- binarizeFilter->SetOutsideValue(GetBackgroundValue());
- binarizeFilter->Update();
- MaskImagePointer injected = binarizeFilter->GetOutput();
-
- // Combine with current support
- clitk::AndNot<MaskImageType>(m_Working_Support, injected, GetBackgroundValue());
-
- StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_1_Limits()
-{
- //--------------------------------------------------------------------
- StartNewStep("[Station8] Left and Right (from Carina to PulmonaryTrunk): Right to LeftPulmonaryArtery");
-
- /*
- We remove LeftPulmonaryArtery structure and what is at Left to
- this structure.
- */
- MaskImagePointer LeftPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
-
- // Relative Position : not at Left
- typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
- typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
- relPosFilter->VerboseStepFlagOff();
- relPosFilter->WriteStepFlagOff();
- relPosFilter->SetBackgroundValue(GetBackgroundValue());
- relPosFilter->SetInput(m_Working_Support);
- relPosFilter->SetInputObject(LeftPulmonaryArtery);
- relPosFilter->RemoveObjectFlagOn(); // remove the object too
- relPosFilter->AddOrientationTypeString("L");
- relPosFilter->InverseOrientationFlagOn(); // Not at Left
- relPosFilter->SetIntermediateSpacing(3);
- relPosFilter->IntermediateSpacingFlagOn();
- relPosFilter->SetFuzzyThreshold(0.7);
- relPosFilter->AutoCropFlagOn();
- relPosFilter->Update();
- m_Working_Support = relPosFilter->GetOutput();
-
- // Release LeftPulmonaryArtery
- GetAFDB()->template ReleaseImage<MaskImageType>("LeftPulmonaryArtery");
-
- StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_2_Limits()
-{
- //--------------------------------------------------------------------
- StartNewStep("[Station8] Left and Right (from PulmTrunk to OriginMiddleLobeBronchus) Right to line from Aorta to PulmonaryTrunk");
+ StartNewStep("[Station8] Left limits: remove Left to line from Aorta to PulmonaryTrunk");
/*
We consider a line from Left part of Aorta to left part of
template <class ImageType>
void
clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits_old2()
-{
-
- //--------------------------------------------------------------------
- StartNewStep("[Station8] Left and Right limits arround esophagus (below Carina)");
-
- // Estract slices for current support for slice by slice processing
- std::vector<typename MaskSliceType::Pointer> slices;
- clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
-
- // Dilate the Esophagus to consider a margins around
- MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
- m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus,
- radiusInMM,
- GetBackgroundValue(),
- GetForegroundValue(), true);
-
- // Remove what is outside the mediastinum in this enlarged Esophagus -> it allows to select
- // 'better' extrema points (not too post).
- MaskImagePointer Lungs = GetAFDB()->template GetImage<MaskImageType>("Lungs");
- clitk::AndNot<MaskImageType>(m_Esophagus, Lungs, GetBackgroundValue());
- GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
-
- // Estract slices of Esophagus (resize like support before to have the same set of slices)
- MaskImagePointer EsophagusForSlice = clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
-
- std::vector<typename MaskSliceType::Pointer> eso_slices;
- clitk::ExtractSlices<MaskImageType>(EsophagusForSlice, 2, eso_slices);
-
- // Estract slices of Vertebral (resize like support before to have the same set of slices)
- MaskImagePointer VertebralBody = GetAFDB()->template GetImage<MaskImageType>("VertebralBody");
- VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
- std::vector<typename MaskSliceType::Pointer> vert_slices;
- clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vert_slices);
-
- // Estract slices of Aorta (resize like support before to have the same set of slices)
- MaskImagePointer Aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
- Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, m_Working_Support, GetBackgroundValue());
- std::vector<typename MaskSliceType::Pointer> aorta_slices;
- clitk::ExtractSlices<MaskImageType>(Aorta, 2, aorta_slices);
-
- // Extract slices of Mediastinum (resize like support before to have the same set of slices)
- m_Mediastinum = GetAFDB()->template GetImage<MaskImageType>("Mediastinum");
- m_Mediastinum = clitk::ResizeImageLike<MaskImageType>(m_Mediastinum, m_Working_Support, GetBackgroundValue());
- std::vector<typename MaskSliceType::Pointer> mediast_slices;
- clitk::ExtractSlices<MaskImageType>(m_Mediastinum, 2, mediast_slices);
-
- // List of points
- std::vector<MaskImagePointType> p_RightMostAnt;
- std::vector<MaskImagePointType> p_RightMostPost;
- std::vector<MaskImagePointType> p_LeftMostAnt;
- std::vector<MaskImagePointType> p_LeftMostPost;
- std::vector<MaskImagePointType> p_AllPoints;
- std::vector<MaskImagePointType> p_LeftAorta;
- std::vector<MaskImagePointType> p_LeftEso;
-
- /*
- In the following, we search for the LeftRight limits. We search
- for the most Right points in Esophagus and in VertebralBody and
- consider a line between those to most right points. All points in
- the support which are most right to this line are discarded. Same
- for the left part. The underlying assumption is that the support
- is concave between Eso/VertebralBody. Esophagus is a bit
- dilatated. On VertebralBody we go right (or left) until we reach
- the lung (but no more 20 mm).
- */
-
- // Loop slices
- MaskImagePointType p;
- MaskImagePointType pp;
- for(uint i=0; i<slices.size() ; i++) {
- // Declare all needed points (sp = slice point)
- typename MaskSliceType::PointType sp_maxRight_Eso;
- typename MaskSliceType::PointType sp_maxRight_Aorta;
- typename MaskSliceType::PointType sp_maxRight_Vertebra;
- typename MaskSliceType::PointType sp_maxLeft_Eso;
- typename MaskSliceType::PointType sp_maxLeft_Aorta;
- typename MaskSliceType::PointType sp_maxLeft_Vertebra;
-
- // Right is at left on screen, coordinate decrease
- // Left is at right on screen, coordinate increase
-
- // Find limit of Vertebral -> only at most Post part of current
- // slice support. First found most ant point in VertebralBody
- typedef MaskSliceType SliceType;
- typename SliceType::PointType p_slice_ant;
- bool found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vert_slices[i], GetBackgroundValue(), 1, true, p_slice_ant);
- if (!found) {
- // It should not happen ! But sometimes, a contour is missing or
- // the VertebralBody is not delineated enough inferiorly ... in
- // those cases, we consider the first found slice.
- std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
- int j=i++;
- bool found = false;
- while (!found) {
- found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vert_slices[j], GetBackgroundValue(), 1, true, p_slice_ant);
- //clitkExceptionMacro("No foreground pixels in this VertebralBody slices ??");
- j++;
- }
- }
- p_slice_ant[1] += GetDistanceMaxToAnteriorPartOfTheSpine(); // Consider offset
-
- // The, find most Right and Left points on that AP position
- typename SliceType::IndexType indexR;
- typename SliceType::IndexType indexL;
- vert_slices[i]->TransformPhysicalPointToIndex(p_slice_ant, indexR);
- indexL = indexR;
- // Check that is inside the mask
- indexR[1] = std::min(indexR[1], (long)vert_slices[i]->GetLargestPossibleRegion().GetSize()[1]-1);
- indexL[1] = indexR[1];
- while (vert_slices[i]->GetPixel(indexR) != GetBackgroundValue()) {
- indexR[0] --; // Go to the right
- }
- while (vert_slices[i]->GetPixel(indexL) != GetBackgroundValue()) {
- indexL[0] ++; // Go to the left
- }
- vert_slices[i]->TransformIndexToPhysicalPoint(indexR, sp_maxRight_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, VertebralBody, i, p);
- p_AllPoints.push_back(p);
- vert_slices[i]->TransformIndexToPhysicalPoint(indexL, sp_maxLeft_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, VertebralBody, i, p);
- p_AllPoints.push_back(p);
-
- // Find last point out of the mediastinum on this line, Right :
- mediast_slices[i]->TransformPhysicalPointToIndex(sp_maxRight_Vertebra, indexR);
- double distance = 0.0;
- while (mediast_slices[i]->GetPixel(indexR) != GetBackgroundValue()) {
- indexR[0] --;
- distance += mediast_slices[i]->GetSpacing()[0];
- }
- if (distance < 30) { // Ok in this case, we found limit with lung
- mediast_slices[i]->TransformIndexToPhysicalPoint(indexR, sp_maxRight_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, m_Mediastinum, i, p);
- }
- else { // in that case, we are probably below the diaphragm, so we
- // add aribtrarly few mm
- sp_maxRight_Vertebra[0] -= 2; // Leave 2 mm around the VertebralBody
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, m_Mediastinum, i, p);
- }
- p_RightMostPost.push_back(p);
- p_AllPoints.push_back(p);
-
- // Find last point out of the mediastinum on this line, Left :
- mediast_slices[i]->TransformPhysicalPointToIndex(sp_maxLeft_Vertebra, indexL);
- distance = 0.0;
- while (mediast_slices[i]->GetPixel(indexL) != GetBackgroundValue()) {
- indexL[0] ++;
- distance += mediast_slices[i]->GetSpacing()[0];
- }
- if (distance < 30) { // Ok in this case, we found limit with lung
- mediast_slices[i]->TransformIndexToPhysicalPoint(indexL, sp_maxLeft_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, m_Mediastinum, i, p);
- }
- else { // in that case, we are probably below the diaphragm, so we
- // add aribtrarly few mm
- sp_maxLeft_Vertebra[0] += 2; // Leave 2 mm around the VertebralBody
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, m_Mediastinum, i, p);
- }
- p_LeftMostPost.push_back(p);
- p_AllPoints.push_back(p);
-
- // Find Eso slice centroid and do not consider what is post to
- // this centroid.
- std::vector<typename MaskSliceType::PointType> c;
- clitk::ComputeCentroids<MaskSliceType>(eso_slices[i], GetBackgroundValue(), c);
- if (c.size() >1) {
- eso_slices[i] =
- clitk::CropImageAbove<MaskSliceType>(eso_slices[i], 1, c[1][1], false, GetBackgroundValue());
- eso_slices[i] =
- clitk::ResizeImageLike<MaskSliceType>(eso_slices[i], aorta_slices[i], GetBackgroundValue());
- // writeImage<MaskSliceType>(eso_slices[i], "eso-slice-"+toString(i)+".mhd");
- }
-
- // Find right limit of Esophagus and Aorta
- bool f =
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(),
- 0, true, sp_maxRight_Eso);
- f = f &&
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(aorta_slices[i], GetBackgroundValue(),
- 0, true, sp_maxRight_Aorta);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Eso, EsophagusForSlice, i, p);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Aorta, Aorta, i, pp);
- pp[0] -= 2; // Add a margin of 2 mm to include the Aorta 'wall'
- p_AllPoints.push_back(p);
- if (f) {
- p_AllPoints.push_back(pp);
- MaskImagePointType A = p_RightMostPost.back();
- MaskImagePointType B = p;
- MaskImagePointType C = pp;
- double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
- if (s>0) p_RightMostAnt.push_back(p);
- else p_RightMostAnt.push_back(pp);
- }
- else { // No more Esophagus in this slice : do nothing
- // p_RightMostAnt.push_back(p);
- p_RightMostPost.pop_back();
- }
-
- // --------------------------------------------------------------------------
- // Find the limit on the Left: most left point between Eso and
- // Eso. (Left is left on screen, coordinate increase)
-
- // Find left limit of Esophagus
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_maxLeft_Eso);
- f = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(aorta_slices[i], GetBackgroundValue(), 0, false, sp_maxLeft_Aorta);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Eso, EsophagusForSlice, i, p);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Aorta, Aorta, i, pp);
- p_AllPoints.push_back(p);
- pp[0] += 2; // Add a margin of 2 mm to include the 'wall'
- if (f) { // not below Aorta
- p_AllPoints.push_back(pp);
- MaskImagePointType A = p_LeftMostPost.back();
- MaskImagePointType B = p;
- MaskImagePointType C = pp;
- double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
- if (s<0) {
- p_LeftMostAnt.push_back(p); // Insert point most at Left, Eso
- }
- else {
- // in this case -> two lines !
- p_LeftMostAnt.push_back(pp); // Insert point most at Left, Aorta (Vert to Aorta)
- // but also consider Aorta to Eso
- p_LeftAorta.push_back(pp);
- p_LeftEso.push_back(p);
- }
- }
- else { // No more Esophagus in this slice : do nothing
- p_LeftMostPost.pop_back();
- //p_LeftMostAnt.push_back(p);
- }
- } // End of slice loop
-
- clitk::WriteListOfLandmarks<MaskImageType>(p_AllPoints, "S8-LR-Eso-Vert.txt");
- clitk::WriteListOfLandmarks<MaskImageType>(p_LeftEso, "S8-Left-Eso.txt");
- clitk::WriteListOfLandmarks<MaskImageType>(p_LeftAorta, "S8-Left-Aorta.txt");
-
- // Now uses these points to limit, slice by slice
- // Line is mainly vertical, so mainDirection=0
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- p_RightMostAnt, p_RightMostPost,
- GetBackgroundValue(), 0, 10);
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- p_LeftMostAnt, p_LeftMostPost,
- GetBackgroundValue(), 0, -10);
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- p_LeftEso,p_LeftAorta,
- GetBackgroundValue(), 0, -10);
- // END
- StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["8"] = m_Working_Support;
- return;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits()
+ExtractStation_8_Left_Inf_Limits()
{
-
//--------------------------------------------------------------------
- StartNewStep("[Station8] Left and Right limits arround esophagus with lines from VertebralBody-Aorta-Esophagus");
+ StartNewStep("[Station8] Left limits around esophagus with lines from VertebralBody-Aorta-Esophagus");
// Estract slices for current support for slice by slice processing
std::vector<typename MaskSliceType::Pointer> slices;
clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
-
- // Dilate the Esophagus to consider a margins around
- MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
- m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus, radiusInMM,
- GetBackgroundValue(), GetForegroundValue(), true);
- // m_Esophagus = EnlargeEsophagusDilatationRadiusInferiorly(m_Esophagus);
// Remove what is outside the mediastinum in this enlarged Esophagus -> it allows to select
// 'better' extrema points (not too post).
GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
// Estract slices of Esophagus (resize like support before to have the same set of slices)
- MaskImagePointer EsophagusForSlice = clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
+ MaskImagePointer EsophagusForSlice =
+ clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
std::vector<typename MaskSliceType::Pointer> eso_slices;
clitk::ExtractSlices<MaskImageType>(EsophagusForSlice, 2, eso_slices);
// Estract slices of Vertebral (resize like support before to have the same set of slices)
MaskImagePointer VertebralBody = GetAFDB()->template GetImage<MaskImageType>("VertebralBody");
VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
+ // Remove what is outside the support to not consider what is to
+ // posterior in the VertebralBody (post the horizontal line)
+ clitk::And<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
+ // writeImage<MaskImageType>(VertebralBody, "vb.mhd");
std::vector<typename MaskSliceType::Pointer> vert_slices;
clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vert_slices);
// Temporary 3D point
MaskImagePointType p;
+ typename MaskSliceType::PointType minSlicePoint;
+ typename MaskSliceType::PointType maxSlicePoint;
+ clitk::GetMinMaxPointPosition<MaskSliceType>(vert_slices[0], minSlicePoint, maxSlicePoint);
+
// Loop slices
for(uint i=0; i<slices.size() ; i++) {
// Declare all needed 2D points (sp = slice point)
- typename MaskSliceType::PointType sp_MostRightVertebralBody;
+ // typename MaskSliceType::PointType sp_MostRightVertebralBody;
typename MaskSliceType::PointType sp_MostLeftVertebralBody;
typename MaskSliceType::PointType sp_MostLeftAorta;
typename MaskSliceType::PointType sp_temp;
typename MaskSliceType::PointType sp_MostLeftEsophagus;
-
- // Right is at left on screen, coordinate decrease
- // Left is at right on screen, coordinate increase
-
+
/* -------------------------------------------------------------------------------------
- Find most Left point in VertebralBody. Consider only the
- horizontal line which is 'DistanceMaxToAnteriorPartOfTheSpine'
- away from the most ant point.
- */
- typename MaskSliceType::PointType sp_MostAntVertebralBody;
- bool found = false;
- int j=i;
- while (!found) {
- found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[j], GetBackgroundValue(), 1, true, sp_MostAntVertebralBody);
- if (!found) {
- // It should not happen ! But sometimes, a contour is missing or
- // the VertebralBody is not delineated enough inferiorly ... in
- // those cases, we consider the first found slice.
- std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
- j++;
- }
- }
- sp_MostAntVertebralBody[1] += GetDistanceMaxToAnteriorPartOfTheSpine(); // Consider offset
+ Find first point not in mediastinum at LEFT
+ */
+ clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[i], GetBackgroundValue(),
+ 0, false, sp_MostLeftVertebralBody);
+ // clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
+ // DD(p);
- // Crop the vertebralbody below this most post line
- vert_slices[j] =
- clitk::CropImageAbove<MaskSliceType>(vert_slices[j], 1, sp_MostAntVertebralBody[1], false, GetBackgroundValue());
- vert_slices[j] =
- clitk::ResizeImageLike<MaskSliceType>(vert_slices[j], aorta_slices[i], GetBackgroundValue());
- // writeImage<MaskSliceType>(vert_slices[i], "vert-slice-"+toString(i)+".mhd");
+ sp_MostLeftVertebralBody =
+ clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, false,
+ sp_MostLeftVertebralBody, GetBackgroundValue(), 30);
+ // clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
+ // DD(p);
- // Find first point not in mediastinum
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[j], GetBackgroundValue(), 0, false, sp_MostLeftVertebralBody);
- sp_MostLeftVertebralBody = clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, false, sp_MostLeftVertebralBody, GetBackgroundValue(), 30);
sp_MostLeftVertebralBody[0] += 2; // 2mm margin
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[j], GetBackgroundValue(), 0, true, sp_MostRightVertebralBody);
- sp_MostRightVertebralBody = clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, true, sp_MostRightVertebralBody, GetBackgroundValue(),30);
- sp_MostRightVertebralBody[0] -= 2; // 2 mm margin
+ // clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
+ // DD(p);
// Convert 2D points into 3D
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostRightVertebralBody, VertebralBody, i, p);
- p_MostRightVertebralBody.push_back(p);
clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
p_MostLeftVertebralBody.push_back(p);
+ /* -------------------------------------------------------------------------------------
+ Find first point not in mediastinum at RIGHT. Not used yet.
+ clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[i], GetBackgroundValue(),
+ 0, true, sp_MostRightVertebralBody);
+ sp_MostRightVertebralBody =
+ clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, true,
+ sp_MostRightVertebralBody, GetBackgroundValue(),30);
+ sp_MostRightVertebralBody[0] -= 2; // 2 mm margin
+
+ // Convert 2D points into 3D
+ clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostRightVertebralBody, VertebralBody, i, p);
+ p_MostRightVertebralBody.push_back(p);
+ */
+
+
/* -------------------------------------------------------------------------------------
Find most Left point in Esophagus
*/
- found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_MostLeftEsophagus);
+ bool found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_MostLeftEsophagus);
if (!found) { // No more Esophagus, I remove the previous point
-
- // if (p_MostLeftEsophagus.size() < 1) {
- p_MostLeftVertebralBody.pop_back();
- // }
- // else {
- // // Consider the previous point
- // p = p_MostLeftEsophagus.back();
- // p_MostLeftEsophagus.push_back(p);
- // sp_MostLeftEsophagus = sp_temp; // Retrieve previous 2D position
- // found = true;
- // }
+ //DD("no eso pop back");
+ p_MostLeftVertebralBody.pop_back();
}
else {
clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftEsophagus, EsophagusForSlice, i, p);
p_MostLeftEsophagus.push_back(p);
- // sp_temp = sp_MostLeftEsophagus; // Store previous 2D position
}
/* -------------------------------------------------------------------------------------
} // End of slice loop
clitk::WriteListOfLandmarks<MaskImageType>(p_MostLeftVertebralBody, "S8-MostLeft-VB-points.txt");
- clitk::WriteListOfLandmarks<MaskImageType>(p_MostRightVertebralBody, "S8-MostRight-VB-points.txt");
+ // clitk::WriteListOfLandmarks<MaskImageType>(p_MostRightVertebralBody, "S8-MostRight-VB-points.txt");
clitk::WriteListOfLandmarks<MaskImageType>(p_MostLeftAorta, "S8-MostLeft-Aorta-points.txt");
clitk::WriteListOfLandmarks<MaskImageType>(p_MostLeftEsophagus, "S8-MostLeft-eso-points.txt");
clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
p_MostLeftAorta, p_MostLeftEsophagus,
GetBackgroundValue(), 0, -10);
-
// END
StopCurrentStep<MaskImageType>(m_Working_Support);
m_ListOfStations["8"] = m_Working_Support;
clitk::ExtractLymphStationsFilter<ImageType>::
ExtractStation_8_Remove_Structures()
{
-
//--------------------------------------------------------------------
- StartNewStep("[Station8] remove some structures");
-
Remove_Structures("8", "Aorta");
Remove_Structures("8", "Esophagus");
+ Remove_Structures("8", "VertebralBody");
// END
StopCurrentStep<MaskImageType>(m_Working_Support);
//--------------------------------------------------------------------
-//--------------------------------------------------------------------
-template <class ImageType>
-typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
-clitk::ExtractLymphStationsFilter<ImageType>::
-EnlargeEsophagusDilatationRadiusInferiorly(MaskImagePointer & Esophagus)
-{
- // Check if Esophagus is delineated at least until Diaphragm. Now,
- // because we use AutoCrop, Origin[2] gives this max inferior
- // position.
-
- DD("BUGGY DONT USE");
- exit(0);
-
- if (Esophagus->GetOrigin()[2] > m_DiaphragmInferiorLimit) {
- // crop first slice without mask
- MaskImagePointType pt;
- clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Esophagus, GetBackgroundValue(), 2, true, pt);
- DD(pt);
- Esophagus =
- clitk::CropImageBelow<MaskImageType>(Esophagus, 2,
- pt[2],
- false, // AutoCrop
- GetBackgroundValue());
- writeImage<MaskImageType>(Esophagus, "crop-eso.mhd");
-
- std::cout << "Warning Esophagus is not delineated until Diaphragm. I mirror-pad it."
- << std::endl;
- double extraSize = Esophagus->GetOrigin()[2]-m_DiaphragmInferiorLimit;
-
- // Pad with few more slices
- typedef itk::MirrorPadImageFilter<MaskImageType, MaskImageType> PadFilterType;
- typename PadFilterType::Pointer padFilter = PadFilterType::New();
- padFilter->SetInput(Esophagus);
- MaskImageSizeType b;
- b[0] = 0; b[1] = 0; b[2] = (uint)ceil(extraSize/Esophagus->GetSpacing()[2])+1;
- padFilter->SetPadLowerBound(b);
- padFilter->Update();
- Esophagus = padFilter->GetOutput();
- }
- return Esophagus;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits_old()
-{
- /*
- Station 8: paraeosphageal nodes
-
- Laterally, it is within the pleural envelope and again abuts the
- descending aorta on the left. Reasonably, the delineation of
- Station 8 is limited to the soft tissue surrounding the esophagus
- (Fig. 3C–H).
- */
-
- StartNewStep("[Station8] Right limits (around esophagus)");
- // Get Esophagus
- MaskImagePointer Esophagus = GetAFDB()->template GetImage<MaskImageType>("Esophagus");
-
- // Autocrop to get first slice with starting Esophagus
- Esophagus = clitk::AutoCrop<MaskImageType>(Esophagus, GetBackgroundValue());
-
- // Dilate
- // LR dilatation -> large to keep point inside
- // AP dilatation -> few mm
- // SI dilatation -> enough to cover Diaphragm (old=GOjunctionZ)
- MaskImagePointType radiusInMM = GetEsophagusDiltationForRight();
- Esophagus = EnlargeEsophagusDilatationRadiusInferiorly(Esophagus);
- Esophagus = clitk::Dilate<MaskImageType>(Esophagus,
- radiusInMM,
- GetBackgroundValue(),
- GetForegroundValue(), true);
- writeImage<MaskImageType>(Esophagus, "dilateEso2.mhd");
-
- writeImage<MaskImageType>(m_Working_Support, "before-relpos2.mhd");
-
- // Remove Right (Left on the screen) part according to this
- // dilatated esophagus
- typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> RelPosFilterType;
- typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
- relPosFilter->VerboseStepFlagOff();
- relPosFilter->WriteStepFlagOff();
- relPosFilter->SetInput(m_Working_Support);
- relPosFilter->SetInputObject(Esophagus);
- relPosFilter->AddOrientationTypeString("NotLeftTo");
- // relPosFilter->InverseOrientationFlagOn(); // Not Left to
- relPosFilter->SetDirection(2); // Z axis
- relPosFilter->UniqueConnectedComponentBySliceOff(); // important
- relPosFilter->SetIntermediateSpacing(4);
- relPosFilter->IntermediateSpacingFlagOn();
- relPosFilter->SetFuzzyThreshold(0.9); // remove few part only
- relPosFilter->RemoveObjectFlagOff();
- relPosFilter->Update();
- m_Working_Support = relPosFilter->GetOutput();
-
- // Get a single 3D CCL
- m_Working_Support = Labelize<MaskImageType>(m_Working_Support, 0, false, 10);
- m_Working_Support = KeepLabels<MaskImageType>(m_Working_Support,
- GetBackgroundValue(),
- GetForegroundValue(), 1, 1, true);
-
-
- /*
- // Re-Add post to Esophagus -> sometimes previous relpos remove some
- // correct part below esophagus.
- MaskImagePointer Esophagus = GetAFDB()->template GetImage<MaskImageType>("Esophagus");
- EnlargeEsophagusDilatationRadiusInferiorly(Esophagus);
- writeImage<MaskImageType>(Esophagus, "e-again.mhd");
- typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> RelPosFilterType;
- typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
- relPosFilter->VerboseStepOff();
- relPosFilter->WriteStepOff();
- relPosFilter->SetInput(m_Working_Support);
- relPosFilter->SetInputObject(Esophagus);
- relPosFilter->SetOrientationTypeString("P");
- relPosFilter->InverseOrientationFlagOff();
- relPosFilter->SetDirection(2); // Z axis
- relPosFilter->UniqueConnectedComponentBySliceOff(); // important
- relPosFilter->SetIntermediateSpacing(4);
- relPosFilter->IntermediateSpacingFlagOn();
- relPosFilter->CombineWithOrFlagOn();
- relPosFilter->SetFuzzyThreshold(0.9); // remove few part only
- relPosFilter->RemoveObjectFlagOff();
- relPosFilter->Update();
- m_Working_Support = relPosFilter->GetOutput();
- */
-
- StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
//--------------------------------------------------------------------
template <class TImageType>
void
--- /dev/null
+
+#include <itkBinaryDilateImageFilter.h>
+#include <itkMirrorPadImageFilter.h>
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void
+clitk::ExtractLymphStationsFilter<ImageType>::
+ExtractStationSupports()
+{
+ DD("ExtractStationSupports");
+
+ // Get initial Mediastinum
+ m_Working_Support = m_Mediastinum = GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true);
+
+ // Superior limits: CricoidCartilag
+ // Inferior limits: lung
+ // (the Mediastinum support already stop at this limit)
+
+ // Consider above Carina
+ m_CarinaZ = FindCarinaSlicePosition();
+ MaskImagePointer m_Support_Superior_to_Carina =
+ clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2,
+ m_CarinaZ, true, GetBackgroundValue());
+ MaskImagePointer m_Support_Inferior_to_Carina =
+ clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2,
+ m_CarinaZ, true, GetBackgroundValue());
+
+ // Consider only Superior to Carina
+ m_Working_Support = m_Support_Superior_to_Carina;
+
+ // Step : S1RL
+ StartNewStep("[Support] sup-inf S1RL");
+ /*
+ Lower border: clavicles bilaterally and, in the midline, the upper
+ border of the manubrium, 1R designates right-sided nodes, 1L,
+ left-sided nodes in this region
+
+ 2R: Upper border: apex of the right lung and pleural space, and in
+ the midline, the upper border of the manubrium
+
+ 2L: Upper border: apex of the left lung and pleural space, and in the
+ midline, the upper border of the manubrium
+ */
+
+
+
+
+
+
+
+
+
+ // // LeftRight cut along trachea
+ // MaskImagePointer Trachea = GetAFDB()->GetImage("Trachea");
+ // // build a ant-post line for each slice
+
+ // MaskImagePointer m_Support_SupRight =
+ // clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2,
+ // m_CarinaZ, true, GetBackgroundValue());
+
+
+
+
+
+ // Store image filenames into AFDB
+ m_ListOfSupports["S1R"] = m_Working_Support;
+ writeImage<MaskImageType>(m_ListOfSupports["S1R"], "seg/Support_S1R.mhd");
+ GetAFDB()->SetImageFilename("Support_S1R", "seg/Support_S1R.mhd");
+ WriteAFDB();
+}
+//--------------------------------------------------------------------
+
+
option "station" - "Force to compute station even if already exist in the DB" string no multiple
section "Options for Station 8"
-option "maxAntSpine" - "Distance max to anterior part of the spine in mm" double no default="10"
-option "esophagusDilatationForAnt" - "Dilatation of esophagus, in mm, for 'anterior' limits (default=15,2,1)" double no multiple
-option "esophagusDilatationForRight" - "Dilatation of esophagus, in mm, for 'right' limits (default=5,10,1)" double no multiple
-option "tS8_Esophagus" - "Threshold for 'Post' to dilated Esophagus" double default="0.5" no
-option "injectedThresholdForS8" - "Threshold injected areas in the ct" double default="150" no
+option "S8_esophagusDilatationForAnt" - "Dilatation of esophagus, in mm, for 'anterior' limits (default=15,2,1)" double no multiple
+option "S8_esophagusDilatationForRight" - "Dilatation of esophagus, in mm, for 'right' limits (default=5,10,1)" double no multiple
+option "S8_ft_Esophagus" - "Fuzzy Threshold for 'Post' to dilated Esophagus" double default="0.5" no
section "Options for Station 7"
-option "tS7_Bronchi" - "Threshold for Left/Right bronchi" double default="0.1" no
-option "tS7_LeftSuperiorPulmonaryVein" - "Threshold for LeftSuperiorPulmonaryVein" double default="0.3" no
-option "tS7_RightSuperiorPulmonaryVein" - "Threshold for RightSuperiorPulmonaryVein" double default="0.2" no
-option "tS7_RightPulmonaryArtery" - "Threshold for RightPulmonaryArtery" double default="0.3" no
-option "tS7_LeftPulmonaryArtery" - "Threshold for LeftPulmonaryArtery (NOT USEFUL YET)" double default="0.5" no
-option "tS7_SVC" - "Threshold for SVC" double default="0.2" no
+option "S7_ft_Bronchi" - "Fuzzy Threshold for Left/Right bronchi" double default="0.1" no
+option "S7_ft_LeftSuperiorPulmonaryVein" - "Fuzzy Threshold for LeftSuperiorPulmonaryVein" double default="0.3" no
+option "S7_ft_RightSuperiorPulmonaryVein" - "Fuzzy Threshold for RightSuperiorPulmonaryVein" double default="0.2" no
+option "S7_ft_RightPulmonaryArtery" - "Fuzzy Threshold for RightPulmonaryArtery" double default="0.3" no
+option "S7_ft_LeftPulmonaryArtery" - "Fuzzy Threshold for LeftPulmonaryArtery (NOT USEFUL YET)" double default="0.5" no
+option "S7_ft_SVC" - "Fuzzy Threshold for SVC" double default="0.2" no
+option "S7_UseMostInferiorPartOnly" - "Inferior separation with S8." flag off
section "Options for Station 3A"
-option "tS3A_Sternum" - "Threshold for Post to Sternum" double default="0.5" no
-option "tS3A_SubclavianArtery" - "Threshold for Ant to SubclavianArtery" double default="0.2" no
+option "S3A_ft_Sternum" - "Fuzzy Threshold for Post to Sternum" double default="0.5" no
+option "S3A_ft_SubclavianArtery" - "Fuzzy Threshold for Ant to SubclavianArtery" double default="0.2" no
section "Options for Station 2RL"
-option "tS2RL_CommonCarotidArtery" - "Threshold for NotAntTo to CommonCarotidArtery" double default="0.7" no
-option "tS2RL_BrachioCephalicTrunk" - "Threshold for NotAntTo to BrachioCephalicTrunk" double default="0.7" no
-option "tS2RL_BrachioCephalicVein" - "Threshold for NotAntTo to BrachioCephalicVein" double default="0.3" no
-option "tS2RL_Aorta" - "Threshold for RightTo to Aorta" double default="0.7" no
-option "tS2RL_SubclavianArteryRight" - "Threshold for NotLeft to SubclavianArteryRight" double default="0.5" no
-option "tS2RL_SubclavianArteryLeft" - "Threshold for NotRight to SubclavianArteryLeft" double default="0.8" no
+option "S2RL_ft_CommonCarotidArtery" - "Threshold for NotAntTo to CommonCarotidArtery" double default="0.7" no
+option "S2RL_ft_BrachioCephalicTrunk" - "Threshold for NotAntTo to BrachioCephalicTrunk" double default="0.7" no
+option "S2RL_ft_BrachioCephalicVein" - "Threshold for NotAntTo to BrachioCephalicVein" double default="0.3" no
+option "S2RL_ft_Aorta" - "Threshold for RightTo to Aorta" double default="0.7" no
+option "S2RL_ft_SubclavianArteryRight" - "Threshold for NotLeft to SubclavianArteryRight" double default="0.5" no
+option "S2RL_ft_SubclavianArteryLeft" - "Threshold for NotRight to SubclavianArteryLeft" double default="0.8" no
typedef itk::Image<MaskImagePixelType, 2> MaskSliceType;
typedef typename MaskSliceType::Pointer MaskSlicePointer;
typedef typename MaskSliceType::PointType MaskSlicePointType;
+ typedef typename MaskSliceType::RegionType MaskSliceRegionType;
+ typedef typename MaskSliceType::SizeType MaskSliceSizeType;
+ typedef typename MaskSliceType::IndexType MaskSliceIndexType;
/** ImageDimension constants */
itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
itkSetMacro(ForegroundValue, MaskImagePixelType);
// Station 8
- itkSetMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
- itkGetConstMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
+ // itkSetMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
+ //itkGetConstMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
itkSetMacro(EsophagusDiltationForAnt, MaskImagePointType);
itkGetConstMacro(EsophagusDiltationForAnt, MaskImagePointType);
itkSetMacro(EsophagusDiltationForRight, MaskImagePointType);
itkGetConstMacro(InjectedThresholdForS8, double);
// Station 7
+ itkGetConstMacro(S7_UseMostInferiorPartOnlyFlag, bool);
+ itkSetMacro(S7_UseMostInferiorPartOnlyFlag, bool);
+ itkBooleanMacro(S7_UseMostInferiorPartOnlyFlag);
// All stations
bool GetComputeStation(std::string s);
MaskImagePointer m_Mediastinum;
MaskImagePointer m_Working_Support;
std::map<std::string, MaskImagePointer> m_ListOfStations;
+ std::map<std::string, MaskImagePointer> m_ListOfSupports;
MaskImagePixelType m_BackgroundValue;
MaskImagePixelType m_ForegroundValue;
std::map<std::string, bool> m_ComputeStationMap;
bool CheckForStation(std::string station);
void Remove_Structures(std::string station, std::string s);
+ // Functions common to several stations
+ void FindLineForS7S8Separation(MaskImagePointType & A, MaskImagePointType & B);
+ double FindCarinaSlicePosition();
+ void FindLeftAndRightBronchi();
+
// Global parameters
typedef std::map<std::string, double> FuzzyThresholdByStructureType;
std::map<std::string, FuzzyThresholdByStructureType> m_FuzzyThreshold;
+ // Station's supports
+ void ExtractStationSupports();
+
// Station 8
- double m_DistanceMaxToAnteriorPartOfTheSpine;
+ // double m_DistanceMaxToAnteriorPartOfTheSpine;
double m_DiaphragmInferiorLimit;
double m_CarinaZ;
double m_OriginOfRightMiddleLobeBronchusZ;
MaskImagePointer m_Esophagus;
MaskImagePointType m_EsophagusDiltationForAnt;
MaskImagePointType m_EsophagusDiltationForRight;
- MaskImagePointer EnlargeEsophagusDilatationRadiusInferiorly(MaskImagePointer & eso);
+
void ExtractStation_8();
void ExtractStation_8_SetDefaultValues();
void ExtractStation_8_SI_Limits();
- void ExtractStation_8_Post_Limits();
- void ExtractStation_8_Ant_Sup_Limits();
- void ExtractStation_8_Ant_Inf_Limits();
- void ExtractStation_8_Ant_Injected_Limits();
- void ExtractStation_8_LR_1_Limits();
- void ExtractStation_8_LR_2_Limits();
+ void ExtractStation_8_Ant_Limits();
+ void ExtractStation_8_Left_Sup_Limits();
+ void ExtractStation_8_Left_Inf_Limits();
void ExtractStation_8_Single_CCL_Limits();
- void ExtractStation_8_LR_Limits();
void ExtractStation_8_Remove_Structures();
- void ExtractStation_8_LR_Limits_old();
- void ExtractStation_8_LR_Limits_old2();
-
+
// Station 3P
void ExtractStation_3P();
void ExtractStation_3P_SetDefaultValues();
void ExtractStation_7();
void ExtractStation_7_SetDefaultValues();
void ExtractStation_7_SI_Limits();
- void ExtractStation_7_RL_Limits();
+ void ExtractStation_7_RL_Interior_Limits();
+
+
+ void ExtractStation_7_RL_Limits_OLD();
void ExtractStation_7_Posterior_Limits();
void ExtractStation_7_Remove_Structures();
+ bool m_S7_UseMostInferiorPartOnlyFlag;
MaskImagePointer m_Working_Trachea;
MaskImagePointer m_LeftBronchus;
MaskImagePointer m_RightBronchus;
#ifndef ITK_MANUAL_INSTANTIATION
#include "clitkExtractLymphStationsFilter.txx"
+#include "clitkExtractLymphStation_Supports.txx"
#include "clitkExtractLymphStation_8.txx"
#include "clitkExtractLymphStation_3P.txx"
#include "clitkExtractLymphStation_2RL.txx"
m_Input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
m_Mediastinum = GetAFDB()->template GetImage <MaskImageType>("Mediastinum");
+ // Global supports for stations
+ StartNewStep("Supports for stations");
+ StartSubStep();
+ ExtractStationSupports();
+ StopSubStep();
+
// Extract Station8
StartNewStep("Station 8");
StartSubStep();
StopSubStep();
// Extract Station2RL
- StartNewStep("Station 2RL");
- StartSubStep();
- ExtractStation_2RL();
- StopSubStep();
+ /*
+ StartNewStep("Station 2RL");
+ StartSubStep();
+ ExtractStation_2RL();
+ StopSubStep();
+ */
// Extract Station3A
StartNewStep("Station 3A");
//--------------------------------------------------------------------
-//--------------------------------------------------------------------
-template <class TImageType>
-void
-clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_8()
-{
- if (CheckForStation("8")) {
- ExtractStation_8_SI_Limits();
- ExtractStation_8_Post_Limits();
- ExtractStation_8_Ant_Sup_Limits();
- ExtractStation_8_Ant_Inf_Limits();
- ExtractStation_8_LR_1_Limits();
- ExtractStation_8_LR_2_Limits();
- ExtractStation_8_LR_Limits();
- ExtractStation_8_Ant_Injected_Limits();
- ExtractStation_8_Single_CCL_Limits();
- ExtractStation_8_Remove_Structures();
- // Store image filenames into AFDB
- writeImage<MaskImageType>(m_ListOfStations["8"], "seg/Station8.mhd");
- GetAFDB()->SetImageFilename("Station8", "seg/Station8.mhd");
- WriteAFDB();
- }
-}
-//--------------------------------------------------------------------
-
-
//--------------------------------------------------------------------
template <class TImageType>
void
//--------------------------------------------------------------------
-//--------------------------------------------------------------------
-template <class TImageType>
-void
-clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_7() {
- if (CheckForStation("7")) {
- ExtractStation_7_SI_Limits();
- ExtractStation_7_RL_Limits();
- ExtractStation_7_Posterior_Limits();
- // ExtractStation_8_Single_CCL_Limits(); // Yes the same than 8
- ExtractStation_7_Remove_Structures();
- // Store image filenames into AFDB
- writeImage<MaskImageType>(m_ListOfStations["7"], "seg/Station7.mhd");
- GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd");
- WriteAFDB();
- }
-}
-//--------------------------------------------------------------------
-
-
//--------------------------------------------------------------------
template <class TImageType>
void
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindLineForS7S8Separation(MaskImagePointType & A, MaskImagePointType & B)
+{
+ // Create line from A to B with
+ // A = upper border of LLL at left
+ // B = lower border of bronchus intermedius (BI) or RightMiddleLobeBronchus
+
+ try {
+ GetAFDB()->GetPoint3D("LineForS7S8Separation_Begin", A);
+ GetAFDB()->GetPoint3D("LineForS7S8Separation_End", B);
+ }
+ catch(clitk::ExceptionObject & o) {
+
+ DD("FindLineForS7S8Separation");
+ // Load LeftLowerLobeBronchus and get centroid point
+ MaskImagePointer LeftLowerLobeBronchus =
+ GetAFDB()->template GetImage <MaskImageType>("LeftLowerLobeBronchus");
+ std::vector<MaskImagePointType> c;
+ clitk::ComputeCentroids<MaskImageType>(LeftLowerLobeBronchus, GetBackgroundValue(), c);
+ A = c[1];
+
+ // Load RightMiddleLobeBronchus and get superior point (not centroid here)
+ MaskImagePointer RightMiddleLobeBronchus =
+ GetAFDB()->template GetImage <MaskImageType>("RightMiddleLobeBronchus");
+ bool b = FindExtremaPointInAGivenDirection<MaskImageType>(RightMiddleLobeBronchus,
+ GetBackgroundValue(),
+ 2, false, B);
+ if (!b) {
+ clitkExceptionMacro("Error while searching most superior point in RightMiddleLobeBronchus. Abort");
+ }
+
+ // Insert into the DB
+ GetAFDB()->SetPoint3D("LineForS7S8Separation_Begin", A);
+ GetAFDB()->SetPoint3D("LineForS7S8Separation_End", B);
+ }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+double
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindCarinaSlicePosition()
+{
+ double z;
+ try {
+ z = GetAFDB()->GetDouble("CarinaZ");
+ }
+ catch(clitk::ExceptionObject e) {
+ DD("FindCarinaSlicePosition");
+ // Get Carina
+ MaskImagePointer Carina = GetAFDB()->template GetImage<MaskImageType>("Carina");
+
+ // Get Centroid and Z value
+ std::vector<MaskImagePointType> centroids;
+ clitk::ComputeCentroids<MaskImageType>(Carina, GetBackgroundValue(), centroids);
+ // We dont need Carina structure from now
+ Carina->Delete();
+
+ // Put inside the AFDB
+ GetAFDB()->SetPoint3D("CarinaPoint", centroids[1]);
+ GetAFDB()->SetDouble("CarinaZ", centroids[1][2]);
+ WriteAFDB();
+ z = centroids[1][2];
+ }
+ return z;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindLeftAndRightBronchi()
+{
+ try {
+ m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
+ m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
+ }
+ catch(clitk::ExceptionObject & o) {
+
+ DD("FindLeftAndRightBronchi");
+ // The goal is to separate the trachea inferiorly to the carina into
+ // a Left and Right bronchus.
+
+ // Get the trachea
+ MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
+
+ // Get the Carina position
+ m_CarinaZ = FindCarinaSlicePosition();
+
+ // Consider only inferiorly to the Carina
+ MaskImagePointer m_Working_Trachea =
+ clitk::CropImageRemoveGreaterThan<MaskImageType>(Trachea, 2, m_CarinaZ, true, // AutoCrop
+ GetBackgroundValue());
+
+ // Labelize the trachea
+ m_Working_Trachea = Labelize<MaskImageType>(m_Working_Trachea, 0, true, 1);
+
+ // Carina position must at the first slice that separate the two
+ // main bronchus (not superiorly). We thus first check that the
+ // upper slice is composed of at least two labels
+ MaskImagePointer RightBronchus;
+ MaskImagePointer LeftBronchus;
+ typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
+ SliceIteratorType iter(m_Working_Trachea, m_Working_Trachea->GetLargestPossibleRegion());
+ iter.SetFirstDirection(0);
+ iter.SetSecondDirection(1);
+ iter.GoToReverseBegin(); // Start from the end (because image is IS not SI)
+ int maxLabel=0;
+ while (!iter.IsAtReverseEndOfSlice()) {
+ while (!iter.IsAtReverseEndOfLine()) {
+ if (iter.Get() > maxLabel) maxLabel = iter.Get();
+ --iter;
+ }
+ iter.PreviousLine();
+ }
+ if (maxLabel < 2) {
+ clitkExceptionMacro("First slice from Carina does not seems to seperate the two main bronchus. Abort");
+ }
+
+ // Compute 3D centroids of both parts to identify the left from the
+ // right bronchus
+ std::vector<ImagePointType> c;
+ clitk::ComputeCentroids<MaskImageType>(m_Working_Trachea, GetBackgroundValue(), c);
+ ImagePointType C1 = c[1];
+ ImagePointType C2 = c[2];
+
+ ImagePixelType rightLabel;
+ ImagePixelType leftLabel;
+ if (C1[0] < C2[0]) { rightLabel = 1; leftLabel = 2; }
+ else { rightLabel = 2; leftLabel = 1; }
+
+ // Select LeftLabel (set one label to Backgroundvalue)
+ RightBronchus =
+ clitk::Binarize<MaskImageType>(m_Working_Trachea, rightLabel, rightLabel,
+ GetBackgroundValue(), GetForegroundValue());
+ /*
+ SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea,
+ leftLabel, GetBackgroundValue(), false);
+ */
+ LeftBronchus = clitk::Binarize<MaskImageType>(m_Working_Trachea, leftLabel, leftLabel,
+ GetBackgroundValue(), GetForegroundValue());
+ /*
+ SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea,
+ rightLabel, GetBackgroundValue(), false);
+ */
+
+ // Crop images
+ RightBronchus = clitk::AutoCrop<MaskImageType>(RightBronchus, GetBackgroundValue());
+ LeftBronchus = clitk::AutoCrop<MaskImageType>(LeftBronchus, GetBackgroundValue());
+
+ // Insert int AFDB if need after
+ GetAFDB()->template SetImage <MaskImageType>("RightBronchus", "seg/rightBronchus.mhd",
+ RightBronchus, true);
+ GetAFDB()->template SetImage <MaskImageType>("LeftBronchus", "seg/leftBronchus.mhd",
+ LeftBronchus, true);
+ }
+}
+//--------------------------------------------------------------------
#endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
f->SetAFDBFilename(mArgsInfo.afdb_arg);
// Station 8
- f->SetDistanceMaxToAnteriorPartOfTheSpine(mArgsInfo.maxAntSpine_arg);
- f->SetFuzzyThreshold("8", "Esophagus", mArgsInfo.tS8_Esophagus_arg);
- f->SetInjectedThresholdForS8(mArgsInfo.injectedThresholdForS8_arg);
+ //f->SetDistanceMaxToAnteriorPartOfTheSpine(mArgsInfo.S8_maxAntSpine_arg);
+ f->SetFuzzyThreshold("8", "Esophagus", mArgsInfo.S8_ft_Esophagus_arg);
+ // f->SetInjectedThresholdForS8(mArgsInfo.tS8_injectedThreshold_arg);
// Check multiple options for radius dilatation
/*
*/
typename FilterType::MaskImagePointType p;
p[0] = 7; p[1] = 5; p[2] = 0; // default value
- if (mArgsInfo.esophagusDilatationForAnt_given == 3) {
+ if (mArgsInfo.S8_esophagusDilatationForAnt_given == 3) {
for(uint i=0; i<3; i++)
- p[i] = mArgsInfo.esophagusDilatationForAnt_arg[i];
+ p[i] = mArgsInfo.S8_esophagusDilatationForAnt_arg[i];
}
else {
- if (mArgsInfo.esophagusDilatationForAnt_given == 1) {
+ if (mArgsInfo.S8_esophagusDilatationForAnt_given == 1) {
for(uint i=0; i<3; i++)
- p[i] = mArgsInfo.esophagusDilatationForAnt_arg[0];
+ p[i] = mArgsInfo.S8_esophagusDilatationForAnt_arg[0];
}
}
f->SetEsophagusDiltationForAnt(p);
p[0] = 5; p[1] = 10; p[2] = 1; // default value
- if (mArgsInfo.esophagusDilatationForRight_given == 3) {
+ if (mArgsInfo.S8_esophagusDilatationForRight_given == 3) {
for(uint i=0; i<3; i++)
- p[i] = mArgsInfo.esophagusDilatationForRight_arg[i];
+ p[i] = mArgsInfo.S8_esophagusDilatationForRight_arg[i];
}
else {
- if (mArgsInfo.esophagusDilatationForRight_given == 1) {
+ if (mArgsInfo.S8_esophagusDilatationForRight_given == 1) {
for(uint i=0; i<3; i++)
- p[i] = mArgsInfo.esophagusDilatationForRight_arg[0];
+ p[i] = mArgsInfo.S8_esophagusDilatationForRight_arg[0];
}
}
f->SetEsophagusDiltationForRight(p);
f->AddComputeStation(mArgsInfo.station_arg[i]);
// Station 7
- f->SetFuzzyThreshold("7", "Bronchi", mArgsInfo.tS7_Bronchi_arg);
- f->SetFuzzyThreshold("7", "LeftSuperiorPulmonaryVein", mArgsInfo.tS7_LeftSuperiorPulmonaryVein_arg);
- f->SetFuzzyThreshold("7", "RightSuperiorPulmonaryVein", mArgsInfo.tS7_RightSuperiorPulmonaryVein_arg);
- f->SetFuzzyThreshold("7", "RightPulmonaryArtery", mArgsInfo.tS7_RightPulmonaryArtery_arg);
- f->SetFuzzyThreshold("7", "LeftPulmonaryArtery", mArgsInfo.tS7_LeftPulmonaryArtery_arg);
- f->SetFuzzyThreshold("7", "SVC", mArgsInfo.tS7_SVC_arg);
+ f->SetFuzzyThreshold("7", "Bronchi", mArgsInfo.S7_ft_Bronchi_arg);
+ f->SetFuzzyThreshold("7", "LeftSuperiorPulmonaryVein", mArgsInfo.S7_ft_LeftSuperiorPulmonaryVein_arg);
+ f->SetFuzzyThreshold("7", "RightSuperiorPulmonaryVein", mArgsInfo.S7_ft_RightSuperiorPulmonaryVein_arg);
+ f->SetFuzzyThreshold("7", "RightPulmonaryArtery", mArgsInfo.S7_ft_RightPulmonaryArtery_arg);
+ f->SetFuzzyThreshold("7", "LeftPulmonaryArtery", mArgsInfo.S7_ft_LeftPulmonaryArtery_arg);
+ f->SetFuzzyThreshold("7", "SVC", mArgsInfo.S7_ft_SVC_arg);
+ f->SetS7_UseMostInferiorPartOnlyFlag(mArgsInfo.S7_UseMostInferiorPartOnly_flag);
// Station 3A
- f->SetFuzzyThreshold("3A", "Sternum", mArgsInfo.tS3A_Sternum_arg);
- f->SetFuzzyThreshold("3A", "SubclavianArtery", mArgsInfo.tS3A_SubclavianArtery_arg);
+ f->SetFuzzyThreshold("3A", "Sternum", mArgsInfo.S3A_ft_Sternum_arg);
+ f->SetFuzzyThreshold("3A", "SubclavianArtery", mArgsInfo.S3A_ft_SubclavianArtery_arg);
// Station 2RL
- f->SetFuzzyThreshold("2RL", "CommonCarotidArtery", mArgsInfo.tS2RL_CommonCarotidArtery_arg);
- f->SetFuzzyThreshold("2RL", "BrachioCephalicTrunk", mArgsInfo.tS2RL_BrachioCephalicTrunk_arg);
- f->SetFuzzyThreshold("2RL", "BrachioCephalicVein", mArgsInfo.tS2RL_BrachioCephalicVein_arg);
- f->SetFuzzyThreshold("2RL", "Aorta", mArgsInfo.tS2RL_Aorta_arg);
- f->SetFuzzyThreshold("2RL", "SubclavianArteryLeft", mArgsInfo.tS2RL_SubclavianArteryLeft_arg);
- f->SetFuzzyThreshold("2RL", "SubclavianArteryRight", mArgsInfo.tS2RL_SubclavianArteryRight_arg);
+ f->SetFuzzyThreshold("2RL", "CommonCarotidArtery", mArgsInfo.S2RL_ft_CommonCarotidArtery_arg);
+ f->SetFuzzyThreshold("2RL", "BrachioCephalicTrunk", mArgsInfo.S2RL_ft_BrachioCephalicTrunk_arg);
+ f->SetFuzzyThreshold("2RL", "BrachioCephalicVein", mArgsInfo.S2RL_ft_BrachioCephalicVein_arg);
+ f->SetFuzzyThreshold("2RL", "Aorta", mArgsInfo.S2RL_ft_Aorta_arg);
+ f->SetFuzzyThreshold("2RL", "SubclavianArteryLeft", mArgsInfo.S2RL_ft_SubclavianArteryLeft_arg);
+ f->SetFuzzyThreshold("2RL", "SubclavianArteryRight", mArgsInfo.S2RL_ft_SubclavianArteryRight_arg);
}
//--------------------------------------------------------------------
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+// clitk
+#include "clitkExtractMediastinalVessels_ggo.h"
+#include "clitkExtractMediastinalVesselsGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+
+ // Init command line
+ GGO(clitkExtractMediastinalVessels, args_info);
+ CLITK_INIT;
+
+ // Filter
+ typedef clitk::ExtractMediastinalVesselsGenericFilter<args_info_clitkExtractMediastinalVessels> FilterType;
+ FilterType::Pointer filter = FilterType::New();
+
+ filter->SetArgsInfo(args_info);
+
+ try {
+ filter->Update();
+ } catch(std::runtime_error e) {
+ std::cout << e.what() << std::endl;
+ }
+
+ return EXIT_SUCCESS;
+} // This is the end, my friend
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkExtractMediastinalVessels.ggo
+package "clitkExtractMediastinalVessels"
+version "1.0"
+purpose "Extract MediastinalVessels"
+
+option "config" - "Config file" string no
+option "imagetypes" - "Display allowed image types" flag off
+option "verbose" v "Verbose" flag off
+option "verboseStep" - "Verbose each step" flag off
+option "writeStep" w "Write image at each step" flag off
+option "verboseOption" - "Display options values" flag off
+option "verboseWarningOff" - "Do not display warning" flag off
+option "verboseMemory" - "Display memory usage" flag off
+
+section "I/O"
+
+option "afdb" a "Input Anatomical Feature DB" string yes
+option "input" i "Input CT filename" string yes
+option "output" o "Output filename" string yes
+option "seed" s "Seed point name in AFDB" string yes
+option "name" n "Name of the vessels to sought" string yes
+
+option "thresholdHigh" t "Initial high threshold" double default="140" no
+option "thresholdLow" l "Initial low threshold" double default="55" no
+option "erode" e "Erosion radius in pixel" int default="2" no
+option "dilate" d "Dilatation radius in pixel" int default="9" no
+option "maxPost" - "Max distance post to Carina" double default="10" no
+option "maxAnt" - "Max distance ant to Carina" double default="40" no
+option "maxLeft" - "Max distance left to Carina" double default="35" no
+option "maxRight" - "Max distance right to Carina" double default="35" no
+option "bif" - "Max number of bifurcation during traking" int default="0" no
+option "open" - "Final opening radius" int default="1" no
\ No newline at end of file
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ ======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSFILTER_H
+#define CLITKEXTRACTLYMPHSTATIONSFILTER_H
+
+// clitk
+#include "clitkFilterBase.h"
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
+
+namespace clitk {
+
+ //--------------------------------------------------------------------
+ /*
+ Try to extract the some Mediastinal Vessels in a thorax CT.
+ Need a set of Anatomical Features (AFDB)
+ */
+ //--------------------------------------------------------------------
+
+ template <class TImageType>
+ class ITK_EXPORT ExtractMediastinalVesselsFilter:
+ public virtual clitk::FilterBase,
+ public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+ public itk::ImageToImageFilter<TImageType, itk::Image<uchar, 3> >
+ {
+
+ public:
+ /** Standard class typedefs. */
+ typedef itk::ImageToImageFilter<TImageType, itk::Image<uchar, 3> > Superclass;
+ typedef ExtractMediastinalVesselsFilter Self;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ /** Method for creation through the object factory. */
+ itkNewMacro(Self);
+
+ /** Run-time type information (and related methods). */
+ itkTypeMacro(ExtractMediastinalVesselsFilter, ImageToImageFilter);
+
+ /** Some convenient typedefs. */
+ typedef TImageType ImageType;
+ typedef typename ImageType::ConstPointer ImageConstPointer;
+ typedef typename ImageType::Pointer ImagePointer;
+ typedef typename ImageType::RegionType ImageRegionType;
+ typedef typename ImageType::PixelType ImagePixelType;
+ typedef typename ImageType::SizeType ImageSizeType;
+ typedef typename ImageType::IndexType ImageIndexType;
+ typedef typename ImageType::PointType ImagePointType;
+
+ typedef uchar MaskImagePixelType;
+ typedef itk::Image<MaskImagePixelType, 3> MaskImageType;
+ typedef typename MaskImageType::Pointer MaskImagePointer;
+ typedef typename MaskImageType::RegionType MaskImageRegionType;
+ typedef typename MaskImageType::SizeType MaskImageSizeType;
+ typedef typename MaskImageType::IndexType MaskImageIndexType;
+ typedef typename MaskImageType::PointType MaskImagePointType;
+
+ typedef itk::Image<MaskImagePixelType, 2> MaskSliceType;
+ typedef typename MaskSliceType::Pointer MaskSlicePointer;
+ typedef typename MaskSliceType::PointType MaskSlicePointType;
+
+ typedef long LabelType;
+ /** ImageDimension constants */
+ itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+ FILTERBASE_INIT;
+
+ itkGetConstMacro(BackgroundValue, MaskImagePixelType);
+ itkSetMacro(BackgroundValue, MaskImagePixelType);
+
+ itkGetConstMacro(ForegroundValue, MaskImagePixelType);
+ itkSetMacro(ForegroundValue, MaskImagePixelType);
+
+ itkGetConstMacro(TemporaryForegroundValue, MaskImagePixelType);
+ itkSetMacro(TemporaryForegroundValue, MaskImagePixelType);
+
+ itkGetConstMacro(ThresholdHigh, ImagePixelType);
+ itkSetMacro(ThresholdHigh, ImagePixelType);
+
+ itkGetConstMacro(ThresholdLow, ImagePixelType);
+ itkSetMacro(ThresholdLow, ImagePixelType);
+
+ itkGetConstMacro(ErosionRadius, int);
+ itkSetMacro(ErosionRadius, int);
+
+ itkGetConstMacro(DilatationRadius, int);
+ itkSetMacro(DilatationRadius, int);
+
+ itkGetConstMacro(MaxDistancePostToCarina, double);
+ itkSetMacro(MaxDistancePostToCarina, double);
+ itkGetConstMacro(MaxDistanceAntToCarina, double);
+ itkSetMacro(MaxDistanceAntToCarina, double);
+ itkGetConstMacro(MaxDistanceLeftToCarina, double);
+ itkSetMacro(MaxDistanceLeftToCarina, double);
+ itkGetConstMacro(MaxDistanceRightToCarina, double);
+ itkSetMacro(MaxDistanceRightToCarina, double);
+
+ itkSetMacro(DebugFlag, bool);
+ itkGetConstMacro(DebugFlag, bool);
+ itkBooleanMacro(DebugFlag);
+
+ itkSetMacro(SoughtVesselSeedName, std::string);
+ itkGetConstMacro(SoughtVesselSeedName, std::string);
+
+ itkSetMacro(SoughtVesselName, std::string);
+ itkGetConstMacro(SoughtVesselName, std::string);
+
+ itkSetMacro(OutputFilename, std::string);
+ itkGetConstMacro(OutputFilename, std::string);
+
+ itkSetMacro(MaxNumberOfFoundBifurcation, int);
+ itkGetConstMacro(MaxNumberOfFoundBifurcation, int);
+
+ itkSetMacro(FinalOpeningRadius, int);
+ itkGetConstMacro(FinalOpeningRadius, int);
+
+ protected:
+ ExtractMediastinalVesselsFilter();
+ virtual ~ExtractMediastinalVesselsFilter() {}
+
+ virtual void GenerateOutputInformation();
+ virtual void GenerateInputRequestedRegion();
+ virtual void GenerateData();
+
+ bool m_DebugFlag;
+ ImagePointer m_Input;
+ MaskImagePointer m_Working_Support;
+ MaskImagePointer m_Mediastinum;
+ MaskImagePointer m_Mask;
+ MaskImagePixelType m_BackgroundValue;
+ MaskImagePixelType m_ForegroundValue;
+ MaskImagePixelType m_TemporaryForegroundValue;
+ ImagePixelType m_ThresholdHigh;
+ ImagePixelType m_ThresholdLow;
+ int m_ErosionRadius;
+ int m_DilatationRadius;
+ double m_MaxDistancePostToCarina;
+ double m_MaxDistanceAntToCarina;
+ double m_MaxDistanceLeftToCarina;
+ double m_MaxDistanceRightToCarina;
+ int m_MaxNumberOfFoundBifurcation;
+ int m_FinalOpeningRadius;
+
+ std::vector<MaskSlicePointer> m_slice_recon;
+ std::vector<MaskSlicePointer> m_slice_recon2;
+
+ // Resulting structures
+ MaskImageType::Pointer m_SoughtVessel;
+ std::string m_SoughtVesselSeedName;
+ std::string m_SoughtVesselName;
+ std::string m_OutputFilename;
+
+ void CropInputImage();
+ void TrackBifurcationFromPoint(MaskImagePointer & recon,
+ std::vector<MaskSlicePointer> & slices_recon,
+ MaskImagePointType point3D,
+ MaskImagePointType pointMaxSlice,
+ LabelType newLabel,
+ std::vector<MaskImagePointType> & bif);
+
+ void TrackVesselsFromPoint(MaskImagePointer & recon,
+ std::vector<MaskSlicePointer> & slices_recon,
+ MaskImagePointType point3D,
+ MaskImagePointType pointMaxSlice,
+ LabelType newLabel);
+
+ private:
+ ExtractMediastinalVesselsFilter(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+
+ }; // end class
+ //--------------------------------------------------------------------
+
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkExtractMediastinalVesselsFilter.txx"
+#endif
+
+#endif
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ ======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSFILTER_TXX
+#define CLITKEXTRACTLYMPHSTATIONSFILTER_TXX
+
+// clitk
+#include "clitkCommon.h"
+#include "clitkExtractMediastinalVesselsFilter.h"
+#include "clitkSegmentationUtils.h"
+#include "clitkReconstructWithConditionalGrayscaleDilateImageFilter.h"
+
+// itk
+#include <itkBinaryThresholdImageFilter.h>
+#include <itkMinimumMaximumImageCalculator.h>
+
+template<class T> struct index_cmp {
+ index_cmp(const T varr) : arr(varr) {}
+ bool operator()(const size_t a, const size_t b) const
+ { return arr[a] < arr[b]; }
+ const T arr;
+};
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+ExtractMediastinalVesselsFilter():
+ clitk::FilterBase(),
+ clitk::FilterWithAnatomicalFeatureDatabaseManagement(),
+ itk::ImageToImageFilter<TImageType, MaskImageType>()
+{
+ this->SetNumberOfRequiredInputs(1);
+ SetBackgroundValue(0);
+ SetForegroundValue(1);
+ SetThresholdHigh(140);
+ SetThresholdLow(55);
+ SetErosionRadius(2);
+ SetDilatationRadius(9);
+ SetMaxDistancePostToCarina(10);
+ SetMaxDistanceAntToCarina(40);
+ SetMaxDistanceLeftToCarina(35);
+ SetMaxDistanceRightToCarina(35);
+ SetSoughtVesselSeedName("NoSeedNameGiven");
+ SetFinalOpeningRadius(1);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+GenerateOutputInformation() {
+ // Get inputs
+ LoadAFDB();
+ m_Input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
+
+ // ------------------------------------------------------------------
+ // Crop the initial image superiorly and inferiorly.
+ // TODO : add options for x cm above/below
+ CropInputImage();
+
+ // ------------------------------------------------------------------
+ // Binarize the image. Need two thresholds, one high to select
+ // structures (CCL) that are almost not connected (after erosion),
+ // and one low thresholds to select the real contours. Will be
+ // reconstructed later.
+ StartNewStep("Binarize with high threshold = "+toString(GetThresholdHigh()));
+ typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> BinarizeFilterType;
+ typename BinarizeFilterType::Pointer binarizeFilter = BinarizeFilterType::New();
+ binarizeFilter->SetInput(m_Input);
+ binarizeFilter->SetLowerThreshold(GetThresholdHigh());
+ binarizeFilter->SetInsideValue(GetForegroundValue());
+ binarizeFilter->SetOutsideValue(GetBackgroundValue());
+ binarizeFilter->Update();
+ m_Mask = binarizeFilter->GetOutput();
+ StopCurrentStep<MaskImageType>(m_Mask);
+
+ // ------------------------------------------------------------------
+ StartNewStep("Binarize with low threshold = "+toString(GetThresholdLow()));
+ binarizeFilter = BinarizeFilterType::New();
+ binarizeFilter->SetInput(m_Input);
+ binarizeFilter->SetLowerThreshold(GetThresholdLow());
+ binarizeFilter->SetInsideValue(GetForegroundValue());
+ binarizeFilter->SetOutsideValue(GetBackgroundValue());
+ binarizeFilter->Update();
+ MaskImagePointer m_Mask2 = binarizeFilter->GetOutput();
+ StopCurrentStep<MaskImageType>(m_Mask2);
+
+ // ------------------------------------------------------------------
+ // Extract slices
+ StartNewStep("Detect objects : erosion, then slice by slice reconstruction");
+ std::vector<MaskSlicePointer> slices_mask;
+ clitk::ExtractSlices<MaskImageType>(m_Mask, 2, slices_mask);
+ std::vector<MaskSlicePointer> slices_mask2;
+ clitk::ExtractSlices<MaskImageType>(m_Mask2, 2, slices_mask2);
+ int radius = GetErosionRadius();
+
+ // List of working slices (debug only)
+ std::vector<MaskSlicePointer> debug_eroded;
+ // std::vector<MaskSlicePointer> debug_labeled;
+
+ // ------------------------------------------------------------------
+ // Loop Slice by Slice in order to break connectivity between
+ // CCL. Erode and reconstruct all labels at the same time without
+ // merging them.
+ for(uint i=0; i<slices_mask.size(); i++) {
+
+ /*// Erosion kernel
+ typedef itk::BinaryBallStructuringElement<MaskSliceType::PixelType,2> KernelType;
+ KernelType structuringElement;
+ structuringElement.SetRadius(radius);
+ structuringElement.CreateStructuringElement();
+ */
+
+ // Erosion -> we break the connectivity between structure
+ MaskSliceType::SizeType r;
+ r[0] = r[1] = radius;
+ MaskSlicePointer eroded = clitk::Opening<MaskSliceType>(slices_mask[i],
+ r,
+ GetBackgroundValue(),
+ GetForegroundValue());
+ /*
+ //typedef itk::BinaryErodeImageFilter<MaskSliceType, MaskSliceType, KernelType> ErodeFilterType;
+ typedef itk::BinaryMorphologicalOpeningImageFilter<MaskSliceType, MaskSliceType, KernelType> ErodeFilterType;
+ typename ErodeFilterType::Pointer eroder = ErodeFilterType::New();
+ eroder->SetInput(slices_mask[i]);
+ eroder->SetBackgroundValue(GetBackgroundValue());
+ eroder->SetForegroundValue(GetForegroundValue());
+ //eroder->SetBoundaryToForeground(true); // ?? for BinaryErodeImageFilter
+ eroder->SetKernel(structuringElement);
+ eroder->Update();
+ MaskSlicePointer eroded = eroder->GetOutput();
+ */
+
+ // Keep slice for debug
+ debug_eroded.push_back(eroded);
+
+ // Labelize (CCL)
+ MaskSlicePointer labeled =
+ clitk::Labelize<MaskSliceType>(eroded, GetBackgroundValue(), true, 1); // Fully connected !
+ // debug_labeled.push_back(labeled);
+
+ // Make Reconstruction filter : dilation all labels at the same
+ // time, prevent to merge them.
+ typedef clitk::ReconstructWithConditionalGrayscaleDilateImageFilter<MaskSliceType> ReconstructFilterType;
+ typename ReconstructFilterType::Pointer reconstructor = ReconstructFilterType::New();
+ reconstructor->SetInput(labeled);
+ reconstructor->SetIterationNumber(radius+GetDilatationRadius());
+ reconstructor->Update();
+ MaskSlicePointer s = reconstructor->GetOutput();
+
+ // Remove Initial BG of the second tresholded image
+ s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, slices_mask2[i],
+ GetBackgroundValue(), GetBackgroundValue(), true);
+ m_slice_recon.push_back(s);
+
+ } // end loop
+
+ // Build 3D images from the slice by slice processing
+ MaskImageType::Pointer eroded = clitk::JoinSlices<MaskImageType>(debug_eroded, m_Mask, 2);
+ writeImage<MaskImageType>(eroded, "erode.mhd");
+ //MaskImageType::Pointer l = clitk::JoinSlices<MaskImageType>(debug_labeled, m_Mask, 2);
+ MaskImageType::Pointer r = clitk::JoinSlices<MaskImageType>(m_slice_recon, m_Mask, 2);
+ writeImage<MaskImageType>(r, "recon1.mhd");
+
+ // ------------------------------------------------------------------
+ // Track the SoughtVessel from the given first point
+ // superiorly. This is done by TrackBifurcationFromPoint
+ MaskImagePointType SoughtVesselSeedPoint;
+ GetAFDB()->GetPoint3D(m_SoughtVesselSeedName, SoughtVesselSeedPoint);
+ MaskImagePointType MaxSlicePoint;
+ if (GetAFDB()->TagExist(m_SoughtVesselSeedName+"Max")) {
+ GetAFDB()->GetPoint3D(m_SoughtVesselSeedName+"Max", MaxSlicePoint);
+ }
+ else {
+ MaxSlicePoint = SoughtVesselSeedPoint;
+ MaxSlicePoint[2] += 1000;
+ }
+
+ // Find the label with the maximum value to set the result
+ typedef itk::MinimumMaximumImageCalculator<MaskImageType> MinMaxFilterType;
+ MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
+ ff->SetImage(r);
+ ff->ComputeMaximum();
+ LabelType newLabel = ff->GetMaximum()+1;
+
+ // the following bifurcations point will the centroids of the
+ // components obtain when (hopefully!) the SoughtVessel
+ // split into CommonArtery and SubclavianArtery.
+ std::vector<MaskImagePointType> bifurcations;
+ // TrackBifurcationFromPoint(r, m_slice_recon, SoughtVesselSeedPoint,
+ // MaxSlicePoint, newLabel, bifurcations);
+
+ TrackVesselsFromPoint(r, m_slice_recon, SoughtVesselSeedPoint,
+ MaxSlicePoint, newLabel);
+
+ // Build the final 3D image from the previous slice by slice processing
+ m_SoughtVessel = clitk::JoinSlices<MaskImageType>(m_slice_recon, m_Mask, 2);
+ writeImage<MaskImageType>(m_SoughtVessel, "recon2.mhd");
+
+ // Set binary image, (remove other labels).
+ m_SoughtVessel =
+ clitk::Binarize<MaskImageType>(m_SoughtVessel, newLabel, newLabel,
+ GetBackgroundValue(), GetForegroundValue());
+
+ // writeImage<MaskImageType>(m_SoughtVessel, "afterbinarize.mhd");
+ m_SoughtVessel = clitk::AutoCrop<MaskImageType>(m_SoughtVessel, GetBackgroundValue());
+
+ // writeImage<MaskImageType>(m_SoughtVessel, "afterautocrop.mhd");
+
+ // Clean the image : Opening (not in Z direction)
+ typename MaskImageType::SizeType rad;
+ rad[0] = rad[1] = GetFinalOpeningRadius();
+ rad[2] = 0;
+ m_SoughtVessel = clitk::Opening<MaskImageType>(m_SoughtVessel, rad,
+ GetBackgroundValue(), GetForegroundValue());
+
+ // writeImage<MaskImageType>(m_SoughtVessel, "afteropen.mhd");
+
+ // Clean the image : keep main CCL slice by slice
+ m_SoughtVessel = clitk::SliceBySliceKeepMainCCL<MaskImageType>(m_SoughtVessel,
+ GetBackgroundValue(),
+ GetForegroundValue());
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+GenerateInputRequestedRegion() {
+ //DD("GenerateInputRequestedRegion (nothing?)");
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+GenerateData() {
+ // Save in the AFDB (not write on the disk here)
+ GetAFDB()->SetImageFilename(GetSoughtVesselName(), GetOutputFilename());
+ WriteAFDB();
+ // Final Step -> graft output
+ this->GraftNthOutput(0, m_SoughtVessel);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+CropInputImage() {
+ StartNewStep("Crop the input image: SI,AP limits with carina and crop with mediastinum");
+ /*
+ Need : Trachea, Carina (roi not point),
+ */
+ // Get Trachea and Carina
+ MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");
+
+ // Compute Carina position
+ double m_CarinaZ;
+ MaskImagePointer Carina = GetAFDB()->template GetImage<MaskImageType>("Carina");
+ std::vector<MaskImagePointType> centroids;
+ clitk::ComputeCentroids<MaskImageType>(Carina, GetBackgroundValue(), centroids);
+ m_CarinaZ = centroids[1][2];
+ // add one slice to include carina
+ m_CarinaZ += Carina->GetSpacing()[2];
+ // We dont need Carina structure from now
+ Carina->Delete();
+ GetAFDB()->SetPoint3D("CarinaPoint", centroids[1]);
+
+ // Crop Inf, remove below Carina
+ m_Input =
+ clitk::CropImageRemoveLowerThan<ImageType>(m_Input, 2, m_CarinaZ, false, GetBackgroundValue());
+
+ // Crop post
+ double m_CarinaY = centroids[1][1];
+ m_Input = clitk::CropImageRemoveGreaterThan<ImageType>(m_Input, 1,
+ m_CarinaY+GetMaxDistancePostToCarina(),
+ false, GetBackgroundValue());
+ // Crop ant
+ m_Input = clitk::CropImageRemoveLowerThan<ImageType>(m_Input, 1,
+ m_CarinaY-GetMaxDistanceAntToCarina(),
+ false, GetBackgroundValue());
+ // Crop Right
+ double m_CarinaX = centroids[1][0];
+ m_Input = clitk::CropImageRemoveLowerThan<ImageType>(m_Input, 0,
+ m_CarinaX-GetMaxDistanceRightToCarina(),
+ false, GetBackgroundValue());
+ // Crop Left
+ m_Input = clitk::CropImageRemoveGreaterThan<ImageType>(m_Input, 0,
+ m_CarinaX+GetMaxDistanceLeftToCarina(),
+ false, GetBackgroundValue());
+
+ /*
+ // AutoCrop with Mediastinum, generaly only allow to remove few slices (superiorly)
+ m_Mediastinum = GetAFDB()->template GetImage<MaskImageType>("Mediastinum");
+ // Resize like input (sup to carina)
+ m_Mediastinum = clitk::ResizeImageLike<MaskImageType>(m_Mediastinum, m_Input, GetBackgroundValue());
+ // Auto crop
+ m_Mediastinum = clitk::AutoCrop<MaskImageType>(m_Mediastinum, GetBackgroundValue());
+ // Resize input
+ m_Input = clitk::ResizeImageLike<ImageType>(m_Input, m_Mediastinum, GetBackgroundValue());
+ */
+
+ // writeImage<ImageType>(m_Input, "crop.mhd");
+ // End
+ StopCurrentStep<ImageType>(m_Input);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+TrackBifurcationFromPoint(MaskImagePointer & recon,
+ std::vector<MaskSlicePointer> & slices_recon,
+ MaskImagePointType point3D,
+ MaskImagePointType pointMaxSlice,
+ LabelType newLabel,
+ std::vector<MaskImagePointType> & bifurcations) {
+ StartNewStep("Track the SoughtVessel from the seed point");
+
+ // Find first slice index
+ MaskImageIndexType index;
+ recon->TransformPhysicalPointToIndex(point3D, index);
+ int numberOfBifurcation = 0;
+ typedef typename MaskSliceType::PointType SlicePointType;
+ SlicePointType previousCenter;
+
+ // Max slice
+ MaskImageIndexType indexMaxSlice;
+ recon->TransformPhysicalPointToIndex(pointMaxSlice, indexMaxSlice);
+ uint maxSlice = indexMaxSlice[2];
+
+ // Get current label at the point3D of interest
+ uint currentSlice=index[2];
+ bool found = false;
+ LabelType previous_slice_label=recon->GetPixel(index);
+ // DD(slices_recon.size());
+ do {
+ // DD(currentSlice);
+ // Consider current reconstructed slice
+ MaskSlicePointer s = slices_recon[currentSlice];
+ MaskSlicePointer previous;
+ if (currentSlice == index[2]) previous = s;
+ else {
+ previous = slices_recon[currentSlice-1];
+ }
+
+ // Get centroids of the labels in the current slice
+ static const unsigned int Dim = MaskSliceType::ImageDimension;
+ typedef itk::ShapeLabelObject< LabelType, Dim > LabelObjectType;
+ typedef itk::LabelMap< LabelObjectType > LabelMapType;
+ typedef itk::LabelImageToLabelMapFilter<MaskSliceType, LabelMapType> ImageToMapFilterType;
+ typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New();
+ typedef itk::ShapeLabelMapFilter<LabelMapType, MaskSliceType> ShapeFilterType;
+ typename ShapeFilterType::Pointer statFilter = ShapeFilterType::New();
+ imageToLabelFilter->SetBackgroundValue(GetBackgroundValue());
+ imageToLabelFilter->SetInput(s);
+ statFilter->SetInput(imageToLabelFilter->GetOutput());
+ // statFilter->SetComputeFeretDiameter( true );
+ statFilter->ComputePerimeterOn(); // To be able to get proper Roundness value
+ statFilter->Update();
+ typename LabelMapType::Pointer labelMap = statFilter->GetOutput();
+
+ // Look what centroid inside the previous largest one
+ std::vector<SlicePointType> centroids;
+ std::vector<LabelType> centroids_label;
+ std::vector<double> labels_size;
+ for(uint c=0; c<labelMap->GetNumberOfLabelObjects(); c++) {
+ int label = labelMap->GetLabels()[c];
+ // DD(label);
+ SlicePointType center = labelMap->GetLabelObject(label)->GetCentroid();
+ // DD(center);
+ // Get label into previous slice
+ typename MaskSliceType::IndexType centerIndex;
+ previous->TransformPhysicalPointToIndex(center, centerIndex);
+ LabelType labelInPreviousSlice = previous->GetPixel(centerIndex);
+ // if this current centroid was in the current label, add it to bifurcations
+ if (labelInPreviousSlice == previous_slice_label) {
+ centroids.push_back(center);
+ centroids_label.push_back(label);
+ labels_size.push_back(labelMap->GetLabelObject(label)->GetPhysicalSize());
+ //DD(labels_size.back());
+ //DD(labelMap->GetLabelObject(label)->GetRoundness());
+ // previousCenter = centroids.back();
+ }
+ }
+
+ // -------------------------
+ // If no centroid were found
+ if (centroids.size() == 0) {
+ // Last attempt to find -> check if previous centroid is inside a CCL
+ // if in s -> get value, getcentroid add.
+ // DD(currentSlice);
+ //DD("Last change to find");
+ //DD(previous_slice_label);
+ //DD(newLabel);
+ typename MaskSliceType::IndexType previousCenterIndex;
+ s->TransformPhysicalPointToIndex(previousCenter, previousCenterIndex);
+ //DD(previousCenter);
+ LabelType labelInSlice = s->GetPixel(previousCenterIndex);
+ //DD(labelInSlice);
+ if (labelInSlice != GetBackgroundValue()) {
+ centroids.push_back(labelMap->GetLabelObject(labelInSlice)->GetCentroid());
+ centroids_label.push_back(labelInSlice);
+ labels_size.push_back(labelMap->GetLabelObject(labelInSlice)->GetPhysicalSize());
+ }
+ }
+
+ // Some centroid were found
+ // If several centroids, we found a bifurcation
+ if (centroids.size() > 1) {
+ // int n = centroids.size();
+ // Debug point
+ std::vector<ImagePointType> d;
+ clitk::PointsUtils<MaskImageType>::Convert2DListTo3DList(centroids, currentSlice, m_Mask, d);
+ // DDV(d, d.size());
+
+ /*
+ // try one or all centroids
+ std::vector<
+ for(uint a<=0; a<nb++; a++) {
+ DD(a);
+ // Create the list of candidates
+ std::vector<int> c;
+ if (a==nb) { for(uint x=0; x<nb; x++) c.push_back(x); }
+ else c.push_back(a);
+ DD(a.size());
+
+ // Test size
+ double size=0.0;
+ for(uint x=0; x<c.size(); c++) { size += labels_size[c[x]]; }
+ DD(size);
+ */
+
+
+ // new potential bifurcation found
+ numberOfBifurcation++;
+ // If the number of bifurcation is greater than the required one, we stop
+ if (numberOfBifurcation > GetMaxNumberOfFoundBifurcation()) {
+ found = true;
+ //DD("max bif reach");
+ for(uint c=0; c<centroids.size(); c++) {
+ ImagePointType bif;
+ clitk::PointsUtils<MaskImageType>::Convert2DTo3D(centroids[c], m_Mask, currentSlice, bif);
+ bifurcations.push_back(bif);
+ }
+ }
+ // Else we continue along the main (largest) connected component
+ else {
+ int indexOfLargest = 0;
+ for(uint b=0; b<centroids.size(); b++) {
+ if (labels_size[b] > labels_size[indexOfLargest]) {
+ indexOfLargest = b;
+ }
+ }
+ //DD(indexOfLargest);
+ //DD(labels_size[indexOfLargest]);
+ SlicePointType c = centroids[indexOfLargest];
+ LabelType l = centroids_label[indexOfLargest];
+ //DD(l);
+ //DD(c);
+ centroids.clear();
+ centroids.push_back(c);
+ centroids_label.clear();
+ centroids_label.push_back(l);
+ }
+ }
+
+
+ /* ==> here all centroid are considered as ok.*/
+
+ // REMOVE IF CENTROID=1, REPLACE BY >0
+
+ // if only one centroids, we change the current image with the current label
+ if (centroids.size() == 1) {
+ //DD(centroids_label[0]);
+ s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, s, centroids_label[0], newLabel, true);
+ slices_recon[currentSlice] = s;
+ previous_slice_label = newLabel;
+ // It can happend that several CCL share this same label. To
+ // prevent this case, we only consider the one that contains
+ // the centroid.
+ MaskSlicePointer temp = clitk::Binarize<MaskSliceType>(s, newLabel, newLabel, GetBackgroundValue(), GetForegroundValue());
+ // writeImage<MaskSliceType>(temp, "bin-"+toString(currentSlice)+".mhd");
+ temp = clitk::Labelize<MaskSliceType>(temp, GetBackgroundValue(), true, 1);
+ //writeImage<MaskSliceType>(temp, "label-"+toString(currentSlice)+".mhd");
+ typename MaskSliceType::IndexType centroids_index;
+ temp->TransformPhysicalPointToIndex(centroids[0], centroids_index);
+ typename MaskSliceType::PixelType v = temp->GetPixel(centroids_index);
+
+ // It can happend that the centroid is inside the BG, so we keep
+ // the largest CCL (the first);
+ if (v == GetBackgroundValue()) {
+ // DD(currentSlice);
+ // DD("inside BG");
+ // DD(centroids[0]);
+ v = 1; // largest one
+ }
+
+ //DD(v);
+ temp = clitk::Binarize<MaskSliceType>(temp, v, v, GetBackgroundValue(), newLabel);
+ //writeImage<MaskSliceType>(temp, "relabel-"+toString(currentSlice)+".mhd");
+ s = temp;
+ slices_recon[currentSlice] = s;
+
+ // I need to recompute the centroid if we have removed some
+ // connected component.
+ clitk::ComputeCentroids<MaskSliceType>(s, GetBackgroundValue(), centroids);
+ previousCenter = centroids[1];
+ }
+
+ if (centroids.size() == 0) {
+ // DD("ZERO");
+ found = true;
+ }
+
+ if (currentSlice == slices_recon.size()-1) {
+ // DD("end of slices");
+ found = true;
+ }
+
+ if (currentSlice == maxSlice) {
+ // DD("end max slice");
+ found = true;
+ }
+
+ // iterate
+ ++currentSlice;
+ } while (!found);
+
+ // End
+ StopCurrentStep();
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+TrackVesselsFromPoint(MaskImagePointer & recon,
+ std::vector<MaskSlicePointer> & slices,
+ MaskImagePointType seedPoint,
+ MaskImagePointType pointMaxSlice,
+ LabelType newLabel) {
+ StartNewStep("Track the SoughtVessel from the seed point");
+
+ // Find first slice index
+ MaskImageIndexType seedIndex;
+ recon->TransformPhysicalPointToIndex(seedPoint, seedIndex);
+ // int numberOfBifurcation = 0;
+ typedef typename MaskSliceType::PointType SlicePointType;
+ SlicePointType previousCentroid;
+ previousCentroid[0] = seedPoint[0];
+ previousCentroid[1] = seedPoint[1];
+
+ // Max slice
+ MaskImageIndexType indexMaxSlice;
+ recon->TransformPhysicalPointToIndex(pointMaxSlice, indexMaxSlice);
+ uint maxSlice = std::min((uint)indexMaxSlice[2], (uint)slices.size());
+ // DD(maxSlice);
+
+ // Get current label at the seedPoint of interest
+ uint currentSlice=seedIndex[2];
+ bool found = false;
+ // LabelType previous_slice_label=recon->GetPixel(seedIndex);
+
+ // Currrent label map variable
+ typedef itk::ShapeLabelObject< LabelType, 2> LabelObjectType;
+ typedef itk::LabelMap< LabelObjectType > LabelMapType;
+ typename LabelMapType::Pointer labelMap;
+ std::vector<typename LabelObjectType::Pointer> shapeObjectsList;
+ std::vector<MaskSlicePointer> shapeObjectsSliceList; // keep slice, useful for 'union'
+ typename LabelObjectType::Pointer previousShapeObject;
+
+ do {
+ // Debug
+ std::cout << std::endl;
+ //DD(currentSlice);
+ ImagePointType c;
+ clitk::PointsUtils<MaskImageType>::Convert2DTo3D(previousCentroid, m_Mask, currentSlice-1, c);
+ //DD(c);
+
+ // Consider current reconstructed slice
+ MaskSlicePointer s = slices[currentSlice];
+ MaskSlicePointer previous;
+ shapeObjectsList.clear();
+ shapeObjectsSliceList.clear();
+
+ // Get shape of all labels in the current slice (it is already labelized)
+
+ // Normal -> same CCL with different label
+ // PB -> sometimes same label in different CCL ! car growing
+ //ADD les deux l+s ? mais avec max entre chaque ccl number (bof)
+ /*
+ for each label in s -> map avec label in l; if different -> change
+ */
+ MaskSlicePointer ll = clitk::Labelize<MaskSliceType>(s, GetBackgroundValue(), true, 1);
+ // writeImage<MaskSliceType>(s, "slice-"+toString(currentSlice)+".mhd");
+ //writeImage<MaskSliceType>(ll, "slice-label-"+toString(currentSlice)+".mhd");
+ typedef itk::ImageRegionIteratorWithIndex<MaskSliceType> IteratorType;
+ IteratorType its(s, s->GetLargestPossibleRegion());
+ IteratorType itl(ll, ll->GetLargestPossibleRegion());
+ std::map<LabelType, LabelType> labelInL;
+ std::map<LabelType, std::map<LabelType, LabelType> > labelToChange;
+ its.GoToBegin();
+ itl.GoToBegin();
+ int currentLabel = newLabel+10;
+ while (!its.IsAtEnd()) {
+ LabelType labs = its.Get();
+ if (labs != GetBackgroundValue()) {
+ LabelType labl = itl.Get();
+ if (labelInL.find(labs) == labelInL.end()) { // Not found in map, first time
+ // DD("first");
+ labelInL[labs] = labl;
+ //DD(labs);
+ //DD(labl);
+ }
+ else {
+ if (labelInL[labs] != labl) { // I found a labs with a different labl. Store it.
+ if (labelToChange[labs].find(labl) == labelToChange[labs].end()) { // if not already found
+ //DD("found");
+ //DD(labs);
+ //DD(labl);
+ //DD(labelInL[labs]);
+ //DD(currentLabel);
+ labelToChange[labs][labl] = currentLabel;
+ ++currentLabel;
+ }
+ }
+ }
+ }
+ ++its;
+ ++itl;
+ }
+
+ its.GoToBegin();
+ itl.GoToBegin();
+ while (!its.IsAtEnd()) {
+ LabelType labs = its.Get();
+ if (labs != GetBackgroundValue()) { // if not BG
+ LabelType labl = itl.Get();
+ if (labelToChange[labs].find(labl) != labelToChange[labs].end()) { // if some labs can change their label
+ its.Set(labelToChange[labs][labl]); // change with the label for <labs-labl>
+ }
+ }
+ ++its;
+ ++itl;
+ } // end while
+
+ // writeImage<MaskSliceType>(s, "slice-final"+toString(currentSlice)+".mhd");
+
+
+ labelMap = clitk::ComputeLabelMap<MaskSliceType, LabelType>(s, GetBackgroundValue(), true);
+ // DD(labelMap->GetNumberOfLabelObjects());
+
+ // If this is the first slice, get the object that contains the seed
+ if (currentSlice == seedIndex[2]) {
+ // DD("First slice");
+ LabelType l = recon->GetPixel(seedIndex);
+ // DD(l);
+ shapeObjectsList.push_back(labelMap->GetLabelObject(l));
+ shapeObjectsSliceList.push_back(s);
+ previous = s;
+ previousCentroid = shapeObjectsList[0]->GetCentroid();
+ previousShapeObject = shapeObjectsList[0];
+ }
+ else {
+ previous = slices[currentSlice-1];
+ // Loop on labels to check if centroid is on the previous contour
+ for(uint c=0; c<labelMap->GetNumberOfLabelObjects(); c++) {
+ // Get the current label number
+ int label = labelMap->GetLabels()[c];
+ //DD(label);
+ // Get the centroids
+ SlicePointType centroid = labelMap->GetLabelObject(label)->GetCentroid();
+ // Convert centroid into index in previous slice (same coordinate)
+ typename MaskSliceType::IndexType centroidIndex;
+ previous->TransformPhysicalPointToIndex(centroid, centroidIndex);
+ LabelType labelInPreviousSlice = previous->GetPixel(centroidIndex);
+ // if this current centroid was in the current label, we keep it
+ //DD(labelInPreviousSlice);
+ if (labelInPreviousSlice == newLabel) {
+ shapeObjectsList.push_back(labelMap->GetLabelObject(label));
+ shapeObjectsSliceList.push_back(s);
+ }
+ }
+ }
+
+
+ // Potentially the previous centroid could be inside another
+ // labels, we consider i
+ typename MaskSliceType::IndexType previousCentroidIndex;
+ s->TransformPhysicalPointToIndex(previousCentroid, previousCentroidIndex);
+ LabelType l = s->GetPixel(previousCentroidIndex);
+ //DD(l);
+ if (l != 0) { // if is not the background label
+ int index = -1;
+ for(uint c=0; c<shapeObjectsList.size(); c++) {
+ if (shapeObjectsList[c]->GetLabel() == l) {
+ index = c;
+ }
+ }
+ if (index == -1) {
+ //DD("not inside");
+ shapeObjectsList.push_back(labelMap->GetLabelObject(l));
+ shapeObjectsSliceList.push_back(s);
+ }
+ else {
+ // DD("already inside");
+ }
+ }
+
+ // for(uint c=0; c<shapeObjectsList.size(); c++) {
+ // std::cout << c << " " << shapeObjectsList[c]->GetLabel() << " "
+ // << shapeObjectsList[c]->GetCentroid() << std::endl;
+ // }
+
+
+ // If several candidates, add one more with the union of all candidates
+ MaskSlicePointer temp;
+ if (shapeObjectsList.size() > 1) {
+ //DD("add union");
+ // Copy the slice
+ temp = clitk::Clone<MaskSliceType>(s);
+ // change label to a single label
+ LabelType l = newLabel+1;
+ for(uint c=0; c<shapeObjectsList.size(); c++) {
+ LabelType ll = shapeObjectsList[c]->GetLabel();
+ temp = clitk::SetBackground<MaskSliceType, MaskSliceType>(temp, temp, ll, l, true);
+ }
+ // Compute Label object properties
+ labelMap = clitk::ComputeLabelMap<MaskSliceType, LabelType>(temp, GetBackgroundValue(), true);
+ shapeObjectsList.push_back(labelMap->GetLabelObject(l));
+ shapeObjectsSliceList.push_back(temp);
+ }
+
+ /*
+ for(uint c=0; c<shapeObjectsList.size(); c++) {
+ std::cout << c << " " << shapeObjectsList[c]->GetLabel() << " "
+ << shapeObjectsList[c]->GetCentroid() << std::endl;
+ }
+ */
+
+
+ for(uint c=0; c<shapeObjectsList.size(); c++) {
+ ImagePointType cc;
+ clitk::PointsUtils<MaskImageType>::Convert2DTo3D(shapeObjectsList[c]->GetCentroid(), m_Mask, currentSlice, cc);
+ // std::cout << c << " " << shapeObjectsList[c]->GetLabel() << " "
+ // // << shapeObjectsList[c]->GetCentroid() << " "
+ // << cc << " "
+ // << shapeObjectsList[c]->GetPhysicalSize() << " "
+ // << shapeObjectsList[c]->GetRoundness() << std::endl;
+ }
+
+
+ if (shapeObjectsList.size() == 0) {
+ found = true;
+ }
+ else {
+ // Heuristic to select the good one. For each candidate, we consider the size
+ std::vector<double> sizes;
+ std::vector<double> roundness;
+ std::vector<size_t> index_sizes;
+ std::vector<size_t> index_roundness;
+ double previousSize = previousShapeObject->GetPhysicalSize();
+ //DD(previousSize);
+ for(uint c=0; c<shapeObjectsList.size(); c++) {
+ double s = shapeObjectsList[c]->GetPhysicalSize();
+ sizes.push_back(fabs(previousSize-s)/previousSize);
+ roundness.push_back(fabs(1.0-shapeObjectsList[c]->GetRoundness()));
+ index_sizes.push_back(c);
+ index_roundness.push_back(c);
+ }
+ //DDV(sizes, sizes.size());
+ //DDV(roundness, roundness.size());
+ // DDV(index_sizes, index_sizes.size());
+ // DDV(index_roundness, index_roundness.size());
+ sort(index_sizes.begin(), index_sizes.end(), index_cmp<std::vector<double>&>(sizes));
+ sort(index_roundness.begin(), index_roundness.end(), index_cmp<std::vector<double>&>(roundness));
+ //DDV(index_sizes, index_sizes.size());
+ // DDV(index_roundness, index_roundness.size());
+
+ // TEMPORARY GET THE FIRST
+ int best = index_sizes[0];
+ // if (currentSlice == seedIndex[2]) { // first contour => idiot, first = single contour
+ // best = index_roundness[0]; // best is more round
+ // }
+ LabelType label = shapeObjectsList[best]->GetLabel();
+ // DD(label);
+ s = shapeObjectsSliceList[best];
+ s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, s, label, newLabel, true);
+
+ // HERE
+
+ // It can happend that several CCL share this same label. To
+ // prevent this case, we only consider the one that contains
+ // the centroid.
+
+ // TODO -> PREVIOUS CENTROID ???
+
+ MaskSlicePointer temp = clitk::Binarize<MaskSliceType>(s, newLabel, newLabel, GetBackgroundValue(), GetForegroundValue());
+ temp = clitk::Labelize<MaskSliceType>(temp, GetBackgroundValue(), true, 1);
+ typename MaskSliceType::IndexType centroids_index;
+ temp->TransformPhysicalPointToIndex(shapeObjectsList[best]->GetCentroid(), centroids_index);
+ typename MaskSliceType::PixelType v = temp->GetPixel(centroids_index);
+ if (v == GetBackgroundValue()) {
+ // DD(currentSlice);
+ // DD("inside BG");
+ //DD(centroids[0]);
+ v = 1; // largest one
+ }
+
+ //DD(v);
+ temp = clitk::Binarize<MaskSliceType>(temp, v, v, GetBackgroundValue(), newLabel);
+ //writeImage<MaskSliceType>(temp, "relabel-"+toString(currentSlice)+".mhd");
+ s = temp;
+
+
+ // end
+ slices[currentSlice] = s;
+ previousCentroid = shapeObjectsList[best]->GetCentroid();
+ previousShapeObject = shapeObjectsList[best];
+ }
+
+ ++currentSlice;
+
+ if (currentSlice == maxSlice) {
+ // DD("end max slice");
+ found = true;
+ }
+
+ } while (!found);
+
+ /*
+ // -------------------------
+ // If no centroid were found
+ if (shapeObjectsList.size() == 0) {
+ // Last attempt to find -> check if previous centroid is inside a CCL
+ // if in s -> get value, getcentroid add.
+ DD(currentSlice);
+ DD("Last change to find");
+ DD(previous_slice_label);
+ DD(newLabel);
+ typename MaskSliceType::IndexType previousCentroidIndex;
+ s->TransformPhysicalPointToIndex(previousCentroid, previousCentroidIndex);
+ DD(previousCentroid);
+ LabelType labelInSlice = s->GetPixel(previousCentroidIndex);
+ DD(labelInSlice);
+ if (labelInSlice != GetBackgroundValue()) {
+ centroids.push_back(labelMap->GetLabelObject(labelInSlice)->GetCentroid());
+ centroids_label.push_back(labelInSlice);
+ labels_size.push_back(labelMap->GetLabelObject(labelInSlice)->GetPhysicalSize());
+ }
+ }
+
+ // Some centroid were found
+ // If several centroids, we found a bifurcation
+ if (centroids.size() > 1) {
+ // int n = centroids.size();
+ // Debug point
+ std::vector<ImagePointType> d;
+ clitk::PointsUtils<MaskImageType>::Convert2DListTo3DList(centroids, currentSlice, m_Mask, d);
+ DDV(d, d.size());
+
+ // new potential bifurcation found
+ numberOfBifurcation++;
+ // If the number of bifurcation is greater than the required one, we stop
+ if (numberOfBifurcation > GetMaxNumberOfFoundBifurcation()) {
+ found = true;
+ DD("max bif reach");
+ for(uint c=0; c<centroids.size(); c++) {
+ ImagePointType bif;
+ clitk::PointsUtils<MaskImageType>::Convert2DTo3D(centroids[c], m_Mask, currentSlice, bif);
+ bifurcations.push_back(bif);
+ }
+ }
+ // Else we continue along the main (largest) connected component
+ else {
+ int indexOfLargest = 0;
+ for(uint b=0; b<centroids.size(); b++) {
+ if (labels_size[b] > labels_size[indexOfLargest]) {
+ indexOfLargest = b;
+ }
+ }
+ DD(indexOfLargest);
+ DD(labels_size[indexOfLargest]);
+ SlicePointType c = centroids[indexOfLargest];
+ LabelType l = centroids_label[indexOfLargest];
+ DD(l);
+ DD(c);
+ centroids.clear();
+ centroids.push_back(c);
+ centroids_label.clear();
+ centroids_label.push_back(l);
+ }
+ }
+ */
+
+ /* ==> here all centroid are considered as ok.*/
+
+ /*
+ // REMOVE IF CENTROID=1, REPLACE BY >0
+
+ // if only one centroids, we change the current image with the current label
+ if (centroids.size() == 1) {
+ DD(centroids_label[0]);
+ s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, s, centroids_label[0], newLabel, true);
+ slices[currentSlice] = s;
+ previous_slice_label = newLabel;
+ // It can happend that several CCL share this same label. To
+ // prevent this case, we only consider the one that contains
+ // the centroid.
+ MaskSlicePointer temp = clitk::Binarize<MaskSliceType>(s, newLabel, newLabel, GetBackgroundValue(), GetForegroundValue());
+ // writeImage<MaskSliceType>(temp, "bin-"+toString(currentSlice)+".mhd");
+ temp = clitk::Labelize<MaskSliceType>(temp, GetBackgroundValue(), true, 1);
+ //writeImage<MaskSliceType>(temp, "label-"+toString(currentSlice)+".mhd");
+ typename MaskSliceType::IndexType centroids_index;
+ temp->TransformPhysicalPointToIndex(centroids[0], centroids_index);
+ typename MaskSliceType::PixelType v = temp->GetPixel(centroids_index);
+
+ // It can happend that the centroid is inside the BG, so we keep
+ // the largest CCL (the first);
+ if (v == GetBackgroundValue()) {
+ DD(currentSlice);
+ DD("inside BG");
+ DD(centroids[0]);
+ v = 1; // largest one
+ }
+
+ //DD(v);
+ temp = clitk::Binarize<MaskSliceType>(temp, v, v, GetBackgroundValue(), newLabel);
+ //writeImage<MaskSliceType>(temp, "relabel-"+toString(currentSlice)+".mhd");
+ s = temp;
+ slices[currentSlice] = s;
+
+ // I need to recompute the centroid if we have removed some
+ // connected component.
+ clitk::ComputeCentroids<MaskSliceType>(s, GetBackgroundValue(), centroids);
+ previousCentroid = centroids[1];
+ }
+
+ if (centroids.size() == 0) {
+ DD("ZERO");
+ found = true;
+ }
+
+ if (currentSlice == slices.size()-1) {
+ DD("end of slices");
+ found = true;
+ }
+
+ if (currentSlice == maxSlice) {
+ DD("end max slice");
+ found = true;
+ }
+
+ // iterate
+ ++currentSlice;
+ } while (!found);
+ */
+
+ // End
+ StopCurrentStep();
+}
+//--------------------------------------------------------------------
+
+
+#endif //#define CLITKEXTRACTMEDIASTINALVESSELSFILTER_TXX
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_H
+#define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_H
+
+#include "clitkIO.h"
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkExtractMediastinalVesselsFilter.h"
+
+//--------------------------------------------------------------------
+namespace clitk
+{
+
+ template<class ArgsInfoType>
+ class ITK_EXPORT ExtractMediastinalVesselsGenericFilter:
+ public ImageToImageGenericFilter<ExtractMediastinalVesselsGenericFilter<ArgsInfoType> >
+ {
+
+ public:
+ //--------------------------------------------------------------------
+ ExtractMediastinalVesselsGenericFilter();
+
+ //--------------------------------------------------------------------
+ typedef ImageToImageGenericFilter<ExtractMediastinalVesselsGenericFilter<ArgsInfoType> > Superclass;
+ typedef ExtractMediastinalVesselsGenericFilter Self;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ //--------------------------------------------------------------------
+ itkNewMacro(Self);
+ itkTypeMacro(ExtractMediastinalVesselsGenericFilter, LightObject);
+
+ //--------------------------------------------------------------------
+ // Options for the GenericFilter
+ void SetArgsInfo(const ArgsInfoType & a);
+
+ //--------------------------------------------------------------------
+ // Options for the Filter
+ template<class FilterType>
+ void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
+
+ //--------------------------------------------------------------------
+ // Main function called each time the filter is updated
+ template<class ImageType>
+ void UpdateWithInputImageType();
+
+ protected:
+ template<unsigned int Dim> void InitializeImageType();
+ ArgsInfoType mArgsInfo;
+
+ private:
+ ExtractMediastinalVesselsGenericFilter(const Self&); //purposely not implemented
+ void operator=(const Self&); //purposely not implemented
+
+ }; // end class
+ //--------------------------------------------------------------------
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkExtractMediastinalVesselsGenericFilter.txx"
+#endif
+
+#endif // #define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_H
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+ ======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_TXX
+#define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_TXX
+
+#include "clitkImageCommon.h"
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::ExtractMediastinalVesselsGenericFilter():
+ ImageToImageGenericFilter<Self>("ExtractMediastinalVessels")
+{
+ // Default values
+ cmdline_parser_clitkExtractMediastinalVessels_init(&mArgsInfo);
+ InitializeImageType<3>(); // Only for 3D images
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<unsigned int Dim>
+void clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::InitializeImageType()
+{
+ ADD_IMAGE_TYPE(Dim, short); // Can add float later
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+void clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a)
+{
+ mArgsInfo=a;
+ SetIOVerbose(mArgsInfo.verbose_flag);
+ if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+ if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void
+clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f)
+{
+ f->SetVerboseOptionFlag(mArgsInfo.verbose_flag);
+ f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+ f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+ f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
+ f->SetAFDBFilename(mArgsInfo.afdb_arg);
+
+ f->SetThresholdHigh(mArgsInfo.thresholdHigh_arg);
+ f->SetThresholdLow(mArgsInfo.thresholdLow_arg);
+ f->SetErosionRadius(mArgsInfo.erode_arg);
+ f->SetDilatationRadius(mArgsInfo.dilate_arg);
+
+ f->SetMaxDistancePostToCarina(mArgsInfo.maxPost_arg);
+ f->SetMaxDistanceAntToCarina(mArgsInfo.maxAnt_arg);
+ f->SetMaxDistanceLeftToCarina(mArgsInfo.maxLeft_arg);
+ f->SetMaxDistanceRightToCarina(mArgsInfo.maxRight_arg);
+
+ f->SetSoughtVesselSeedName(mArgsInfo.seed_arg);
+ f->SetSoughtVesselName(mArgsInfo.name_arg);
+ f->SetMaxNumberOfFoundBifurcation(mArgsInfo.bif_arg);
+
+ f->SetFinalOpeningRadius(mArgsInfo.open_arg);
+
+ // Output filename
+ this->AddOutputFilename(mArgsInfo.output_arg);
+ f->SetOutputFilename(mArgsInfo.output_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class ImageType>
+void clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
+{
+ // Reading input
+ typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
+
+ // Create filter
+ typedef clitk::ExtractMediastinalVesselsFilter<ImageType> FilterType;
+ typename FilterType::Pointer filter = FilterType::New();
+
+ // Set global Options
+ filter->SetInput(input);
+ SetOptionsFromArgsInfoToFilter<FilterType>(filter);
+
+ // Go !
+ filter->Update();
+
+ // Write/Save results
+ for(uint i=0; i<filter->GetNumberOfOutputs(); i++) {
+ typedef uchar MaskImagePixelType;
+ typedef itk::Image<MaskImagePixelType, 3> OutputImageType;
+ typename OutputImageType::Pointer output = filter->GetOutput(i);
+ this->template SetNextOutput<OutputImageType>(output);
+ }
+}
+//--------------------------------------------------------------------
+
+#endif //#define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_TXX
section "I/O"
option "input" i "Input CT filename" string yes
-option "afdb" a "Input Anatomical Feature DB" string no
+option "output" o "Output lungs mask filename" string yes
+option "afdb" a "Input Anatomical Feature DB (needs Patient, Lungs, Trachea, VertebralBody)" string no
option "useBones" - "If set : do use bones mask (when image is not injected)" flag off
+option "maxAntSpine" - "Distance max to anterior part of the VertebralBody (spine) in mm" double no default="10"
-option "output" o "Output lungs mask filename" string yes
-
-section "Step 1 : Left/Right limits with lungs"
option "spacing" - "Intermediate resampling spacing" double no default="6"
-option "fuzzy1" - "Fuzzy relative position threshold" double no default="0.5"
+option "ft_LR_lungs" - "RelPos LR limits lungs" double no default="0.3"
+option "ft_bones" - "RelPos AP limits bones" double no default="0.6"
+option "ft_inf_lungs" - "RelPos inf limits bones" double no default="0.05"
+option "ft_ant_sternum" - "RelPos ant limits sternum" double no default="0.5"
+
+#section "Step 1 : Left/Right limits with lungs"
section "Step 2 : Ant/Post limits with bones"
-option "fuzzy2" - "Fuzzy relative position threshold" double no default="0.6"
-option "antSpine" - "Distance max to anterior part of the spine in mm" double no default="10"
+#option "antSpine" - "Distance max to anterior part of the spine in mm" double no default="10"
-section "Step 3 : Inf limits with Lung"
-option "fuzzy3" - "Fuzzy relative position threshold" double no default="0.05"
+#section "Step 3 : Inf limits with Lung"
-section "Step x : threshold for removing bones and injected parts"
-option "upper" - "Upper threshold" double no default="150"
-option "lower" - "Lower threshold" double no default="-200"
\ No newline at end of file
+# section "Step x : threshold for removing bones and injected parts"
+# option "upper" - "Upper threshold" double no default="150"
+# option "lower" - "Lower threshold" double no default="-200"
\ No newline at end of file
//--------------------------------------------------------------------
/*
Try to extract the mediastinum part of a thorax CT.
- Inputs :
- - Patient label image
- - Lungs label image
- - Bones label image
- - Trachea label image
+ Input masks needed :
+ - Patient
+ - Lungs
+ - Bones [Optional]
+ - Trachea
+ - VertebralBody
*/
//--------------------------------------------------------------------
typedef typename MaskImageType::IndexType MaskImageIndexType;
typedef typename MaskImageType::PointType MaskImagePointType;
+ typedef itk::Image<MaskImagePixelType, 2> MaskSliceType;
+ typedef typename MaskSliceType::Pointer MaskSlicePointer;
+ typedef typename MaskSliceType::PointType MaskSlicePointType;
+
/** Standard class typedefs. */
typedef itk::ImageToImageFilter<TImageType, MaskImageType> Superclass;
typedef ExtractMediastinumFilter Self;
itkSetMacro(IntermediateSpacing, double);
itkGetConstMacro(IntermediateSpacing, double);
- itkSetMacro(FuzzyThreshold1, double);
- itkGetConstMacro(FuzzyThreshold1, double);
-
- itkSetMacro(FuzzyThreshold2, double);
- itkGetConstMacro(FuzzyThreshold2, double);
-
- itkSetMacro(FuzzyThreshold3, double);
- itkGetConstMacro(FuzzyThreshold3, double);
-
itkBooleanMacro(UseBones);
itkSetMacro(UseBones, bool);
itkGetConstMacro(UseBones, bool);
- itkSetMacro(UpperThreshold, double);
- itkGetConstMacro(UpperThreshold, double);
+ itkSetMacro(DistanceMaxToAnteriorPartOfTheVertebralBody, double);
+ itkGetConstMacro(DistanceMaxToAnteriorPartOfTheVertebralBody, double);
- itkSetMacro(LowerThreshold, double);
- itkGetConstMacro(LowerThreshold, double);
+ void SetFuzzyThreshold(std::string tag, double value);
+ double GetFuzzyThreshold(std::string tag);
protected:
ExtractMediastinumFilter();
MaskImagePixelType m_BackgroundValue;
MaskImagePixelType m_ForegroundValue;
- typename MaskImageType::Pointer output;
+ MaskImagePointer output;
+ MaskImagePointer patient;
+ MaskImagePointer lung;
+ MaskImagePointer bones;
+ MaskImagePointer trachea;
+ std::map<std::string, double> m_FuzzyThreshold;
double m_IntermediateSpacing;
- double m_FuzzyThreshold1;
- double m_FuzzyThreshold2;
- double m_FuzzyThreshold3;
bool m_UseBones;
- double m_UpperThreshold;
- double m_LowerThreshold;
+ double m_DistanceMaxToAnteriorPartOfTheVertebralBody;
+
+ void RemovePostPartOfVertebralBody();
std::string m_OutputMediastinumFilename;
itk::ImageToImageFilter<ImageType, MaskImageType>()
{
this->SetNumberOfRequiredInputs(1);
-
SetBackgroundValuePatient(0);
SetBackgroundValueLung(0);
SetBackgroundValueBones(0);
SetForegroundValueRightLung(2);
SetBackgroundValue(0);
SetForegroundValue(1);
-
SetIntermediateSpacing(6);
- SetFuzzyThreshold1(0.5);
- SetFuzzyThreshold2(0.6);
- SetFuzzyThreshold3(0.05);
-
- SetOutputMediastinumFilename("mediastinum.mhd");
-
+ SetFuzzyThreshold("LR_lungs", 0.3);
+ SetFuzzyThreshold("bones", 0.6);
+ SetFuzzyThreshold("inf_lungs", 0.05);
+ SetDistanceMaxToAnteriorPartOfTheVertebralBody(10);
+ SetOutputMediastinumFilename("mediastinum.mhd");
UseBonesOff();
}
//--------------------------------------------------------------------
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+template <class ImageType>
+void
+clitk::ExtractMediastinumFilter<ImageType>::
+SetFuzzyThreshold(std::string tag, double value)
+{
+ m_FuzzyThreshold[tag] = value;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+double
+clitk::ExtractMediastinumFilter<ImageType>::
+GetFuzzyThreshold(std::string tag)
+{
+ if (m_FuzzyThreshold.find(tag) == m_FuzzyThreshold.end()) {
+ clitkExceptionMacro("Could not find options "+tag+" in the list of FuzzyThresholds.");
+ return 0.0;
+ }
+
+ return m_FuzzyThreshold[tag];
+}
+//--------------------------------------------------------------------
+
//--------------------------------------------------------------------
template <class ImageType>
//--------------------------------------------------------------------
// Get input pointers
- clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
LoadAFDB();
ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
- MaskImagePointer patient = GetAFDB()->template GetImage <MaskImageType>("Patient");
- MaskImagePointer lung = GetAFDB()->template GetImage <MaskImageType>("Lungs");
- MaskImagePointer bones;
+ MaskImagePointer patient, lung, bones, trachea;
+ patient = GetAFDB()->template GetImage <MaskImageType>("Patient");
+ lung = GetAFDB()->template GetImage <MaskImageType>("Lungs");
if (GetUseBones()) {
bones = GetAFDB()->template GetImage <MaskImageType>("Bones");
}
- MaskImagePointer trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");
-
- clitk::PrintMemory(GetVerboseMemoryFlag(), "After read patient, lung");
+ trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");
//--------------------------------------------------------------------
- // Step 1: Crop support (patient) to lung extend in RL
+ // Step : Crop support (patient) to lung extend in RL
StartNewStep("Crop support like lungs along LR");
typedef clitk::CropLikeImageFilter<MaskImageType> CropFilterType;
typename CropFilterType::Pointer cropFilter = CropFilterType::New();
cropFilter->Update();
output = cropFilter->GetOutput();
this->template StopCurrentStep<MaskImageType>(output);
-
+
//--------------------------------------------------------------------
- // Step 2: Crop support (previous) to bones extend in AP
+ // Step : Crop support (previous) to bones extend in AP
if (GetUseBones()) {
StartNewStep("Crop support like bones along AP");
cropFilter = CropFilterType::New();
}
//--------------------------------------------------------------------
- // Step 3: patient minus lungs, minus bones, minus trachea
+ // Step : patient minus lungs, minus bones, minus trachea
StartNewStep("Patient contours minus lungs, trachea [and bones]");
typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
typename BoolFilterType::Pointer boolFilter = BoolFilterType::New();
this->template StopCurrentStep<MaskImageType>(output);
//--------------------------------------------------------------------
- // Step 4: LR limits from lung (need separate lung ?)
+ // Step : LR limits from lung (need separate lung ?)
// Get separate lung images to get only the right and left lung
// (because RelativePositionPropImageFilter only consider fg=1);
// (label must be '1' because right is greater than left). (WE DO
relPosFilter->WriteStepFlagOff();
relPosFilter->SetInput(output);
relPosFilter->SetInputObject(left_lung);
- // relPosFilter->SetInputObject(lung);
relPosFilter->AddOrientationType(RelPosFilterType::AtRightTo); // warning left lung is at right ;)
relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
- relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
+ relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("LR_lungs"));
relPosFilter->Update();
output = relPosFilter->GetOutput();
- //writeImage<MaskImageType>(right_lung, "step4-left.mhd");
relPosFilter = RelPosFilterType::New();
relPosFilter->SetInput(output);
relPosFilter->WriteStepFlagOff();
relPosFilter->SetInput(output);
relPosFilter->SetInputObject(right_lung);
- //relPosFilter->SetInputObject(lung);
relPosFilter->AddOrientationType(RelPosFilterType::AtLeftTo);
relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
- relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
+ relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("LR_lungs"));
relPosFilter->Update();
output = relPosFilter->GetOutput();
this->template StopCurrentStep<MaskImageType>(output);
//--------------------------------------------------------------------
- // Step 5: AP limits from bones
+ // Step : superior limits
+ StartNewStep("Keep inferior to CricoidCartilag");
+ // load Cricoid, get centroid, cut above (or below), lower bound
+ MaskImagePointer CricoidCartilag = GetAFDB()->template GetImage <MaskImageType>("CricoidCartilag");
+ MaskImagePointType p;
+ p[0] = p[1] = p[2] = 0.0; // to avoid warning
+ clitk::FindExtremaPointInAGivenDirection<MaskImageType>(CricoidCartilag, GetBackgroundValue(), 2, true, p);
+ output = clitk::CropImageRemoveGreaterThan<MaskImageType>(output, 2, p[2], true, GetBackgroundValue());
+ this->template StopCurrentStep<MaskImageType>(output);
+
+ //--------------------------------------------------------------------
+ // Step : AP limits from bones
// Separate the bones in the ant-post middle
MaskImageConstPointer bones_ant;
MaskImageConstPointer bones_post;
relPosFilter->SetInputObject(bones_post);
relPosFilter->AddOrientationType(RelPosFilterType::AntTo);
relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
- relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold2());
+ relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("bones"));
relPosFilter->Update();
output = relPosFilter->GetOutput();
// writeImage<MaskImageType>(output, "post.mhd");
relPosFilter->SetInputObject(bones_ant);
relPosFilter->AddOrientationType(RelPosFilterType::PostTo);
relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
- relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold2());
+ relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("bones"));
relPosFilter->Update();
output = relPosFilter->GetOutput();
this->template StopCurrentStep<MaskImageType>(output);
}
//--------------------------------------------------------------------
- // Step 6: Get CCL
+ // Step: Get CCL
StartNewStep("Keep main connected component");
output = clitk::Labelize<MaskImageType>(output, GetBackgroundValue(), false, 500);
// output = RemoveLabels<MaskImageType>(output, BG, param->GetLabelsToRemove());
GetForegroundValue(), 1, 1, 0);
this->template StopCurrentStep<MaskImageType>(output);
-
- //--------------------------------------------------------------------
- // Step 8: Trial segmentation KMeans
- if (0) {
- StartNewStep("K means");
- // Take input, crop like current mask
- typedef CropLikeImageFilter<ImageType> CropLikeFilterType;
- typename CropLikeFilterType::Pointer cropLikeFilter = CropLikeFilterType::New();
- cropLikeFilter->SetInput(input);
- cropLikeFilter->SetCropLikeImage(output);
- cropLikeFilter->Update();
- ImagePointer working_input = cropLikeFilter->GetOutput();
- writeImage<ImageType>(working_input, "crop-input.mhd");
- // Set bG at -1000
- working_input = clitk::SetBackground<ImageType, MaskImageType>(working_input, output, GetBackgroundValue(), -1000, true);
- writeImage<ImageType>(working_input, "crop-input2.mhd");
- // Kmeans
- typedef itk::ScalarImageKmeansImageFilter<ImageType> KMeansFilterType;
- typename KMeansFilterType::Pointer kmeansFilter = KMeansFilterType::New();
- kmeansFilter->SetInput(working_input);
- // const unsigned int numberOfInitialClasses = 3;
- // const unsigned int useNonContiguousLabels = 0;
- kmeansFilter->AddClassWithInitialMean(-1000);
- kmeansFilter->AddClassWithInitialMean(30);
- kmeansFilter->AddClassWithInitialMean(-40); // ==> I want this one
- DD("Go!");
- kmeansFilter->Update();
- DD("End");
- typename KMeansFilterType::ParametersType estimatedMeans = kmeansFilter->GetFinalMeans();
- const unsigned int numberOfClasses = estimatedMeans.Size();
- for ( unsigned int i = 0 ; i < numberOfClasses ; ++i ) {
- std::cout << "cluster[" << i << "] ";
- std::cout << " estimated mean : " << estimatedMeans[i] << std::endl;
- }
- MaskImageType::Pointer kmeans = kmeansFilter->GetOutput();
- kmeans = clitk::SetBackground<MaskImageType, MaskImageType>(kmeans, kmeans,
- 1, GetBackgroundValue(), true);
- writeImage<MaskImageType>(kmeans, "kmeans.mhd");
- // Get final results, and remove from current mask
- boolFilter = BoolFilterType::New();
- boolFilter->InPlaceOn();
- boolFilter->SetInput1(output);
- boolFilter->SetInput2(kmeans);
- boolFilter->SetOperationType(BoolFilterType::And);
- boolFilter->Update();
- output = boolFilter->GetOutput();
- writeImage<MaskImageType>(output, "out-kmean.mhd");
- this->template StopCurrentStep<MaskImageType>(output);
-
- // TODO -> FillMASK ?
- // comment speed ? mask ? 2 class ?
-
-
- //TODO
- // Confidence connected ?
-
- }
-
//--------------------------------------------------------------------
- // Step 8: Lower limits from lung (need separate lung ?)
- if (0) {
- // StartNewStep("Trial : minus segmented struct");
- // MaskImagePointer heart = GetAFDB()->template GetImage <MaskImageType>("heart");
- // boolFilter = BoolFilterType::New();
- // boolFilter->InPlaceOn();
- // boolFilter->SetInput1(output);
- // boolFilter->SetInput2(heart);
- // boolFilter->SetOperationType(BoolFilterType::AndNot);
- // boolFilter->Update();
- // output = boolFilter->GetOutput(); // not needed because InPlace
-
- // Not below the heart
- // relPosFilter = RelPosFilterType::New();
- // relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
- // relPosFilter->VerboseStepFlagOff();
- // relPosFilter->WriteStepFlagOff();
- // relPosFilter->SetInput(output);
- // relPosFilter->SetInputObject(heart);
- // relPosFilter->SetOrientationType(RelPosFilterType::SupTo);
- // relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
- // relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold3());
- // relPosFilter->Update();
- // output = relPosFilter->GetOutput();
- }
+ // Step: Remove post part from VertebralBody
+ StartNewStep("Remove post part according to VertebralBody");
+ RemovePostPartOfVertebralBody();
+ this->template StopCurrentStep<MaskImageType>(output);
//--------------------------------------------------------------------
- // Step 8: Lower limits from lung (need separate lung ?)
- if (0) {
- StartNewStep("Lower limits with lungs");
- // TODO BOFFF ????
- relPosFilter = RelPosFilterType::New();
- relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
- relPosFilter->VerboseStepFlagOff();
- relPosFilter->WriteStepFlagOff();
- relPosFilter->SetInput(output);
- // relPosFilter->SetInputObject(left_lung);
- relPosFilter->SetInputObject(lung);
- relPosFilter->AddOrientationType(RelPosFilterType::SupTo);
- relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
- relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold3());
- relPosFilter->Update();
- output = relPosFilter->GetOutput();
- this->template StopCurrentStep<MaskImageType>(output);
- }
+ // Step: Remove ant part according to Sternum
+ StartNewStep("Remove ant part according to Sternum");
+ MaskImagePointer Sternum = GetAFDB()->template GetImage <MaskImageType>("Sternum");
+ output = clitk::SliceBySliceRelativePosition<MaskImageType>(output, Sternum, 2,
+ GetFuzzyThreshold("ant_sternum"),
+ "PostTo", false, 3, true, false);
+ this->template StopCurrentStep<MaskImageType>(output);
//--------------------------------------------------------------------
- // Step 10: Slice by Slice CCL
+ // Step: Slice by Slice CCL
StartNewStep("Slice by Slice keep only one component");
typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
// typename ExtractSliceFilterType::Pointer
output = joinFilter->GetOutput();
this->template StopCurrentStep<MaskImageType>(output);
- //--------------------------------------------------------------------
- // Step 9: Binarize to remove too high HU
- // --> warning CCL slice by slice must be done before
- if (0) {
- StartNewStep("Remove hypersignal (bones and injected part");
- // Crop initial ct like current support
- typedef CropLikeImageFilter<ImageType> CropLikeFilterType;
- typename CropLikeFilterType::Pointer cropLikeFilter = CropLikeFilterType::New();
- cropLikeFilter->SetInput(input);
- cropLikeFilter->SetCropLikeImage(output);
- cropLikeFilter->Update();
- ImagePointer working_input = cropLikeFilter->GetOutput();
- // writeImage<ImageType>(working_input, "crop-ct.mhd");
- // Binarize
- typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> InputBinarizeFilterType;
- typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
- binarizeFilter->SetInput(working_input);
- binarizeFilter->SetLowerThreshold(GetLowerThreshold());
- binarizeFilter->SetUpperThreshold(GetUpperThreshold());
- binarizeFilter->SetInsideValue(this->GetBackgroundValue()); // opposite
- binarizeFilter->SetOutsideValue(this->GetForegroundValue()); // opposite
- binarizeFilter->Update();
- MaskImagePointer working_bin = binarizeFilter->GetOutput();
- // writeImage<MaskImageType>(working_bin, "bin.mhd");
- // Remove from support
- boolFilter = BoolFilterType::New();
- boolFilter->InPlaceOn();
- boolFilter->SetInput1(output);
- boolFilter->SetInput2(working_bin);
- boolFilter->SetOperationType(BoolFilterType::AndNot);
- boolFilter->Update();
- output = boolFilter->GetOutput();
- StopCurrentStep<MaskImageType>(output);
- }
-
//--------------------------------------------------------------------
// Step 10 : AutoCrop
StartNewStep("AutoCrop");
output = clitk::AutoCrop<MaskImageType>(output, GetBackgroundValue());
this->template StopCurrentStep<MaskImageType>(output);
- // Bones ? pb with RAM ? FillHoles ?
-
- // how to do with post part ? spine /lung ?
- // POST the spine (should be separated from the rest)
- /// DO THAT ---->>
- // histo Y on the whole bones_post (3D) -> result is the Y center on the spine (?)
- // by slice on bones_post
- // find the most ant point in the center
- // from this point go to post until out of bones.
- //
-
-
// End, set the real size
this->GetOutput(0)->SetRegions(output->GetLargestPossibleRegion());
this->GetOutput(0)->SetLargestPossibleRegion(output->GetLargestPossibleRegion());
WriteAFDB();
}
//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void
+clitk::ExtractMediastinumFilter<ImageType>::
+RemovePostPartOfVertebralBody()
+{
+
+ /*
+ Posteriorly, Station 8 abuts the descending aorta and the anterior
+ aspect of the vertebral body until an imaginary horizontal line
+ running 1 cm posterior to the anterior border of the vertebral
+ body (Fig. 3C).
+
+ => We use this definition for all the mediastinum
+
+ Find most Ant point in VertebralBody. Consider the horizontal line
+ which is 'DistanceMaxToAnteriorPartOfTheVertebralBody' away from
+ the most ant point.
+ */
+
+ // Get VertebralBody mask image
+ MaskImagePointer VertebralBody =
+ GetAFDB()->template GetImage <MaskImageType>("VertebralBody");
+
+ // Consider vertebral body slice by slice
+ std::vector<MaskSlicePointer> vertebralSlices;
+ clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vertebralSlices);
+
+ // For each slice, compute the most anterior point
+ std::map<int, MaskSlicePointType> vertebralAntPositionBySlice;
+ for(uint i=0; i<vertebralSlices.size(); i++) {
+ MaskSlicePointType p;
+ bool found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vertebralSlices[i],
+ GetBackgroundValue(),
+ 1, true, p);
+ if (found) {
+ vertebralAntPositionBySlice[i] = p;
+ }
+ else {
+ // It should not happen ! But sometimes, a contour is missing or
+ // the VertebralBody is not delineated enough inferiorly ... in
+ // those cases, we consider the first found slice.
+ // std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
+ // [ Possible alternative -> consider previous limit ]
+ }
+ }
+
+ // Convert 2D points in slice into 3D points
+ std::vector<MaskImagePointType> vertebralAntPositions;
+ clitk::PointsUtils<MaskImageType>::Convert2DMapTo3DList(vertebralAntPositionBySlice,
+ VertebralBody,
+ vertebralAntPositions);
+
+ // DEBUG : write list of points
+ clitk::WriteListOfLandmarks<MaskImageType>(vertebralAntPositions,
+ "VertebralBodyMostAnteriorPoints.txt");
+
+ // Cut support posteriorly 1cm the most anterior point of the
+ // VertebralBody. Do nothing below and above the VertebralBody. To
+ // do that compute several region, slice by slice and fill.
+ MaskImageRegionType region;
+ MaskImageSizeType size;
+ MaskImageIndexType start;
+ size[2] = 1; // a single slice
+ start[0] = output->GetLargestPossibleRegion().GetIndex()[0];
+ size[0] = output->GetLargestPossibleRegion().GetSize()[0];
+ for(uint i=0; i<vertebralAntPositions.size(); i++) {
+ typedef typename itk::ImageRegionIterator<MaskImageType> IteratorType;
+ IteratorType iter =
+ IteratorType(output, output->GetLargestPossibleRegion());
+ MaskImageIndexType index;
+ // Consider some cm posterior to most anterior positions (usually
+ // 1 cm).
+ vertebralAntPositions[i][1] += GetDistanceMaxToAnteriorPartOfTheVertebralBody();
+ // Get index of this point
+ output->TransformPhysicalPointToIndex(vertebralAntPositions[i], index);
+ // Compute region (a single slice)
+ start[2] = index[2];
+ start[1] = output->GetLargestPossibleRegion().GetIndex()[1]+index[1];
+ size[1] = output->GetLargestPossibleRegion().GetSize()[1]-start[1];
+ region.SetSize(size);
+ region.SetIndex(start);
+ // Fill region
+ if (output->GetLargestPossibleRegion().IsInside(start)) {
+ itk::ImageRegionIterator<MaskImageType> it(output, region);
+ it.GoToBegin();
+ while (!it.IsAtEnd()) {
+ it.Set(GetBackgroundValue());
+ ++it;
+ }
+ }
+ }
+}
+//--------------------------------------------------------------------
+
#endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
f->SetOutputMediastinumFilename(mArgsInfo.output_arg);
f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
+ f->SetDistanceMaxToAnteriorPartOfTheVertebralBody(mArgsInfo.maxAntSpine_arg);
f->SetUseBones(mArgsInfo.useBones_flag);
+
f->SetIntermediateSpacing(mArgsInfo.spacing_arg);
- f->SetFuzzyThreshold1(mArgsInfo.fuzzy1_arg);
- f->SetFuzzyThreshold2(mArgsInfo.fuzzy2_arg);
- f->SetFuzzyThreshold3(mArgsInfo.fuzzy3_arg);
- f->SetUpperThreshold(mArgsInfo.upper_arg);
- f->SetLowerThreshold(mArgsInfo.lower_arg);
+ f->SetFuzzyThreshold("LR_lungs", mArgsInfo.ft_LR_lungs_arg);
+ f->SetFuzzyThreshold("bones", mArgsInfo.ft_bones_arg);
+ f->SetFuzzyThreshold("inf_lungs", mArgsInfo.ft_inf_lungs_arg);
+ f->SetFuzzyThreshold("ant_sternum", mArgsInfo.ft_ant_sternum_arg);
}
//--------------------------------------------------------------------
option "lower" - "Initial lower threshold" double no
option "upper" - "Initial upper threshold" double no default="-300"
+option "openingRadius" - "Radius for opening after threshold" int no default="0"
section "First Label Image (air=1)"
itkSetMacro(LowerThreshold, InputImagePixelType);
itkGetMacro(LowerThreshold, InputImagePixelType);
- itkSetMacro(UseLowerThreshold, bool);
+ itkSetMacro(UseLowerThreshold, bool);
+ itkGetMacro(PrimaryOpeningRadius, unsigned int);
+ itkSetMacro(PrimaryOpeningRadius, unsigned int);
itkGetConstMacro(UseLowerThreshold, bool);
itkBooleanMacro(UseLowerThreshold);
bool m_DecomposeAndReconstructDuringFirstStep;
bool m_DecomposeAndReconstructDuringSecondStep;
bool m_FinalOpenClose;
+ unsigned m_PrimaryOpeningRadius;
InternalImageSizeType m_Radius1;
InternalImageSizeType m_Radius2;
int m_MaximumNumberOfLabels1;
/*=========================================================================
Program: vv http://www.creatis.insa-lyon.fr/rio/vv
- Authors belong to:
+ Authors belong to:
- University of LYON http://www.universite-lyon.fr/
- Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
#include "itkBinaryMorphologicalOpeningImageFilter.h"
#include "itkBinaryBallStructuringElement.h"
#include "itkCastImageFilter.h"
+#include "itkConstantPadImageFilter.h"
//--------------------------------------------------------------------
template <class TInputImageType>
this->SetNumberOfRequiredInputs(1);
SetBackgroundValue(0); // Must be zero
SetForegroundValue(1);
+ SetPrimaryOpeningRadius(0);
// Step 1: Threshold + CC + sort (Find low density areas)
SetUpperThreshold(-300);
SetRadius2(r);
SetMaximumNumberOfLabels2(2);
SetNumberOfNewLabels2(1);
-
+
// Step 5: Only keep label corresponding (Keep patient's labels)
SetFirstKeep(1);
SetLastKeep(1);
-
+
// Step 4: OpenClose (option)
FinalOpenCloseOff();
AutoCropOn();
//--------------------------------------------------------------------
template <class TInputImageType>
-void
+void
clitk::ExtractPatientFilter<TInputImageType>::
-SetInput(const TInputImageType * image)
+SetInput(const TInputImageType * image)
{
this->SetNthInput(0, const_cast<TInputImageType *>(image));
}
//--------------------------------------------------------------------
template <class TInputImageType>
-void
+void
clitk::ExtractPatientFilter<TInputImageType>::
-GenerateOutputInformation() {
+GenerateOutputInformation() {
clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
// Get input pointers
static const unsigned int Dim = InputImageType::ImageDimension;
//input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
-
+
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- // Step 1:
+ // Step 1:
StartNewStep("Find low densities areas");
- typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> BinarizeFilterType;
+
+ // Pad images with air to prevent patient touching the image border
+ typedef itk::ConstantPadImageFilter<InputImageType, InputImageType> PadFilterType;
+ typename PadFilterType::Pointer padFilter = PadFilterType::New();
+ padFilter->SetInput(input);
+ padFilter->SetConstant(GetUpperThreshold() - 1);
+ typename InputImageType::SizeType bounds;
+ for (unsigned i = 0; i < Dim - 1; ++i)
+ bounds[i] = 1;
+ bounds[Dim - 1] = 0;
+ padFilter->SetPadLowerBound(bounds);
+ padFilter->SetPadUpperBound(bounds);
+ padFilter->Update();
+
+ typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> BinarizeFilterType;
typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
- binarizeFilter->SetInput(input);
+ binarizeFilter->SetInput(padFilter->GetOutput());
if (m_UseLowerThreshold) binarizeFilter->SetLowerThreshold(GetLowerThreshold());
binarizeFilter->SetUpperThreshold(GetUpperThreshold());
binarizeFilter ->SetInsideValue(this->GetForegroundValue());
binarizeFilter ->SetOutsideValue(this->GetBackgroundValue());
+ padFilter->GetOutput()->ReleaseData();
+ working_image = binarizeFilter->GetOutput();
+
+ typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> KernelType;
+ unsigned int radius = this->GetPrimaryOpeningRadius();
+ if (radius > 0)
+ {
+ if (this->GetVerboseOptionFlag()) std::cout << ("Opening after threshold; R = ") << radius << std::endl;
+ KernelType kernel;
+ kernel.SetRadius(radius);
+
+ typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> OpenFilterType2;
+ typename OpenFilterType2::Pointer openFilter2 = OpenFilterType2::New();
+ openFilter2->SetInput(working_image);
+ openFilter2->SetBackgroundValue(0);
+ openFilter2->SetForegroundValue(1);
+ openFilter2->SetKernel(kernel);
+ openFilter2->Update();
+ working_image->ReleaseData();
+ working_image = openFilter2->GetOutput();
+ }
+ if (this->GetVerboseOptionFlag()) std::cout << ("Labelling") << std::endl;
// Connected component labeling
typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
- connectFilter->SetInput(binarizeFilter->GetOutput());
+ connectFilter->SetInput(working_image);
connectFilter->SetBackgroundValue(this->GetBackgroundValue());
connectFilter->SetFullyConnected(false);
-
+ connectFilter->Update();
+ working_image->ReleaseData();
+ working_image = connectFilter->GetOutput();
+
+ if (this->GetVerboseOptionFlag()) std::cout << ("RelabelComponentImageFilter") << std::endl;
// Sort labels according to size
typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
relabelFilter->InPlaceOn();
relabelFilter->SetInput(connectFilter->GetOutput());
relabelFilter->Update();
+ working_image->ReleaseData();
working_image = relabelFilter->GetOutput();
-
+
// End
StopCurrentStep<InternalImageType>(working_image);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- // [Optional]
+ // [Optional]
if (GetDecomposeAndReconstructDuringFirstStep()) {
StartNewStep("First Decompose & Reconstruct step");
typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
f->SetFullyConnected(true);
f->SetNumberOfNewLabels(GetNumberOfNewLabels1());
f->Update();
+ working_image->ReleaseData();
working_image = f->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
}
-
+
//--------------------------------------------------------------------
//--------------------------------------------------------------------
+ if (this->GetVerboseOptionFlag()) std::cout << ("Remove the air (largest area)") << std::endl;
StartNewStep("Remove the air (largest area)");
- typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> iBinarizeFilterType;
+ typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> iBinarizeFilterType;
typename iBinarizeFilterType::Pointer binarizeFilter2 = iBinarizeFilterType::New();
binarizeFilter2->SetInput(working_image);
binarizeFilter2->SetLowerThreshold(GetFirstKeep());
binarizeFilter2->SetUpperThreshold(GetLastKeep());
binarizeFilter2 ->SetInsideValue(0);
binarizeFilter2 ->SetOutsideValue(1);
- // binarizeFilter2 ->Update(); // NEEDED ?
+ binarizeFilter2 ->Update();
+ working_image->ReleaseData();
+ working_image = binarizeFilter2->GetOutput();
typename ConnectFilterType::Pointer connectFilter2 = ConnectFilterType::New();
- connectFilter2->SetInput(binarizeFilter2->GetOutput());
+ connectFilter2->SetInput(working_image);
connectFilter2->SetBackgroundValue(this->GetBackgroundValue());
connectFilter2->SetFullyConnected(false);
+ connectFilter2->Update();
+ working_image->ReleaseData();
+ working_image = connectFilter2->GetOutput();
typename RelabelFilterType::Pointer relabelFilter2 = RelabelFilterType::New();
- relabelFilter2->SetInput(connectFilter2->GetOutput());
+ relabelFilter2->SetInput(working_image);
relabelFilter2->Update();
+ working_image->ReleaseData();
working_image = relabelFilter2->GetOutput();
-
+
// Keep main label
working_image = KeepLabels<InternalImageType>
- (working_image, GetBackgroundValue(), GetForegroundValue(), 1, 1, true);
+ (working_image, GetBackgroundValue(), GetForegroundValue(), 1, 1, true);
StopCurrentStep<InternalImageType>(working_image);
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- // [Optional]
+ // [Optional]
if (GetDecomposeAndReconstructDuringSecondStep()) {
StartNewStep("Second Decompose & Reconstruct step");
typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
f->SetFullyConnected(true);
f->SetNumberOfNewLabels(GetNumberOfNewLabels2());
f->Update();
+ working_image->ReleaseData();
working_image = f->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
}
if (GetFinalOpenClose()) {
StartNewStep("Final OpenClose");
// Open
- typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> KernelType;
KernelType structuringElement;
structuringElement.SetRadius(1);
structuringElement.CreateStructuringElement();
openFilter->SetInput(working_image);
openFilter->SetBackgroundValue(this->GetBackgroundValue());
openFilter->SetForegroundValue(this->GetForegroundValue());
- openFilter->SetKernel(structuringElement);
+ openFilter->SetKernel(structuringElement);
// Close
typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> CloseFilterType;
typename CloseFilterType::Pointer closeFilter = CloseFilterType::New();
closeFilter->SetForegroundValue(this->GetForegroundValue());
// closeFilter->SetBackgroundValue(SetBackgroundValue());
closeFilter->SetKernel(structuringElement);
- closeFilter->Update();
+ closeFilter->Update();
+ working_image->ReleaseData();
working_image = closeFilter->GetOutput();
StopCurrentStep<InternalImageType>(working_image);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
- // Final Cast
+ // Final Cast
typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
caster->SetInput(working_image);
caster->Update();
+ working_image->ReleaseData();
output = caster->GetOutput();
//--------------------------------------------------------------------
typename CropFilterType::Pointer cropFilter = CropFilterType::New();
cropFilter->SetInput(output);
cropFilter->SetBackgroundValue(GetBackgroundValue());
- cropFilter->Update();
+ cropFilter->Update();
+ output->ReleaseData();
output = cropFilter->GetOutput();
StopCurrentStep<MaskImageType>(output);
}
+ else
+ {
+ // Remove Padding region
+ typedef itk::CropImageFilter<MaskImageType, MaskImageType> CropFilterType;
+ typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+ cropFilter->SetInput(output);
+ cropFilter->SetLowerBoundaryCropSize(bounds);
+ cropFilter->SetUpperBoundaryCropSize(bounds);
+ cropFilter->Update();
+ output->ReleaseData();
+ output = cropFilter->GetOutput();
+ }
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
template <class TInputImageType>
-void
+void
clitk::ExtractPatientFilter<TInputImageType>::
GenerateData() {
// Final Graft
this->GraftOutput(output);
// Store image filename into AFDB
- GetAFDB()->SetImageFilename("Patient", this->GetOutputPatientFilename());
+ GetAFDB()->SetImageFilename("Patient", this->GetOutputPatientFilename());
WriteAFDB();
}
//--------------------------------------------------------------------
-
+
#endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
f->SetUpperThreshold(mArgsInfo.upper_arg);
f->SetLowerThreshold(mArgsInfo.lower_arg);
+ f->SetPrimaryOpeningRadius(mArgsInfo.openingRadius_arg);
f->SetDecomposeAndReconstructDuringFirstStep(mArgsInfo.erode1_flag);
p.Fill(1);
SetRadius(p);
SetBoundaryToForegroundFlag(false);
+ VerboseFlagOff();
}
//--------------------------------------------------------------------
void clitk::MorphoMathFilter<ImageType>::
SetOperationType(int type)
{
- switch (type) {
- case 0: m_OperationType = Erode; return;
- case 1: m_OperationType = Dilate; return;
- case 2: m_OperationType = Open; return;
- case 3: m_OperationType = Close; return;
- case 4: m_OperationType = CondErode; return;
- case 5: m_OperationType = CondDilate; return;
- default: clitkExceptionMacro("Operation type must be between 0-5 (0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x))), 4=CondErode, 5=CondDilate)");
- }
+ if(type<0 || type>5)
+ clitkExceptionMacro("Operation type must be between 0-5 (0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x))), 4=CondErode, 5=CondDilate)");
+ m_OperationType = OperationTypeEnumeration(type);
}
//--------------------------------------------------------------------
typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
oCaster->SetInput(filter->GetOutput());
oCaster->Update();
+
this->SetNthOutput(0, oCaster->GetOutput());
+ //this->GraftOutput(oCaster->GetOutput()); // NO
}
//--------------------------------------------------------------------
connectFilter->SetBackgroundValue(0);
connectFilter->SetFullyConnected(true);
if (m_Verbose) std::cout<<"Labeling the connected components..."<<std::endl;
+ connectFilter->Update();
+ if (m_Verbose) std::cout<<"found "<< connectFilter->GetObjectCount() << std::endl;
//---------------------------------
// Sort the labels according to size
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkReconstructThroughDilationImageFilter_h
-#define clitkReconstructThroughDilationImageFilter_h
-
-/* =================================================
- * @file clitkReconstructThroughDilationImageFilter.h
- * @author
- * @date
- *
- * @brief
- *
- ===================================================*/
-
-
-// clitk include
-#include "clitkIO.h"
-#include "clitkCommon.h"
-#include "clitkConditionalBinaryDilateImageFilter.h"
-
-//itk include
-#include "itkImageToImageFilter.h"
-#include "itkBinaryBallStructuringElement.h"
-#include "itkConnectedComponentImageFilter.h"
-#include "itkStatisticsImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "itkDifferenceImageFilter.h"
-#include "itkThresholdImageFilter.h"
-
-namespace clitk
-{
-
- template <class InputImageType, class OutputImageType>
- class ITK_EXPORT ReconstructThroughDilationImageFilter :
- public itk::ImageToImageFilter<InputImageType, OutputImageType>
- {
- public:
- //----------------------------------------
- // ITK
- //----------------------------------------
- typedef ReconstructThroughDilationImageFilter Self;
- typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
- typedef itk::SmartPointer<Self> Pointer;
- typedef itk::SmartPointer<const Self> ConstPointer;
-
- // Method for creation through the object factory
- itkNewMacro(Self);
-
- // Run-time type information (and related methods)
- itkTypeMacro( ReconstructThroughDilationImageFilter, ImageToImageFilter );
-
- /** Dimension of the domain space. */
- itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
- itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
-
- //----------------------------------------
- // Typedefs
- //----------------------------------------
- typedef typename OutputImageType::RegionType OutputImageRegionType;
- typedef int InternalPixelType;
- typedef typename InputImageType::PixelType InputPixelType;
- typedef typename OutputImageType::PixelType OutputPixelType;
- typedef typename InputImageType::SizeType SizeType;
-
- //----------------------------------------
- // Set & Get
- //----------------------------------------
- itkBooleanMacro(Verbose);
- itkSetMacro( Verbose, bool);
- itkGetConstReferenceMacro( Verbose, bool);
- void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
- SizeType GetRadius(void){return m_Radius;}
- itkSetMacro( ErosionPaddingValue, OutputPixelType);
- itkGetConstMacro( ErosionPaddingValue, OutputPixelType)
- itkSetMacro( MaximumNumberOfLabels, unsigned int);
- itkGetConstMacro( MaximumNumberOfLabels, unsigned int);
- itkSetMacro( BackgroundValue, InternalPixelType);
- itkGetConstMacro( BackgroundValue, InternalPixelType);
- itkSetMacro( ForegroundValue, InternalPixelType);
- itkGetConstMacro( ForegroundValue, InternalPixelType);
-
- protected:
-
- //----------------------------------------
- // Constructor & Destructor
- //----------------------------------------
- ReconstructThroughDilationImageFilter();
- ~ReconstructThroughDilationImageFilter() {};
-
- //----------------------------------------
- // Update
- //----------------------------------------
- // Generate Data
- void GenerateData(void);
-
- // // Threaded Generate Data
- // void BeforeThreadedGenerateData(void );
- // void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
- // void AfterThreadedGenerateData(void );
- // // Override defaults
- // virtual void GenerateInputRequestedRegion();
- // virtual void GenerateOutputInformation (void);
- // virtual void EnlargeOutputRequestedRegion(DataObject *data);
- // void AllocateOutputs();
- //----------------------------------------
- // Data members
- //----------------------------------------
- bool m_Verbose;
- InternalPixelType m_BackgroundValue;
- InternalPixelType m_ForegroundValue;
- unsigned int m_MaximumNumberOfLabels;
- OutputPixelType m_ErosionPaddingValue;
- SizeType m_Radius;
-
- };
-
-
-} // end namespace clitk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkReconstructThroughDilationImageFilter.txx"
-#endif
-
-#endif // #define clitkReconstructThroughDilationImageFilter_h
-
-
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-======================================================================-====*/
-#ifndef clitkReconstructThroughDilationImageFilter_txx
-#define clitkReconstructThroughDilationImageFilter_txx
-
-namespace clitk
-{
-
- //-------------------------------------------------------------------
- // Update with the number of dimensions
- //-------------------------------------------------------------------
- template<class InputImageType, class OutputImageType>
- ReconstructThroughDilationImageFilter<InputImageType, OutputImageType>::ReconstructThroughDilationImageFilter()
- {
- m_Verbose=false;
- m_BackgroundValue=0;
- m_ForegroundValue=1;
- m_ErosionPaddingValue=static_cast<InputPixelType>(-1);
- for (unsigned int i=0; i<InputImageDimension; i++)
- m_Radius[i]=1;
- m_MaximumNumberOfLabels=10;
- }
-
-
- //-------------------------------------------------------------------
- // Update with the number of dimensions and the pixeltype
- //-------------------------------------------------------------------
- template<class InputImageType, class OutputImageType>
- void
- ReconstructThroughDilationImageFilter<InputImageType, OutputImageType>::GenerateData()
- {
-
- //---------------------------------
- // Typedefs
- //---------------------------------
-
- // Internal type
- typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
-
- // Filters used
- typedef itk::CastImageFilter<InputImageType, InternalImageType> InputCastImageFilterType;
- typedef itk::ThresholdImageFilter<InternalImageType> InputThresholdImageFilterType;
- typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
- typedef itk::BinaryBallStructuringElement<InternalPixelType,InputImageDimension > KernelType;
- typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> ConditionalBinaryDilateImageFilterType;
- typedef itk::DifferenceImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
- typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
- typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
-
- //---------------------------------
- // Cast
- //---------------------------------
- typename InputCastImageFilterType::Pointer castImageFilter=InputCastImageFilterType::New();
- castImageFilter->SetInput(this->GetInput());
- castImageFilter->Update();
-
- //---------------------------------
- // Threshold
- //---------------------------------
- typename InputThresholdImageFilterType::Pointer thresholdImageFilter=InputThresholdImageFilterType::New();
- thresholdImageFilter->SetInput(castImageFilter->GetOutput());
- thresholdImageFilter->ThresholdAbove(m_MaximumNumberOfLabels);
- thresholdImageFilter->SetOutsideValue(m_ForegroundValue);
- if(m_Verbose) std::cout<<"Thresholding the input to "<<m_MaximumNumberOfLabels<<" labels ..."<<std::endl;
- thresholdImageFilter->Update();
-
- //---------------------------------
- // Set -1 to padding value
- //---------------------------------
- typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
- setBackgroundFilter->SetInput(thresholdImageFilter->GetOutput());
- setBackgroundFilter->SetInput2(castImageFilter->GetOutput());
- setBackgroundFilter->SetMaskValue(m_ErosionPaddingValue);
- setBackgroundFilter->SetOutsideValue(-1);
- if(m_Verbose) std::cout<<"Setting the eroded region from "<<m_ErosionPaddingValue<<" to -1..."<<std::endl;
-
-
- //---------------------------------
- // Count the initial labels
- //---------------------------------
- typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
- inputStatisticsImageFilter->SetInput(setBackgroundFilter->GetOutput());
- if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
- inputStatisticsImageFilter->Update();
- unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
- if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
- unsigned int numberOfConsideredLabels=std::min(initialNumberOfLabels, m_MaximumNumberOfLabels);
- if(m_Verbose) std::cout<<"Performing dilation the first "<<numberOfConsideredLabels<<" disctictive labels..."<<std::endl;
-
- //---------------------------------
- // Dilate while change
- //---------------------------------
- typename itk::NumericTraits<InputPixelType>::AccumulateType difference=1;
- typename InternalImageType::Pointer labelImage=inputStatisticsImageFilter->GetOutput();
- typename InternalImageType::Pointer oldLabelImage=inputStatisticsImageFilter->GetOutput();
-
- // element
- KernelType structuringElement;
- structuringElement.SetRadius(m_Radius);
- structuringElement.CreateStructuringElement();
-
- while( difference)
- {
- // Dilate all labels once
- for ( int label=0; label<(int)numberOfConsideredLabels+1;label++)
- if ( m_BackgroundValue != label)
- {
- typename ConditionalBinaryDilateImageFilterType::Pointer dilateFilter=ConditionalBinaryDilateImageFilterType::New();
- dilateFilter->SetBoundaryToForeground(false);
- dilateFilter->SetKernel(structuringElement);
- dilateFilter->SetBackgroundValue (-1);
- dilateFilter->SetInput (labelImage);
- dilateFilter->SetForegroundValue (label);
- if(m_Verbose) std::cout<<"Dilating the label "<<label<<"..."<<std::endl;
- dilateFilter->Update();
- labelImage=dilateFilter->GetOutput();
- }
-
- // Difference with previous labelImage
- typename DifferenceImageFilterType::Pointer differenceFilter=DifferenceImageFilterType::New();
- differenceFilter->SetValidInput(oldLabelImage);
- differenceFilter->SetTestInput(labelImage);
- differenceFilter->Update();
- difference =differenceFilter->GetTotalDifference();
- if(m_Verbose) std::cout<<"The change in this iteration was "<<difference<<"..."<<std::endl;
- oldLabelImage=labelImage;
- }
-
- //---------------------------------
- // Set -1 to padding value
- //---------------------------------
- typename SetBackgroundImageFilterType::Pointer setBackgroundFilter2 =SetBackgroundImageFilterType::New();
- setBackgroundFilter2->SetInput(labelImage);
- setBackgroundFilter2->SetInput2(labelImage);
- setBackgroundFilter2->SetMaskValue(-1);
- setBackgroundFilter2->SetOutsideValue(m_ErosionPaddingValue);
- if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
-
- //---------------------------------
- // Cast
- //---------------------------------
- typename OutputCastImageFilterType::Pointer outputCastImageFilter=OutputCastImageFilterType::New();
- outputCastImageFilter->SetInput(setBackgroundFilter2->GetOutput());
- if(m_Verbose) std::cout<<"Casting the output..."<<std::endl;
- outputCastImageFilter->Update();
-
- //---------------------------------
- // SetOutput
- //---------------------------------
- this->SetNthOutput(0, outputCastImageFilter->GetOutput());
-
-
- }
-
-
-}//end clitk
-
-#endif //#define clitkReconstructThroughDilationImageFilter_txx
-# Tests are organized to mirror the clitk directory tree.
-# Eacho subdirectory has its own CMakeLists.txt with the compiling directives
-
-IF (BUILD_TESTING)
-
- set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/bin)
-
- # default data path is searched in the project source tree
- FIND_PATH(CLITK_DATA_PATH data PATHS ${PROJECT_SOURCE_DIR})
- IF (CLITK_DATA_PATH STREQUAL "CLITK_DATA_PATH-NOTFOUND")
- MESSAGE(FATAL_ERROR "Data path must be given when tests are enabled.")
- ENDIF (CLITK_DATA_PATH STREQUAL "CLITK_DATA_PATH-NOTFOUND")
-
- set(CLITK_DATA_PATH ${CLITK_DATA_PATH}/data)
- ADD_DEFINITIONS(-DCLITK_DATA_PATH='"${CLITK_DATA_PATH}"')
-
+cmake_policy(SET CMP0005 NEW)
+#=========================================================
+#=========================================================
+# Data tests path
+FIND_PATH(CLITK_TEST_DATA_PATH Lung3D.mhd)
+IF(NOT ${CLITK_TEST_DATA_PATH} MATCHES "NOTFOUND$")
+ SET(CLITK_TEST_DATA_PATH "${CLITK_TEST_DATA_PATH}/")
+ENDIF()
+ADD_DEFINITIONS(-DCLITK_TEST_DATA_PATH="${CLITK_TEST_DATA_PATH}")
+#=========================================================
+#=========================================================
+SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/bin)
+SET(BUILDNAME ${CMAKE_SYSTEM_NAME}${CMAKE_OSX_ARCHITECTURES} CACHE INTERNAL DOCSTRING)
+#=========================================================
+#=========================================================
+# Enabled options to test
+IF(CLITK_BUILD_TOOLS)
ADD_SUBDIRECTORY(tools)
- #ADD_SUBDIRECTORY(segmentation)
- #ADD_SUBDIRECTORY(registration)
- #ADD_SUBDIRECTORY(common)
+ENDIF()
+#IF(CLITK_BUILD_VV)
+# ADD_SUBDIRECTORY(vv)
+#ENDIF()
+# IF(CLITK_BUILD_SEGMENTATION)
+# ADD_SUBDIRECTORY(segmentation)
+# ENDIF()
+#
+# IF(CLITK_BUILD_REGISTATION)
+# ADD_SUBDIRECTORY(registration)
+# ENDIF()
+#ADD_SUBDIRECTORY(common)
+#=========================================================
-ENDIF(BUILD_TESTING)
-# Add test apps and test executions to this part
-# Test apps are compiled as any other app in the
-# project. Test executions are run using "make test"
-#
-IF(BUILD_TESTING)
+include_directories(
+ ${PROJECT_SOURCE_DIR}/common
+ ${PROJECT_SOURCE_DIR}/tools
+ ${GTEST_DIR}/include
+)
- # clitkImageInfo
- ADD_EXECUTABLE(clitkImageInfoTest clitkImageInfoTest.cxx)
- TARGET_LINK_LIBRARIES(clitkImageInfoTest ITKIO)
- ADD_TEST(NAME clitkImageInfoTest COMMAND clitkImageInfoTest)
+SET (CUSTOM_TEST_SRC
+ clitkImageInfoTest.cxx
+ vvMainTest.cxx
+)
- # clitkWriteDicomSeries
- ADD_EXECUTABLE(clitkWriteDicomSeriesTest clitkWriteDicomSeriesTest.cxx)
- TARGET_LINK_LIBRARIES(clitkWriteDicomSeriesTest ITKIO)
- ADD_TEST(NAME clitkWriteDicomSeriesTest COMMAND clitkWriteDicomSeriesTest)
+SET(BUILDNAME ${BUILDNAME}_tools CACHE INTERNAL DOCSTRING)
+ADD_DEFINITIONS(-DCLITK_TEST_TOOLS_PATH=\"${PROJECT_BINARY_DIR}/bin/\")
+SET (srcs
+ toolTestRunner.cxx
+)
-ENDIF(BUILD_TESTING)
+ADD_EXECUTABLE(toolTestRunner ${srcs})
+TARGET_LINK_LIBRARIES(toolTestRunner vvLib ${vvExternalLibs})
+SET(exe ${EXECUTABLE_OUTPUT_PATH}/toolTestRunner)
+SET(p ${CLITK_TEST_DATA_PATH})
+SET(tmpFile "feve51zd")
+#=========================================================
+# clitkImageInfo
+ADD_TEST(clitkImageInfo_4d ${exe} clitkImageInfo ${p}Deformation4D.mhd ${p}Deformation4D_ref.info)
+ADD_TEST(clitkImageInfo_3d ${exe} clitkImageInfo ${p}Lung3D.mhd ${p}Lung3D_ref.info)
+#=========================================================
+# clitkGetSpacing
+ADD_TEST(clitkGetSpacing_4d ${exe} clitkGetSpacing -i ${p}Deformation4D.mhd ${p}Deformation4D_ref.spacing)
+ADD_TEST(clitkGetSpacing_3d ${exe} clitkGetSpacing -i ${p}Lung3D.mhd ${p}Lung3D_ref.spacing)
+#=========================================================
+# clitkGetOrigin
+ADD_TEST(clitkGetOrigin_4d ${exe} clitkGetOrigin -i ${p}Deformation4D.mhd ${p}Deformation4D_ref.origin)
+ADD_TEST(clitkGetOrigin_3d ${exe} clitkGetOrigin -i ${p}Lung3D.mhd ${p}Lung3D_ref.origin)
+#=========================================================
+# clitkGetSize
+ADD_TEST(clitkGetSize_4d ${exe} clitkGetSize -i ${p}Deformation4D.mhd ${p}Deformation4D_ref.size)
+ADD_TEST(clitkGetSize_3d ${exe} clitkGetSize -i ${p}Lung3D.mhd ${p}Lung3D_ref.size)
+#=========================================================
+# clitkGetDirection
+ADD_TEST(clitkGetDirection_4d ${exe} clitkGetDirection -i ${p}Deformation4D.mhd ${p}Deformation4D_ref.direction)
+ADD_TEST(clitkGetDirection_3d ${exe} clitkGetDirection -i ${p}Lung3D.mhd ${p}Lung3D_ref.direction)
+#=========================================================
+# clitkBinarize
+ADD_TEST(clitkBinarizeBGl0.1356_4d ${exe} clitkBinarizeImage -i ${p}Deformation4D.mhd --mode BG -l 0.1356 -o Deformation4D_ref.binarizeBGl0.1356.mhd ${p}Deformation4D_ref.binarizeBGl0.1356)
+ADD_TEST(clitkBinarizeFGl0.1556_3d ${exe} clitkBinarizeImage -i ${p}Lung3D.mhd --mode FG -l 0.1556 -o Lung3D_ref.binarizeFGl0.1556.mhd ${p}Lung3D_ref.binarizeFGl0.1556)
+
+UNSET(tmpFile)
+UNSET(exe)
+UNSET(p)
\ No newline at end of file
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-#include <cstdlib>
-#include <cstdio>
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include <itksys/SystemTools.hxx>
-
-
-const size_t NUMTESTS=2;
-
-// test files
-const char mhd_files[NUMTESTS][128] = {
- CLITK_DATA_PATH"/4d/mhd/00.mhd",
- CLITK_DATA_PATH"/4d/mhd/bh.mhd"
-};
-
-// pre-written validation files. the idea
-// is that the output generated from the test
-// files match the verification files
-const char validation_files[NUMTESTS][128] = {
- CLITK_DATA_PATH"/tools/clitkImageInfoTestValidate3D.out",
- CLITK_DATA_PATH"/tools/clitkImageInfoTestValidate4D.out"
-};
-
-int main(int argc, char** argv)
-{
- system("pwd");
-
- bool failed = false;
- for (size_t i = 0; i < NUMTESTS; i++) {
- std::ostringstream cmd_line;
- cmd_line << "clitkImageInfo " << mhd_files[i] << " > clitkImageInfoTest.out";
-
- std::cout << "Executing " << cmd_line.str() << std::endl;
- system(cmd_line.str().c_str());
-
- // compare output with validation file
- std::cout << "Validating output against " << validation_files[i] << std::endl;
- bool differ = itksys::SystemTools::FilesDiffer("clitkImageInfoTest.out", validation_files[i]);
- if (differ)
- {
- failed = true;
- std::cout << "FAILED: Program output and reference do not match." << std::endl;
- }
- else
- {
- itksys::SystemTools::RemoveFile("clitkImageInfoTest.out");
- std::cout << "PASSED" << std::endl;
- }
- }
- return failed ? -1 : 0;
-}
\ No newline at end of file
+++ /dev/null
-/*=========================================================================
- Program: vv http://www.creatis.insa-lyon.fr/rio/vv
-
- Authors belong to:
- - University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
- - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
-
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the copyright notices for more information.
-
- It is distributed under dual licence
-
- - BSD See included LICENSE.txt file
- - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-#include <cstdlib>
-#include <cstdio>
-
-#include <iostream>
-#include <sstream>
-#include <cassert>
-
-#include <itksys/SystemTools.hxx>
-
-const size_t NUMTESTS=1;
-
-const char mhd_files[NUMTESTS][128] = {
- CLITK_DATA_PATH"/3d/mhd/00.mhd"
-};
-
-const char dcm_dirs[NUMTESTS][128] = {
- CLITK_DATA_PATH"/3d/dcm/1.2.840.113704.1.111.536.1248695032.26"
-};
-
-int main(int argc, char** argv)
-{
- bool failed = false;
- for (size_t i = 0; i < NUMTESTS; i++) {
- std::ostringstream cmd_line;
- cmd_line << "clitkWriteDicomSeries -i " << mhd_files[i] << " -d " << dcm_dirs[i] << " -o dcm --verbose";
-
- std::cout << "Executing " << cmd_line.str() << std::endl;
- int err = system(cmd_line.str().c_str());
- if (err != 0)
- {
- failed = true;
- std::cout << "FAILED (errno = " << err << ")" << std::endl;
- }
- else
- {
- itksys::SystemTools::RemoveADirectory("dcm");
- std::cout << "PASSED" << std::endl;
- }
- }
- return failed ? -1 : 0;
-}
\ No newline at end of file
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <fstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <itksys/SystemTools.hxx>
+const int NO_OUTPUT_OPTION=-1;
+const int TEST_EXITED=1;
+int getOutputOptionIndex(int argc, char** argv){
+ for(int i=1; i<argc; i++){
+ std::string s = argv[i];
+ if(s=="-o"){
+ return i+1;
+ }
+ }
+ return NO_OUTPUT_OPTION;
+}
+
+std::string getTmpFileName(){
+#ifdef _WIN32
+ char fileName[L_tmpnam_s];
+ errno_t err = tmpnam_s(fileName);
+#else
+ char fileName[] = "/tmp/vvTempXXXXXX";
+ int err=0;
+ int fd = mkstemp(fileName);
+ if(fd==-1) err=1;
+#endif
+ if(err){
+ std::cout<<"couldnot create file. Exiting"<<std::endl;
+ exit(TEST_EXITED);
+ }
+ return std::string(fileName);
+}
+
+void assertFalse(int fail, const std::string &message=""){
+ if(fail){
+ std::cout<<message<<std::endl;
+ exit(1);
+ }
+}
+/**
+ * argv
+ * [1] executable
+ * [2] random options
+ * [2.x] -o
+ * [3] reference file
+ *
+ * [2.x] is optional. If set a temporary file will be generated. So NO need to pass a random outputFileName
+ */
+int main(int argc, char** argv){
+ //reference file must exist or we fail
+ char* refFile = argv[argc-1];
+ assertFalse(!(itksys::SystemTools::FileExists(refFile, true)), "refFile "+std::string(refFile)+" doesn't exist");
+
+ std::ostringstream cmd_line;
+ cmd_line<<CLITK_TEST_TOOLS_PATH;
+ for(int i=1; i<argc-1; i++){
+ //we should ensure the file exists, find an -i index or a long file name maybe?
+ cmd_line<<argv[i]<<" ";
+ }
+
+ //look for the need of generating an output file
+ int outputOptionIndex = getOutputOptionIndex(argc, argv);
+ std::string outFile;
+ if(NO_OUTPUT_OPTION==outputOptionIndex){
+ outFile = getTmpFileName();
+ cmd_line<<">"<<outFile;
+ }else{
+ outFile = argv[argc-2];
+ }
+ std::cout<<cmd_line.str()<<std::endl;;
+ //run the command line
+ system(cmd_line.str().c_str());
+
+ //compare source files
+ assertFalse((itksys::SystemTools::FilesDiffer(outFile.c_str(), refFile)), "Source Files are different");
+
+ //eventually raw files associated
+ //should be passed as a boolean to check also for raw or not
+
+ std::string refRawFile = std::string(refFile)+".raw";
+
+
+ int found=outFile.find_last_of(".");
+ std::string rawFile = outFile.substr(0, found)+".raw";
+ if((itksys::SystemTools::FileExists(refRawFile.c_str(), true))){
+ //compare the raw stuff
+ if((itksys::SystemTools::FileExists(rawFile.c_str(), true))){
+ std::cout<<"Checking raws"<<std::endl;
+ assertFalse(itksys::SystemTools::FilesDiffer(refRawFile.c_str(), rawFile.c_str()), "Raws are different");
+ }
+ //file is not removed if there is a fail
+ remove(rawFile.c_str());
+ }
+ //neither the mhd is
+ remove(outFile.c_str());
+
+ //success
+ return 0;
+}
ADD_LIBRARY(clitkMedianImageFilterLib clitkMedianImageGenericFilter.cxx ${clitkMedianImageFilter_GGO_C})
IF (CLITK_BUILD_TOOLS)
- WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo)
- ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C})
- TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkDicom2Image_GGO_C clitkDicom2Image.ggo)
- ADD_EXECUTABLE(clitkDicom2Image clitkDicom2Image.cxx ${clitkDicom2Image_GGO_C})
- TARGET_LINK_LIBRARIES(clitkDicom2Image clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkImageInfo_GGO_C clitkImageInfo.ggo)
- ADD_EXECUTABLE(clitkImageInfo clitkImageInfo.cxx ${clitkImageInfo_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageInfo clitkCommon ${ITK_LIBRARIES})
-
- ADD_EXECUTABLE(clitkImageConvert clitkImageConvert.cxx)
- TARGET_LINK_LIBRARIES(clitkImageConvert clitkImageConvertLib clitkCommon ${ITK_LIBRARIES})
-
- ADD_EXECUTABLE(clitkBinarizeImage clitkBinarizeImage.cxx)
- TARGET_LINK_LIBRARIES(clitkBinarizeImage clitkBinarizeImageLib clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkVFResample_GGO_C clitkVFResample.ggo)
- ADD_EXECUTABLE(clitkVFResample clitkVFResample.cxx clitkVFResampleGenericFilter.cxx ${clitkVFResample_GGO_C})
- TARGET_LINK_LIBRARIES(clitkVFResample clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkImageCreate_GGO_C clitkImageCreate.ggo)
- ADD_EXECUTABLE(clitkImageCreate clitkImageCreate.cxx ${clitkImageCreate_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageCreate clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkZeroVF_GGO_C clitkZeroVF.ggo)
- ADD_EXECUTABLE(clitkZeroVF clitkZeroVF.cxx ${clitkZeroVF_GGO_C} clitkZeroVFGenericFilter.cxx)
- TARGET_LINK_LIBRARIES(clitkZeroVF clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkImageExtractLine_GGO_C clitkImageExtractLine.ggo)
- ADD_EXECUTABLE(clitkImageExtractLine clitkImageExtractLine.cxx ${clitkImageExtractLine_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageExtractLine clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkSplitImage_GGO_C clitkSplitImage.ggo)
- ADD_EXECUTABLE(clitkSplitImage clitkSplitImage.cxx clitkSplitImageGenericFilter.cxx ${clitkSplitImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkSplitImage clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkVFMerge_GGO_C clitkVFMerge.ggo)
- ADD_EXECUTABLE(clitkVFMerge clitkVFMerge.cxx ${clitkVFMerge_GGO_C})
- TARGET_LINK_LIBRARIES(clitkVFMerge clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkWriteDicomSeries_GGO_C clitkWriteDicomSeries.ggo)
- ADD_EXECUTABLE(clitkWriteDicomSeries clitkWriteDicomSeries.cxx ${clitkWriteDicomSeries_GGO_C})
- TARGET_LINK_LIBRARIES(clitkWriteDicomSeries clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkAverageTemporalDimension_GGO_C clitkAverageTemporalDimension.ggo)
- ADD_EXECUTABLE(clitkAverageTemporalDimension clitkAverageTemporalDimension.cxx ${clitkAverageTemporalDimension_GGO_C})
- TARGET_LINK_LIBRARIES(clitkAverageTemporalDimension clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkMedianTemporalDimension_GGO_C clitkMedianTemporalDimension.ggo)
- ADD_EXECUTABLE(clitkMedianTemporalDimension clitkMedianTemporalDimension.cxx
- ${clitkMedianTemporalDimension_GGO_C})
- TARGET_LINK_LIBRARIES(clitkMedianTemporalDimension clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkWarpImage_GGO_C clitkWarpImage.ggo)
- ADD_EXECUTABLE(clitkWarpImage clitkWarpImage.cxx ${clitkWarpImage_GGO_C} clitkWarpImageGenericFilter.cxx)
- TARGET_LINK_LIBRARIES(clitkWarpImage clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkInvertVF_GGO_C clitkInvertVF.ggo)
- ADD_EXECUTABLE(clitkInvertVF clitkInvertVF.cxx ${clitkInvertVF_GGO_C})
- TARGET_LINK_LIBRARIES(clitkInvertVF clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkAffineTransform_GGO_C clitkAffineTransform.ggo)
- ADD_EXECUTABLE(clitkAffineTransform clitkAffineTransform.cxx ${clitkAffineTransform_GGO_C})
- TARGET_LINK_LIBRARIES(clitkAffineTransform clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkSetBackground_GGO_C clitkSetBackground.ggo)
- ADD_EXECUTABLE(clitkSetBackground clitkSetBackground.cxx clitkSetBackgroundGenericFilter.cxx ${clitkSetBackground_GGO_C})
- TARGET_LINK_LIBRARIES(clitkSetBackground clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkGuerreroVentilation_GGO_C clitkGuerreroVentilation.ggo)
- ADD_EXECUTABLE(clitkGuerreroVentilation clitkGuerreroVentilation.cxx clitkGuerreroVentilationGenericFilter.cxx ${clitkGuerreroVentilation_GGO_C})
- TARGET_LINK_LIBRARIES(clitkGuerreroVentilation clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
- ADD_EXECUTABLE(clitkGammaIndex clitkGammaIndex.cxx ${clitkGammaIndex_GGO_C})
- TARGET_LINK_LIBRARIES(clitkGammaIndex vtkCommon vtkFiltering vtkGraphics vtkIO vtkImaging)
-
- ADD_EXECUTABLE(clitkImageArithm clitkImageArithm.cxx)
- TARGET_LINK_LIBRARIES(clitkImageArithm clitkImageArithmImageLib clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo)
- ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C})
- TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkFooImage_GGO_C clitkFooImage.ggo)
- ADD_EXECUTABLE(clitkFooImage clitkFooImage.cxx ${clitkFooImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
- ADD_EXECUTABLE(clitkMedianImageFilter clitkMedianImageFilter.cxx ${clitkMedianImageFilter_GGO_C})
- TARGET_LINK_LIBRARIES(clitkMedianImageFilter clitkCommon ${ITK_LIBRARIES})
-
- ADD_EXECUTABLE(clitkResampleImage clitkResampleImage.cxx)
- TARGET_LINK_LIBRARIES(clitkResampleImage clitkResampleImageLib clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkMinMaxMask_GGO_C clitkMinMaxMask.ggo)
- ADD_EXECUTABLE(clitkMinMaxMask clitkMinMaxMask.cxx ${clitkMinMaxMask_GGO_C})
- TARGET_LINK_LIBRARIES(clitkMinMaxMask clitkCommon ${ITK_LIBRARIES} )
-
- # WRAP_GGO(clitkAutoCrop_GGO_C clitkAutoCrop.ggo)
- # ADD_EXECUTABLE(clitkAutoCrop clitkAutoCrop.cxx ${clitkAutoCrop_GGO_C})
- # TARGET_LINK_LIBRARIES(clitkAutoCrop clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkDicomRTStruct2BinaryImage_GGO_C clitkDicomRTStruct2BinaryImage.ggo)
- ADD_EXECUTABLE(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct2BinaryImage.cxx ${clitkDicomRTStruct2BinaryImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkImageLog_GGO_C clitkImageLog.ggo)
- ADD_EXECUTABLE(clitkImageLog clitkImageLog.cxx ${clitkImageLog_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageLog ${ITK_LIBRARIES} clitkCommon)
-
- WRAP_GGO(clitkFilter_GGO_C clitkFilter.ggo)
- ADD_EXECUTABLE(clitkFilter clitkFilter.cxx clitkFilterGenericFilter.cxx ${clitkFilter_GGO_C})
- TARGET_LINK_LIBRARIES(clitkFilter ${ITK_LIBRARIES} clitkCommon)
-
- WRAP_GGO(clitkConeBeamProjectImage_GGO_C clitkConeBeamProjectImage.ggo)
- ADD_EXECUTABLE(clitkConeBeamProjectImage clitkConeBeamProjectImage.cxx clitkConeBeamProjectImageGenericFilter.cxx ${clitkConeBeamProjectImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkConeBeamProjectImage ${ITK_LIBRARIES} clitkCommon )
-
- WRAP_GGO(clitkComposeVF_GGO_C clitkComposeVF.ggo)
- ADD_EXECUTABLE(clitkComposeVF clitkComposeVFGenericFilter.cxx clitkComposeVF.cxx ${clitkComposeVF_GGO_C})
- TARGET_LINK_LIBRARIES(clitkComposeVF ${ITK_LIBRARIES} clitkCommon)
-
- WRAP_GGO(clitkMergeSequence_GGO_C clitkMergeSequence.ggo)
- ADD_EXECUTABLE(clitkMergeSequence clitkMergeSequence.cxx clitkMergeSequenceGenericFilter.cxx ${clitkMergeSequence_GGO_C})
- TARGET_LINK_LIBRARIES(clitkMergeSequence ${ITK_LIBRARIES} clitkCommon)
-
- WRAP_GGO(clitkBackProjectImage_GGO_C clitkBackProjectImage.ggo)
- ADD_EXECUTABLE(clitkBackProjectImage clitkBackProjectImage.cxx clitkBackProjectImageGenericFilter.cxx ${clitkBackProjectImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkBackProjectImage ${ITK_LIBRARIES} clitkCommon )
-
- ADD_EXECUTABLE(clitkCropImage clitkCropImage.cxx ${clitkCropImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkCropImage clitkCropImageLib clitkCommon ${ITK_LIBRARIES})
-
- # WRAP_GGO(clitkExtractSlice_GGO_C clitkExtractSlice.ggo)
- # ADD_EXECUTABLE(clitkExtractSlice clitkExtractSlice.cxx clitkExtractSliceGenericFilter.cxx ${clitkExtractSlice_GGO_C})
- # TARGET_LINK_LIBRARIES(clitkExtractSlice clitkCommon ${ITK_LIBRARIES})
+ WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo)
+ ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL clitkDicomInfo)
+
+ WRAP_GGO(clitkDicom2Image_GGO_C clitkDicom2Image.ggo)
+ ADD_EXECUTABLE(clitkDicom2Image clitkDicom2Image.cxx ${clitkDicom2Image_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkDicom2Image clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+ WRAP_GGO(clitkImageInfo_GGO_C clitkImageInfo.ggo)
+ ADD_EXECUTABLE(clitkImageInfo clitkImageInfo.cxx ${clitkImageInfo_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageInfo clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageInfo)
+
+ ADD_EXECUTABLE(clitkImageConvert clitkImageConvert.cxx)
+ TARGET_LINK_LIBRARIES(clitkImageConvert clitkImageConvertLib clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageConvert)
+
+ ADD_EXECUTABLE(clitkBinarizeImage clitkBinarizeImage.cxx)
+ TARGET_LINK_LIBRARIES(clitkBinarizeImage clitkBinarizeImageLib clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBinarizeImage)
+
+ WRAP_GGO(clitkVFResample_GGO_C clitkVFResample.ggo)
+ ADD_EXECUTABLE(clitkVFResample clitkVFResample.cxx clitkVFResampleGenericFilter.cxx ${clitkVFResample_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkVFResample clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFResample)
+
+ WRAP_GGO(clitkImageCreate_GGO_C clitkImageCreate.ggo)
+ ADD_EXECUTABLE(clitkImageCreate clitkImageCreate.cxx ${clitkImageCreate_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageCreate clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageCreate)
+
+ WRAP_GGO(clitkZeroVF_GGO_C clitkZeroVF.ggo)
+ ADD_EXECUTABLE(clitkZeroVF clitkZeroVF.cxx ${clitkZeroVF_GGO_C} clitkZeroVFGenericFilter.cxx)
+ TARGET_LINK_LIBRARIES(clitkZeroVF clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkZeroVF)
+
+ WRAP_GGO(clitkImageExtractLine_GGO_C clitkImageExtractLine.ggo)
+ ADD_EXECUTABLE(clitkImageExtractLine clitkImageExtractLine.cxx ${clitkImageExtractLine_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageExtractLine clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageExtractLine)
+
+ WRAP_GGO(clitkSplitImage_GGO_C clitkSplitImage.ggo)
+ ADD_EXECUTABLE(clitkSplitImage clitkSplitImage.cxx clitkSplitImageGenericFilter.cxx ${clitkSplitImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkSplitImage clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSplitImage)
+
+ WRAP_GGO(clitkVFMerge_GGO_C clitkVFMerge.ggo)
+ ADD_EXECUTABLE(clitkVFMerge clitkVFMerge.cxx ${clitkVFMerge_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkVFMerge clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFMerge)
+
+ WRAP_GGO(clitkWriteDicomSeries_GGO_C clitkWriteDicomSeries.ggo)
+ ADD_EXECUTABLE(clitkWriteDicomSeries clitkWriteDicomSeries.cxx ${clitkWriteDicomSeries_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkWriteDicomSeries clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkWriteDicomSeries)
+
+ WRAP_GGO(clitkAverageTemporalDimension_GGO_C clitkAverageTemporalDimension.ggo)
+ ADD_EXECUTABLE(clitkAverageTemporalDimension clitkAverageTemporalDimension.cxx ${clitkAverageTemporalDimension_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkAverageTemporalDimension clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkAverageTemporalDimension)
+
+ WRAP_GGO(clitkMedianTemporalDimension_GGO_C clitkMedianTemporalDimension.ggo)
+ ADD_EXECUTABLE(clitkMedianTemporalDimension clitkMedianTemporalDimension.cxx
+ ${clitkMedianTemporalDimension_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkMedianTemporalDimension clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMedianTemporalDimension)
+
+ WRAP_GGO(clitkWarpImage_GGO_C clitkWarpImage.ggo)
+ ADD_EXECUTABLE(clitkWarpImage clitkWarpImage.cxx ${clitkWarpImage_GGO_C} clitkWarpImageGenericFilter.cxx)
+ TARGET_LINK_LIBRARIES(clitkWarpImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkWarpImage)
+
+ WRAP_GGO(clitkInvertVF_GGO_C clitkInvertVF.ggo)
+ ADD_EXECUTABLE(clitkInvertVF clitkInvertVF.cxx ${clitkInvertVF_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkInvertVF clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkInvertVF)
+
+ WRAP_GGO(clitkAffineTransform_GGO_C clitkAffineTransform.ggo)
+ ADD_EXECUTABLE(clitkAffineTransform clitkAffineTransform.cxx ${clitkAffineTransform_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkAffineTransform clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+ WRAP_GGO(clitkSetBackground_GGO_C clitkSetBackground.ggo)
+ ADD_EXECUTABLE(clitkSetBackground clitkSetBackground.cxx clitkSetBackgroundGenericFilter.cxx ${clitkSetBackground_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkSetBackground clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetBackground)
+
+ WRAP_GGO(clitkGuerreroVentilation_GGO_C clitkGuerreroVentilation.ggo)
+ ADD_EXECUTABLE(clitkGuerreroVentilation clitkGuerreroVentilation.cxx clitkGuerreroVentilationGenericFilter.cxx ${clitkGuerreroVentilation_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkGuerreroVentilation clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGuerreroVentilation)
+
+ WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
+ ADD_EXECUTABLE(clitkGammaIndex clitkGammaIndex.cxx ${clitkGammaIndex_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkGammaIndex vtkCommon vtkFiltering vtkGraphics vtkIO vtkImaging)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGammaIndex)
+
+ ADD_EXECUTABLE(clitkImageArithm clitkImageArithm.cxx)
+ TARGET_LINK_LIBRARIES(clitkImageArithm clitkImageArithmImageLib clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageArithm)
+
+ WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo)
+ ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkUnsharpMask)
+
+ WRAP_GGO(clitkFooImage_GGO_C clitkFooImage.ggo)
+ ADD_EXECUTABLE(clitkFooImage clitkFooImage.cxx ${clitkFooImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFooImage)
+
+ #WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
+ #ADD_EXECUTABLE(clitkMedianImageFilter clitkMedianImageFilter.cxx ${clitkMedianImageFilter_GGO_C})
+ #TARGET_LINK_LIBRARIES(clitkMedianImageFilter clitkMedianImageFilterLib clitkCommon ${ITK_LIBRARIES})
+ #SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMedianImageFilter)
+
+ ADD_EXECUTABLE(clitkResampleImage clitkResampleImage.cxx)
+ TARGET_LINK_LIBRARIES(clitkResampleImage clitkResampleImageLib clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkResampleImage)
+
+ WRAP_GGO(clitkMinMaxMask_GGO_C clitkMinMaxMask.ggo)
+ ADD_EXECUTABLE(clitkMinMaxMask clitkMinMaxMask.cxx ${clitkMinMaxMask_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkMinMaxMask clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMinMaxMask)
+
+ WRAP_GGO(clitkAutoCrop_GGO_C clitkAutoCrop.ggo)
+ ADD_EXECUTABLE(clitkAutoCrop clitkAutoCrop.cxx ${clitkAutoCrop_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkAutoCrop clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkAutoCrop)
+
+ WRAP_GGO(clitkDicomRTStruct2BinaryImage_GGO_C clitkDicomRTStruct2BinaryImage.ggo)
+ ADD_EXECUTABLE(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct2BinaryImage.cxx ${clitkDicomRTStruct2BinaryImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicomRTStruct2BinaryImage)
+
+ WRAP_GGO(clitkImageLog_GGO_C clitkImageLog.ggo)
+ ADD_EXECUTABLE(clitkImageLog clitkImageLog.cxx ${clitkImageLog_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageLog ${ITK_LIBRARIES} clitkCommon)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageLog)
+
+ WRAP_GGO(clitkFilter_GGO_C clitkFilter.ggo)
+ ADD_EXECUTABLE(clitkFilter clitkFilter.cxx clitkFilterGenericFilter.cxx ${clitkFilter_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkFilter ${ITK_LIBRARIES} clitkCommon)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFilter)
+
+ WRAP_GGO(clitkConeBeamProjectImage_GGO_C clitkConeBeamProjectImage.ggo)
+ ADD_EXECUTABLE(clitkConeBeamProjectImage clitkConeBeamProjectImage.cxx clitkConeBeamProjectImageGenericFilter.cxx ${clitkConeBeamProjectImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkConeBeamProjectImage ${ITK_LIBRARIES} clitkCommon )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkConeBeamProjectImage)
+
+ WRAP_GGO(clitkComposeVF_GGO_C clitkComposeVF.ggo)
+ ADD_EXECUTABLE(clitkComposeVF clitkComposeVFGenericFilter.cxx clitkComposeVF.cxx ${clitkComposeVF_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkComposeVF ${ITK_LIBRARIES} clitkCommon)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkComposeVF)
+
+ WRAP_GGO(clitkMergeSequence_GGO_C clitkMergeSequence.ggo)
+ ADD_EXECUTABLE(clitkMergeSequence clitkMergeSequence.cxx clitkMergeSequenceGenericFilter.cxx ${clitkMergeSequence_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkMergeSequence ${ITK_LIBRARIES} clitkCommon)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMergeSequence)
+
+ WRAP_GGO(clitkBackProjectImage_GGO_C clitkBackProjectImage.ggo)
+ ADD_EXECUTABLE(clitkBackProjectImage clitkBackProjectImage.cxx clitkBackProjectImageGenericFilter.cxx ${clitkBackProjectImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkBackProjectImage ${ITK_LIBRARIES} clitkCommon )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBackProjectImage)
+
+ ADD_EXECUTABLE(clitkCropImage clitkCropImage.cxx ${clitkCropImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkCropImage clitkCropImageLib clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkCropImage)
+
+ # WRAP_GGO(clitkExtractSlice_GGO_C clitkExtractSlice.ggo)
+ # ADD_EXECUTABLE(clitkExtractSlice clitkExtractSlice.cxx clitkExtractSliceGenericFilter.cxx ${clitkExtractSlice_GGO_C})
+ # TARGET_LINK_LIBRARIES(clitkExtractSlice clitkCommon ${ITK_LIBRARIES})
+ #SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkExtractSlice)
+
+ WRAP_GGO(clitkFlipImage_GGO_C clitkFlipImage.ggo)
+ ADD_EXECUTABLE(clitkFlipImage clitkFlipImage.cxx clitkFlipImageGenericFilter.cxx ${clitkFlipImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkFlipImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFlipImage)
+
+ WRAP_GGO(clitkMirrorPadImage_GGO_C clitkMirrorPadImage.ggo)
+ ADD_EXECUTABLE(clitkMirrorPadImage clitkMirrorPadImage.cxx clitkMirrorPadImageGenericFilter.cxx ${clitkMirrorPadImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkMirrorPadImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMirrorPadImage)
+
+ WRAP_GGO(clitkImageMoment_GGO_C clitkImageMoment.ggo)
+ ADD_EXECUTABLE(clitkImageMoment clitkImageMoment.cxx clitkImageMomentGenericFilter.cxx ${clitkImageMoment_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageMoment clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+ WRAP_GGO(clitkImageStatistics_GGO_C clitkImageStatistics.ggo)
+ ADD_EXECUTABLE(clitkImageStatistics clitkImageStatistics.cxx clitkImageStatisticsGenericFilter.cxx ${clitkImageStatistics_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageStatistics clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageStatistics)
+
+ WRAP_GGO(clitkSetOrigin_GGO_C clitkSetOrigin.ggo)
+ ADD_EXECUTABLE(clitkSetOrigin clitkSetOrigin.cxx clitkSetOriginGenericFilter.cxx ${clitkSetOrigin_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkSetOrigin clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetOrigin)
- WRAP_GGO(clitkFlipImage_GGO_C clitkFlipImage.ggo)
- ADD_EXECUTABLE(clitkFlipImage clitkFlipImage.cxx clitkFlipImageGenericFilter.cxx ${clitkFlipImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkFlipImage clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkMirrorPadImage_GGO_C clitkMirrorPadImage.ggo)
- ADD_EXECUTABLE(clitkMirrorPadImage clitkMirrorPadImage.cxx clitkMirrorPadImageGenericFilter.cxx ${clitkMirrorPadImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkMirrorPadImage clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkImageMoment_GGO_C clitkImageMoment.ggo)
- ADD_EXECUTABLE(clitkImageMoment clitkImageMoment.cxx clitkImageMomentGenericFilter.cxx ${clitkImageMoment_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageMoment clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkImageStatistics_GGO_C clitkImageStatistics.ggo)
- ADD_EXECUTABLE(clitkImageStatistics clitkImageStatistics.cxx clitkImageStatisticsGenericFilter.cxx ${clitkImageStatistics_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageStatistics clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkSetOrigin_GGO_C clitkSetOrigin.ggo)
- ADD_EXECUTABLE(clitkSetOrigin clitkSetOrigin.cxx clitkSetOriginGenericFilter.cxx ${clitkSetOrigin_GGO_C})
- TARGET_LINK_LIBRARIES(clitkSetOrigin clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkGetOrigin_GGO_C clitkGetOrigin.ggo)
- ADD_EXECUTABLE(clitkGetOrigin clitkGetOrigin.cxx clitkGetOriginGenericFilter.cxx ${clitkGetOrigin_GGO_C})
- TARGET_LINK_LIBRARIES(clitkGetOrigin clitkCommon ${ITK_LIBRARIES} )
-
- WRAP_GGO(clitkGetDirection_GGO_C clitkGetDirection.ggo)
- ADD_EXECUTABLE(clitkGetDirection clitkGetDirection.cxx clitkGetDirectionGenericFilter.cxx ${clitkGetDirection_GGO_C})
- TARGET_LINK_LIBRARIES(clitkGetDirection clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkSetDirection_GGO_C clitkSetDirection.ggo)
- ADD_EXECUTABLE(clitkSetDirection clitkSetDirection.cxx clitkSetDirectionGenericFilter.cxx ${clitkSetDirection_GGO_C})
- TARGET_LINK_LIBRARIES(clitkSetDirection clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkGetSize_GGO_C clitkGetSize.ggo)
- ADD_EXECUTABLE(clitkGetSize clitkGetSize.cxx clitkGetSizeGenericFilter.cxx ${clitkGetSize_GGO_C})
- TARGET_LINK_LIBRARIES(clitkGetSize clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkGetSpacing_GGO_C clitkGetSpacing.ggo)
- ADD_EXECUTABLE(clitkGetSpacing clitkGetSpacing.cxx clitkGetSpacingGenericFilter.cxx ${clitkGetSpacing_GGO_C})
- TARGET_LINK_LIBRARIES(clitkGetSpacing clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkSetSpacing_GGO_C clitkSetSpacing.ggo)
- ADD_EXECUTABLE(clitkSetSpacing clitkSetSpacing.cxx clitkSetSpacingGenericFilter.cxx ${clitkSetSpacing_GGO_C})
- TARGET_LINK_LIBRARIES(clitkSetSpacing clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkCombineImage_GGO_C clitkCombineImage.ggo)
- ADD_EXECUTABLE(clitkCombineImage clitkCombineImage.cxx clitkCombineImageGenericFilter.cxx ${clitkCombineImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkCombineImage clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkPermuteAxes_GGO_C clitkPermuteAxes.ggo)
- ADD_EXECUTABLE(clitkPermuteAxes clitkPermuteAxes.cxx clitkPermuteAxesGenericFilter.cxx ${clitkPermuteAxes_GGO_C})
- TARGET_LINK_LIBRARIES(clitkPermuteAxes clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkChangeImageOrientation_GGO_C clitkChangeImageOrientation.ggo)
- ADD_EXECUTABLE(clitkChangeImageOrientation clitkChangeImageOrientation.cxx clitkChangeImageOrientationGenericFilter.cxx ${clitkChangeImageOrientation_GGO_C})
- TARGET_LINK_LIBRARIES(clitkChangeImageOrientation clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkVFConvert_GGO_C clitkVFConvert.ggo)
- ADD_EXECUTABLE(clitkVFConvert clitkVFConvert.cxx clitkVFConvertGenericFilter.cxx ${clitkVFConvert_GGO_C})
- TARGET_LINK_LIBRARIES(clitkVFConvert ${ITK_LIBRARIES} clitkCommon )
-
- WRAP_GGO(clitkImageToVectorImage_GGO_C clitkImageToVectorImage.ggo)
- ADD_EXECUTABLE(clitkImageToVectorImage clitkImageToVectorImage.cxx clitkImageToVectorImageGenericFilter.cxx ${clitkImageToVectorImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkImageToVectorImage clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkVectorImageToImage_GGO_C clitkVectorImageToImage.ggo)
- ADD_EXECUTABLE(clitkVectorImageToImage clitkVectorImageToImage.cxx clitkVectorImageToImageGenericFilter.cxx ${clitkVectorImageToImage_GGO_C})
- TARGET_LINK_LIBRARIES(clitkVectorImageToImage clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkBSplineCoefficientsToValues_GGO_C clitkBSplineCoefficientsToValues.ggo)
- ADD_EXECUTABLE(clitkBSplineCoefficientsToValues clitkBSplineCoefficientsToValues.cxx clitkBSplineCoefficientsToValuesGenericFilter.cxx ${clitkBSplineCoefficientsToValues_GGO_C})
- TARGET_LINK_LIBRARIES(clitkBSplineCoefficientsToValues clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkValuesToBSplineCoefficients_GGO_C clitkValuesToBSplineCoefficients.ggo)
- ADD_EXECUTABLE(clitkValuesToBSplineCoefficients clitkValuesToBSplineCoefficients.cxx clitkValuesToBSplineCoefficientsGenericFilter.cxx ${clitkValuesToBSplineCoefficients_GGO_C})
- TARGET_LINK_LIBRARIES(clitkValuesToBSplineCoefficients clitkCommon ${ITK_LIBRARIES})
-
- ADD_EXECUTABLE(clitkMIP clitkMIP.cxx clitkMIPGenericFilter.cxx)
- TARGET_LINK_LIBRARIES(clitkMIP clitkMIPLib clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkRelativePosition_GGO_C clitkRelativePosition.ggo)
- ADD_EXECUTABLE(clitkRelativePosition clitkRelativePosition.cxx ${clitkRelativePosition_GGO_C})
- TARGET_LINK_LIBRARIES(clitkRelativePosition clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkTransformLandmarks_GGO_C clitkTransformLandmarks.ggo)
- ADD_EXECUTABLE(clitkTransformLandmarks clitkTransformLandmarks.cxx ${clitkTransformLandmarks_GGO_C})
- TARGET_LINK_LIBRARIES(clitkTransformLandmarks clitkCommon ${ITK_LIBRARIES})
-
- WRAP_GGO(clitkLineProfile_GGO_C clitkLineProfile.ggo)
- ADD_EXECUTABLE(clitkLineProfile clitkLineProfile.cxx clitkLineProfileGenericFilter.cxx ${clitkLineProfile_GGO_C})
- TARGET_LINK_LIBRARIES(clitkLineProfile clitkCommon ${ITK_LIBRARIES})
+ WRAP_GGO(clitkGetOrigin_GGO_C clitkGetOrigin.ggo)
+ ADD_EXECUTABLE(clitkGetOrigin clitkGetOrigin.cxx clitkGetOriginGenericFilter.cxx ${clitkGetOrigin_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkGetOrigin clitkCommon ${ITK_LIBRARIES} )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetOrigin)
+
+ WRAP_GGO(clitkGetDirection_GGO_C clitkGetDirection.ggo)
+ ADD_EXECUTABLE(clitkGetDirection clitkGetDirection.cxx clitkGetDirectionGenericFilter.cxx ${clitkGetDirection_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkGetDirection clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetDirection)
+
+ WRAP_GGO(clitkSetDirection_GGO_C clitkSetDirection.ggo)
+ ADD_EXECUTABLE(clitkSetDirection clitkSetDirection.cxx clitkSetDirectionGenericFilter.cxx ${clitkSetDirection_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkSetDirection clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetDirection)
+
+ WRAP_GGO(clitkGetSize_GGO_C clitkGetSize.ggo)
+ ADD_EXECUTABLE(clitkGetSize clitkGetSize.cxx clitkGetSizeGenericFilter.cxx ${clitkGetSize_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkGetSize clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetSize)
+
+ WRAP_GGO(clitkGetSpacing_GGO_C clitkGetSpacing.ggo)
+ ADD_EXECUTABLE(clitkGetSpacing clitkGetSpacing.cxx clitkGetSpacingGenericFilter.cxx ${clitkGetSpacing_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkGetSpacing clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetSpacing)
+
+ WRAP_GGO(clitkSetSpacing_GGO_C clitkSetSpacing.ggo)
+ ADD_EXECUTABLE(clitkSetSpacing clitkSetSpacing.cxx clitkSetSpacingGenericFilter.cxx ${clitkSetSpacing_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkSetSpacing clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+ WRAP_GGO(clitkCombineImage_GGO_C clitkCombineImage.ggo)
+ ADD_EXECUTABLE(clitkCombineImage clitkCombineImage.cxx clitkCombineImageGenericFilter.cxx ${clitkCombineImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkCombineImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkCombineImage)
+
+ WRAP_GGO(clitkPermuteAxes_GGO_C clitkPermuteAxes.ggo)
+ ADD_EXECUTABLE(clitkPermuteAxes clitkPermuteAxes.cxx clitkPermuteAxesGenericFilter.cxx ${clitkPermuteAxes_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkPermuteAxes clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkPermuteAxes)
+
+ WRAP_GGO(clitkChangeImageOrientation_GGO_C clitkChangeImageOrientation.ggo)
+ ADD_EXECUTABLE(clitkChangeImageOrientation clitkChangeImageOrientation.cxx clitkChangeImageOrientationGenericFilter.cxx ${clitkChangeImageOrientation_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkChangeImageOrientation clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkChangeImageOrientation)
+
+ WRAP_GGO(clitkVFConvert_GGO_C clitkVFConvert.ggo)
+ ADD_EXECUTABLE(clitkVFConvert clitkVFConvert.cxx clitkVFConvertGenericFilter.cxx ${clitkVFConvert_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkVFConvert ${ITK_LIBRARIES} clitkCommon )
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFConvert)
+
+ WRAP_GGO(clitkImageToVectorImage_GGO_C clitkImageToVectorImage.ggo)
+ ADD_EXECUTABLE(clitkImageToVectorImage clitkImageToVectorImage.cxx clitkImageToVectorImageGenericFilter.cxx ${clitkImageToVectorImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkImageToVectorImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageToVectorImage)
+
+ WRAP_GGO(clitkVectorImageToImage_GGO_C clitkVectorImageToImage.ggo)
+ ADD_EXECUTABLE(clitkVectorImageToImage clitkVectorImageToImage.cxx clitkVectorImageToImageGenericFilter.cxx ${clitkVectorImageToImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkVectorImageToImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVectorImageToImage)
+
+ WRAP_GGO(clitkBSplineCoefficientsToValues_GGO_C clitkBSplineCoefficientsToValues.ggo)
+ ADD_EXECUTABLE(clitkBSplineCoefficientsToValues clitkBSplineCoefficientsToValues.cxx clitkBSplineCoefficientsToValuesGenericFilter.cxx ${clitkBSplineCoefficientsToValues_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkBSplineCoefficientsToValues clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBSplineCoefficientsToValues)
+
+ WRAP_GGO(clitkValuesToBSplineCoefficients_GGO_C clitkValuesToBSplineCoefficients.ggo)
+ ADD_EXECUTABLE(clitkValuesToBSplineCoefficients clitkValuesToBSplineCoefficients.cxx clitkValuesToBSplineCoefficientsGenericFilter.cxx ${clitkValuesToBSplineCoefficients_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkValuesToBSplineCoefficients clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkValuesToBSplineCoefficients)
+
+ ADD_EXECUTABLE(clitkMIP clitkMIP.cxx clitkMIPGenericFilter.cxx)
+ TARGET_LINK_LIBRARIES(clitkMIP clitkMIPLib clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMIP)
+
+ WRAP_GGO(clitkRelativePosition_GGO_C clitkRelativePosition.ggo)
+ ADD_EXECUTABLE(clitkRelativePosition clitkRelativePosition.cxx ${clitkRelativePosition_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkRelativePosition clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkRelativePosition)
+
+ WRAP_GGO(clitkTransformLandmarks_GGO_C clitkTransformLandmarks.ggo)
+ ADD_EXECUTABLE(clitkTransformLandmarks clitkTransformLandmarks.cxx ${clitkTransformLandmarks_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkTransformLandmarks clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkTransformLandmarks)
+
+ WRAP_GGO(clitkLineProfile_GGO_C clitkLineProfile.ggo)
+ ADD_EXECUTABLE(clitkLineProfile clitkLineProfile.cxx clitkLineProfileGenericFilter.cxx ${clitkLineProfile_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkLineProfile clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkLineProfile)
+
+ ADD_EXECUTABLE(clitkMakeSphereImage clitkMakeSphereImage.cxx) # clitkLineProfileGenericFilter.cxx ${clitkLineProfile_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkMakeSphereImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMakeSphereImage)
+
+ WRAP_GGO(clitkJacobianImage_GGO_C clitkJacobianImage.ggo)
+ ADD_EXECUTABLE(clitkJacobianImage clitkJacobianImage.cxx clitkJacobianImageGenericFilter.cxx ${clitkJacobianImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkJacobianImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkJacobianImage)
+
+ WRAP_GGO(clitkPadImage_GGO_C clitkPadImage.ggo)
+ ADD_EXECUTABLE(clitkPadImage clitkPadImage.cxx ${clitkPadImage_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkPadImage clitkCommon ${ITK_LIBRARIES})
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkPadImage)
+
+ IF(CLITK_EXPERIMENTAL)
+
+ WRAP_GGO(clitkBinaryImageToMesh_GGO_C clitkBinaryImageToMesh.ggo)
+ ADD_EXECUTABLE(clitkBinaryImageToMesh clitkBinaryImageToMesh.cxx ${clitkBinaryImageToMesh_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkBinaryImageToMesh ${ITK_LIBRARIES} vtkCommon vtkRendering)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBinaryImageToMesh)
+
+ WRAP_GGO(clitkMeshViewer_GGO_C clitkMeshViewer.ggo)
+ ADD_EXECUTABLE(clitkMeshViewer clitkMeshViewer.cxx ${clitkMeshViewer_GGO_C})
+ TARGET_LINK_LIBRARIES(clitkMeshViewer vtkCommon vtkRendering)
+ SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMeshViewer)
+ ENDIF(CLITK_EXPERIMENTAL)
+
+ SET_TARGET_PROPERTIES(${TOOLS_INSTALL} PROPERTIES INSTALL_RPATH "${VTK_DIR}:${ITK_DIR}" )
+ INSTALL (TARGETS ${TOOLS_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
ENDIF(CLITK_BUILD_TOOLS)
option "input" i "Input image filename" string yes
option "output" o "Output image filename" string yes
option "like" l "Resample output this image (size, spacing,origin)" string no
+option "transform_grid" - "Apply affine transform to input grid for output's" flag off
section "Options"
option "size" - "New output size if different from input" int no multiple
likeReader->SetFileName(m_ArgsInfo.like_arg);
likeReader->Update();
resampler->SetOutputParametersFromImage(likeReader->GetOutput());
+ } else if(m_ArgsInfo.transform_grid_flag) {
+ typename itk::Matrix<double, Dimension+1, Dimension+1> invMatrix( matrix.GetInverse() );
+ typename itk::Matrix<double, Dimension, Dimension> invRotMatrix( clitk::GetRotationalPartMatrix(invMatrix) );
+ typename itk::Vector<double,Dimension> invTrans = clitk::GetTranslationPartMatrix(invMatrix);
+
+ // Spacing is influenced by affine transform matrix and input direction
+ typename InputImageType::SpacingType outputSpacing;
+ outputSpacing = invRotMatrix *
+ input->GetDirection() *
+ input->GetSpacing();
+
+ // Origin is influenced by translation but not by input direction
+ typename InputImageType::PointType outputOrigin;
+ outputOrigin = invRotMatrix *
+ input->GetOrigin() +
+ invTrans;
+
+ // Size is influenced by affine transform matrix and input direction
+ // Size is converted to double, transformed and converted back to size type.
+ vnl_vector<double> vnlOutputSize(Dimension);
+ for(unsigned int i=0; i< Dimension; i++) {
+ vnlOutputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
+ }
+ vnlOutputSize = invRotMatrix *
+ input->GetDirection().GetVnlMatrix() *
+ vnlOutputSize;
+ typename OutputImageType::SizeType outputSize;
+ for(unsigned int i=0; i< Dimension; i++) {
+ // If the size is negative, we have a flip and we must modify
+ // the origin and the spacing accordingly.
+ if(vnlOutputSize[i]<0.) {
+ vnlOutputSize[i] *= -1.;
+ outputOrigin[i] = outputOrigin[i] + outputSpacing[i] * (vnlOutputSize[i]-1);
+ outputSpacing[i] *= -1.;
+ }
+ outputSize[i] = lrint(vnlOutputSize[i]);
+ }
+ resampler->SetSize( outputSize );
+ resampler->SetOutputSpacing( outputSpacing );
+ resampler->SetOutputOrigin( outputOrigin );
} else {
//Size
typename OutputImageType::SizeType outputSize;
for(unsigned int i=0; i< Dimension; i++)
outputSize[i]=m_ArgsInfo.size_arg[i];
} else outputSize=input->GetLargestPossibleRegion().GetSize();
- std::cout<<"Setting the size to "<<outputSize<<"..."<<std::endl;
//Spacing
typename OutputImageType::SpacingType outputSpacing;
for(unsigned int i=0; i< Dimension; i++)
outputSpacing[i]=m_ArgsInfo.spacing_arg[i];
} else outputSpacing=input->GetSpacing();
- std::cout<<"Setting the spacing to "<<outputSpacing<<"..."<<std::endl;
//Origin
typename OutputImageType::PointType outputOrigin;
for(unsigned int i=0; i< Dimension; i++)
outputOrigin[i]=m_ArgsInfo.origin_arg[i];
} else outputOrigin=input->GetOrigin();
- std::cout<<"Setting the origin to "<<outputOrigin<<"..."<<std::endl;
// Set
resampler->SetSize( outputSize );
}
+ if (m_ArgsInfo.verbose_flag) {
+ std::cout << "Setting the output size to " << resampler->GetSize() << "..." << std::endl;
+ std::cout << "Setting the output spacing to " << resampler->GetOutputSpacing() << "..." << std::endl;
+ std::cout << "Setting the output origin to " << resampler->GetOutputOrigin() << "..." << std::endl;
+ }
+
resampler->SetInput( input );
resampler->SetTransform( affineTransform );
resampler->SetInterpolator( genericInterpolator->GetInterpolatorPointer());
#include "itkBSplineResampleImageFunction.h"
#include "clitkVectorBSplineResampleImageFunction.h"
#include "itkAddImageFilter.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkTransformToDisplacementFieldSource.h"
+#else
+ #include "itkTransformToDeformationFieldSource.h"
+#endif
namespace clitk
{
// Matrix Transform
if(m_ArgsInfo.matrix_given)
{
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::TransformToDisplacementFieldSource<OutputImageType, double> ConvertorType;
+#else
typedef itk::TransformToDeformationFieldSource<OutputImageType, double> ConvertorType;
+#endif
typename ConvertorType::Pointer filter= ConvertorType::New();
filter->SetOutputParametersFromImage(output);
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+#include "clitkBinaryImageToMesh_ggo.h"
+#include "clitkImageToImageGenericFilter.h"
+
+#include "vtkMetaImageReader.h"
+#include "vtkContourFilter.h"
+#include "vtkDecimatePro.h"
+#include "vtkPolyDataMapper.h"
+#include "vtkRenderer.h"
+#include "vtkRenderWindow.h"
+#include "vtkActor.h"
+#include "vtkCamera.h"
+#include "vtkOBJExporter.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkSmartPointer.h"
+
+#include "itksys/SystemTools.hxx"
+
+void run(const args_info_clitkBinaryImageToMesh& argsInfo);
+
+int main(int argc, char** argv)
+{
+ GGO(clitkBinaryImageToMesh, args_info);
+
+ run(args_info);
+
+ return EXIT_SUCCESS;
+}
+
+void run(const args_info_clitkBinaryImageToMesh& argsInfo)
+{
+ std::string file = argsInfo.input_arg;
+
+ vtkSmartPointer<vtkMetaImageReader> pbmp_reader = vtkMetaImageReader::New();
+ pbmp_reader->SetFileName(file.c_str());
+ pbmp_reader->Update();
+
+ printf("Filtering...\n");
+ vtkSmartPointer<vtkContourFilter> pcontour = vtkContourFilter::New();
+ pcontour->SetValue(0, 0.5);
+ pcontour->SetInputConnection(pbmp_reader->GetOutputPort());
+
+ vtkSmartPointer<vtkDecimatePro> psurface = vtkDecimatePro::New();
+ psurface->SetInputConnection(pcontour->GetOutputPort());
+
+ vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkPolyDataMapper::New();
+ skinMapper->SetInputConnection(psurface->GetOutputPort());
+ skinMapper->ScalarVisibilityOff();
+
+ vtkSmartPointer<vtkActor> skin = vtkActor::New();
+ skin->SetMapper(skinMapper);
+
+ vtkSmartPointer<vtkCamera> aCamera = vtkCamera::New();
+ aCamera->SetViewUp (0, 0, -1);
+ aCamera->SetPosition (0, 1, 0);
+ aCamera->SetFocalPoint (0, 0, 0);
+ aCamera->ComputeViewPlaneNormal();
+ aCamera->Dolly(1.5);
+
+ vtkSmartPointer<vtkRenderer> aRenderer = vtkRenderer::New();
+ aRenderer->AddActor(skin);
+ aRenderer->SetActiveCamera(aCamera);
+ aRenderer->ResetCamera ();
+ aRenderer->SetBackground(0,0,0);
+ aRenderer->ResetCameraClippingRange ();
+
+ vtkSmartPointer<vtkRenderWindow> renWin = vtkRenderWindow::New();
+ renWin->AddRenderer(aRenderer);
+ renWin->SetSize(640, 480);
+
+ vtkSmartPointer<vtkOBJExporter> pwriter2 = vtkOBJExporter::New();
+ pwriter2->SetRenderWindow(renWin);
+
+ std::string output;
+ if (argsInfo.output_given) {
+ output = argsInfo.output_arg;
+ if (itksys::SystemTools::FileIsDirectory(output.c_str())) {
+ file = itksys::SystemTools::GetFilenameName(file.c_str());
+ file = itksys::SystemTools::GetFilenameWithoutExtension(file.c_str());
+ file = itksys::SystemTools::CollapseFullPath(file.c_str(), output.c_str());
+ }
+ else {
+ file = output;
+ }
+ }
+ else {
+ file = itksys::SystemTools::GetFilenameWithoutExtension(file);
+ }
+ pwriter2->SetFilePrefix(file.c_str());
+ pwriter2->Write();
+
+ vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkRenderWindowInteractor::New();
+ iren->SetRenderWindow(renWin);
+
+ skinMapper->Update();
+ bool interact = argsInfo.view_flag;
+ if (interact)
+ {
+ iren->Initialize();
+ iren->Start();
+ }
+ else
+ renWin->Render();
+}
+
+
--- /dev/null
+#File clitkBinaryImageToMesh.ggo
+package "clitkBinaryImageToMesh"
+version "1.0"
+purpose "Get the HU profile along the given line. Output to stdout."
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input image" string yes
+option "output" o "Output mesh file prefix (if empty, use input file's base name as prefix; if a directoy, output to it using input file's base name as prefix; otherwise, use given name as prefix" string no
+option "view" - "View result" flag off
option "spacing" - "Spacing for the output image" double multiple no default="0.8"
option "panel_position" - "Approximate position of the panel: small, medium or large" string no default="small"
-option "panel_shift" - "Precise position of the panel in mm" double no
+option "panel_shift" - "Precise position of the panel in mm" double multiple no
}
/** Set the panelshift. */
- void SetPanelShift(double shift)
+ void SetPanelShift(double x, double y)
{
- if (m_PanelShift!=shift)
+ if (m_PanelShift[0] != x)
{
- m_PanelShift=shift;
+ m_PanelShift[0] = x;
+ m_IsInitialized=false;
+ }
+ if (m_PanelShift[1] != y)
+ {
+ m_PanelShift[1] = y;
m_IsInitialized=false;
}
}
double m_SourceToScreen;
double m_SourceToAxis;
double m_ProjectionAngle;
- double m_PanelShift;
+ double m_PanelShift[2];
MatrixType m_RigidTransformMatrix;
OutputPixelType m_EdgePaddingValue;
m_IsoCenter.Fill(0.0);
m_SourceToScreen=1536.;
m_SourceToAxis=1000.;
+ m_PanelShift[0] = 0.;
+ m_PanelShift[1] = 0.;
m_ProjectionAngle=0.;
m_RigidTransformMatrix.SetIdentity();
m_EdgePaddingValue=itk::NumericTraits<OutputPixelType>::Zero;//density images
spacingOutput[1] = m_OutputSpacing[0]; // pixel spacing along Y of the 2D DRR image [mm]
spacingOutput[2] = m_OutputSpacing[1]; // pixel spacing along Y of the 2D DRR image [mm]
m_Resampler->SetOutputSpacing( spacingOutput );
- if (m_Verbose)std::cout<<"The output size is "<< m_OutputSpacing <<"..."<< std::endl;
+ if (m_Verbose)std::cout<<"The output spacing is "<< m_OutputSpacing <<"..."<< std::endl;
// The position of the DRR is specified, we presume that for an angle of 0° the flatpanel is located at the negative x-axis
// JV -1 seems to correspond better with shearwarp of Simon Rit
typename InterpolatorType::InputPointType originOutput;
originOutput[0] = m_IsoCenter[0]- (m_SourceToScreen - m_SourceToAxis);
DD(m_PanelShift);
- originOutput[1] = m_IsoCenter[1]-static_cast<double>(sizeOuput[1]-1)*spacingOutput[1]/2.0 - m_PanelShift;
- originOutput[2] = m_IsoCenter[2]-static_cast<double>(sizeOuput[2]-1)*spacingOutput[2]/2.0;
+ originOutput[1] = m_IsoCenter[1]-static_cast<double>(sizeOuput[1]-1)*spacingOutput[1]/2.0 - m_PanelShift[0];
+ originOutput[2] = m_IsoCenter[2]-static_cast<double>(sizeOuput[2]-1)*spacingOutput[2]/2.0 - m_PanelShift[1];
m_Resampler->SetOutputOrigin( originOutput );
if (m_Verbose)std::cout<<"The origin of the flat panel is at "<< originOutput <<",..."<< std::endl;
DD(m_ArgsInfo.panel_position_arg);
if (m_ArgsInfo.panel_shift_given) // one should read the specific values for each angle in Frame.dbf
- filter->SetPanelShift(m_ArgsInfo.panel_shift_arg);
+ filter->SetPanelShift(m_ArgsInfo.panel_shift_arg[0], m_ArgsInfo.panel_shift_arg[1]);
else { // approximate panel positions hard coded values for the elekta synergy
if (strcmp(m_ArgsInfo.panel_position_arg,"small") ==0)
- filter->SetPanelShift(0.);
+ filter->SetPanelShift(0., 0.);
else if (strcmp(m_ArgsInfo.panel_position_arg,"medium") ==0)
- filter->SetPanelShift(114.84);
+ filter->SetPanelShift(114.84, 0.); // VD : 120 , 0 ?
else if (strcmp(m_ArgsInfo.panel_position_arg,"large") ==0)
- filter->SetPanelShift(190.);
+ filter->SetPanelShift(190., 0.);
else assert(false); //Unsupported panel position
}
// Output image info
filter->SetArgsInfo(args_info);
- try {
+ try {
filter->Update();
} catch(std::runtime_error e) {
std::cout << e.what() << std::endl;
option "output" o "Output image filename" string yes
section "Used determined crop"
-option "boundingBox" b "Bounding box of the crop region (in 2D: =x1,y2, x2,y2)" int no multiple
+option "boundingBox" b "Bounding box of the crop region (in 3D: =x1,x2,y1,y2,z1,z2)" int no multiple
option "lower" l "Size of the lower crop region (multiple values)" int no multiple
option "upper" u "Size of the upper crop region (multiple values)" int no multiple
option "origin" - "Set new origin to zero" flag off
{
// Reading input
typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
+ typename ImageType::RegionType input_region = input->GetLargestPossibleRegion();
// Check options
if (mArgsInfo.BG_given && mArgsInfo.like_given)
// ------------------------------------------------
typename ImageType::SizeType lSize;
typename ImageType::SizeType uSize;
+ if (mArgsInfo.verbose_flag) std::cout << "input region " << input_region << std::endl;
if (mArgsInfo.boundingBox_given) {
for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
lSize[i] = mArgsInfo.boundingBox_arg[2*i];
- uSize[i] = input->GetLargestPossibleRegion().GetSize()[i]-mArgsInfo.boundingBox_arg[2*i+1]-1;
+ uSize[i] = input_region.GetSize()[i]-mArgsInfo.boundingBox_arg[2*i+1]-1;
}
}
else {
}
else uSize.Fill(0);
}
+
+ if (mArgsInfo.verbose_flag) {
+ std::cout << "lower " << lSize << " upper " << uSize << std::endl;
+ }
+
typedef itk::CropImageFilter<ImageType, ImageType> CropImageFilterType;
typename CropImageFilterType::Pointer filter=CropImageFilterType::New();
filter->SetInput(input);
origin.Fill(itk::NumericTraits<double>::Zero);
output->SetOrigin(origin);
}
-
+
+ // adjust image origin and force index to zero
+ typename ImageType::RegionType region = output->GetLargestPossibleRegion();
+ typename ImageType::IndexType index = region.GetIndex();
+ typename ImageType::PointType origin = output->GetOrigin();
+ typename ImageType::SpacingType spacing = output->GetSpacing();
+ if (mArgsInfo.verbose_flag) std::cout << "origin before crop " << origin << std::endl;
+ for (unsigned int i = 0; i < output->GetImageDimension(); i++)
+ origin[i] += index[i]*spacing[i];
+ if (mArgsInfo.verbose_flag) std::cout << "origin after crop " << origin << std::endl;
+ output->SetOrigin(origin);
+
+ index.Fill(itk::NumericTraits<double>::Zero);
+ region.SetIndex(index);
+ output->SetRegions(region);
+
// Write/Save results
this->template SetNextOutput<ImageType>(output);
}
// Read and display information
clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
s->Read(args_info.input_arg);
- // s->Print(std::cout);
+ if (args_info.verboseFile_flag) {
+ s->Print(std::cout);
+ }
// New filter to convert to binary image
clitk::DicomRT_ROI_ConvertToImageFilter filter;
option "config" - "Config file" string no
option "verbose" v "Verbose" flag off
+option "verboseFile" - "Verbose file content" flag off
option "input" i "Input Dicom file" string yes
option "image" j "Used to read image info (spacing, origin)" string yes
option "roi" r "ROI to binarize (if -1 = all roi)" int no default="-1"
option "output" o "Output image filename" string yes
option "scalar" s "Scalar value" double no
-option "operation" t "Type of operation : \n With another image : 0=add, 1=multiply, 2=divide,\n 3=max, 4=min, 5=absdiff, 6=squareddiff, 7=difference, 8=relativ diff\n For 'scalar' : 0=add, 1=multiply, 2=inverse,\n 3=max, 4=min 5=absval 6=squareval\n 7=log 8=exp 9=sqrt 10=EPID" int default="0" no
+option "operation" t "Type of operation : \n With another image : 0=add, 1=multiply, 2=divide,\n 3=max, 4=min, 5=absdiff, 6=squareddiff, 7=difference, 8=relativ diff\n For 'scalar' : 0=add, 1=multiply, 2=inverse,\n 3=max, 4=min 5=absval 6=squareval\n 7=log 8=exp 9=sqrt 10=EPID 11=divide 12=normalize (divide by max)" int default="0" no
option "pixelValue" - "Default value for NaN/Inf" double default="0.0" no
option "setFloatOutput" f "Set output to float pixel type" flag off
#include "clitkImageCommon.h"
+#include "itkMinimumMaximumImageCalculator.h"
+
namespace clitk
{
typename ImageType::Pointer input2 = NULL;
IteratorType it2;
+ // Special case for normalisation
+ if (mTypeOfOperation == 12) {
+ typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxFilterType;
+ typename MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
+ ff->SetImage(input1);
+ ff->ComputeMaximum();
+ mScalar = ff->GetMaximum();
+ mTypeOfOperation = 11; // divide
+ }
if (mIsOperationUseASecondImage) {
// Read input2
// Set input image iterator
it2 = IteratorType(input2, input2->GetLargestPossibleRegion());
// Check dimension
- if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(input1, input2)) {
- std::cerr << "* ERROR * the images (input and input2) must have the same size & spacing";
- return;
+ if (!clitk::HaveSameSize<ImageType, ImageType>(input1, input2)) {
+ itkExceptionMacro(<< "The images (input and input2) must have the same size");
+ }
+ if(!clitk::HaveSameSpacing<ImageType, ImageType>(input1, input2)) {
+ itkWarningMacro(<< "The images (input and input2) do not have the same spacing. "
+ << "Using first input's information.");
}
}
++ito;
}
break;
+ case 11: // divide
+ while (!it.IsAtEnd()) {
+ ito.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() / mScalar) );
+ ++it;
+ ++ito;
+ }
+ break;
default: // error ?
std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
exit(-1);
filter->SetInputFilenames(l);
filter->SetIOVerbose(args_info.verbose_flag);
filter->SetOutputFilename(args_info.output_arg);
+ filter->EnableWriteCompression(args_info.compression_flag);
if (args_info.type_given) filter->SetOutputPixelType(args_info.type_arg);
// Go !
option "output" o "Output image filename" string yes
option "type" t "Output type (float, ushort ...)" string no
option "verbose" v "Verbose" flag off
+option "compression" c "Compress output" flag off
DD(direction);
std::vector<double> val(dim[b]);
- for (int i=0; i<dim[b]; i++)
+ for (size_t i=0; i<dim[b]; i++)
val[i]=0;
int k;
//itk include
#include "itkLightObject.h"
-#include "itkInverseDeformationFieldImageFilter.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkInverseDisplacementFieldImageFilter.h"
+#else
+ #include "itkInverseDeformationFieldImageFilter.h"
+#endif
namespace clitk
{
case 1: {
// Create the InverseDeformationFieldFilter
+#if ITK_VERSION_MAJOR >= 4
+ typedef itk::InverseDisplacementFieldImageFilter<InputImageType,OutputImageType> FilterType;
+#else
typedef itk::InverseDeformationFieldImageFilter<InputImageType,OutputImageType> FilterType;
+#endif
typename FilterType::Pointer filter =FilterType::New();
filter->SetInput(input);
filter->SetOutputOrigin(input->GetOrigin());
--- /dev/null
+#include "clitkJacobianImage_ggo.h"
+#include "clitkJacobianImageGenericFilter.h"
+
+int main(int argc, char** argv) {
+ // Init command line
+ GGO(clitkJacobianImage, args_info);
+
+ // Filter
+ typedef clitk::JacobianImageGenericFilter<args_info_clitkJacobianImage> FilterType;
+ FilterType::Pointer genericFilter = FilterType::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}
\ No newline at end of file
--- /dev/null
+#File clitkJacobianImage.ggo
+#Author: Rômulo Pinho <pinho@lyon.fnclcc.fr>
+#Date : Tue 21 June 16.10
+
+package "clitk"
+version "Read a DVF and calculate the corresponding jacobian image."
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input VF filename" string yes
+option "output" o "Output VF filename" string yes
- BSD See included LICENSE.txt file
- CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-// }
+===========================================================================*/
+#include "clitkJacobianImageGenericFilter.h"
+
+namespace clitk
+{
+
+}
\ No newline at end of file
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef clitkJacobianImageGenericFilter_h
+#define clitkJacobianImageGenericFilter_h
+
+/* =================================================
+ * @file clitkJacobianImageGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkJacobianImage_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#if ITK_VERSION_MAJOR >= 4
+ #include "itkInverseDisplacementFieldImageFilter.h"
+#else
+ #include "itkInverseDeformationFieldImageFilter.h"
+#endif
+
+namespace clitk
+{
+
+ template<class args_info_type>
+ class ITK_EXPORT JacobianImageGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef JacobianImageGenericFilter Self;
+ typedef itk::LightObject Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ // Method for creation through the object factory
+ itkNewMacro(Self);
+
+ // Run-time type information (and related methods)
+ itkTypeMacro( JacobianImageGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_type & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ JacobianImageGenericFilter();
+ ~JacobianImageGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_type m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkJacobianImageGenericFilter.txx"
+#endif
+
+#endif // #define clitkJacobianImageGenericFilter_h
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef clitkJacobianImageGenericFilter_txx
+#define clitkJacobianImageGenericFilter_txx
+
+/* =================================================
+ * @file clitkJacobianImageGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkImageCommon.h"
+#include "itkDeformationFieldJacobianDeterminantFilter.h"
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkVector.h"
+#include "itkNormalizeImageFilter.h"
+
+namespace clitk
+{
+
+//-----------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------
+template<class args_info_type>
+JacobianImageGenericFilter<args_info_type>::JacobianImageGenericFilter()
+{
+ m_Verbose=false;
+ m_InputFileName="";
+}
+
+
+//-----------------------------------------------------------
+// Update
+//-----------------------------------------------------------
+template<class args_info_type>
+void JacobianImageGenericFilter<args_info_type>::Update()
+{
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+}
+
+//-------------------------------------------------------------------
+// Update with the number of dimensions
+//-------------------------------------------------------------------
+template<class args_info_type>
+template<unsigned int Dimension>
+void
+JacobianImageGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
+{
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ // if(PixelType == "short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed short>();
+ // }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ // else if (PixelType == "unsigned_char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ // }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ // else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, itk::Vector<float, Dimension> >();
+ // }
+}
+
+
+//-------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//-------------------------------------------------------------------
+template<class args_info_type>
+template <unsigned int Dimension, class PixelType>
+void
+JacobianImageGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
+{
+ std::string vfield_file = m_ArgsInfo.input_arg;
+
+ const unsigned int dim = Dimension;
+ typedef itk::Vector<double, dim> VectorType;
+ typedef itk::Image<VectorType, dim> VectorFieldType;
+ typedef itk::ImageFileReader<VectorFieldType> VectorFieldReaderType;
+
+ typename VectorFieldReaderType::Pointer vfield_reader = VectorFieldReaderType::New();
+ vfield_reader->SetFileName(vfield_file.c_str());
+
+ typedef double OutputPixelType;
+ typedef itk::Image<OutputPixelType, dim> ImageType;
+ //typedef itk::DeformationFieldJacobianDeterminantFilter<VectorFieldType, PixelType, ImageType> JacobianFilterType;
+ typedef itk::DisplacementFieldJacobianDeterminantFilter<VectorFieldType, OutputPixelType, ImageType> JacobianFilterType;
+
+ typename VectorFieldType::Pointer vfield = vfield_reader->GetOutput();
+ typename JacobianFilterType::Pointer jac = JacobianFilterType::New();
+ jac->SetInput(vfield);
+ jac->Update();
+
+ typedef itk::NormalizeImageFilter<ImageType, ImageType> NormalizeFilterType;
+ typename NormalizeFilterType::Pointer normalize = NormalizeFilterType::New();
+ normalize->SetInput(jac->GetOutput());
+ normalize->Update();
+
+ typedef itk::ImageFileWriter<ImageType> ImageFileWriterType;
+ typename ImageFileWriterType::Pointer image_writer = ImageFileWriterType::New();
+
+ std::string image_file = m_ArgsInfo.output_arg;
+ image_writer->SetFileName(image_file.c_str());
+ image_writer->SetInput(jac->GetOutput());
+ image_writer->Update();
+
+}
+
+
+}//end clitk
+
+#endif //#define clitkJacobianImageGenericFilter_txx
--- /dev/null
+#include "itkImage.h"
+#include "itkSphereSpatialFunction.h"
+#include <itkImageRegionIterator.h>
+#include "itkImageFileWriter.h"
+
+int main(int argc, char** argv) {
+
+ const unsigned int dim = 3;
+ typedef char PixelType;
+ typedef itk::Image<PixelType, dim> ImageType;
+ typedef ImageType::IndexType IndexType;
+ typedef ImageType::PointType PointType;
+ typedef ImageType::SizeType SizeType;
+ typedef ImageType::RegionType RegionType;
+
+ IndexType index;
+ index.Fill(0);
+
+ SizeType size;
+ size[0] = atoi(argv[2]);
+ size[1] = atoi(argv[3]);
+ size[2] = atoi(argv[4]);
+
+ PointType origin;
+ origin[0] = atoi(argv[5]);
+ origin[1] = atoi(argv[6]);
+ origin[2] = atoi(argv[7]);
+
+ RegionType region;
+ region.SetIndex(index);
+ region.SetSize(size);
+
+ ImageType::Pointer image = ImageType::New();
+ image->SetRegions(region);
+ image->Allocate();
+
+ typedef itk::SphereSpatialFunction<dim, PointType> ShpereFunctionType;
+ ShpereFunctionType::Pointer sphere = ShpereFunctionType::New();
+
+ double radius = atof(argv[8])/2;
+ sphere->SetCenter(origin);
+ sphere->SetRadius(radius);
+
+ PixelType max = itk::NumericTraits<PixelType>::max();
+ typedef itk::ImageRegionIterator<ImageType> ImageIteratorType;
+ ImageIteratorType it(image, region);
+ PointType point;
+ for (it.GoToBegin(); !it.IsAtEnd(); ++it) {
+ image->TransformIndexToPhysicalPoint(it.GetIndex(), point);
+ if (sphere->Evaluate(point)) {
+ PixelType value = static_cast<PixelType>(max*(point - origin).GetNorm()/radius);
+ it.Set(value);
+ }
+ else
+ it.Set(0);
+ }
+
+ typedef itk::ImageFileWriter<ImageType> ImageWriterType;
+ ImageWriterType::Pointer writer = ImageWriterType::New();
+ writer->SetInput(image);
+ writer->SetFileName(argv[1]);
+ writer->Update();
+}
\ No newline at end of file
// Take the median
double value;
+ typename InputImageType::IndexValueType temporal_dimension = size4D[Dimension-1];
+ std::vector<PixelType> temp(temporal_dimension);
while (!(iterators[0]).IsAtEnd()) {
value=0.;
- std::vector<PixelType> temp;
- for (unsigned int i=0; i<size4D[Dimension-1]; i++) {
- temp.push_back(iterators[i].Get());
+ for (unsigned int i=0; i<temporal_dimension; i++) {
+ temp[i] = iterators[i].Get();
++(iterators[i]);
}
- if (temp.size() % 2) {
- nth_element(temp.begin(),temp.begin()+((temp.size()-1)/2+1),temp.end());
- value=temp[(temp.size()-1)/2];
+ if (temporal_dimension & 1) {
+ nth_element(temp.begin(), temp.begin() + temporal_dimension/2,temp.end());
+ value = temp[temporal_dimension/2];
} else {
- nth_element(temp.begin(),temp.begin()+(temp.size())/2,temp.end());
- value=temp[temp.size()/2];
- nth_element(temp.begin(),temp.begin()+ (temp.size()/2+1),temp.end());
- value+=temp[temp.size()/2+1];
- value/=2;
+ nth_element(temp.begin(), temp.begin() + temporal_dimension/2 - 1, temp.end());
+ value = temp[temporal_dimension/2 - 1];
+ nth_element(temp.begin(), temp.begin() + temporal_dimension/2, temp.end());
+ value += temp[temporal_dimension/2];
+ value /= 2;
}
avIt.Set(value);
++avIt;
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+
+#include "vtkOBJReader.h"
+#include "vtkPolyDataMapper.h"
+#include "vtkRenderer.h"
+#include "vtkRenderWindow.h"
+#include "vtkActor.h"
+#include "vtkCamera.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkSmartPointer.h"
+#include "vtkCommand.h"
+#include "vtkAnimationCue.h"
+#include "vtkAnimationScene.h"
+#include "vtkProperty.h"
+#include "vtkInteractorStyle.h"
+
+#include "clitkCommon.h"
+#include "clitkMeshViewer_ggo.h"
+
+#include <string>
+#include <iostream>
+#include <vector>
+
+typedef vtkSmartPointer<vtkOBJReader> ObjReaderType;
+typedef vtkSmartPointer<vtkPolyDataMapper> MapperType;
+typedef vtkSmartPointer<vtkActor> ActorType;
+
+
+long run(const args_info_clitkMeshViewer& argsInfo);
+
+// Adapted from vtkAnimationCue example...
+class CueAnimator
+{
+public:
+ CueAnimator(std::vector<ActorType>& rActors) : m_Fps(1), m_CurrentActor(0), m_rActors(rActors) {
+ m_rActors[0]->SetVisibility(1);
+ for (unsigned int i = 1; i < m_rActors.size(); i++) {
+ m_rActors[i]->SetVisibility(0);
+ }
+ }
+
+ ~CueAnimator() {
+ }
+
+ void SetFps(double fps) {
+ m_Fps = fps;
+ }
+
+ void StartCue(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info),
+ vtkRenderer *ren)
+ {
+ //std::cout << "StartCue" << std::endl;
+ }
+
+ void Tick(vtkAnimationCue::AnimationCueInfo *info,
+ vtkRenderer *ren)
+ {
+ //std::cout << "Tick AT:" << info->AnimationTime << " DT:" << info->DeltaTime << " CT:" << info->ClockTime << std::endl;
+
+ m_rActors[m_CurrentActor]->SetVisibility(0);
+
+ int step = lrint(m_Fps * info->AnimationTime);
+ int actor = step % m_rActors.size();
+
+ //if (actor != m_CurrentActor) std::cout << "Showing frame: " << m_CurrentActor << std::endl;
+ m_CurrentActor = actor;
+ m_rActors[m_CurrentActor]->SetVisibility(1);
+
+ ren->Render();
+ }
+
+ void EndCue(vtkAnimationCue::AnimationCueInfo *info,
+ vtkRenderer *ren)
+ {
+ //std::cout << "EndCue" << std::endl;
+ }
+
+protected:
+
+ double m_Fps;
+ clock_t m_LastTick;
+ double m_TotalTicks;
+ int m_CurrentActor;
+ std::vector<ActorType>& m_rActors;
+};
+
+class vtkAnimationCueObserver : public vtkCommand
+{
+public:
+ static vtkAnimationCueObserver *New()
+ {
+ return new vtkAnimationCueObserver;
+ }
+
+ virtual void Execute(vtkObject *vtkNotUsed(caller),
+ unsigned long event,
+ void *calldata)
+ {
+ if(this->Animator!=0 && this->Renderer!=0)
+ {
+ vtkAnimationCue::AnimationCueInfo *info=
+ static_cast<vtkAnimationCue::AnimationCueInfo *>(calldata);
+ switch(event)
+ {
+ case vtkCommand::StartAnimationCueEvent:
+ this->Animator->StartCue(info,this->Renderer);
+ break;
+ case vtkCommand::EndAnimationCueEvent:
+ this->Animator->EndCue(info,this->Renderer);
+ break;
+ case vtkCommand::AnimationCueTickEvent:
+ this->Animator->Tick(info,this->Renderer);
+ break;
+ }
+ }
+ if(this->RenWin!=0)
+ {
+ this->RenWin->Render();
+ }
+ }
+
+ vtkRenderer *Renderer;
+ vtkRenderWindow *RenWin;
+ CueAnimator *Animator;
+
+protected:
+ vtkAnimationCueObserver()
+ {
+ this->Renderer=0;
+ this->Animator=0;
+ this->RenWin=0;
+ }
+};
+
+class vtkWindowObserver : public vtkCommand
+{
+public:
+ static vtkWindowObserver *New()
+ {
+ return new vtkWindowObserver;
+ }
+
+ virtual void Execute(vtkObject *caller,
+ unsigned long event,
+ void *calldata)
+ {
+ vtkRenderWindowInteractor *isi = dynamic_cast<vtkRenderWindowInteractor *>(caller);
+ //std::cout << "Execute" << std::endl;
+ switch (event)
+ {
+ case vtkCommand::KeyPressEvent:
+ {
+ std::string key = isi->GetKeySym();
+ //std::cout << key[0] << std::endl;
+ switch (key[0])
+ {
+ case 'P':
+ case 'p':
+ if (this->m_Scene)
+ this->m_Scene->Play();
+ break;
+
+ case 'M':
+ case 'm':
+ if (this->m_Scene)
+ this->m_Scene->Stop();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ default:
+ break;
+
+ }
+
+ }
+
+ vtkAnimationScene* m_Scene;
+
+ protected:
+
+ vtkWindowObserver() : m_Scene(0) {}
+};
+
+int main(int argc, char** argv)
+{
+ GGO(clitkMeshViewer, args_info);
+
+ return run(args_info);
+}
+
+long run(const args_info_clitkMeshViewer& argsInfo)
+{
+ std::vector<ObjReaderType> objs;
+ std::vector<MapperType> mappers;
+ std::vector<ActorType> actors;
+
+ bool verbose = argsInfo.verbose_flag;
+
+ int nfiles = argsInfo.inputs_num;
+ if (nfiles == 0)
+ {
+ std::cout << "At leas one mesh (.OBJ) file must be given. See clitkMeshViewer -h." << std::endl;
+ return -1;
+ }
+
+ if (verbose)
+ std::cout << nfiles << " file(s) to be loaded..." << std::endl;
+
+ vtkSmartPointer<vtkRenderer> aRenderer = vtkRenderer::New();
+ for (int i = 0; i < nfiles; i++) {
+ std::string file = argsInfo.inputs[i];
+ if (verbose)
+ std::cout << "Reading " << file << std::endl;
+
+ vtkSmartPointer<vtkOBJReader> preader = vtkOBJReader::New();
+ preader->SetFileName(file.c_str());
+ preader->Update();
+ objs.push_back(preader);
+
+ vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkPolyDataMapper::New();
+ skinMapper->SetInputConnection(preader->GetOutputPort());
+ skinMapper->ScalarVisibilityOff();
+ mappers.push_back(skinMapper);
+
+ vtkSmartPointer<vtkActor> skin = vtkActor::New();
+ skin->SetMapper(skinMapper);
+ actors.push_back(skin);
+
+ aRenderer->AddActor(skin);
+ }
+
+ vtkSmartPointer<vtkCamera> aCamera = vtkCamera::New();
+ aCamera->SetViewUp (0, 0, -1);
+ aCamera->SetPosition (0, 1, 0);
+ aCamera->SetFocalPoint (0, 0, 0);
+ aCamera->ComputeViewPlaneNormal();
+ aCamera->Dolly(1.5);
+
+ aRenderer->SetActiveCamera(aCamera);
+ aRenderer->ResetCamera ();
+ aRenderer->SetBackground(0,0,0);
+ aRenderer->ResetCameraClippingRange ();
+
+ vtkSmartPointer<vtkRenderWindow> renWin = vtkRenderWindow::New();
+ renWin->AddRenderer(aRenderer);
+ renWin->SetSize(640, 480);
+
+ vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkRenderWindowInteractor::New();
+ iren->SetRenderWindow(renWin);
+ iren->Initialize();
+
+ vtkSmartPointer<vtkAnimationScene> scene;
+ vtkSmartPointer<vtkAnimationCue> cue1;
+ vtkSmartPointer<vtkAnimationCueObserver> anim_observer;
+ vtkSmartPointer<vtkWindowObserver> window_observer;
+ CueAnimator animator(actors);
+
+ bool animate = argsInfo.animate_flag;
+ if (animate) {
+ double fps = argsInfo.fps_arg;
+ animator.SetFps(fps);
+
+ // Create an Animation Scene
+ scene=vtkAnimationScene::New();
+ scene->SetModeToRealTime();
+
+ scene->SetLoop(1);
+ scene->SetTimeModeToRelative();
+ scene->SetStartTime(0);
+ scene->SetEndTime(actors.size()/fps);
+
+ // Create an Animation Cue.
+ cue1=vtkAnimationCue::New();
+ cue1->SetTimeModeToRelative();
+ cue1->SetStartTime(0);
+ cue1->SetEndTime(actors.size()/fps);
+ scene->AddCue(cue1);
+
+ // Create Cue anim_observer.
+ anim_observer=vtkAnimationCueObserver::New();
+ anim_observer->Renderer=aRenderer;
+ anim_observer->Animator=&animator;
+ anim_observer->RenWin=renWin;
+ cue1->AddObserver(vtkCommand::StartAnimationCueEvent,anim_observer);
+ cue1->AddObserver(vtkCommand::EndAnimationCueEvent,anim_observer);
+ cue1->AddObserver(vtkCommand::AnimationCueTickEvent,anim_observer);
+
+ window_observer = vtkWindowObserver::New();
+ window_observer->m_Scene = scene;
+ iren->AddObserver(vtkCommand::KeyPressEvent, window_observer);
+
+ }
+
+ iren->Start();
+ return 0;
+}
+
+
--- /dev/null
+#File clitkMeshViewer.ggo
+package "clitkMeshViewer"
+version "1.0"
+purpose "Visualize a set of meshes"
+usage "clitkMeshViewer FILE1 FILE2 ... [OPTIONS]"
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "animate" - "Enable animation mode (type p/m to start/stop animation)" flag off
+option "fps" - "Set the animation's frame rate (in fps)" double default="4.0" no
--- /dev/null
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkConstantPadImageFilter.h"
+#include "clitkCommon.h"
+#include "clitkPadImage_ggo.h"
+#include <string>
+#include "itkMath.h"
+
+enum
+{
+ ERR_SUCCESS = 0,
+ ERR_NOT_SAME_SPACING = -1,
+ ERR_NOT_LIKE_LARGER = -2
+};
+
+typedef unsigned int DimType;
+
+template <class ImageType, class PadBoundType, DimType dim>
+int pad_like(typename ImageType::Pointer input, const std::string& likeFile, PadBoundType* padLower, PadBoundType* padUpper)
+{
+ typedef typename ImageType::SpacingType SpacingType;
+ typedef typename ImageType::RegionType RegionType;
+ typedef typename ImageType::SizeType SizeType;
+ typedef typename ImageType::IndexType IndexType;
+ typedef typename ImageType::PointType PointType;
+ typedef typename ImageType::PointValueType PointValueType;
+
+ typedef itk::ImageFileReader<ImageType> ImageReaderType;
+ typename ImageReaderType::Pointer reader = ImageReaderType::New();
+ reader->SetFileName(likeFile);
+ reader->Update();
+
+ typename ImageType::Pointer like_image = reader->GetOutput();
+
+ SpacingType spacing = input->GetSpacing(), like_spacing = like_image->GetSpacing();
+ if (spacing != like_spacing) {
+ std::cerr << "Like-image must have same spacing as input: " << spacing << " " << like_spacing << std::endl;
+ return ERR_NOT_SAME_SPACING;
+ }
+
+ SizeType size = input->GetLargestPossibleRegion().GetSize(), like_size = like_image->GetLargestPossibleRegion().GetSize();
+ PointType origin = input->GetOrigin(), like_origin = like_image->GetOrigin();
+
+ PointType lower_bound, like_lower_bound;
+ PointType upper_bound, like_upper_bound;
+ PointValueType auxl = 0, auxu = 0;
+ for (DimType i = 0; i < dim; i++) {
+ lower_bound[i] = origin[i];
+ like_lower_bound[i] = like_origin[i];
+ auxl = itk::Math::Round<PointValueType>(((lower_bound[i] - like_lower_bound[i])/spacing[i]));
+
+ upper_bound[i] = (lower_bound[i] + size[i]*spacing[i]);
+ like_upper_bound[i] = (like_lower_bound[i] + like_size[i]*spacing[i]);
+ auxu = itk::Math::Round<PointValueType>(((like_upper_bound[i] - upper_bound[i])/spacing[i]));
+
+ if (auxl < 0 || auxu < 0) {
+ std::cerr << "Like-image's bounding box must be larger than input's" << std::endl;
+ return ERR_NOT_LIKE_LARGER;
+ }
+
+ padLower[i] = (PadBoundType)auxl;
+ padUpper[i] = (PadBoundType)auxu;
+ }
+
+ return ERR_SUCCESS;
+}
+
+int main(int argc, char** argv)
+{
+ const DimType dim = 3;
+ typedef short PixelType;
+ typedef itk::Image<PixelType, dim> ImageType;
+ typedef itk::ImageFileReader<ImageType> ImageReaderType;
+ typedef itk::ImageFileWriter<ImageType> ImageWriterType;
+ typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
+ typedef PadFilterType::SizeValueType PadBoundType;
+
+ GGO(clitkPadImage, args_info);
+
+ ImageReaderType::Pointer reader = ImageReaderType::New();
+ reader->SetFileName(args_info.input_arg);
+ reader->Update();
+
+ PadBoundType pad_lower[dim], pad_upper[dim];
+ ImageType::Pointer input = reader->GetOutput();
+ if (args_info.like_given) {
+ int err = pad_like<ImageType, PadBoundType, dim>(input, args_info.like_arg, pad_lower, pad_upper);
+ if (err) {
+ std::cerr << "Error processing like image." << std::endl;
+ return err;
+ }
+ }
+ else {
+ for (DimType i = 0; i < dim; i++) {
+ pad_lower[i] = args_info.lower_arg[i];
+ pad_upper[i] = args_info.upper_arg[i];
+ }
+ }
+
+ PadFilterType::Pointer filter = PadFilterType::New();
+ filter->SetPadLowerBound(pad_lower);
+ filter->SetPadUpperBound(pad_upper);
+ filter->SetInput(input);
+ filter->SetConstant(args_info.value_arg);
+ filter->Update();
+
+ ImageType::Pointer output = filter->GetOutput();
+ ImageWriterType::Pointer writer = ImageWriterType::New();
+ writer->SetInput(output);
+ writer->SetFileName(args_info.output_arg);
+ writer->Update();
+
+ return ERR_SUCCESS;
+}
+
--- /dev/null
+#File clitkCropImage.ggo
+package "clitkCropImage"
+version "1.0"
+purpose "Pad an image according to a given extends or like another image"
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+section "I/O"
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+
+section "Used determined padding"
+option "lower" l "Size of the lower crop region (multiple values)" int no multiple
+option "upper" u "Size of the upper crop region (multiple values)" int no multiple
+
+section "Pad like another image"
+option "like" - "Pad like this image (must have the same spacing and bounding box must be larger)" string no
+
+section "Extra parameters"
+option "value" - "Value to be set in padded area" float default="0" no
+
+
+
+
size[mSplitDimension]=0;
typename ImageType::RegionType extracted_region;
extracted_region.SetSize(size);
+#if ITK_VERSION_MAJOR >= 4
+ filter->SetDirectionCollapseToSubmatrix();
+#endif
filter->SetExtractionRegion(extracted_region);
filter->Update();
void read_points_pts(const std::string& fileName, PointArrayType& points);
void write_points_pts(const std::string& fileName, const PointArrayType& points);
+void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output);
void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output);
GGO(clitkTransformLandmarks, args_info);
verbose = args_info.verbose_flag;
- MatrixType matrix = clitk::ReadMatrix3D(args_info.matrix_arg);
-
TxtDataArrayType data;
PointArrayType inputPoints;
if (strcmp(args_info.type_arg, "txt") == 0) {
}
PointArrayType outputPoints;
- transform_points(inputPoints, matrix, outputPoints);
+ PointArrayType spacingPoints;
+ PointArrayType* workingInputPoints = &inputPoints;
+ PointArrayType* workingOutputPoints = &outputPoints;
+ if (args_info.spacing_given) {
+ if (verbose) std::cout << "Processing spacing..." << std::endl;
+
+ apply_spacing(*workingInputPoints, args_info.spacing_arg, spacingPoints);
+ workingInputPoints = &spacingPoints;
+ workingOutputPoints = &spacingPoints;
+ }
+
+ MatrixType matrix;
+ if (args_info.matrix_given) {
+ matrix = clitk::ReadMatrix3D(args_info.matrix_arg);
+ transform_points(*workingInputPoints, matrix, outputPoints);
+ workingOutputPoints = &outputPoints;
+ }
if (strcmp(args_info.type_arg, "txt") == 0) {
- write_points_txt(args_info.output_arg, outputPoints, data);
+ write_points_txt(args_info.output_arg, *workingOutputPoints, data);
}
else {
- write_points_pts(args_info.output_arg, outputPoints);
+ write_points_pts(args_info.output_arg, *workingOutputPoints);
}
return 0;
{
std::ifstream landmarksFile(fileName.c_str());
if (landmarksFile.fail()) {
- std::cout << "ERROR: could not open '" << fileName << "'" << std::endl;
+ std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl;
exit(-2);
}
std::string line;
std::getline(landmarksFile, line);
if (line.find("LANDMARKS") == std::string::npos) {
- std::cout << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
+ std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
exit(-3);
}
{
std::ifstream landmarksFile(fileName.c_str());
if (landmarksFile.fail()) {
- std::cout << "ERROR: could not open '" << fileName << "'" << std::endl;
+ std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl;
exit(-2);
}
std::string line;
std::getline(landmarksFile, line);
if (line.find("#X") != 0) {
- std::cout << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
+ std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
exit(-3);
}
landmarksFile << points[i][0] << "\t" << points[i][1] << "\t" << points[i][2] << "\t" << std::endl;
}
+void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output)
+{
+ PointType out;
+ out.Fill(1);
+
+ for (size_t i = 0; i < input.size(); i++) {
+ out[0] = input[i][0] * spacing[0];
+ out[1] = input[i][1] * spacing[1];
+ out[2] = input[i][2] * spacing[2];
+ if (verbose){
+ std::cout << "output " << out << std::endl;
+ }
+ output.push_back(out);
+ }
+}
+
void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output)
{
for (size_t i = 0; i < input.size(); i++) {
option "verbose" v "Verbose" flag off
option "input" i "Input landmarks filename" string yes
-option "matrix" m "Input 4x4 matrix filename ('.mat' file)" string yes
+option "matrix" m "Input 4x4 matrix filename ('.mat' file)" string no
+option "spacing" s "If given, applies the given spacing (x,y,z) to the input points." double no multiple default="1"
option "output" o "Output landmarks filename" string yes
option "type" t "Landmarks type ('pts' for Jef; 'txt' for VV)" string no default="txt"
//Backward mapping
typedef itk::WarpImageFilter<InputImageType, InputImageType, DeformationFieldType> BackwardWarpFilterType;
typename BackwardWarpFilterType::Pointer backwardWarpFilter= BackwardWarpFilterType::New();
+#if ITK_VERSION_MAJOR >= 4
+ backwardWarpFilter->SetDisplacementField( deformationField );
+#else
backwardWarpFilter->SetDeformationField( deformationField );
+#endif
backwardWarpFilter->SetEdgePaddingValue( static_cast<PixelType>(m_ArgsInfo.pad_arg) );
backwardWarpFilter->SetOutputSpacing( deformationField->GetSpacing() );
backwardWarpFilter->SetOutputOrigin( input->GetOrigin() );
+++ /dev/null
-build/*
-Louise
-tests_jef
-mctools
-*.swp
-Makefile
-tags
-doc
-CVS
-CMakeFiles
-CMakeCache.txt
-.vimrc
-*_ggo.*
-*.directory
endif(COMMAND cmake_policy)
#=========================================================
+
#=========================================================
#List of vv tools to compile
SET(vv_TOOLS
vvToolResample
# vvToolExtractPatient
# vvToolExtractLung
+ vvToolStructureSetManager
vvToolMIP
vvToolConvert ## with dummy vvToolConvert.ui
vvToolWidgetBase
vvToolSimpleInputSelectorWidget
vvToolInputSelectorWidget
- vvToolStructureSetManager
+ vvRegisterForm
)
# All others sources
QT4_ADD_RESOURCES(vv_SRCS vvIcons.qrc)
-#Add the autotools and the common files ui
+# Add the autotools in the header vvToolsList.h for initialization of the dummy
+# variables in vv.cxx for the tools contained in vvLib
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h)
+foreach(tool ${vv_TOOLS})
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h "#include \"${tool}.h\"\n")
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h "extern const vvToolCreator<${tool}> *dummy${tool};\n")
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h "const vvToolCreator<${tool}> *dummy${tool}2 = dummy${tool};\n\n")
+endforeach(tool)
+
+# Add the autotools and the common files ui
foreach(tool ${vv_TOOLS} ${vv_COMMON_WITH_UI})
SET(vv_SRCS ${vv_SRCS} ${tool}.cxx)
QT4_WRAP_CPP(vv_SRCS ${tool}.h)
QT4_WRAP_UI(vv_UI_CXX qt_ui/${tool}.ui)
endforeach(tool)
-#Add the common source files
+# Add the common source files
foreach(tool ${vv_COMMON})
SET(vv_SRCS ${vv_SRCS} ${tool}.cxx)
QT4_WRAP_CPP(vv_SRCS ${tool}.h)
../segmentation
)
-IF(WIN32)
- SET(EXE_ICON vvIcon.rc)
-ENDIF(WIN32)
-
LINK_DIRECTORIES(${QT_LIBRARY_DIR})
-ADD_EXECUTABLE(vv ${vv_SRCS} vv.cxx ${vv_UI_CXX} ${EXE_ICON})
-ADD_DEPENDENCIES(vv clitkSegmentationGgoLib)
-TARGET_LINK_LIBRARIES(vv clitkDicomRTStruct)
-
#=========================================================
#Add each tool's dependencies
foreach(tool ${vv_TOOLS})
- target_link_libraries(vv ${${tool}_LIBS})
+ SET(toolLibs ${toolLibs} ${${tool}_LIBS})
endforeach(tool)
-
#=========================================================
#Add Foundation Libraries (this should be after our libraries, since we depend
#on them)
-TARGET_LINK_LIBRARIES(vv
-clitkCommon ${ITK_LIBRARIES} QVTK vtkHybrid)
+SET(foundationLibraries clitkCommon ${ITK_LIBRARIES} QVTK vtkHybrid)
+
+#=========================================================
+#Create binary and libs for tests
+SET(vvExternalLibs ${QT_QTNETWORK_LIBRARY} clitkSegmentationGgoLib clitkDicomRTStruct ${toolLibs} ${foundationLibraries})
+# QtNetwork is required by vvRegisterForm
+
+ADD_LIBRARY(vvLib ${vv_SRCS} ${vv_UI_CXX})
+TARGET_LINK_LIBRARIES(vvLib ${vvExternalLibs})
+
+IF(WIN32)
+ ADD_EXECUTABLE(vv WIN32 vv.cxx vvIcon.rc)
+ELSE(WIN32)
+ ADD_EXECUTABLE(vv vv.cxx)
+ENDIF(WIN32)
+
+#TARGET_LINK_LIBRARIES(vv vvLib)
+TARGET_LINK_LIBRARIES(vv vvLib)
+
#=========================================================
# Install options (also used by CPack)
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReadMe.txt")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
SET(CPACK_PACKAGE_VERSION_MAJOR "1")
-SET(CPACK_PACKAGE_VERSION_MINOR "1")
-SET(CPACK_PACKAGE_VERSION_PATCH "0")
+SET(CPACK_PACKAGE_VERSION_MINOR "2")
+SET(CPACK_PACKAGE_VERSION_PATCH "2")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "vv")
+SET(CPACK_STRIP_FILES TRUE)
IF(WIN32)
# There is a bug in NSI that does not handle full unix paths properly. Make
ENDIF(WIN32)
INCLUDE(CPack)
#=========================================================
+#=========================================================
+configure_file(vvConfiguration.h.in vvConfiguration.h)
+#=========================================================
Authors belong to:
- University of LYON http://www.universite-lyon.fr/
- - Léon Bérard cancer center http://www.centreleonberard.fr
+ - Léon Bérard cancer center http://www.centreleonberard.fr
- CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
This software is distributed WITHOUT ANY WARRANTY; without even
Copyright (c) 2008 CLB / CREATIS-LRMN
-CLB = Léon Bérard cancer center http://www.centreleonberard.fr
+CLB = Léon Bérard cancer center http://www.centreleonberard.fr
CREATIS-LMRN = Centre de Recherche et d'Applications en Traitement de l'Image http://www.creatis.insa-lyon.fr
All rights reserved.
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">F1: </span><span style=" font-size:12pt;">Help (this window)</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Slice Selection</span></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; font-weight:600;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">F2:</span><span style=" font-size:12pt;"> Sagital</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">0,1,2,3,4,5</span><span style=" font-size:12pt;"> : Windowing Preset Selection</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">6,7,8,9</span><span style=" font-size:12pt;">: Colormap Selection</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">w</span><span style=" font-size:12pt;">: Local </span><span style=" font-size:12pt; text-decoration: underline;">w</span><span style=" font-size:12pt;">indowing around mouse cursor</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Ctrl+w</span><span style=" font-size:12pt;">: Idem for fusion or overlay</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Miscellaneous</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">l</span><span style=" font-size:12pt;">: Toggle </span><span style=" font-size:12pt; text-decoration: underline;">l</span><span style=" font-size:12pt;">inear interpolation</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">c</span><span style=" font-size:12pt;">: Toggle </span><span style=" font-size:12pt; text-decoration: underline;">c</span><span style=" font-size:12pt;">ontour superposition mode</span></p></body></html></string>
</property>
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">space</span><span style=" font-size:12pt;">: Landmark</span></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600; text-decoration: underline;">Navigation</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">u</span><span style=" font-size:12pt;">: </span><span style=" font-size:12pt; text-decoration: underline;">U</span><span style=" font-size:12pt;">pdate Image</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">f</span><span style=" font-size:12pt;">: </span><span style=" font-size:12pt; text-decoration: underline;">F</span><span style=" font-size:12pt;">ly To Mouse Position</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">g</span><span style=" font-size:12pt;">: </span><span style=" font-size:12pt; text-decoration: underline;">G</span><span style=" font-size:12pt;">o to Crosshair Position</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Ctrl+g</span><span style=" font-size:12pt;">: </span><span style=" font-size:12pt; text-decoration: underline;">G</span><span style=" font-size:12pt;">o to Coordinate System Origin</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">h</span><span style=" font-size:12pt;">: </span><span style=" font-size:12pt; text-decoration: underline;">H</span><span style=" font-size:12pt;">ide Crosshair and corner annotations</span></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Up,Down</span><span style=" font-size:12pt;">: Change Slice</span></p>
<normaloff>:/common/icons/ducky.png</normaloff>:/common/icons/ducky.png</iconset>
</property>
<property name="statusTip">
- <string>Type 'h' on image to display help on navigation</string>
+ <string>Type 'F1' on image to display help on navigation</string>
</property>
<widget class="QWidget" name="centralwidget">
<property name="sizePolicy">
</sizepolicy>
</property>
<property name="statusTip">
- <string>Type 'h' on image to display help on navigation</string>
+ <string>Type 'F1' on image to display help on navigation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<string>Cold</string>
</property>
</item>
+ <item>
+ <property name="text">
+ <string>Dosimetry</string>
+ </property>
+ </item>
<item>
<property name="text">
<string>Full Color</string>
<number>2</number>
</property>
<item row="0" column="0">
- <widget class="QVTKWidget" name="NOViewWidget" native="true">
+ <widget class="QVTKWidget" name="NOViewWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
<number>2</number>
</property>
<item row="0" column="0">
- <widget class="QVTKWidget" name="SOViewWidget" native="true">
+ <widget class="QVTKWidget" name="SOViewWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
<number>2</number>
</property>
<item row="0" column="0">
- <widget class="QVTKWidget" name="NEViewWidget" native="true">
+ <widget class="QVTKWidget" name="NEViewWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
<number>2</number>
</property>
<item row="0" column="0">
- <widget class="QVTKWidget" name="SEViewWidget" native="true">
+ <widget class="QVTKWidget" name="SEViewWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
</property>
<addaction name="actionNavigation_Help"/>
<addaction name="actionDocumentation"/>
+ <addaction name="actionRegister_vv"/>
</widget>
<widget class="QMenu" name="menuOverlay">
<property name="title">
<normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
</property>
<property name="text">
- <string>Merge several xD images into a single (x+1)D image</string>
+ <string>Merge several nD images into a single (n+1)D image</string>
</property>
</action>
<action name="actionSlice_Image_As_Multiple_Images">
<normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
</property>
<property name="text">
- <string>Slice a xD image into several (x-1)D images</string>
+ <string>Slice a nD image into several (n-1)D images</string>
</property>
</action>
<action name="actionOpen_one_Image_as_Multiple">
<normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
</property>
<property name="text">
- <string>Open xD image(s) as (x-1)D + t</string>
+ <string>Open a nD image as a (n-1)D + t image</string>
</property>
</action>
<action name="actionMerge_images_as_n_dim_t">
<normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
</property>
<property name="text">
- <string>Open several xD images into a single xD+t images</string>
+ <string>Open several nD images into a single nD+t image</string>
</property>
</action>
<action name="actionAdd_fusion_image">
<string>Experimental...</string>
</property>
</action>
+ <action name="actionRegister_vv">
+ <property name="text">
+ <string>Register vv</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>
<rect>
<x>0</x>
<y>0</y>
- <width>323</width>
- <height>447</height>
+ <width>342</width>
+ <height>480</height>
</rect>
</property>
<property name="sizePolicy">
</item>
<item>
<widget class="QToolButton" name="vfColorButton">
- <property name="styleSheet">
- <string>
+ <property name="styleSheet">
+ <string>
background-color: rgb(0, 255, 0);
border: 0px;
</string>
- </property>
+ </property>
</widget>
</item>
</layout>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout">
+ <layout class="QGridLayout" name="compareGridLayout">
<property name="margin">
<number>2</number>
</property>
</property>
</widget>
</item>
- <item row="1" column="2">
+ <item row="1" column="1" colspan="5">
<widget class="QSlider" name="colorHorizontalSlider">
<property name="maximum">
<number>359</number>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="3">
+ <item row="2" column="0" colspan="5">
<widget class="QLabel" name="refValueLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property>
</widget>
</item>
- <item row="3" column="0" colspan="3">
+ <item row="3" column="0" colspan="5">
<widget class="QLabel" name="valueLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property>
</widget>
</item>
- <item row="4" column="0" colspan="3">
+ <item row="4" column="0" colspan="5">
<widget class="QLabel" name="diffValueLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property>
</widget>
</item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Window :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QDoubleSpinBox" name="overlayWindowSpinBox">
+ <property name="decimals">
+ <number>4</number>
+ </property>
+ <property name="minimum">
+ <double>-999999.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>999999.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>100.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Level :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="3">
+ <widget class="QDoubleSpinBox" name="overlayLevelSpinBox">
+ <property name="decimals">
+ <number>4</number>
+ </property>
+ <property name="minimum">
+ <double>-999999.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>999999.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>10.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>1000.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="4">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="5" column="5">
+ <widget class="QCheckBox" name="overlayLinkCheckBox">
+ <property name="text">
+ <string>Link</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout">
- <property name="margin">
- <number>2</number>
- </property>
- <property name="spacing">
- <number>2</number>
- </property>
+ <layout class="QGridLayout" name="fusionGridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="maximumSize">
</property>
</widget>
</item>
- <item row="0" column="1" colspan="4">
+ <item row="0" column="1" colspan="2">
<widget class="QLabel" name="dataFusionnedLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property>
</widget>
</item>
- <item row="1" column="0" colspan="2">
+ <item row="1" column="0" colspan="3">
<widget class="QLabel" name="opacityLabel">
<property name="text">
- <string>Opacity :</string>
+ <string>Global Opacity :</string>
</property>
</widget>
</item>
- <item row="1" column="2" colspan="3">
+ <item row="1" column="3" colspan="3">
<widget class="QSlider" name="opacityHorizontalSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property>
</widget>
</item>
- <item row="2" column="0" colspan="2">
+ <item row="2" column="0" colspan="3">
+ <widget class="QLabel" name="thresOpacityLabel">
+ <property name="toolTip">
+ <string>All colors below the threshold will be made transparent.</string>
+ </property>
+ <property name="statusTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Transparency Threshold :</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" colspan="3">
+ <widget class="QSlider" name="thresOpacityHorizontalSlider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</property>
</widget>
</item>
- <item row="2" column="2" colspan="2">
+ <item row="3" column="2" colspan="2">
<widget class="QComboBox" name="fusionColorMapComboBox">
<property name="currentIndex">
- <number>3</number>
+ <number>0</number>
</property>
<item>
<property name="text">
<string>Cold</string>
</property>
</item>
+ <item>
+ <property name="text">
+ <string>Dosimetry</string>
+ </property>
+ </item>
<item>
<property name="text">
<string>Full Color Range</string>
</item>
</widget>
</item>
- <item row="3" column="0" colspan="2">
+ <item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Window :</string>
</property>
</widget>
</item>
- <item row="3" column="2">
- <widget class="QDoubleSpinBox" name="windowSpinBox">
+ <item row="4" column="2" colspan="2">
+ <widget class="QDoubleSpinBox" name="fusionWindowSpinBox">
<property name="decimals">
<number>4</number>
</property>
</property>
</widget>
</item>
- <item row="3" column="3">
+ <item row="4" column="4">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Level :</string>
</property>
</widget>
</item>
- <item row="3" column="4">
- <widget class="QDoubleSpinBox" name="levelSpinBox">
+ <item row="4" column="5">
+ <widget class="QDoubleSpinBox" name="fusionLevelSpinBox">
<property name="decimals">
<number>4</number>
</property>
</property>
</widget>
</item>
- <item row="4" column="0" colspan="5">
+ <item row="5" column="0" colspan="3">
<widget class="QLabel" name="valueFusionnedLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</layout>
</widget>
<resources>
- <include location="../vvIcons.qrc"/>
<include location="../vvIcons.qrc"/>
<include location="vvIcons.qrc"/>
</resources>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>vvRegisterForm</class>
+ <widget class="QDialog" name="vvRegisterForm">
+ <property name="windowModality">
+ <enum>Qt::ApplicationModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>350</width>
+ <height>396</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>VV registration</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextBrowser" name="textBrowser">
+ <property name="contextMenuPolicy">
+ <enum>Qt::DefaultContextMenu</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="html">
+ <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
+<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;"><img src=":/common/icons/weNeedYou.png" style="float: left;" /><span style=" font-size:11pt; font-weight:600; color:#0000c0;">Welcome to VV !</span><br /><br />We wish to keep an estimate of the number of persons using VV. This is really important for us to justify the ressources spent in developing this software.</p>
+<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;"></p>
+<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;">Please, take a few seconds to fill in the following fields and send us the information by clicking OK. If you still prefer to remain anonymous, simply click &quot;Cancel&quot; (you can still register afterwards using the help menu).</p>
+<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;"></p>
+<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;">Privacy: the collected information is for internal and non-commercial use only. We will only use your email for vv release announcements.</p></body></html></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>First name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="firstName"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="lastName"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Email</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="email"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Institute</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="group"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>OS name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="osName">
+ <property name="text">
+ <string>OS name</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../vvIcons.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>vvRegisterForm</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>vvRegisterForm</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
+++ /dev/null
-#!/bin/bash
-cd current
-echo -n "Patients before: "
-find . -type l | wc -l
-for i in /home/gauthier/Base_de_donnees_stereo_poumon/*; do [ -e "$i" ] || ln -s "$i" .; done
-echo -n "Patients after: "
-find . -type l | wc -l
-for i in $(find . -type l); do date; echo $i; irsync -rv "$i" "i:/rhone-alpes/home/clb/patients/$i" >> "$i"_$(date "+%H:%m-%d_%b%Y").log; done
#include "clitkIO.h"
#include "vvMainWindow.h"
+#include "vvToolsList.h"
#include <vtkFileOutputWindow.h>
#include <vtkSmartPointer.h>
#include <itkFileOutputWindow.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <errno.h>
+#include <errno.h>
void load_image_first_error()
{
}
//------------------------------------------------------------------------------
+#ifdef _WIN32
+int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+ int argc = __argc;
+ char **argv = __argv;
+#else
int main( int argc, char** argv )
{
+#endif
+
CLITK_INIT;
QApplication app( argc, argv );
Q_INIT_RESOURCE(vvIcons);
- //QPixmap pixmap(":/splashscreen.PNG");
- QSplashScreen *splash = new QSplashScreen(QPixmap(QString::fromUtf8(":/new/prefix1/splashscreen.PNG")));
- /*splash->showMessage("VV 1.0 developped by Léon Bérard c`ancer center http://www.centreleonberard.fr and CREATIS-LRMN http://www.creatis.insa-lyon.fr",(Qt::AlignRight | Qt::AlignBottom));*/
- // splash->show();
- QTimer::singleShot(2000, splash, SLOT(close()));
- while (!splash->isHidden())
- app.processEvents();
+
+ //
+ // ATTENTION: Rômulo Pinho - 05/08/2011
+ // Forcing the locale of the application is necessary
+ // because QT initialization changes it to the locale
+ // of the language of the system. This can cause
+ // inconsistencies when, e.g., reading float values
+ // from DICOM fields with gdcm, since the decimal
+ // point may be changed for a comma (as in French).
+ // In practice, functions such as scanf and its
+ // variations are directly affected.
+ // https://bugreports.qt.nokia.com//browse/QTBUG-15247?page=com.atlassian.jira.plugin.system.issuetabpanels%253Achangehistory-tabpanel
+ //
+#ifndef _WIN32
+ std::string old_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "POSIX");
+#endif
vvMainWindow window;
if(itksys::SystemTools::FileExists(log_dir.c_str()) &&
!itksys::SystemTools::FileIsDirectory(log_dir.c_str())) {
- itkGenericExceptionMacro(<< "Error creating log directory, file exists and is not a directory.");
+ std::cerr << "Error creating log directory, file exists and is not a directory." << std::endl;
+ exit(1);
} else if(!itksys::SystemTools::MakeDirectory(log_dir.c_str())) {
- itkGenericExceptionMacro(<< "Error creating log directory.");
+ std::cerr << "Error creating log directory." << std::endl;
+ exit(1);
}
std::string log_file = log_dir + "/" + create_timed_string() + ".log";
}
if(win!="" && lev!="") {
- window.WindowLevelChanged(atof(win.c_str()), atof(lev.c_str()), 6, 0);
+ window.SetWindowLevel(atof(win.c_str()), atof(lev.c_str()));
window.ApplyWindowLevelToAllImages();
}
+#ifndef _WIN32
+ // restoring the locale, just to be clean...
+ setlocale(LC_NUMERIC, old_locale.c_str());
+#endif
+
return app.exec();
}
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#ifndef vv_configuration_h
+#define vv_configuration_h
+
+#define VV_VERSION "v@CPACK_PACKAGE_VERSION_MAJOR@.@CPACK_PACKAGE_VERSION_MINOR@.@CPACK_PACKAGE_VERSION_PATCH@"
+
+#endif
<RCC>
<qresource prefix="common">
<file>icons/mip.png</file>
+ <file>icons/weNeedYou.png</file>
<file>icons/tool-roi.png</file>
<file>icons/plastimatch.png</file>
<file>icons/lung-overlay.png</file>
<file>icons/adjustsize.png</file>
<file>icons/standardbutton-apply-16.png</file>
<file>icons/standardbutton-cancel-16.png</file>
+ <file>icons/identity.png</file>
</qresource>
</RCC>
mHiddenImageIsUsed = false;
mDisplayModeIsPreserveMemory = true;
SetPreserveMemoryModeEnabled(true);
+ mPreviousOrientation = -1;
}
//------------------------------------------------------------------------------
if (mPreviousValue == value) {
if (mPreviousSlice == mSlicer->GetSlice()) {
if (mPreviousTSlice == mSlicer->GetTSlice()) {
- return; // Nothing to do
+ if (mPreviousOrientation == ComputeCurrentOrientation()) {
+ return; // Nothing to do
+ }
}
}
}
UpdateWithFastCacheMode();
}
- // mSlicer->Render(); //DS ---> REMOVE ??
+ //mSlicer->Render(); //DS ---> REMOVE ??
mPreviousTSlice = mSlicer->GetTSlice();
mPreviousSlice = mSlicer->GetSlice();
mPreviousValue = value;
+ mPreviousOrientation = ComputeCurrentOrientation();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vvImageContour::UpdateWithPreserveMemoryMode() {
// Only change actor visibility if tslice change
- int mPreviousTslice = mTSlice;
+ mPreviousTslice = mTSlice;
mTSlice = mSlicer->GetTSlice();
vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
+ vtkPolyDataMapper* mapper = mSquaresMapperList[mTSlice];
vtkImageClip * mClipper = mClipperList[mTSlice];
vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
int orientation = ComputeCurrentOrientation();
- UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
- //mSquaresActorList[mTSlice]->VisibilityOn();
+ UpdateActor(mSquaresActor, mapper, mSquares, mClipper, mValue, orientation, mSlice);
if (mPreviousTslice != mTSlice) {
if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
}
+
+ mSlicer->Render();
}
//------------------------------------------------------------------------------
clipper->SetInput(mHiddenImage->GetVTKImages()[0]);
else
clipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
+
squares->SetInput(clipper->GetOutput());
squaresMapper->SetInput(squares->GetOutput());
squaresMapper->ScalarVisibilityOff();
//------------------------------------------------------------------------------
void vvImageContour::UpdateActor(vtkActor * actor,
+ vtkPolyDataMapper * mapper,
vtkMarchingSquares * squares,
vtkImageClip * clipper,
double threshold, int orientation, int slice) {
+
// Set parameter for the MarchigSquare
squares->SetValue(0, threshold);
} else {
extent2 = extent;
+ actor->VisibilityOn();
}
clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
if (mHiddenImageIsUsed) delete extent2;
// Move the actor to be visible
- switch (orientation) {
- case 0:
- actor->SetPosition(-1,0,0);
- /*
- // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0]);
- if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
- actor->SetPosition(1,0,0);
- } else {
- actor->SetPosition(-1,0,0);
- }*/
- break;
- case 1:
- actor->SetPosition(0,-1,0);
- /*
- // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1]);
- if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
- actor->SetPosition(0,1,0);
- } else {
- actor->SetPosition(0,-1,0);
- }
- */
- break;
- case 2:
- actor->SetPosition(0,0,-1);
- /*
- DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2]);
- if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
- DD("1");
- actor->SetPosition(0,0,1);
- } else {
- DD("-1");
- actor->SetPosition(0,0,-1);
- }
- */
- break;
- }
-
- squares->Update();
+ double position[3] = {0, 0, 0};
+ position[orientation] = -1;
+ actor->SetPosition(position);
+
+ mapper->Update();
}
//------------------------------------------------------------------------------
void UpdateWithPreserveMemoryMode();
void UpdateWithFastCacheMode();
void CreateNewActor(int numImage);
- void UpdateActor(vtkActor * actor, vtkMarchingSquares * squares, vtkImageClip * clipper,
+ void UpdateActor(vtkActor * actor, vtkPolyDataMapper * mapper, vtkMarchingSquares * squares, vtkImageClip * clipper,
double threshold, int orientation, int slice);
void CreateActor(int orientation, int slice);
int ComputeCurrentOrientation();
private:
vvImageContour();
~vvImageContour();
+ int mPreviousTslice;
}; // end class vvImageContour
//------------------------------------------------------------------------------
jacobian_filter->SetUseImageSpacingOn();
vf_connector->SetInput(mVF->GetVTKImages()[num]);
warp_filter->SetInput(input[num]);
+#if ITK_VERSION_MAJOR >= 4
+ warp_filter->SetDisplacementField(vf_connector->GetOutput());
+#else
warp_filter->SetDeformationField(vf_connector->GetOutput());
+#endif
jacobian_filter->SetInput(vf_connector->GetOutput());
warp_filter->SetOutputSpacing(input[num]->GetSpacing());
warp_filter->SetOutputOrigin(input[num]->GetOrigin());
#include "vvInfoPanel.h"
#include "clitkMemoryUsage.h"
+#include "clitkConfiguration.h"
+
+//------------------------------------------------------------------------------
+vvInfoPanel::vvInfoPanel(QWidget * parent):QWidget(parent)
+{
+ setupUi(this);
+#if CLITK_MEMORY_INFO==0
+ memoryUsageLabel->hide();
+#endif
+}
+//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vvInfoPanel::setTransformation(QString text)
//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-void vvInfoPanel::setViews(int window, int view, int slice)
-{/*
- QString viewString;
- switch (view) {
- case 0: {
- viewString = "Sagital, ";
- break;
- }
- case 1: {
- viewString = "Coronal, ";
- break;
- }
- case 2: {
- viewString = "Axial, ";
- break;
- }
- }
-
- QString text = viewString;
- if (view != -1) {
- text += "current slice : ";
- text += QString::number(slice);
- } else {
- text = "Disable";
- }
-
- switch (window) {
- case 0: {
- ULLabel->setText(text);
- break;
- }
- case 1: {
- URLabel->setText(text);
- break;
- }
- case 2: {
- DLLabel->setText(text);
- break;
- }
- case 3: {
- DRLabel->setText(text);
- break;
- }
- }*/
-}
-//------------------------------------------------------------------------------
-
-
//------------------------------------------------------------------------------
void vvInfoPanel::setMemoryInMb(QString text)
{
Q_OBJECT
public:
- vvInfoPanel(QWidget * parent=0):QWidget(parent) {
- setupUi(this);
- }
+ vvInfoPanel(QWidget * parent=0);
~vvInfoPanel() {}
void setTransformation(QString text);
void setDimension(QString text);
void setSizePixel(QString text);
void setCurrentInfo(int visibility, double x, double y, double z, double X, double Y, double Z, double value);
- void setViews(int window, int view, int slice);
void setMemoryInMb(QString text);
public slots:
#include <QInputDialog>
#include <QTimer>
#include "QTreePushButton.h"
+#include <QUrl>
+#include <QSettings>
// VV include
#include "vvMainWindow.h"
#include "vvHelpDialog.h"
+#include "vvRegisterForm.h"
#include "vvDocumentation.h"
#include "vvProgressDialog.h"
#include "vvQDicomSeriesSelector.h"
#include <vtkPNMWriter.h>
#include <vtkPNGWriter.h>
#include <vtkJPEGWriter.h>
-#include <vtkFFMPEGWriter.h>
+#ifdef VTK_USE_FFMPEG_ENCODER
+# include <vtkFFMPEGWriter.h>
+#endif
#ifdef VTK_USE_MPEG2_ENCODER
- #include <vtkMPEG2Writer.h>
+# include <vtkMPEG2Writer.h>
#endif
#include <vtkMatrix4x4.h>
#include <vtkTransform.h>
#define COLUMN_RELOAD_IMAGE 6
#define COLUMN_IMAGE_NAME 7
-#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.hdr *.vox *.his *.xdr *.SCAN )"
+#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN )"
/*Data Tree values
0,Qt::UserRole full filename
connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage()));
contextActions.push_back(actionAdd_fusion_image);
+ contextMenu.addSeparator();
+ QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")),
+ tr("Reset transformation to identity"));
+ connect(actionResetMatrix, SIGNAL(triggered()), this,SLOT(ResetTransformationToIdentity()));
+
// TRIAL DS
/*
QMenu * m = new QMenu(menubar);
connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField()));
connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
+ connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
///////////////////////////////////////////////
connect(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage()));
connect(linkPanel,SIGNAL(addLink(QString,QString)),this,SLOT(AddLink(QString,QString)));
connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString)));
connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double)));
- connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int)),this,SLOT(SetOverlayProperty(int)));
- connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,double,double)),
- this,SLOT(SetFusionProperty(int,int,double,double)));
+ connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int,int,double,double)),
+ this,SLOT(SetOverlayProperty(int,int,double,double)));
+ connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double)),
+ this,SLOT(SetFusionProperty(int,int,int,double,double)));
connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
playMode = 0;//pause
//Recently opened files
std::list<std::string> recent_files = GetRecentlyOpenedImages();
+ recentlyOpenedFilesMenu=NULL;
if ( !recent_files.empty() ) {
- QMenu * rmenu = new QMenu("Recently opened files...");
- rmenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png")));
- menuFile->insertMenu(actionOpen_Image_With_Time,rmenu);
- menuFile->insertSeparator(actionOpen_Image_With_Time);
- for (std::list<std::string>::iterator i = recent_files.begin(); i!=recent_files.end(); i++) {
- QAction* current=new QAction(QIcon(QString::fromUtf8(":/common/icons/open.png")),
- (*i).c_str(),this);
- rmenu->addAction(current);
- connect(current,SIGNAL(triggered()),this,SLOT(OpenRecentImage()));
- }
+ createRecentlyOpenedFilesMenu();
+ updateRecentlyOpenedFilesMenu(recent_files);
}
// Adding all new tools (insertion in the menu)
vvToolManager::GetInstance()->InsertToolsInMenu(this);
+ vvToolManager::GetInstance()->EnableToolsInMenu(this, false);
if (!CLITK_EXPERIMENTAL)
menuExperimental->menuAction()->setVisible(false);
//timerMemory->setInterval(5);
connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage()));
timerMemory->start(2000);
-
}
//------------------------------------------------------------------------------
-
-
+void vvMainWindow::show()
+{
+ vvMainWindowBase::show();
+ PopupRegisterForm(true);
+}
//------------------------------------------------------------------------------
void vvMainWindow::UpdateMemoryUsage()
{
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void vvMainWindow::createRecentlyOpenedFilesMenu()
+{
+ recentlyOpenedFilesMenu = new QMenu("Recently opened files...");
+ recentlyOpenedFilesMenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png")));
+ menuFile->insertMenu(actionOpen_Image_With_Time,recentlyOpenedFilesMenu);
+ menuFile->insertSeparator(actionOpen_Image_With_Time);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+
+void vvMainWindow::updateRecentlyOpenedFilesMenu(const std::list<std::string> &recent_files)
+{
+ if(recentlyOpenedFilesMenu==NULL) {
+ createRecentlyOpenedFilesMenu();
+ } else {
+ recentlyOpenedFilesMenu->clear();
+ }
+ for (std::list<std::string>::const_iterator i = recent_files.begin(); i!=recent_files.end(); i++) {
+ QAction* current=new QAction(QIcon(QString::fromUtf8(":/common/icons/open.png")), i->c_str(),this);
+ recentlyOpenedFilesMenu->addAction(current);
+ connect(current,SIGNAL(triggered()),this,SLOT(OpenRecentImage()));
+ }
+}
+//------------------------------------------------------------------------------
+
+
//------------------------------------------------------------------------------
void vvMainWindow::ComputeMidPosition()
{
if (files.size() == 1) {
QFileInfo finfo=tr(files[0].c_str());
AddToRecentlyOpenedImages(finfo.absoluteFilePath().toStdString());
+ updateRecentlyOpenedFilesMenu(GetRecentlyOpenedImages());
}
//init the progress events
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
item->setData(0,Qt::UserRole,files[i].c_str());
QFileInfo fileinfo(imageManager->GetFileName().c_str()); //Do not show the path
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
- item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+ item->setData(1,Qt::UserRole,tr("image"));
+ item->setToolTip(COLUMN_IMAGE_NAME, imageManager->GetListOfAbsoluteFilePathInOneString("image").c_str());
qApp->processEvents();
//Create the buttons for reload and close
connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
this,SLOT(CurrentImageChanged(std::string)));
- connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
- this, SLOT(CurrentPickedImageChanged(std::string)));
+ connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
+ this, SLOT(CurrentPickedImageChanged(std::string)));
connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)),
this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double)));
connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)),
this, SLOT(OverlayChanged(int,double,double)));
connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
this, SLOT(FusionChanged(int,double)));
- connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
- this,SLOT(WindowsChanged(int, int, int)));
- connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
- this,SLOT(WindowLevelChanged(double, double, int, int)));
+ connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
+ this,SLOT(WindowLevelChanged()));
connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
this,SLOT(UpdateSlice(int,int)));
connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
actionNorth_West_Window->setEnabled(1);
actionSouth_East_Window->setEnabled(1);
actionSouth_West_Window->setEnabled(1);
+ vvToolManager::GetInstance()->EnableToolsInMenu(this, true);
inverseButton->setEnabled(1);
goToCursorPushButton->setEnabled(1);
vvImage::Pointer imageSelected;
if (DataTree->topLevelItem(index) == DataTree->selectedItems()[0]) {
imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
- dimension = imageSelected->GetNumberOfDimensions();
- origin.resize(dimension);
- inputSpacing.resize(dimension);
- inputSize.resize(dimension);
- sizeMM.resize(dimension);
- pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
- for (int i = 0; i < dimension; i++) {
- origin[i] = imageSelected->GetOrigin()[i];
- inputSpacing[i] = imageSelected->GetSpacing()[i];
- inputSize[i] = imageSelected->GetSize()[i];
- sizeMM[i] = inputSize[i]*inputSpacing[i];
- NPixel *= inputSize[i];
- }
- inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
} else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "vector") {
imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetVF();
- dimension = imageSelected->GetNumberOfDimensions();
- origin.resize(dimension);
- inputSpacing.resize(dimension);
- inputSize.resize(dimension);
- sizeMM.resize(dimension);
- pixelType = mSlicerManagers[index]->GetVF()->GetScalarTypeAsITKString().c_str();
- for (int i = 0; i < dimension; i++) {
- origin[i] = imageSelected->GetOrigin()[i];
- inputSpacing[i] = imageSelected->GetSpacing()[i];
- inputSize[i] = imageSelected->GetSize()[i];
- sizeMM[i] = inputSize[i]*inputSpacing[i];
- NPixel *= inputSize[i];
- }
- inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
} else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "overlay") {
imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetOverlay();
- dimension = imageSelected->GetNumberOfDimensions();
- origin.resize(dimension);
- inputSpacing.resize(dimension);
- inputSize.resize(dimension);
- sizeMM.resize(dimension);
- pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
- for (int i = 0; i < dimension; i++) {
- origin[i] = imageSelected->GetOrigin()[i];
- inputSpacing[i] = imageSelected->GetSpacing()[i];
- inputSize[i] = imageSelected->GetSize()[i];
- sizeMM[i] = inputSize[i]*inputSpacing[i];
- NPixel *= inputSize[i];
- }
- inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
} else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusion") {
imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
- dimension = imageSelected->GetNumberOfDimensions();
- origin.resize(dimension);
- inputSpacing.resize(dimension);
- inputSize.resize(dimension);
- sizeMM.resize(dimension);
- pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
- for (int i = 0; i < dimension; i++) {
- origin[i] = imageSelected->GetOrigin()[i];
- inputSpacing[i] = imageSelected->GetSpacing()[i];
- inputSize[i] = imageSelected->GetSize()[i];
- sizeMM[i] = inputSize[i]*inputSpacing[i];
- NPixel *= inputSize[i];
- }
- inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
+ }
+ else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "contour") {
+ imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+ }
+ else {
+ imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
}
+ dimension = imageSelected->GetNumberOfDimensions();
+ origin.resize(dimension);
+ inputSpacing.resize(dimension);
+ inputSize.resize(dimension);
+ sizeMM.resize(dimension);
+ pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
+ for (int i = 0; i < dimension; i++) {
+ origin[i] = imageSelected->GetOrigin()[i];
+ inputSpacing[i] = imageSelected->GetSpacing()[i];
+ inputSize[i] = imageSelected->GetSize()[i];
+ sizeMM[i] = inputSize[i]*inputSpacing[i];
+ NPixel *= inputSize[i];
+ }
+ inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
+
QString dim = QString::number(dimension) + " (";
dim += pixelType + ")";
break;
}
}
- windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
- levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
- presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
- colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
infoPanel->setFileName(image);
infoPanel->setDimension(dim);
break;
}
}
- windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
- levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
- presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
- colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
+ WindowLevelChanged();
if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str());
}
if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
- overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor());
} else {
overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
- overlayPanel->getOverlayProperty(-1);
}
+
if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
- overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
- mSlicerManagers[index]->GetFusionColorMap(),
- mSlicerManagers[index]->GetFusionWindow(),
- mSlicerManagers[index]->GetFusionLevel());
} else {
overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
- overlayPanel->getFusionProperty(-1, -1,-1,-1);
}
}
}
{
documentation->show();
}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::PopupRegisterForm(bool checkCanPush)
+{
+ vvRegisterForm* registerForm = new vvRegisterForm(QUrl("http://www.creatis.insa-lyon.fr/~dsarrut/vvregister/write.php"), getVVSettingsPath(), getSettingsOptionFormat());
+ if(!checkCanPush) {
+ registerForm->show();
+ } else {
+ if(registerForm->canPush()) {
+ registerForm->show();
+ registerForm->acquitPushed();//too bad if there is not internet connection anymore.
+ }
+ }
+}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvMainWindow::ShowHelpDialog()
{
//------------------------------------------------------------------------------
void vvMainWindow::ChangeViewMode()
{
- QListIterator<int> it0(splitter_3->sizes());
- QListIterator<int> it1(splitter_3->sizes());
- int max0 = 0;
- int max1 = 1;
- while (it0.hasNext()) {
- max0 += it0.next();
- }
- while (it1.hasNext()) {
- max1 += it1.next();
- }
- QList<int> size0;
- QList<int> size1;
+ QList<int> size;
if (viewMode == 1) {
viewMode = 0;
- size0.push_back(max0);
- size0.push_back(0);
- size1.push_back(max1);
- size1.push_back(0);
- splitter_3->setSizes(size0);
- OSplitter->setSizes(size1);
+ size.push_back(1);
+ size.push_back(0);
+ splitter_3->setSizes(size);
+ OSplitter->setSizes(size);
DataTree->setColumnHidden(2,1);
DataTree->setColumnHidden(3,1);
DataTree->setColumnHidden(4,1);
} else {
viewMode = 1;
- size0.push_back(int(max0/2));
- size0.push_back(int(max0/2));
- size1.push_back(int(max1/2));
- size1.push_back(int(max1/2));
- splitter_3->setSizes(size0);
- OSplitter->setSizes(size1);
+ size.push_back(1);
+ size.push_back(1);
+ splitter_3->setSizes(size);
+ OSplitter->setSizes(size);
DataTree->setColumnHidden(2,0);
DataTree->setColumnHidden(3,0);
DataTree->setColumnHidden(4,0);
}
+ UpdateRenderWindows();
+ /*
+ ** I don't know why but for both resized QVTKWidget we also need to render
+ ** the associated Slicer to redraw crosses.
+ */
+ for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
+ if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1)
+ mSlicerManagers[i]->GetSlicer(0)->Render();
+ if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1)
+ mSlicerManagers[i]->GetSlicer(2)->Render();
+ }
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvMainWindow::DisplayChanged(QTreeWidgetItem *clicked_item, int column)
+void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column)
{
- int index = GetSlicerIndexFromItem(clicked_item);
if ( column >= COLUMN_CLOSE_IMAGE || column <= 0)
return;
+
+ // Get parent information (might be the same item)
+ int slicerManagerIndex = GetSlicerIndexFromItem(clickedItem);
+ QTreeWidgetItem* clickedParentItem = DataTree->topLevelItem(slicerManagerIndex);
+ vvSlicer* clickedSlicer = mSlicerManagers[slicerManagerIndex]->GetSlicer(column-1);
+
+ // Go over the complete item tree (only 2 levels, parents and children)
for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
- //Trick to avoid redoing twice the job for a key (sr)
- mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()-> GetInteractor()->SetKeySym("Crap");
-
- QTreeWidgetItem* current_row=DataTree->topLevelItem(i);
- if (DataTree->topLevelItem(index) == current_row) {
- vvSlicer* clicked_slicer=mSlicerManagers[i]->GetSlicer(column-1);
- if (current_row == clicked_item) {
- //If we just activated a slicer
- if (current_row->data(column,Qt::CheckStateRole).toInt() > 0) {
- mSlicerManagers[i]->UpdateSlicer(column-1,clicked_item->data(column,Qt::CheckStateRole).toInt());
- mSlicerManagers[i]->UpdateInfoOnCursorPosition(column-1);
- DisplaySliders(i,column-1);
- std::map<std::string,int> overlay_counts;
- for (int child = 0; child < current_row->childCount(); child++) {
- std::string overlay_type =
- current_row->child(child)->data(1,Qt::UserRole).toString().toStdString();
- overlay_counts[overlay_type]++;
- current_row->child(child)->setData(column,Qt::CheckStateRole,
- current_row->data(column,Qt::CheckStateRole));
- clicked_slicer->SetActorVisibility(overlay_type,overlay_counts[overlay_type]-1,true);
- }
- } else { //We don't allow simply desactivating a slicer
- clicked_item->setData(column,Qt::CheckStateRole,2);
- return;
- }
+ // Trick to avoid redoing twice the job for a key (sr)
+ mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()->GetInteractor()->SetKeySym("Crap");
+
+ QTreeWidgetItem* currentParentItem = DataTree->topLevelItem(i);
+ if(currentParentItem != clickedParentItem) {
+ // Not the branch of the clicked item, uncheck all
+
+ // Parent
+ currentParentItem->setData(column,Qt::CheckStateRole, 0);
+ mSlicerManagers[i]->UpdateSlicer(column-1, false);
+
+ // Children
+ for (int iChild = 0; iChild < currentParentItem->childCount(); iChild++) {
+ currentParentItem->child(iChild)->setData(column,Qt::CheckStateRole, 0);
}
- //if we clicked on the vector(or overlay) and not the image
- else {
- if (clicked_item->data(column,Qt::CheckStateRole).toInt()) {
- current_row->setData(column,Qt::CheckStateRole,2);
- mSlicerManagers[i]->UpdateSlicer(column-1,2);
- mSlicerManagers[i]->UpdateInfoOnCursorPosition(column-1);
- DisplaySliders(i,column-1);
- }
- int vis = clicked_item->data(column,Qt::CheckStateRole).toInt();
- std::string overlay_type = clicked_item->data(1,Qt::UserRole).toString().toStdString();
- int overlay_index=0;
- for (int child = 0; child < current_row->childCount(); child++) {
- if (current_row->child(child)->data(1,Qt::UserRole).toString().toStdString() == overlay_type)
- overlay_index++;
- if (current_row->child(child) == clicked_item) break;
- }
- clicked_slicer->SetActorVisibility(
- clicked_item->data(1,Qt::UserRole).toString().toStdString(), overlay_index-1,vis);
+ }
+ else {
+ // Branch of the clicked one: get check status from actor visibility in slicer
+ // and toggle the clicked one
+
+ // Parent
+ bool vis = clickedSlicer->GetActorVisibility("image", 0);
+ bool draw = clickedSlicer->GetRenderer()->GetDraw();
+
+ // Update slicer (after getting visibility)
+ mSlicerManagers[slicerManagerIndex]->UpdateSlicer(column-1, true);
+ mSlicerManagers[slicerManagerIndex]->UpdateInfoOnCursorPosition(column-1);
+ DisplaySliders(slicerManagerIndex, column-1);
+ if(clickedParentItem == clickedItem) {
+ // Toggle
+ vis = !draw || !vis;
}
- } else if (current_row->data(column,Qt::CheckStateRole).toInt() > 0) {
- current_row->setData(column,Qt::CheckStateRole,0);
- mSlicerManagers[i]->UpdateSlicer(column-1,0);
- std::map<std::string,int> overlay_counts;
- for (int child = 0; child < current_row->childCount(); child++) {
- std::string overlay_type =
- current_row->child(child)->data(1,Qt::UserRole).toString().toStdString();
- overlay_counts[overlay_type]++;
- current_row->child(child)->setData(column,Qt::CheckStateRole,0);
- vvSlicer * current_slicer=mSlicerManagers[i]->GetSlicer(column-1);
- current_slicer->SetActorVisibility(overlay_type,overlay_counts[overlay_type]-1,false);
+ clickedSlicer->SetActorVisibility("image", 0, vis);
+ clickedParentItem->setData(column, Qt::CheckStateRole, vis?2:0);
+
+ // Children
+ std::map<std::string, int> actorTypeCounts;
+ for (int iChild = 0; iChild < clickedParentItem->childCount(); iChild++) {
+ QTreeWidgetItem* currentChildItem = clickedParentItem->child(iChild);
+ std::string actorType = currentChildItem->data(1,Qt::UserRole).toString().toStdString();
+ vis = clickedSlicer->GetActorVisibility(actorType, actorTypeCounts[actorType]);
+ if(currentChildItem == clickedItem) {
+ // Toggle or force visibility if it was not on this branch so far
+ vis = !draw || !vis;
+ clickedSlicer->SetActorVisibility(actorType, actorTypeCounts[actorType], vis);
+ }
+ currentChildItem->setData(column, Qt::CheckStateRole, vis?2:0);
+ actorTypeCounts[actorType]++;
}
}
- //mSlicerManagers[i]->SetColorMap(-1);
- mSlicerManagers[i]->SetColorMap();
}
- mSlicerManagers[index]->GetSlicer(column-1)->Render();
+
+ clickedSlicer->Render();
}
//------------------------------------------------------------------------------
int index = GetSlicerIndexFromItem(item);
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QString role=item->data(1,Qt::UserRole).toString();
- if ( role == "vector")
+ if ( role == "vector"){
mSlicerManagers[index]->ReloadVF();
- else if (role == "overlay")
+ }
+ else if (role == "overlay"){
mSlicerManagers[index]->ReloadOverlay();
- else if (role == "fusion")
+ }
+ else if (role == "fusion"){
mSlicerManagers[index]->ReloadFusion();
- else
+ }
+ else{
mSlicerManagers[index]->Reload();
-
+ }
// Update view and info
ImageInfoChanged();
mSlicerManagers[index]->Render();
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvMainWindow::WindowsChanged(int window, int view, int slice)
+void vvMainWindow::WindowLevelChanged()
{
- infoPanel->setViews(window, view, slice);
+ // Base image
+ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+ if(index==-1) return;
+ windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
+ levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
+ colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
+ presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
+
+ // Overlay image
+ if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay())
+ overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor(),
+ mSlicerManagers[index]->GetLinkOverlayWindowLevel(),
+ mSlicerManagers[index]->GetOverlayColorWindow(),
+ mSlicerManagers[index]->GetOverlayColorLevel());
+ else
+ overlayPanel->getOverlayProperty(-1,0,0.,0.);
+
+ // Fusion image
+ if (mSlicerManagers[index]->GetSlicer(0)->GetFusion())
+ overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
+ mSlicerManagers[index]->GetFusionThresholdOpacity(),
+ mSlicerManagers[index]->GetFusionColorMap(),
+ mSlicerManagers[index]->GetFusionWindow(),
+ mSlicerManagers[index]->GetFusionLevel());
+ else
+ overlayPanel->getFusionProperty(-1, -1, -1, -1, -1);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvMainWindow::WindowLevelChanged(double window, double level,int preset,int colormap)
+void vvMainWindow::WindowLevelEdited()
{
- windowSpinBox->setValue(window);
- levelSpinBox->setValue(level);
- colorMapComboBox->setCurrentIndex(colormap);
- presetComboBox->setCurrentIndex(preset);
+ presetComboBox->setCurrentIndex(6);
+ UpdateWindowLevel();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvMainWindow::WindowLevelEdited()
+void vvMainWindow::SetWindowLevel(double w, double l)
{
+ windowSpinBox->setValue(w);
+ levelSpinBox->setValue(l);
presetComboBox->setCurrentIndex(6);
+ colorMapComboBox->setCurrentIndex(0);
UpdateWindowLevel();
}
//------------------------------------------------------------------------------
mSlicerManagers[index]->SetColorLevel(levelSpinBox->value());
mSlicerManagers[index]->SetPreset(presetComboBox->currentIndex());
mSlicerManagers[index]->Render();
- windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
- levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
+ WindowLevelChanged();
}
}
//------------------------------------------------------------------------------
item->setData(1,Qt::UserRole,tr("overlay"));
QFileInfo fileinfo(file); //Do not show the path
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
- item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+ item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("overlay").c_str());
qApp->processEvents();
for (int j = 1; j <= 4; j++) {
item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
- mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("overlay",0,
- DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
}
//Create the buttons for reload and close
error += mSlicerManagers[index]->GetLastError().c_str();
QMessageBox::information(this,tr("Problem reading image !"),error);
}
+ WindowLevelChanged();
}
//------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void vvMainWindow::ResetTransformationToIdentity()
+{
+ std::string actorType = DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString().toStdString();
+ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+ mSlicerManagers[index]->ResetTransformationToIdentity(actorType);
+ ImageInfoChanged();
+}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvMainWindow::AddFusionImage(int index, QString file)
{
item->setData(1,Qt::UserRole,tr("fusion"));
QFileInfo fileinfo(filename.c_str()); //Do not show the path
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
- item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+ item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str());
qApp->processEvents();
for (int j = 1; j <= 4; j++) {
item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
- mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("fusion",0,
- DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
}
//Create the buttons for reload and close
}
QString Extensions = "Images ( *.mhd)";
+ Extensions += ";;Images ( *.mha)";
Extensions += ";;Images ( *.vf)";
QString file = QFileDialog::getOpenFileName(this,tr("Load deformation field"),mInputPathName,Extensions);
if (!file.isEmpty())
item->setData(1,Qt::UserRole,tr("vector"));
QFileInfo fileinfo(filename); //Do not show the path
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
- item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+ item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("vector").c_str());
qApp->processEvents();
for (int j = 1; j <= 4; j++) {
item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
- mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("vector",0,
- DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
}
//Create the buttons for reload and close
//------------------------------------------------------------------------------
-void vvMainWindow::SetOverlayProperty(int color)
+void vvMainWindow::SetOverlayProperty(int color, int linked, double window, double level)
{
int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
mSlicerManagers[index]->SetOverlayColor(color);
mSlicerManagers[index]->SetColorMap(0);
+ mSlicerManagers[index]->SetLinkOverlayWindowLevel(linked);
+ mSlicerManagers[index]->SetOverlayColorWindow(window);
+ mSlicerManagers[index]->SetOverlayColorLevel(level);
mSlicerManagers[index]->Render();
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvMainWindow::SetFusionProperty(int opacity, int colormap,double window, double level)
+void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap,double window, double level)
{
int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
- mSlicerManagers[index]->SetFusionOpacity(opacity);
mSlicerManagers[index]->SetFusionColorMap(colormap);
+ mSlicerManagers[index]->SetFusionOpacity(opacity);
+ mSlicerManagers[index]->SetFusionThresholdOpacity(thresOpacity);
mSlicerManagers[index]->SetFusionWindow(window);
mSlicerManagers[index]->SetFusionLevel(level);
mSlicerManagers[index]->SetColorMap(0);
OutputListeFormat.push_back(".jpeg");
OutputListeFormat.push_back(".tif");
OutputListeFormat.push_back(".mhd");
+ OutputListeFormat.push_back(".mha");
OutputListeFormat.push_back(".hdr");
OutputListeFormat.push_back(".vox");
} else if (dimension == 3) {
OutputListeFormat.push_back(".mhd");
+ OutputListeFormat.push_back(".mha");
OutputListeFormat.push_back(".hdr");
OutputListeFormat.push_back(".vox");
} else if (dimension == 4) {
OutputListeFormat.push_back(".mhd");
+ OutputListeFormat.push_back(".mha");
}
QString Extensions = "AllFiles(*.*)";
for (int i = 0; i < OutputListeFormat.count(); i++) {
{
unsigned int sm1 = 0;
unsigned int sm2 = 0;
-
+
for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
if (image1.toStdString() == mSlicerManagers[i]->GetId()) {
mSlicerManagers[i]->AddLink(image2.toStdString());
if (linkPanel->isLinkAll()) {
emit UpdateLinkedNavigation(mSlicerManagers[sm1]->GetId(), mSlicerManagers[mCurrentPickedImageIndex], mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(0));
emit UpdateLinkedNavigation(mSlicerManagers[sm2]->GetId(), mSlicerManagers[mCurrentPickedImageIndex], mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(0));
- }
- else {
+ } else {
emit UpdateLinkedNavigation(mSlicerManagers[sm2]->GetId(), mSlicerManagers[sm1], mSlicerManagers[sm1]->GetSlicer(0));
}
}
index = (index+offset) % mSlicerManagers.size();
QTreeWidgetItem* item = GetItemFromSlicerManager(mSlicerManagers[index]);
- //CurrentImageChanged(mSlicerManagers[index]->GetId()); //select new image
item->setData(slicer+1,Qt::CheckStateRole,2); //change checkbox
+ CurrentImageChanged(mSlicerManagers[index]->GetId()); //select new image
DisplayChanged(item,slicer+1);
}
//------------------------------------------------------------------------------
void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax)
{
int position = int((min+max)/2);
- int tPosition = int((tmin+tmax)/2);
if (slicer == 0) {
NOVerticalSlider->setValue(position);
NOVerticalSlider->setRange(min,max);
NOHorizontalSlider->setRange(tmin,tmax);
- NOHorizontalSlider->setValue(tPosition);
} else if (slicer == 1) {
NEVerticalSlider->setValue(position);
NEVerticalSlider->setRange(min,max);
NEHorizontalSlider->setRange(tmin,tmax);
- NEHorizontalSlider->setValue(tPosition);
} else if (slicer == 2) {
SOVerticalSlider->setValue(position);
SOVerticalSlider->setRange(min,max);
SOHorizontalSlider->setRange(tmin,tmax);
- SOHorizontalSlider->setValue(tPosition);
} else if (slicer == 3) {
SEVerticalSlider->setValue(position);
SEVerticalSlider->setRange(min,max);
SEHorizontalSlider->setRange(tmin,tmax);
- SEHorizontalSlider->setValue(tPosition);
}
}
//------------------------------------------------------------------------------
vvImage * vvImg = mSlicerManagers[smIndex]->GetImage();
int nSlice = vvImg->GetVTKImages().size();
- for(int i=0; i<nSlice; i++)
- {
+ for(int i=0; i<nSlice; i++) {
mSlicerManagers[smIndex]->SetNextTSlice(0);
vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
w2i->SetInput(widget->GetRenderWindow());
vvImage * vvImg = mSlicerManagers[smIndex]->GetImage();
int nSlice = vvImg->GetVTKImages().size();
- for(int i=0; i<nSlice; i++)
- {
+ for(int i=0; i<nSlice; i++) {
mSlicerManagers[smIndex]->SetNextTSlice(0);
vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
w2i->SetInput(widget->GetRenderWindow());
//create an item in the tree with good settings
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setData(0,Qt::UserRole,slicer_manager->GetFileName().c_str());//files[i].c_str());
+ item->setData(1,Qt::UserRole,tr("image"));
item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,slicer_manager->GetFileName().c_str());//filename.c_str());
qApp->processEvents();
this, SLOT(OverlayChanged(int,double,double)));
connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
this, SLOT(FusionChanged(int,double)));
- connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
- this,SLOT(WindowsChanged(int, int, int)));
- connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
- this,SLOT(WindowLevelChanged(double, double, int, int)));
+ connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
+ this,SLOT(WindowLevelChanged()));
connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
this,SLOT(UpdateSlice(int,int)));
connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
void ImageInfoChanged();
void ShowHelpDialog();
void ShowDocumentation();
+ void PopupRegisterForm(bool checkCanPush=false);
void ComputeDeformableRegistration();
void WarpImage();
void ChangeViewMode();
void SegmentationOnCurrentImage();
void SurfaceViewerLaunch();
- void WindowsChanged(int window, int view, int slice);
- void WindowLevelChanged(double window, double level,int preset, int colormap);
+ void WindowLevelChanged();
void UpdateSlice(int slicer, int slice);
void UpdateTSlice(int slicer, int slice);
void UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax);
void WindowLevelEdited();
+ void SetWindowLevel(double w, double l);
void UpdateColorMap();
void UpdateWindowLevel();
void SwitchWindowLevel();
void OpenField();
void SelectOverlayImage();
void SelectFusionImage();
+ void ResetTransformationToIdentity();
void SetVFProperty(int subsampling,int scale,int lut, int width, double r, double g, double b);
- void SetOverlayProperty(int color);
- void SetFusionProperty(int opacity,int colormap,double window,double level);
+ void SetOverlayProperty(int color, int linked, double window, double level);
+ void SetFusionProperty(int opacity, int tresOpacity, int colormap,double window,double level);
void GoToCursor();
void PlayPause();
}
void UpdateRenderWindows();
void UpdateMemoryUsage();
-
+ void show();
+
+protected:
+
+ void createRecentlyOpenedFilesMenu();
+ void updateRecentlyOpenedFilesMenu(const std::list<std::string> &files);
+
private:
//variables
int GetImageDuplicateFilenameNumber(std::string filename);
QMenu contextMenu;
+ QMenu* recentlyOpenedFilesMenu;
//QMenu *AddSubImageMenu;
std::vector<QAction*> contextActions;
std::vector<QSlider*> horizontalSliders;
};
-#include "vvMainWindow.txx"
-
#endif
double * samp_origin=sample->GetOrigin();
double * spacing=sample->GetSpacing();
binary_image->SetSpacing(spacing);
+
/// Put the origin on a voxel to avoid small skips
binary_image->SetOrigin(floor((bounds[0]-samp_origin[0])/spacing[0]-2)*spacing[0]+samp_origin[0],
floor((bounds[2]-samp_origin[1])/spacing[1]-2)*spacing[1]+samp_origin[1],
stencil->SetInput(binary_image);
stencil->Update();
this->AddMask(stencil->GetOutput());
- //vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
- //w->SetInput(stencil->GetOutput());
- //w->SetFileName("binary.mhd");
- //w->Write();
+
+ /*
+ vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
+ w->SetInput(stencil->GetOutput());
+ w->SetFileName("binary.mhd");
+ w->Write();
+ */
}
}
{
std::vector<vvMesh::Pointer> result;
#if GDCM_MAJOR_VERSION == 2
+ gdcm::Reader reader;
+ reader.SetFileName(filename.c_str());
+ reader.Read();
+
+ const gdcm::DataSet &ds = reader.GetFile().GetDataSet();
+
+ gdcm::SmartPointer<gdcm::SequenceOfItems> rois = ds.GetDataElement(gdcm::Tag(0x3006,0x39)).GetValueAsSQ();
+ gdcm::SmartPointer<gdcm::SequenceOfItems> roi_info = ds.GetDataElement(gdcm::Tag(0x3006,0x20)).GetValueAsSQ();
+ assert(rois); // TODO error message
+ assert(roi_info); // TODO error message
+ assert(rois->GetNumberOfItems() == roi_info->GetNumberOfItems());
+
+ for (unsigned ridx = 0; ridx < rois->GetNumberOfItems(); ++ridx)
+ {
+ vtkSmartPointer<vtkAppendPolyData> append=vtkSmartPointer<vtkAppendPolyData>::New();
+ const gdcm::DataSet& ds_rois = rois->GetItem( ridx + 1).GetNestedDataSet();
+ const gdcm::DataSet& ds_roi_info = roi_info->GetItem( ridx + 1).GetNestedDataSet();
+
+ gdcm::Attribute<0x3006,0x84> roinumber;
+ roinumber.SetFromDataSet(ds_rois);
+ if (std::find(selected_contours.begin(), selected_contours.end(), roinumber.GetValue()) != selected_contours.end()) //Only read selected ROIs
+ {
+ gdcm::Attribute<0x3006,0x2a> trgb;
+ trgb.SetFromDataSet(ds_rois);
+ vvMesh::Pointer current_roi=vvMesh::New();
+ current_roi->r = trgb[0] / 255;
+ current_roi->g = trgb[1] / 255;
+ current_roi->b = trgb[2] / 255;
+
+ gdcm::Attribute<0x3006,0x26> tstructure_name;
+ tstructure_name.SetFromDataSet(ds_roi_info);
+ current_roi->structure_name = tstructure_name.GetValue();
+
+ gdcm::SmartPointer<gdcm::SequenceOfItems> roi_seq = ds_rois.GetDataElement(gdcm::Tag(0x3006,0x40)).GetValueAsSQ();
+ double z0=-1; //Used to determine spacing between slices, assumed to be constant
+ for (unsigned j = 0; j < roi_seq->GetNumberOfItems(); ++j)
+ {
+ gdcm::Item & item_roi_seq = roi_seq->GetItem(j + 1); // Item starts at 1
+ const gdcm::DataSet& ds_roi_seq = item_roi_seq.GetNestedDataSet();
+ gdcm::Attribute<0x3006,0x42> tcontour_type;
+ tcontour_type.SetFromDataSet(ds_roi_seq);
+ std::string contour_type = tcontour_type.GetValue();
+ if (contour_type=="CLOSED_PLANAR ")
+ {
+ gdcm::Attribute<0x3006,0x46> tpoint_number;
+ tpoint_number.SetFromDataSet(ds_roi_seq);
+ const gdcm::DataElement & points_data = ds_roi_seq.GetDataElement(gdcm::Tag(0x3006,0x50));
+ gdcm::Attribute<0x3006,0x50> tpoints;
+ tpoints.SetFromDataElement(points_data);
+ assert(tpoints.GetNumberOfValues() == static_cast<unsigned int>(tpoint_number.GetValue()) * 3);
+ const double* points = tpoints.GetValues();
+ if (z0 == -1) //First contour
+ z0=points[2];
+ else
+ if (current_roi->GetSpacing()==-1 && points[2] != z0 )
+ current_roi->SetSpacing(points[2]-z0);
+ vtkPolyData * contour=vtkPolyData::New();
+ contour->Allocate(); //for cell structures
+ contour->SetPoints(vtkPoints::New());
+ vtkIdType ids[2];
+ for (unsigned idx = 0; idx < tpoints.GetNumberOfValues(); idx += 3)
+ {
+ contour->GetPoints()->InsertNextPoint(points[idx], points[idx+1], points[idx+2]);
+ ids[0] = idx / 3;
+ ids[1] = (ids[0] + 1) % tpoint_number.GetValue(); //0-1,1-2,...,n-1-0
+ contour->GetLines()->InsertNextCell(2, ids);
+ }
+ append->AddInput(contour);
+ }
+ else
+ if (contour_type == "POINT ")
+ ; // silently ignore POINT type since we don't need them at the moment
+ else
+ std::cerr << "Warning: contour type " << contour_type << " not handled!" << std::endl;
+ }
+ append->Update();
+ current_roi->AddMesh(append->GetOutput());
+ result.push_back(current_roi);
+ }
+ else
+ {
+ //std::cerr << "Warning: ignoring ROI #" << roi_number << std::endl;
+ }
+ }
#else
gdcm::File reader;
reader.SetFileName(filename.c_str());
typename FilterType::Pointer warp_filter = FilterType::New();
warp_filter->SetInput(input);
+#if ITK_VERSION_MAJOR >= 4
+ warp_filter->SetDisplacementField(resampler->GetOutput());
+#else
warp_filter->SetDeformationField(resampler->GetOutput());
+#endif
warp_filter->SetOutputSpacing(input->GetSpacing());
warp_filter->SetOutputOrigin(input->GetOrigin());
warp_filter->SetOutputSize(input->GetLargestPossibleRegion().GetSize());
connect(vfColorButton,SIGNAL(clicked()),this,SLOT(VFColorChangeRequest()));
connect(colorHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(setOverlayProperty()));
connect(opacityHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionProperty()));
+ connect(thresOpacityHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionProperty()));
connect(fusionColorMapComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setFusionProperty()));
- connect(windowSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
- connect(levelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
+ connect(fusionWindowSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
+ connect(fusionLevelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
+ connect(overlayWindowSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setOverlayProperty()));
+ connect(overlayLevelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setOverlayProperty()));
+ connect(overlayLinkCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setOverlayProperty()));
+
+ disableFusionSignals = false;
}
void vvOverlayPanel::getCurrentImageName(QString name)
imageComparedLabel->setText(filename.toStdString().c_str());
}
-void vvOverlayPanel::getOverlayProperty(int value)
+void vvOverlayPanel::getOverlayProperty(int color, int linked, double window, double level)
{
- if (value > -1) {
+ if (color > -1) {
compareFrame->show();
compareFrame->setEnabled(1);
colorHorizontalSlider->setEnabled(1);
- colorHorizontalSlider->setValue(value);
+ colorHorizontalSlider->setValue(color);
+ overlayLinkCheckBox->setCheckState( (linked)?Qt::Checked:Qt::Unchecked );
+ overlayWindowSpinBox->setValue(window);
+ overlayLevelSpinBox->setValue(level);
} else {
compareFrame->hide();
compareFrame->setEnabled(0);
void vvOverlayPanel::setOverlayProperty()
{
- emit OverlayPropertyUpdated(colorHorizontalSlider->value());
+ overlayWindowSpinBox->setEnabled(!overlayLinkCheckBox->checkState());
+ overlayLevelSpinBox->setEnabled(!overlayLinkCheckBox->checkState());
+ emit OverlayPropertyUpdated(colorHorizontalSlider->value(),
+ overlayLinkCheckBox->checkState(),
+ overlayWindowSpinBox->value(),
+ overlayLevelSpinBox->value());
}
void vvOverlayPanel::getCurrentOverlayInfo(int visibility,double valueOver, double valueRef)
dataFusionnedLabel->setText(filename.toStdString().c_str());
}
-void vvOverlayPanel::getFusionProperty(int opacity, int colormap, double window, double level)
+void vvOverlayPanel::getFusionProperty(int opacity, int thresOpacity, int colormap, double window, double level)
{
if (opacity > -1) {
+ //first disable signals generated by each setValue() call
+ disableFusionSignals = true;
fusionFrame->show();
fusionFrame->setEnabled(1);
- opacityHorizontalSlider->setEnabled(1);
- opacityHorizontalSlider->setValue(opacity);
fusionColorMapComboBox->setEnabled(1);
fusionColorMapComboBox->setCurrentIndex(colormap);
- windowSpinBox->setEnabled(1);
- levelSpinBox->setEnabled(1);
- windowSpinBox->setValue(window);
- levelSpinBox->setValue(level);
+ opacityHorizontalSlider->setEnabled(1);
+ opacityHorizontalSlider->setValue(opacity);
+ thresOpacityHorizontalSlider->setEnabled(1);
+ thresOpacityHorizontalSlider->setValue(thresOpacity);
+ fusionWindowSpinBox->setEnabled(1);
+ fusionLevelSpinBox->setEnabled(1);
+ fusionWindowSpinBox->setValue(window);
+ fusionLevelSpinBox->setValue(level);
+
+ // re-enable signals and trigger slot function
+ disableFusionSignals = false;
+ setFusionProperty();
} else {
fusionFrame->hide();
fusionFrame->setEnabled(0);
opacityHorizontalSlider->setEnabled(0);
opacityHorizontalSlider->setValue(0);
+ thresOpacityHorizontalSlider->setEnabled(0);
+ thresOpacityHorizontalSlider->setValue(0);
fusionColorMapComboBox->setEnabled(0);
fusionColorMapComboBox->setCurrentIndex(-1);
- windowSpinBox->setEnabled(0);
- levelSpinBox->setEnabled(0);
+ fusionWindowSpinBox->setEnabled(0);
+ fusionLevelSpinBox->setEnabled(0);
}
}
void vvOverlayPanel::setFusionProperty()
{
- emit FusionPropertyUpdated(opacityHorizontalSlider->value(), fusionColorMapComboBox->currentIndex(),
- windowSpinBox->value(), levelSpinBox->value());
+ if (disableFusionSignals)
+ return;
+
+ emit FusionPropertyUpdated(opacityHorizontalSlider->value(), thresOpacityHorizontalSlider->value(), fusionColorMapComboBox->currentIndex(),
+ fusionWindowSpinBox->value(), fusionLevelSpinBox->value());
}
void vvOverlayPanel::getCurrentFusionInfo(int visibility,double value)
void getVFProperty(int subsampling, int scale, int log);
void getVFName(QString name);
- void getOverlayProperty(int color);
+ void getOverlayProperty(int color, int linked, double window, double level);
void getOverlayName(QString name);
- void getFusionProperty(int opacity, int colormap, double window, double level);
+ void getFusionProperty(int opacity, int thresOpacity, int colormap, double window, double level);
void getFusionName(QString name);
void getCurrentVectorInfo(int visibility, double x, double y, double z, double value);
signals:
void VFPropertyUpdated(int subsampling, int scale, int log, int width, double r, double g, double b);
- void OverlayPropertyUpdated(int color);
- void FusionPropertyUpdated(int opacity, int colormap, double window, double level);
+ void OverlayPropertyUpdated(int color, int linked, double window, double level);
+ void FusionPropertyUpdated(int opacity, int thresOpacity, int colormap, double window, double level);
+
+
+private:
+ bool disableFusionSignals;
+
}; // end class vvOverlayPanel
//====================================================================
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#include <QApplication>
+
+#include "vvRegisterForm.h"
+#include <QNetworkRequest>
+#include <QDir>
+#include <QPalette>
+#include "clitkConfiguration.h"
+#include "vvConfiguration.h"
+#include "vvUtils.h"
+
+vvRegisterForm::vvRegisterForm(QUrl url, QString path, QSettings::Format format):url(url), settings(path, format){
+ manager = new QNetworkAccessManager(this);
+ setupUi(this);
+ textBrowser->viewport()->setAutoFillBackground(false);
+}
+
+void vvRegisterForm::sendData(){
+ QUrl url2(url);
+ url2.addQueryItem("name", firstName->text().toUtf8());
+ url2.addQueryItem("lastName", lastName->text().toUtf8());
+ url2.addQueryItem("email", email->text().toUtf8());
+ url2.addQueryItem("group", group->text().toUtf8());
+ url2.addQueryItem("os", OS_NAME);
+ url2.addQueryItem("vvVersion", VV_VERSION);
+ url2.addQueryItem("architecture", ARCHITECTURE);
+ url2.addQueryItem("adressing", QString::number(sizeof(char*)*8)+"-bit");
+ url2.addQueryItem("compilationDate", QString(__DATE__) + ", " + QString(__TIME__) );
+
+ manager->get(QNetworkRequest(url2));
+}
+void vvRegisterForm::accept(){
+ sendData();
+ settings.setValue("name", firstName->text().toUtf8());
+ settings.setValue("lastName", lastName->text().toUtf8());
+ settings.setValue("email", email->text().toUtf8());
+ settings.setValue("group", group->text().toUtf8());
+ settings.setValue("os", osName->text().toUtf8());
+ QDialog::accept();
+}
+bool vvRegisterForm::canPush(){
+ ///maybe we show this dialog only for new major release, not for any patches?
+ return settings.value("vvVersion").toString().toStdString()<VV_VERSION;
+}
+void vvRegisterForm::acquitPushed(){
+ settings.setValue("vvVersion", VV_VERSION);
+}
+void vvRegisterForm::show(){
+ firstName->setText(settings.value("name").toString());
+ lastName->setText(settings.value("lastName").toString());
+ email->setText(settings.value("email").toString());
+ group->setText(settings.value("group").toString());
+ osName->setText(QString::fromStdString(OS_NAME) + ", " +
+ ARCHITECTURE + ", " +
+ QString::number(sizeof(char*)*8)+"-bit");
+ QDialog::show();
+}
--- /dev/null
+/*=========================================================================
+ Program: vv http://www.creatis.insa-lyon.fr/rio/vv
+
+ Authors belong to:
+ - University of LYON http://www.universite-lyon.fr/
+ - Léon Bérard cancer center http://www.centreleonberard.fr
+ - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the copyright notices for more information.
+
+ It is distributed under dual licence
+
+ - BSD See included LICENSE.txt file
+ - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef vvRegisterForm_h
+#define vvRegisterForm_h
+
+#include "ui_vvRegisterForm.h"
+#include <QUrl>
+#include <QSettings>
+#include <QNetworkAccessManager>
+class vvRegisterForm : public QDialog, private Ui::vvRegisterForm
+{
+ Q_OBJECT
+
+public:
+ vvRegisterForm(QUrl url, QString path, QSettings::Format format);
+ void sendData();
+ ~vvRegisterForm() {}
+ virtual bool canPush();
+ virtual void acquitPushed();
+public slots:
+ virtual void accept();
+ virtual void show();
+protected:
+ QUrl url;
+ QSettings settings;
+ QNetworkAccessManager* manager;
+};
+
+#endif
#include <vtkImageAccumulate.h>
#include <vtkImageReslice.h>
-// template <class T, unsigned int dim>
-// void print_vector(const char* pmsg, T* pvec)
-// {
-// std::cout << pmsg << ": ";
-// for (unsigned int i = 0; i < dim; i++)
-// std::cout << pvec[i] << " ";
-// std::cout << std::endl;
-// }
-
-
vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
vtkStandardNewMacro(vvSlicer);
-
+static void copyExtent(int* in, int* to){
+ for(int i=0; i<6; ++i) to[i]=in[i];
+}
//------------------------------------------------------------------------------
vvSlicer::vvSlicer()
{
this->UnInstallPipeline();
mImage = NULL;
+ mReducedExtent = new int[6];
mCurrentTSlice = 0;
mUseReducedExtent = false;
mVFColor[1] = 1;
mVFColor[2] = 0;
- std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
- text += "F5 = horizontal flip; F6 = vertical flip\n\n";
- text += "0,1,2,3,4,5 : preset windowing\n";
- text += "6,7,8,9 : preset colormap\n";
- text += "z : local windowing\n";
- text += "r : reset view\n";
- text += "l : reload image\n";
- text += "f : fly to mouse position\n";
- text += "g : go to cross hair position\n\n";
- text += "Up,down : change slice\n";
- text += "Left,right : change tenporal slice\n\n";
- text += "Scrollbar (or w/x) : zoom in/out\n";
- text += "left button : synchronize all views\n";
- text += "middle button : grab image\n";
- text += "right button : change windowing\n";
-
crossCursor = vtkSmartPointer<vtkCursor2D>::New();
crossCursor->AllOff();
crossCursor->AxesOn();
this->WindowLevel = vvImageMapToWLColors::New();
this->InstallPipeline();
+
+ mLinkOverlayWindowLevel = true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper()
+vtkImageMapToColors* vvSlicer::GetFusionMapper()
{
return mFusionMapper.GetPointer();
}
//------------------------------------------------------------------------------
void vvSlicer::SetReducedExtent(int * ext)
{
- mReducedExtent = ext;
+ copyExtent(ext, mReducedExtent);
}
//------------------------------------------------------------------------------
for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
i!=mSurfaceCutActors.end(); i++)
delete (*i);
+ delete [] mReducedExtent;
}
//------------------------------------------------------------------------------
// Prevent crash when reload -> change slice if outside extent
if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
- Slice = (extent[SliceOrientation*2+1]-extent[SliceOrientation*2])/2.0;
+ Slice = (extent[SliceOrientation*2+1]+extent[SliceOrientation*2])/2.0;
}
// Make sure that the required part image has been computed
mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
mOverlayActor->SetInput(mOverlayMapper->GetOutput());
mOverlayActor->SetPickable(0);
- mOverlayActor->SetVisibility(false);
+ mOverlayActor->SetVisibility(true);
mOverlayActor->SetOpacity(0.5);
}
this->GetRenderer()->AddActor(mOverlayActor);
//Synchronize orientation and slice
- this->SetSliceOrientation(this->SliceOrientation);
+ AdjustResliceToSliceOrientation(mOverlayReslice);
+ this->UpdateDisplayExtent();
this->SetTSlice(mCurrentTSlice);
}
}
mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData());
if (!mFusionMapper)
- mFusionMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
+ mFusionMapper = vtkSmartPointer<vtkImageMapToColors>::New();
+
+ vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
+ lut->SetRange(0, 1);
+ lut->SetValueRange(0, 1);
+ lut->SetSaturationRange(0, 0);
+ lut->Build();
+ mFusionMapper->SetLookupTable(lut);
mFusionMapper->SetInput(mFusionReslice->GetOutput());
if (!mFusionActor) {
mFusionActor = vtkSmartPointer<vtkImageActor>::New();
mFusionActor->SetInput(mFusionMapper->GetOutput());
mFusionActor->SetPickable(0);
- mFusionActor->SetVisibility(false);
+ mFusionActor->SetVisibility(true);
mFusionActor->SetOpacity(0.7);
this->GetRenderer()->AddActor(mFusionActor);
}
//Synchronize orientation and slice
- this->SetSliceOrientation(this->SliceOrientation);
+ AdjustResliceToSliceOrientation(mFusionReslice);
+ this->UpdateDisplayExtent();
this->SetTSlice(mCurrentTSlice);
}
}
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
+{
+ bool vis = false;
+ if (actor_type == "image") {
+ vis = this->ImageActor->GetVisibility();
+ }
+ else if (actor_type == "vector") {
+ vis = this->mVFActor->GetVisibility();
+ }
+ else if (actor_type == "overlay") {
+ vis = this->mOverlayActor->GetVisibility();
+ }
+ else if (actor_type == "fusion") {
+ vis = this->mFusionActor->GetVisibility();
+ }
+ else if (actor_type == "contour")
+ vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
+
+ return vis;
+}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
{
- if (actor_type == "vector") {
+ if (actor_type == "image") {
+ this->ImageActor->SetVisibility(vis);
+ }
+ else if (actor_type == "vector") {
this->mVFActor->SetVisibility(vis);
}
- if (actor_type == "overlay") {
+ else if (actor_type == "overlay") {
this->mOverlayActor->SetVisibility(vis);
}
- if (actor_type == "fusion") {
+ else if (actor_type == "fusion") {
this->mFusionActor->SetVisibility(vis);
}
- if (actor_type == "contour")
+ else if (actor_type == "contour")
this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
UpdateDisplayExtent();
}
//------------------------------------------------------------------------------
-
//------------------------------------------------------------------------------
void vvSlicer::SetVF(vvImage::Pointer vf)
{
reslice->SetOutputOrigin(origin);
reslice->SetOutputSpacing(spacing);
reslice->UpdateInformation();
+ reslice->GetOutput()->UpdateInformation();
}
//------------------------------------------------------------------------------
//----------------------------------------------------------------------------
-int * vvSlicer::GetExtent()
-{
+int * vvSlicer::GetExtent(){
int *w_ext;
if (mUseReducedExtent) {
w_ext = mReducedExtent;
// Local copy of extent
int w_ext[6];
- for(unsigned int i=0; i<6; i++){
- if (mUseReducedExtent)
- w_ext[i] = mReducedExtent[i];
- else
- w_ext[i] = input->GetWholeExtent()[i];
- }
-
+ copyExtent(GetExtent(), w_ext);
// Set slice value
w_ext[ this->SliceOrientation*2 ] = this->Slice;
w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
// Overlay image actor
if (mOverlay && mOverlayActor->GetVisibility()) {
+ AdjustResliceToSliceOrientation(mOverlayReslice);
int overExtent[6];
- mOverlayReslice->GetOutput()->UpdateInformation();
this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
mOverlayActor->SetDisplayExtent( overExtent );
// Fusion image actor
if (mFusion && mFusionActor->GetVisibility()) {
+ AdjustResliceToSliceOrientation(mFusionReslice);
int fusExtent[6];
- mFusionReslice->GetOutput()->UpdateInformation();
this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
mFusionActor->SetDisplayExtent(fusExtent);
//----------------------------------------------------------------------------
void vvSlicer::SetDisplayMode(bool i)
{
- this->GetImageActor()->SetVisibility(i);
- this->GetAnnotation()->SetVisibility(i);
this->GetRenderer()->SetDraw(i);
- if (mLandActor)
- mLandActor->SetVisibility(i);
- pdmA->SetVisibility(i);
if (i)
UpdateDisplayExtent();
}
vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
if (cam) {
double *position = cam->GetPosition();
- switch (this->SliceOrientation) {
+ double factor[3] = {1, 1, 1};
+ factor[this->SliceOrientation] = -1;
+ cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]);
+
+/* switch (this->SliceOrientation) {
case vtkImageViewer2::SLICE_ORIENTATION_XY:
cam->SetPosition(position[0],position[1],-position[2]);
break;
case vtkImageViewer2::SLICE_ORIENTATION_YZ:
cam->SetPosition(-position[0],position[1],position[2]);
break;
- }
+ }*/
+
this->Renderer->ResetCameraClippingRange();
this->UpdateDisplayExtent();
}
}
//----------------------------------------------------------------------------
-
//----------------------------------------------------------------------------
void vvSlicer::SetColorLevel(double level)
{
}
//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+double vvSlicer::GetOverlayColorWindow()
+{
+ if(mOverlayMapper)
+ return mOverlayMapper->GetWindow();
+ else
+ return 0.;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+double vvSlicer::GetOverlayColorLevel()
+{
+ if(mOverlayMapper)
+ return mOverlayMapper->GetLevel();
+ else
+ return 0.;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicer::SetOverlayColorWindow(double window)
+{
+ mOverlayMapper->SetWindow(window);
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicer::SetOverlayColorLevel(double level)
+{
+ mOverlayMapper->SetLevel(level);
+}
+//----------------------------------------------------------------------------
+
//----------------------------------------------------------------------------
// Returns the min an the max value in a 41x41 region around the mouse pointer
-void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
+void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image)
{
//Get mouse pointer position in view coordinates
double fLocalExtents[6];
//Convert to image pixel coordinates (rounded)
int iLocalExtents[6];
for(int i=0; i<3; i++) {
- fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
- fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
+ fLocalExtents[i*2 ] = (fLocalExtents[i*2 ] - image->GetOrigin()[i])/image->GetSpacing()[i];
+ fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - image->GetOrigin()[i])/image->GetSpacing()[i];
iLocalExtents[i*2 ] = lrint(fLocalExtents[i*2 ]);
iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
}
vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
- voiFilter->SetInput(this->GetInput());
+ voiFilter->SetInput(image);
voiFilter->SetVOI(iLocalExtents);
voiFilter->Update();
if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
int ix, iy, iz;
double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz);
- worldPos << "data value : " << value << std::endl;
+ if(ImageActor->GetVisibility())
+ worldPos << "data value : " << value << std::endl;
+
worldPos << "mm : " << lrint(mCurrent[0]) << ' '
<< lrint(mCurrent[1]) << ' '
<< lrint(mCurrent[2]) << ' '
if (mOverlay && mOverlayActor->GetVisibility()) {
- mOverlayMapper->SetWindow(this->GetColorWindow());
- mOverlayMapper->SetLevel(this->GetColorLevel());
+ if(mLinkOverlayWindowLevel) {
+ mOverlayMapper->SetWindow(this->GetColorWindow());
+ mOverlayMapper->SetLevel(this->GetColorLevel());
+ }
mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
mOverlayMapper->GetOutput()->Update();
mOverlayMapper->Update();
//----------------------------------------------------------------------------
void vvSlicer::UpdateCursorPosition()
{
- if (this->GetImageActor()->GetVisibility()) {
- pdmA->SetVisibility(true);
- mCursor[0] = mCurrent[0];
- mCursor[1] = mCurrent[1];
- mCursor[2] = mCurrent[2];
- mCursor[3] = mCurrentTSlice;
- }
+ pdmA->SetVisibility(true);
+ mCursor[0] = mCurrent[0];
+ mCursor[1] = mCurrent[1];
+ mCursor[2] = mCurrent[2];
+ mCursor[3] = mCurrentTSlice;
}
//----------------------------------------------------------------------------
{
if (mSurfaceCutActors.size() > 0)
for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
- i!=mSurfaceCutActors.end(); i++)
+ i!=mSurfaceCutActors.end(); i++) {
+
+ (*i)->SetSlicingOrientation(this->SliceOrientation);
(*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
this->GetImage()->GetOrigin()[this->SliceOrientation]);
+ }
}
//----------------------------------------------------------------------------
#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkImageReslice.h>
+#include <vtkImageMapToColors.h>
class vtkActor;
class vtkActor2D;
}
vtkImageMapToWindowLevelColors* GetOverlayMapper();
vvBlendImageActor* GetOverlayActor() ;
- vtkImageMapToWindowLevelColors* GetFusionMapper() ;
+ vtkImageMapToColors* GetFusionMapper() ;
vtkImageActor* GetFusionActor() ;
vtkActor* GetVFActor() ;
vtkCornerAnnotation* GetAnnotation();
return mFusion;
}
- /**Set an actor's visibility ("overlay, fusion, vf, contour...")
+ /**Get/Set an actor's visibility ("overlay, fusion, vf, contour...")
Overlay index is the index of the overlay by type, eg. if there are
5 contours and we want to activate the 3rd one, pass 2 **/
+ bool GetActorVisibility(const std::string& actor_type, int overlay_index);
void SetActorVisibility(const std::string& actor_type, int overlay_index,bool vis);
void RemoveActor(const std::string& actor_type, int overlay_index);
void SetCornerAnnotationVisibility(bool s);
bool GetCornerAnnotationVisibility();
- void GetExtremasAroundMousePointer(double & min, double & max);
+ void GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image);
void UpdateLandmarks();
void ForceUpdateDisplayExtent();
virtual void SetColorWindow(double s);
virtual void SetColorLevel(double s);
-
+ double GetOverlayColorWindow();
+ double GetOverlayColorLevel();
+ bool GetLinkOverlayWindowLevel() { return mLinkOverlayWindowLevel; }
+
+ void SetOverlayColorWindow(double s);
+ void SetOverlayColorLevel(double s);
+ void SetLinkOverlayWindowLevel(bool b) { mLinkOverlayWindowLevel = b; }
+
+ /**
+ * When it is enabled, beware of a call to GetExtent.
+ * we must have setted mReducedExtent otherwhise random values
+ * are returned by GetExtent
+ * */
void EnableReducedExtent(bool b);
void SetReducedExtent(int * ext);
vtkSmartPointer<vtkImageMapToWindowLevelColors> mOverlayMapper;
vtkSmartPointer<vvBlendImageActor> mOverlayActor;
vtkSmartPointer<vtkImageReslice> mFusionReslice;
- vtkSmartPointer<vtkImageMapToWindowLevelColors> mFusionMapper;
+ vtkSmartPointer<vtkImageMapToColors> mFusionMapper;
vtkSmartPointer<vtkImageActor> mFusionActor;
vtkSmartPointer<vtkCornerAnnotation> ca;
vtkSmartPointer<vtkCursor2D> crossCursor;
bool mUseReducedExtent;
int * mReducedExtent;
int * mInitialExtent;
+ bool mLinkOverlayWindowLevel;
private:
void UpdateOrientation();
#include <vtksys/SystemTools.hxx>
#include <vtkCamera.h>
+#include <qfileinfo.h>
+
//----------------------------------------------------------------------------
vvSlicerManager::vvSlicerManager(int numberOfSlicers)
{
mOverlayColor = 130;
mFusionOpacity = 70;
+ mFusionThresOpacity = 1;
mFusionColorMap = 3;
mFusionWindow = 1000;
mFusionLevel = 1000;
}
//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+std::string vvSlicerManager::GetListOfAbsoluteFilePathInOneString(const std::string &actorType)
+{
+ vvImageReader *reader = NULL;
+
+ if(actorType=="image")
+ reader = mReader;
+ else if(actorType=="overlay")
+ reader = mOverlayReader;
+ else if(actorType=="fusion")
+ reader = mFusionReader;
+ else if(actorType=="vector")
+ reader = mVectorReader;
+
+ if(!reader)
+ return "";
+
+ std::string list;
+ for(unsigned int i=0; i<reader->GetInputFilenames().size(); i++){
+ QFileInfo fileinfo(reader->GetInputFilenames()[i].c_str()); //Do not show the path
+ if(i)
+ list += '\n';
+ list += fileinfo.absoluteFilePath().toStdString();
+ }
+ return list;
+}
+//----------------------------------------------------------------------------
+
//----------------------------------------------------------------------------
bool vvSlicerManager::SetImage(std::string filename, vvImageReader::LoadedImageType type, int n, unsigned int slice)
double *fusRange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
mFusionLevel = (fusRange[0]+fusRange[1])/2;
mFusionWindow = fusRange[1]-fusRange[0];
+
return true;
}
//----------------------------------------------------------------------------
if (mVectorReader.IsNull())
mVectorReader = vvImageReader::New();
mVectorReader->SetInputFilename(filename);
- mVectorReader->Update(vvImageReader::VECTORFIELD);
+
+ if (mType == vvImageReader::IMAGEWITHTIME)
+ mVectorReader->Update(vvImageReader::VECTORFIELDWITHTIME);
+ else
+ mVectorReader->Update(vvImageReader::VECTORFIELD);
if (mVectorReader->GetLastError().size() != 0) {
mLastError = mVectorReader->GetLastError();
return false;
}
//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetSliceOrientation(int slicer, int orientation)
+{
+ mSlicers[slicer]->SetSliceOrientation(orientation);
+ emit UpdateOrientation(slicer, orientation);
+}
+//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void vvSlicerManager::SetTSlice(int slice)
for ( unsigned int i = 0; i < mSlicers.size(); i++) {
if (slice != mSlicers[i]->GetTSlice()) {
mSlicers[i]->SetTSlice(slice);
- if (mSlicers[i]->GetImageActor()->GetVisibility())
UpdateTSlice(i);
}
}
t++;
if (t > mSlicers[0]->GetTMax())
t = 0;
+ //std::cout << "vvSlicerManager::SetNextTSlice" << std::endl;
emit UpdateTSlice(originating_slicer,t);
}
//----------------------------------------------------------------------------
t--;
if (t < 0)
t = mSlicers[0]->GetTMax();
+ //std::cout << "vvSlicerManager::SetPreviousTSlice" << std::endl;
emit UpdateTSlice(originating_slicer,t);
}
//----------------------------------------------------------------------------
if (mSlicers[slicer]->GetTSlice() == tslice) return;
mSlicers[slicer]->SetTSlice(tslice);
- if (mSlicers[slicer]->GetImageActor()->GetVisibility())
- UpdateTSlice(slicer);
+ UpdateTSlice(slicer);
}
//----------------------------------------------------------------------------
}
//----------------------------------------------------------------------------
-
//----------------------------------------------------------------------------
void vvSlicerManager::SetColorLevel(double s)
{
}
//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetOverlayColorWindow(double s)
+{
+ for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+ mSlicers[i]->SetOverlayColorWindow(s);
+ }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetOverlayColorLevel(double s)
+{
+ for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+ mSlicers[i]->SetOverlayColorLevel(s);
+ }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetLinkOverlayWindowLevel(bool b)
+{
+ for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+ mSlicers[i]->SetLinkOverlayWindowLevel(b);
+ }
+}
+//----------------------------------------------------------------------------
+
//----------------------------------------------------------------------------
void vvSlicerManager::SetCursorAndCornerAnnotationVisibility(int s)
{
mSlicers[slicer]->Render();
for ( unsigned int i = 0; i < mSlicers.size(); i++) {
- if (i != (unsigned int)slicer && mSlicers[i]->GetImageActor()->GetVisibility()
+ if (i != (unsigned int)slicer
+ && mSlicers[i]->GetRenderer()->GetDraw()
&& mSlicers[i]->GetRenderWindow()->GetSize()[0] > 2
&& mSlicers[i]->GetRenderWindow()->GetSize()[1] > 2) {
mSlicers[i]->SetCurrentPosition(mSlicers[slicer]->GetCurrentPosition()[0],
}
//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetOverlayColorWindow()
+{
+ if (mSlicers.size())
+ return mSlicers[0]->GetOverlayColorWindow();
+ return -1;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetOverlayColorLevel()
+{
+ if (mSlicers.size())
+ return mSlicers[0]->GetOverlayColorLevel();
+ return -1;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool vvSlicerManager::GetLinkOverlayWindowLevel()
+{
+ if (mSlicers.size())
+ return mSlicers[0]->GetLinkOverlayWindowLevel();
+ return -1;
+}
+//----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvSlicerManager::ResetTransformationToIdentity(const std::string actorType)
+{
+ if(actorType == "image")
+ this->GetImage()->GetTransform()->Identity();
+ else if(actorType == "overlay")
+ this->GetSlicer(0)->GetOverlay()->GetTransform()->Identity();
+ else if(actorType == "fusion")
+ this->GetSlicer(0)->GetFusion()->GetTransform()->Identity();
+ else if(actorType == "vf")
+ this->GetVF()->GetTransform()->Identity();
+ else
+ return;
+
+ for(int i=0; i< this->GetNumberOfSlicers(); i++){
+ this->GetSlicer(i)->ForceUpdateDisplayExtent();
+ this->GetSlicer(i)->ResetCamera();
+ this->GetSlicer(i)->Render();
+ }
+}
+//------------------------------------------------------------------------------
//----------------------------------------------------------------------------
void vvSlicerManager::Render()
Z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) {
value = this->GetScalarComponentAsDouble(mSlicers[slicer]->GetInput(), X, Y, Z);
- if (mSlicers[slicer]->GetVFActor() && mSlicers[slicer]->GetVFActor()->GetVisibility()) {
+ if (mSlicers[slicer]->GetVFActor() ) {
displayVec = 1;
unsigned int currentTime = mSlicers[slicer]->GetTSlice();
vtkImageData *vf = NULL;
valueVec = sqrt(xVec*xVec + yVec*yVec + zVec*zVec);
}
}
- if (mSlicers[slicer]->GetOverlayActor() && mSlicers[slicer]->GetOverlayActor()->GetVisibility()) {
+ if (mSlicers[slicer]->GetOverlayActor() ) {
displayOver = 1;
vtkImageData *overlay = dynamic_cast<vtkImageData*>(mSlicers[slicer]->GetOverlayMapper()->GetInput());
double Xover = (x - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0];
double Zover = (z - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2];
valueOver = this->GetScalarComponentAsDouble(overlay, Xover, Yover, Zover);
}
- if (mSlicers[slicer]->GetFusionActor() && mSlicers[slicer]->GetFusionActor()->GetVisibility()) {
+ if (mSlicers[slicer]->GetFusionActor() ) {
displayFus = 1;
vtkImageData *fusion = dynamic_cast<vtkImageData*>(mSlicers[slicer]->GetFusionMapper()->GetInput());
double Xover = (x - fusion->GetOrigin()[0]) / fusion->GetSpacing()[0];
emit UpdateVector(displayVec,xVec, yVec, zVec, valueVec);
emit UpdateOverlay(displayOver,valueOver,value);
emit UpdateFusion(displayFus,valueFus);
- for (unsigned int i = 0; i < mSlicers.size(); i++) {
- if (mSlicers[i]->GetImageActor()->GetVisibility() == 1)
- emit UpdateWindows(i,mSlicers[i]->GetSliceOrientation(),mSlicers[i]->GetSlice());
- else
- emit UpdateWindows(i,-1,-1);
- }
}
}
//----------------------------------------------------------------------------
}
//----------------------------------------------------------------------------
+
//----------------------------------------------------------------------------
void vvSlicerManager::UpdateWindowLevel()
{
- emit WindowLevelChanged(mSlicers[0]->GetColorWindow(),mSlicers[0]->GetColorLevel(),mPreset,mColorMap);
+ emit WindowLevelChanged();
}
//----------------------------------------------------------------------------
//DD("============= NOTHING");
return;
}
+ //std::cout << "vvSlicerManager::UpdateSlice " << slicer << " " << mSlicers[slicer]->GetSlice() << std::endl;
emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice());
mSlicers[slicer]->Render(); // DS <-- I add this, this could/must be the only Render ...
mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice();
//----------------------------------------------------------------------------
void vvSlicerManager::UpdateTSlice(int slicer)
{
- if (mPreviousSlice[slicer] == mSlicers[slicer]->GetSlice()) {
- if (mPreviousTSlice[slicer] == mSlicers[slicer]->GetTSlice()) {
+ int slice = mSlicers[slicer]->GetSlice();
+ int tslice = mSlicers[slicer]->GetTSlice();
+ if (mPreviousSlice[slicer] == slice) {
+ if (mPreviousTSlice[slicer] == tslice) {
// DD("************** NOTHING ***********");
return;
}
}
- mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice();
- mPreviousTSlice[slicer] = mSlicers[slicer]->GetTSlice();
- emit UpdateTSlice(slicer,mSlicers[slicer]->GetTSlice());
+ mPreviousSlice[slicer] = slice;
+ mPreviousTSlice[slicer] = tslice;
+ //std::cout << "vvSlicerManager::UpdateTSlice " << slicer << " " << tslice << std::endl;
+ emit UpdateTSlice(slicer, tslice);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
-void vvSlicerManager::SetLocalColorWindowing(const int slicer)
+void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlKey)
{
double min, max;
- this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max);
- this->SetColorWindow(max-min);
- this->SetColorLevel(0.5*(min+max));
- this->UpdateWindowLevel();
+ int t = this->mSlicers[slicer]->GetTSlice();
+ if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) {
+ this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t]);
+ this->SetFusionWindow(max-min);
+ this->SetFusionLevel(0.5*(min+max));
+ this->SetColorMap(mColorMap);
+ }
+ else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) {
+ this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t]);
+ if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){
+ this->SetColorWindow(max-min);
+ this->SetColorLevel(0.5*(min+max));
+ } else {
+ this->SetOverlayColorWindow(max-min);
+ this->SetOverlayColorLevel(0.5*(min+max));
+ }
+ }
+ else {
+ this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetInput());
+ this->SetColorWindow(max-min);
+ this->SetColorLevel(0.5*(min+max));
+ this->SetPreset(6);
+ }
this->Render();
-}
-//----------------------------------------------------------------------------
-
-
-//----------------------------------------------------------------------------
-void vvSlicerManager::SetColorMap()
-{
- SetColorMap(mColorMap);
+ this->UpdateWindowLevel();
}
//----------------------------------------------------------------------------
LUT->SetHueRange(0.4,0.80);
break;
case 3:
+ if (LUT == NULL)
+ LUT = vtkLookupTable::New();
+ LUT->SetValueRange(0.5,1);
+ LUT->SetSaturationRange(1,1);
+ LUT->SetHueRange(0.666,0);
+ break;
+ case 4:
if (LUT == NULL)
LUT = vtkLookupTable::New();
LUT->SetValueRange(0,1);
LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
LUT->Build();
}
- vtkLookupTable* fusLUT = NULL;
- if (mSlicers[0]->GetFusion()) {
- fusLUT = vtkLookupTable::New();
+ vtkWindowLevelLookupTable* fusLUT = NULL;
+ if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) {
+ fusLUT = vtkWindowLevelLookupTable::New();
double fusRange [2];
fusRange[0] = mFusionLevel - mFusionWindow/2;
fusRange[1] = mFusionLevel + mFusionWindow/2;
- fusLUT->SetTableRange(fusRange[0],fusRange[1]);
+ double* frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
+ fusLUT->SetTableRange(frange);
fusLUT->SetValueRange(1,1);
fusLUT->SetSaturationRange(1,1);
+ fusLUT->SetAlphaRange(1, 1);
+ fusLUT->SetWindow(mFusionWindow);
+ fusLUT->SetLevel(mFusionLevel);
if (mFusionColorMap == 1)
fusLUT->SetHueRange(0,0.18);
else if (mFusionColorMap == 2)
fusLUT->SetHueRange(0.4,0.80);
else if (mFusionColorMap == 3)
+ {
+ fusLUT->SetHueRange(0.666, 0);
+ fusLUT->SetValueRange(0.5, 1);
+ }
+ else if (mFusionColorMap == 4)
fusLUT->SetHueRange(0,1);
- fusLUT->Build();
- if (mFusionColorMap == 0)
- fusLUT = NULL;
+ else if (mFusionColorMap <= 0)
+ {
+ fusLUT->SetValueRange(0,1);
+ fusLUT->SetSaturationRange(0,0);
+ }
+
+ fusLUT->ForceBuild();
+
+ // set color table transparency
+ double alpha_range_end = frange[0] + (double)mFusionThresOpacity*(frange[1] - frange[0])/100;
+ for (double i = frange[0]; i < alpha_range_end; i++) {
+ double v[4];
+ vtkIdType index = fusLUT->GetIndex(i);
+ fusLUT->GetTableValue(index, v);
+ v[3] = 0;
+ fusLUT->SetTableValue(index, v);
+ }
}
for ( unsigned int i = 0; i < mSlicers.size(); i++) {
- if (mSlicers[i]->GetOverlay() && mSlicers[i]->GetOverlayActor()->GetVisibility()) {
+
+ if (mSlicers[i]->GetOverlay()) {
vtkLookupTable* supLUT = vtkLookupTable::New();
supLUT->SetTableRange(range[0],range[1]);
supLUT->SetValueRange(1,1);
} else {
mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
}
- if (mSlicers[i]->GetFusion() && mSlicers[i]->GetFusionActor()->GetVisibility()) {
- mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
+
+ if (mSlicers[i]->GetFusion()) {
mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT);
- mSlicers[i]->GetFusionMapper()->SetWindow(mFusionWindow);
- mSlicers[i]->GetFusionMapper()->SetLevel(mFusionLevel);
+ mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
}
}
if (fusLUT)
std::string GetVFName() { return mVFName; }
std::string GetOverlayName() { return mOverlayName; }
std::string GetFusionName() { return mFusionName; }
+ std::string GetListOfAbsoluteFilePathInOneString(const std::string &actorType);
///Switch between nearest neighbor and linear interpolation
void ToggleInterpolation();
void SetFilename(std::string f, int number=0);
+ void SetSliceOrientation(int slicer, int orientation);
void SetTSlice(int slice);
void SetNextTSlice(int originating_slicer);
void SetPreviousTSlice(int originating_slicer);
void GenerateDefaultLookupTable();
void SetColorWindow(double s);
void SetColorLevel(double s);
- void SetLocalColorWindowing(const int slicer);
+ void SetOverlayColorWindow(double s);
+ void SetOverlayColorLevel(double s);
+ void SetLinkOverlayWindowLevel(bool b);
+ void SetLocalColorWindowing(const int slicer, const bool bCtrlKey);
void SetOpacity(int i, double factor);
- void SetColorMap();
void SetColorMap(int colormap);
void SetPreset(int preset);
void SetOverlayColor(int color) {
void SetFusionOpacity(int opacity) {
mFusionOpacity = opacity;
}
+ void SetFusionThresholdOpacity(int thresOpacity) {
+ mFusionThresOpacity = thresOpacity;
+ }
void SetFusionColorMap(int colorMap) {
mFusionColorMap = colorMap;
}
double GetColorWindow();
double GetColorLevel();
+ double GetOverlayColorWindow();
+ double GetOverlayColorLevel();
+ bool GetLinkOverlayWindowLevel();
int GetColorMap() {
return mColorMap;
}
int GetOverlayColor() {
return mOverlayColor;
}
-
int GetFusionOpacity() {
return mFusionOpacity;
}
+ int GetFusionThresholdOpacity() {
+ return mFusionThresOpacity;
+ }
int GetFusionColorMap() {
return mFusionColorMap;
}
void UpdateViews(int current, int slicer);
void UpdateLinked(int slicer);
void UpdateLinkedNavigation(vvSlicer *slicer, bool bPropagate=false);
+ void ResetTransformationToIdentity(const std::string actorType);
void Render();
void AddLink(std::string newId) {
void UpdateVector(int display, double x, double y, double z, double value);
void UpdateOverlay(int display, double valueOver, double valueRef);
void UpdateFusion(int display, double valueFus);
- void UpdateWindows(int slicer, int view, int slice);
+ void UpdateOrientation(int slicer, int orientation);
void UpdateSlice(int slicer, int slice);
void UpdateTSlice(int slicer, int slice);
void UpdateSliceRange(int slice, int min, int max, int tmin, int tmax);
- void WindowLevelChanged(double window, double level, int preset, int colormap);
+ void WindowLevelChanged();
void UpdateLinkManager(std::string, int slicer, double x, double y, double z, int temps);
void UpdateLinkedNavigation(std::string, vvSlicerManager*, vvSlicer*);
void LandmarkAdded();
int mOverlayColor;
int mFusionOpacity;
+ int mFusionThresOpacity;
int mFusionColorMap;
double mFusionWindow;
double mFusionLevel;
if ( VisibleInWindow > -1 ) {
if (event == vtkCommand::KeyPressEvent) {
std::string KeyPress = isi->GetInteractor()->GetKeySym();
+ bool bCtrlKey = isi->GetInteractor()->GetControlKey();
if (KeyPress == "Tab") {
if(isi->GetInteractor()->GetShiftKey())
this->SM->PrevImage(VisibleInWindow);
return;
}
if (KeyPress == "w") {
- this->SM->SetLocalColorWindowing(VisibleInWindow);
+ this->SM->SetLocalColorWindowing(VisibleInWindow, bCtrlKey);
return;
}
if (KeyPress == "0") {
return;
}
if (KeyPress == "h") {
- std::cout << "KeyPress == \"h\"\n";
this->SM->SetCursorAndCornerAnnotationVisibility(0);
this->SM->Render();
return;
return;
}
if (KeyPress == "g") {
- double* cursorPos = this->SM->GetSlicer(VisibleInWindow)->GetCursorPosition();
- this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(
- cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
+ if(bCtrlKey)
+ this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(0,0,0,0);
+ else {
+ double* cursorPos = this->SM->GetSlicer(VisibleInWindow)->GetCursorPosition();
+ this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(
+ cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
+ }
this->SM->UpdateViews(1,VisibleInWindow);
this->SM->UpdateLinked(VisibleInWindow);
return;
if (KeyPress == "F2") {
this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Sagital\n<slice>");
- this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(0);
+ //this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(0);
+ this->SM->SetSliceOrientation(VisibleInWindow, 0);
this->SM->UpdateSliceRange(VisibleInWindow);
}
if (KeyPress == "F3") {
this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Coronal\n<slice>");
- this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(1);
+ //this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(1);
+ this->SM->SetSliceOrientation(VisibleInWindow, 1);
this->SM->UpdateSliceRange(VisibleInWindow);
}
if (KeyPress == "F4") {
this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Axial\n<slice>");
- this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(2);
+ //this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(2);
+ this->SM->SetSliceOrientation(VisibleInWindow, 2);
this->SM->UpdateSliceRange(VisibleInWindow);
}
this->SM->SetColorWindow(window*dx);
this->SM->SetColorLevel(level-dy);
this->SM->SetPreset(6);
- this->SM->UpdateWindowLevel();
this->SM->Render();
+ this->SM->UpdateWindowLevel();
return;
}
}
connect(mCurrentSlicerManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
connect(mCurrentSlicerManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
+
+ connect(mCurrentSlicerManager,SIGNAL(UpdateOrientation(int,int)),this,SLOT(UpdateOrientation(int, int)));
// connect(mCurrentSlicerManager, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int)));
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void vvToolBinarize::UpdateOrientation(int slicer,int orientation)
+{
+ Update(slicer);
+}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvToolBinarize::UpdateSlice(int slicer,int slices)
+{
+ Update(slicer);
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvToolBinarize::Update(int slicer)
{
if (!mInteractiveDisplayIsEnabled) return;
if (!mCurrentSlicerManager) close();
}
//------------------------------------------------------------------------------
-
//------------------------------------------------------------------------------
void vvToolBinarize::GetArgsInfoFromGUI()
{
virtual void reject();
void valueChangedT1(double v);
void valueChangedT2(double v);
+ void UpdateOrientation(int slicer, int orientation);
void UpdateSlice(int slicer,int slices);
void enableLowerThan(bool b);
void useFGBGtoggled(bool);
std::vector<vvImageContour::Pointer> mImageContour;
std::vector<vvImageContour::Pointer> mImageContourLower;
bool mInteractiveDisplayIsEnabled;
+
+ void Update(int slicer);
}; // end class vvToolBinarize
//------------------------------------------------------------------------------
#include <QMenu>
//------------------------------------------------------------------------------
-vvToolCreatorBase::vvToolCreatorBase(QString name): mExperimental(false)
+vvToolCreatorBase::vvToolCreatorBase(QString name): mAction(NULL), mExperimental(false)
{
mUseContextMenu = false;
mToolName = name;
#include <QCursor>
#include <QApplication>
#include <QMessageBox>
+#include <QSignalMapper>
// vtk
#include <vtkImageClip.h>
ADD_TOOL(vvToolCropImage);
//------------------------------------------------------------------------------
-
+//same order of int* returned by VtkImageData::WholeExtent
+enum sliderId {xmin, xmax, ymin, ymax, zmin, zmax, tmin, tmax};
//------------------------------------------------------------------------------
vvToolCropImage::vvToolCropImage(vvMainWindowBase * parent, Qt::WindowFlags f):
vvToolWidgetBase(parent, f),
vvToolBase<vvToolCropImage>(parent),
- Ui::vvToolCropImage()
+ Ui::vvToolCropImage(),mSliders(8)
{
// GUI Initialization
Ui_vvToolCropImage::setupUi(mToolWidget);
- // mTLabel2->setHidden(false);
- // tminSlider->setHidden(false);
- // tmaxSlider->setHidden(false);
- // spin_tmin->setHidden(false);
- // spin_tmax->setHidden(false);
- // mLabelTimeCropping->setHidden(false);
mTLabel1->setHidden(true);
mTLabel2->setHidden(true);
tminSlider->setHidden(true);
// Set how many inputs are needed for this tool
AddInputSelector("Select one image");
+
+ mSliders[xmin]=xminSlider;
+ mSliders[xmax]=xmaxSlider;
+ mSliders[ymin]=yminSlider;
+ mSliders[ymax]=ymaxSlider;
+ mSliders[zmin]=zminSlider;
+ mSliders[zmax]=zmaxSlider;
+ mSliders[tmin]=tminSlider;
+ mSliders[tmax]=tmaxSlider;
+
+ // Record initial extend
+ mReducedExtent = new int[6];
+ mInitialExtent = new int[6];
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
vvToolCropImage::~vvToolCropImage()
{
-
+ delete [] mReducedExtent;
+ delete [] mInitialExtent;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vvToolCropImage::closeEvent(QCloseEvent *event)
{
- // Reset extends
- for(int i=0; i<mExtentSize; i++) mReducedExtent[i] = mInitialExtent[i];
- UpdateExtent();
- event->accept();
+ if(mCurrentSlicerManager){
+// Reset extends
+ for(int i=0; i<mExtentSize; i++){
+ mReducedExtent[i] = mInitialExtent[i];
+ }
+ UpdateExtent();
+ }
+ vvToolWidgetBase::closeEvent(event);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-void vvToolCropImage::sliderXMinValueChanged(int s)
-{
- xmaxSlider->setMinimum(xminSlider->value());
- mReducedExtent[0] = xminSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderXMaxValueChanged(int s)
-{
- xminSlider->setMaximum(xmaxSlider->value());
- mReducedExtent[1] = xmaxSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderYMinValueChanged(int s)
-{
- ymaxSlider->setMinimum(yminSlider->value());
- mReducedExtent[2] = yminSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderYMaxValueChanged(int s)
-{
- yminSlider->setMaximum(ymaxSlider->value());
- mReducedExtent[3] = ymaxSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderZMinValueChanged(int s)
-{
- zmaxSlider->setMinimum(zminSlider->value());
- mReducedExtent[4] = zminSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderZMaxValueChanged(int s)
+void vvToolCropImage::sliderValueChanged(int dim)
{
- zminSlider->setMaximum(zmaxSlider->value());
- mReducedExtent[5] = zmaxSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderTMinValueChanged(int s) {
- tmaxSlider->setMinimum(tminSlider->value());
- mReducedExtent[6] = tminSlider->value();
- UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderTMaxValueChanged(int s) {
- tminSlider->setMaximum(tmaxSlider->value());
- mReducedExtent[7] = tmaxSlider->value();
+ int dimMin = dim;
+ if(dim%2==0){//case we are minimum
+ mSliders[dim+1]->setMinimum(mSliders[dim]->value());
+ }else {
+ mSliders[--dimMin]->setMaximum(mSliders[dim]->value());
+ }
+ mReducedExtent[dim] = mSliders[dim]->value() + mInitialExtent[dimMin];
UpdateExtent();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer)
{
-
// Change interface according to number of dimension
mExtentSize = 2*slicer->GetDimension();
if (slicer->GetDimension()<4) {
spin_zmax->setHidden(true);
}
- // Record initial extend
- mReducedExtent = new int[mExtentSize];
- mInitialExtent = new int[mExtentSize];
- mReducedExtent = mCurrentSlicerManager->GetImage()->GetFirstVTKImageData()->GetWholeExtent();
- for(int i=0; i<mExtentSize; i++) mInitialExtent[i] = mReducedExtent[i];
+ int *a = mCurrentImage->GetFirstVTKImageData()->GetWholeExtent();
+ for(int i=0; i<6; i++){
+ mInitialExtent[i] = a[i];
+ mReducedExtent[i] = a[i];
+ }
for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
mCurrentSlicerManager->GetSlicer(i)->EnableReducedExtent(true);
+ mCurrentSlicerManager->GetSlicer(i)->SetReducedExtent(mInitialExtent);
}
- // Set initial sliders values
+// Set initial sliders values
std::vector<int> imsize = mCurrentSlicerManager->GetImage()->GetSize();
- xminSlider->setMaximum(imsize[0]-1);
- xmaxSlider->setMaximum(imsize[0]-1);
- xmaxSlider->setValue(imsize[0]-1);
-
- yminSlider->setMaximum(imsize[1]-1);
- ymaxSlider->setMaximum(imsize[1]-1);
- ymaxSlider->setValue(imsize[1]-1);
-
- if (slicer->GetDimension() >2) {
- zminSlider->setMaximum(imsize[2]-1);
- zmaxSlider->setMaximum(imsize[2]-1);
- zmaxSlider->setValue(imsize[2]-1);
- }
-
- if (slicer->GetDimension() >3) {
- tminSlider->setMaximum(imsize[3]-1);
- tmaxSlider->setMaximum(imsize[3]-1);
- tmaxSlider->setValue(imsize[3]-1);
+ for(int dim=0; dim<slicer->GetDimension() && dim<3; ++dim){
+ mSliders[dim*2]->setMaximum(imsize[dim]-1);
+ mSliders[dim*2+1]->setMaximum(imsize[dim]-1);
+ mSliders[dim*2+1]->setValue(imsize[dim]-1);
}
-
spin_xmin->setMaximum(imsize[0]-1);
spin_xmax->setMaximum(imsize[0]-1);
spin_xmax->setValue(imsize[0]-1);
spin_tmax->setValue(imsize[3]-1);
}
- // Connect
- connect(xminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderXMinValueChanged(int)));
- connect(xmaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderXMaxValueChanged(int)));
- connect(yminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderYMinValueChanged(int)));
- connect(ymaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderYMaxValueChanged(int)));
- connect(zminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderZMinValueChanged(int)));
- connect(zmaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderZMaxValueChanged(int)));
- connect(tminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderTMinValueChanged(int)));
- connect(tmaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderTMaxValueChanged(int)));
-
- // connect(mCurrentSlicerManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateExtent()));
- //connect(mCurrentSlicerManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateExtent()));
-
- // connect(mIntensitySlider, SIGNAL(valueChanged(double)), this, SLOT(autoCropValueChanged(double)));
+ QSignalMapper* signalMapper = new QSignalMapper(this);
+ connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(sliderValueChanged(int)));
+ for(unsigned int i=0; i<mSliders.size(); ++i){
+ signalMapper->setMapping(mSliders[i], i);
+ connect(mSliders[i], SIGNAL(valueChanged(int)), signalMapper, SLOT(map()));
+ }
UpdateExtent();
}
//------------------------------------------------------------------------------
int n = mCurrentSlicerManager->GetDimension()*2; // 2D and 3D only
mArgsInfo.boundingBox_given = n;
mArgsInfo.boundingBox_arg = new int[n];
- mArgsInfo.boundingBox_arg[0] = xminSlider->value();
- mArgsInfo.boundingBox_arg[1] = xmaxSlider->value();
- mArgsInfo.boundingBox_arg[2] = yminSlider->value();
- mArgsInfo.boundingBox_arg[3] = ymaxSlider->value();
- if (n>3) { // 3D
- mArgsInfo.boundingBox_arg[4] = zminSlider->value();
- mArgsInfo.boundingBox_arg[5] = zmaxSlider->value();
+
+ for(int dim=0; dim<mCurrentSlicerManager->GetDimension() && dim<3; ++dim){
+ mArgsInfo.boundingBox_arg[dim*2] = mSliders[dim*2]->value();
+ mArgsInfo.boundingBox_arg[dim*2+1] = mSliders[dim*2+1]->value();
}
-
if (n>6) { // 4D
- // mArgsInfo.boundingBox_arg[6] = tminSlider->value();
- // mArgsInfo.boundingBox_arg[7] = tmaxSlider->value();
mArgsInfo.boundingBox_arg[6] = 0;
mArgsInfo.boundingBox_arg[7] = mCurrentImage->GetSize()[3]-1;
}
-
// We MUST reset initial extend to input image before using the
// filter to retrieve the correct image size
for(int i=0; i<mExtentSize; i++) {
mReducedExtent[i] = mInitialExtent[i];
- // DD(mArgsInfo.boundingBox_arg[i]);
}
+
UpdateExtent();
-
// Main filter
CropFilterType::Pointer filter = CropFilterType::New();
filter->SetInputVVImage(mCurrentImage);
catch(clitk::ExceptionObject & e) {
DD(e.what());
QApplication::restoreOverrideCursor();
+ delete [] mArgsInfo.boundingBox_arg;
close();
}
-
+ std::ostringstream croppedImageName;
+ croppedImageName << "Cropped_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
// Retrieve result and display it
vvImage::Pointer output = filter->GetOutputVVImage();
- std::ostringstream osstream;
- osstream << "Croped_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
- AddImage(output,osstream.str());
-
+
+ AddImage(output,croppedImageName.str());
+
// End
QApplication::restoreOverrideCursor();
+ delete [] mArgsInfo.boundingBox_arg;
close();
-
- /**
- // OLD approach with VTK
-
- QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
- vvImage::Pointer mResult=vvImage::New();
- vvImage::Pointer image= mCurrentSlicerManager->GetImage();
- for (std::vector<vtkImageData*>::const_iterator i=image->GetVTKImages().begin();
- i!=image->GetVTKImages().end(); i++) {
- vtkSmartPointer<vtkImageClip> filter=vtkSmartPointer<vtkImageClip>::New();
- ///Vtk is very weird, you need to "translate the extent" to get the correct origin
- //http://markmail.org/message/vndc2tr6kcabiakp#query:vtkImageClip%20origin+page:1+mid:6na7y57floutklvz+state:results
- vtkSmartPointer<vtkImageTranslateExtent> translate=vtkSmartPointer<vtkImageTranslateExtent>::New();
- filter->SetInput(*i);
- filter->SetOutputWholeExtent(xminSlider->value(),xmaxSlider->value(),
- yminSlider->value(),ymaxSlider->value(),
- zminSlider->value(),zmaxSlider->value());
- translate->SetTranslation(-xminSlider->value(),-yminSlider->value(),-zminSlider->value());
- translate->SetInput(filter->GetOutput());
- filter->ClipDataOn(); //Really create a cropped copy of the image
- translate->Update();
- vtkImageData* output=vtkImageData::New();
- output->ShallowCopy(translate->GetOutput());
- mResult->AddImage(output);
- }
- QApplication::restoreOverrideCursor();
- std::ostringstream osstream;
- osstream << "Crop_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
- AddImage(mResult, osstream.str());
- close();
-
- **/
}
//------------------------------------------------------------------------------
//qt
#include <QtDesigner/QDesignerExportWidget>
#include <QDialog>
-
+#include <QSlider>
// vv
#include "vvToolBase.h"
#include "vvToolWidgetBase.h"
virtual void apply();
virtual bool close();
virtual void reject();
- void sliderXMinValueChanged(int s);
- void sliderXMaxValueChanged(int s);
- void sliderYMinValueChanged(int s);
- void sliderYMaxValueChanged(int s);
- void sliderZMinValueChanged(int s);
- void sliderZMaxValueChanged(int s);
- void sliderTMinValueChanged(int s);
- void sliderTMaxValueChanged(int s);
void autoCropValueChanged(double v);
+ void sliderValueChanged(int id);
+
//-----------------------------------------------------
static void Initialize() {
void UpdateExtent();
virtual void closeEvent(QCloseEvent *event);
+ std::vector<QSlider*> mSliders;
}; // end class vvToolCropImage
//------------------------------------------------------------------------------
#include "vvToolManager.h"
#include "vvToolCreatorBase.h"
#include "vvMainWindowBase.h"
-
+#include <QAction>
//------------------------------------------------------------------------------
/// Unique static instance
vvToolManager* vvToolManager::mSingleton=0;
}
//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvToolManager::EnableToolsInMenu(vvMainWindowBase * m, bool enable){
+ std::vector<vvToolCreatorBase *>::iterator it;
+ for(it=GetInstance()->mListOfTools.begin(); it!=GetInstance()->mListOfTools.end(); ++it){
+ if((*it)->mAction){
+ (*it)->mAction->setEnabled(enable);
+ }
+ }
+}
/// Called in MainWindow, insert all tools into the menu
static void InsertToolsInMenu(vvMainWindowBase * m);
+ /// Called in MainWindow, make the tools enabled/disabled
+ static void EnableToolsInMenu(vvMainWindowBase * m, bool enable);
+
protected:
/// Singleton object pointer
if (mCurrentImage->GetNumberOfDimensions() != 3) {
QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
close();
+ return;
}
// Hide selector
HideInputSelector(); // splitter
- BSD See included LICENSE.txt file
- CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
===========================================================================**/
-#include <fstream>
+#include <sstream>
#include <algorithm>
#include <QDir>
-
#include "clitkCommon.h"
#include "vvUtils.h"
const std::string vv_user_file=".vv_settings.txt";
+const std::string recentFileList="recentFiles";
typedef std::list<std::string> FileListType;
+QString getVVSettingsPath(){
+ return QDir::homePath()+QString::fromStdString("/"+vv_user_file);
+}
+
+QSettings::Format getSettingsOptionFormat(){
+ return QSettings::IniFormat;
+}
+
///Returns the last images opened by the user
FileListType GetRecentlyOpenedImages()
{
- std::ifstream in((QDir::homePath().toStdString() + "/" + vv_user_file).c_str());
- std::string current_file;
+ QSettings settings(getVVSettingsPath(), getSettingsOptionFormat());
FileListType result;
- in >> current_file;
- while (in.good()) {
- result.push_back(current_file);
- in >> current_file;
- }
- in.close();
+ settings.beginGroup(QString::fromStdString(recentFileList));
+ QStringList keys = settings.childKeys();
+ for(int i=0; i<keys.size(); i++){
+ std::string value=settings.value(QString::fromStdString (keys[i].toStdString())).toString().toStdString();
+ result.push_back(value);
+ }
+ settings.endGroup();
return result;
}
///Adds an image to the list of recently opened images
void AddToRecentlyOpenedImages(std::string filename)
{
+ QSettings settings(getVVSettingsPath(), getSettingsOptionFormat());
FileListType file_list = GetRecentlyOpenedImages();
+
FileListType::iterator i = std::find(file_list.begin(),file_list.end(),filename);
if (i != file_list.end()) // avoid dupes
file_list.erase(i);
while (file_list.size() >= 6) //keep list to a reasonable size
file_list.pop_back();
file_list.push_front(filename);
- std::ofstream out((QDir::homePath().toStdString() + "/" + vv_user_file).c_str(),std::ios_base::out | std::ios_base::trunc);
- for (FileListType::iterator j = file_list.begin() ; j != file_list.end() ; j++)
- out << (*j) << std::endl;
- out.close();
+
+ settings.beginGroup(QString::fromStdString(recentFileList));
+ int index=0;
+ for (FileListType::iterator j = file_list.begin() ; j != file_list.end() ; j++){
+ QString s=QString(index++);
+ settings.setValue(s, QString::fromStdString ( *j ));
+ }
+ settings.endGroup();
}
+
#define vvXXX_h
#include <list>
#include <string>
+#include <QSettings>
///Returns the last images opened by the user
std::list<std::string> GetRecentlyOpenedImages();
///Adds an image to the list of recently opened images
void AddToRecentlyOpenedImages(std::string filename);
+///path to user settings
+QString getVVSettingsPath();
+
+///by default nativeFormat
+QSettings::Format getSettingsOptionFormat();
+
#endif
--- /dev/null
+<?php
+define('HIDDEN_DATABASE_FILE_NAME', './customers.csv');
+$file=fopen(HIDDEN_DATABASE_FILE_NAME, 'a');
+if($file===FALSE)exit(1);
+define('TOKEN_CSV', '|');
+define('ENTRY_SEPARATOR', "\n");
+define('NAME_LENGTH', 30);
+define('EMAIL_LENGTH', 40);
+define('GROUP_LENGTH', 30);
+define('OS_LENGTH', 20);
+define('VV_VERSION_LENGTH', 30);
+define('COUNTRY_LENGTH', 30);
+define('ARCHITECTURE_LENGTH',10);
+define('ADRESSING_LENGTH',10);
+define('COMPILATION_DATE_LENGTH', 30);
+function ensureString($var, $length){
+ $var = str_replace("\n", '',$var);
+ $var = str_replace(TOKEN_CSV, '', $var);
+ return substr($var, 0, $length);
+}
+function writeLine($file, $data){
+ fwrite($file, implode(TOKEN_CSV, $data).ENTRY_SEPARATOR);
+}
+$data['name'] = ensureString($_GET['name'], NAME_LENGTH);
+$data['lastname'] = ensureString($_GET['lastName'], NAME_LENGTH);
+$data['email'] = ensureString($_GET['email'], EMAIL_LENGTH);
+$data['group'] = ensureString($_GET['group'], GROUP_LENGTH);
+$data['ip'] = $_SERVER['REMOTE_ADDR'];
+$data['os'] = ensureString($_GET['os'], OS_LENGTH);
+$data['vvVersion']= ensureString($_GET['vvVersion'], VV_VERSION_LENGTH);
+$data['time'] = date("F j, Y, g:i a");
+$data['geoloc'] = ensureString(file_get_contents('http://api.hostip.info/country.php?ip='.$_SERVER['REMOTE_ADDR']), COUNTRY_LENGTH);
+$data['architecture'] = ensureString($_GET['architecture'], ARCHITECTURE_LENGTH);
+$data['adressing'] = ensureString($_GET['adressing'], ADRESSING_LENGTH);
+$data['compilationDate'] = ensureString($_GET['compilationDate'], COMPILATION_DATE_LENGTH);
+writeLine($file, $data);
+fclose();