gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 0dfdc34 069/125: Option values directly set in


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 0dfdc34 069/125: Option values directly set in library
Date: Sun, 23 Apr 2017 22:36:39 -0400 (EDT)

branch: master
commit 0dfdc346c0e80b024b1b387ea6293d55d5eff758
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Option values directly set in library
    
    Until now, the option values were allocated and stored in a void pointer in
    the `value' field of `argp_option'. So when the option was not set by the
    user or in configuration files, `value==NULL'. But this forced us to go
    through the options one later time and put those values into the main
    program structure, in this secondary loop, we would also have to check if
    the options are mandatory or not. This is very frustrating and prone to
    many bugs. So the new `mandatory' and `set' fields were created in the
    `argp_option' structure and the `value' pointer now directly points to the
    final location of the variable in the main program structure. These steps
    effectively removed the need for any second loop after control comes out of
    `gal_options_read_config_set', the program author can directly use the
    values in their structure.
    
    To do this, some major modifications were necessary, because we needed
    access to the main program structure (`p'), and common parameters structure
    (`cp') when the options array is defined. So the basic Argp global
    variables like `argp_program_version', `argp_program_bug_address',
    `args_doc', and `doc' were taken out of `args.h' and now directly defined
    in `ui.c'. The `option_keys_enum' is also defined in `ui.c'. We now
    "include" `args.h' and `commonopts.h' directly into the high-level
    `ui_read_check_inputs_setup'.
    
    Also to make the definition of the options more clear/readable, many new
    enumerator types were defined and are now used in the programs.
    
    Work on the MakeProfiles program is still ongoing and these changes were
    all in line with diong that. So currently MakeProfiles just reaches the end
    of `ui_read_check_inputs_setup'.
---
 bin/arithmetic/args.h     | 132 ++----------
 bin/arithmetic/ui.c       | 210 +++++++++++++-----
 bin/arithmetic/ui.h       |   4 +-
 bin/imgwarp/ui.h          |  20 +-
 bin/mkprof/args.h         | 533 +++++++++++++++++++++-------------------------
 bin/mkprof/astmkprof.conf |   1 +
 bin/mkprof/main.h         | 148 ++++++-------
 bin/mkprof/mkprof.c       |  12 +-
 bin/mkprof/oneprofile.c   |  11 +-
 bin/mkprof/ui.c           | 310 ++++++++++++++++++++-------
 bin/table/args.h          | 163 ++++----------
 bin/table/asttable.conf   |   5 +-
 bin/table/main.c          |   2 +-
 bin/table/main.h          |  28 +--
 bin/table/ui.c            | 251 +++++++++++++++-------
 bootstrap.conf            |  66 +++---
 lib/commonopts.h          | 146 ++++++++-----
 lib/data.c                |  18 +-
 lib/gnuastro/arithmetic.h |   2 +
 lib/gnuastro/data.h       |   3 +-
 lib/gnuastro/table.h      |  20 +-
 lib/linkedlist.c          |   2 +-
 lib/options.c             | 259 ++++++++--------------
 lib/options.h             |  98 +++++++--
 lib/table.c               |   2 +-
 25 files changed, 1281 insertions(+), 1165 deletions(-)

diff --git a/bin/arithmetic/args.h b/bin/arithmetic/args.h
index d984fea..041d93a 100644
--- a/bin/arithmetic/args.h
+++ b/bin/arithmetic/args.h
@@ -25,85 +25,26 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-
-
-/* Include necessary headers. */
-#define NOT_COMMON_HDU_PARSER 1
-#include <commonopts.h>
-#include <authors-cite.h>
-#include <fixedstringmacros.h>
-
-
-
-/* Definition parameters for the argp: */
-const char *
-argp_program_version = PROGRAM_STRING "\n"
-                       GAL_STRINGS_COPYRIGHT
-                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
-
-const char *
-argp_program_bug_address = PACKAGE_BUGREPORT;
-
-static char
-args_doc[] = "ASTRdata or number [ASTRdata] OPERATOR ...";
-
-const char
-doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" will do arithmetic "
-  "operations on one or multiple images and numbers. Simply put, the name "
-  "of the image along with the arithmetic operators and possible numbers "
-  "are given as arguments. The extensions of each input are specified with "
-  "(possibly multiple) calls to the `--hdu' option."
-  "\n\nCurrently "PROGRAM_NAME" only supports postfix or reverse polish "
-  "notation. For example to get the result of `5+6', you should write "
-  "`5 6 +', or to get the average of two images, you should write `a.fits "
-  "b.fits + 2 /' (or more simply use the `average' operator with "
-  "`a.fits b.fits average'). Please see the manual for more information. "
-  "\n\nThe operators/functions recognized by "PROGRAM_NAME" are: +, -, *, "
-  "/, abs, pow, sqrt, log, log10, minvalue, maxvalue, min, max, average, "
-  "median, lt, le, gt, ge, eq, ne, and, or, not, isblank, and the full set "
-  "of bitwise operators. Please run `info gnuastro \"Arithmetic "
-  "operators\"' for detailed information on each operator. Note that "
-  "multiplication should be quoted (like \"*\", or '*') to avoid shell "
-  "expansion.\n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Available letters for short options:
-
-   a b c d e f g i j k l m n p r s t u v w x y z
-   A B C E F G H I J L M O Q R T U W X Y Z                */
-enum option_keys_enum
-{
-  /* With short-option version. */
-  ARGS_OPTION_HDU_KEY        = 'h',
-
-  /* Only with long version (start with a value 1000, the rest will be set
-     automatically). */
-};
-
-static struct argp_option options[] =
+/* Definition of program-specific options. */
+struct argp_option program_options[] =
   {
     {
       0, 0, 0, 0,
       "Input:",
-      1
+      GAL_OPTIONS_GROUP_INPUT
     },
     {
       "hdu",
-      ARGS_OPTION_HDU_KEY,
+      ARGS_OPTION_KEY_HDU,
       "STR",
       0,
       "Nth call of this option, used for Nth input FITS.",
-      1,
-      NULL,
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->hdus,
       GAL_DATA_TYPE_STRLL,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -112,7 +53,7 @@ static struct argp_option options[] =
     {
       0, 0, 0, 0,
       "Output:",
-      2
+      GAL_OPTIONS_GROUP_OUTPUT,
     },
 
 
@@ -121,7 +62,7 @@ static struct argp_option options[] =
     {
       0, 0, 0, 0,
       "Operating modes:",
-      -1
+      GAL_OPTIONS_GROUP_OPERATING_MODE
     },
 
 
@@ -132,57 +73,14 @@ static struct argp_option options[] =
 
 
 
-/* Parse a single option: */
-error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-  struct imgarithparams *p = state->input;
-
-  /* Pass `gal_options_common_params' into the child parser.  */
-  state->child_inputs[0] = &p->cp;
-
-  /* In case the user incorrectly uses the equal sign (for example
-     with a short format or with space in the long format, then `arg`
-     start with (if the short version was called) or be (if the long
-     version was called with a space) the equal sign. So, here we
-     check if the first character of arg is the equal sign, then the
-     user is warned and the program is stopped: */
-  if(arg && arg[0]=='=')
-    argp_error(state, "incorrect use of the equal sign (`=`). For short "
-               "options, `=` should not be used and for long options, "
-               "there should be no space between the option, equal sign "
-               "and value");
-
-  /* Set the key to this option. */
-  switch(key)
-    {
-
-    /* Read the non-option tokens (arguments): */
-    case ARGP_KEY_ARG:
-      gal_linkedlist_add_to_stll(&p->tokens, arg, 1);
-      break;
-
-
-    /* This is an option, set its value. */
-    default:
-      return gal_options_set_from_key(key, arg, options, &p->cp);
-    }
-
-  return 0;
-}
-
-
-
-
-
 /* Define the child argp structure. */
-static struct argp
+struct argp
 gal_options_common_child = {gal_commonopts_options,
                             gal_options_common_argp_parse,
                             NULL, NULL, NULL, NULL, NULL};
 
 /* Use the child argp structure in list of children (only one for now). */
-static struct argp_child
+struct argp_child
 children[]=
 {
   {&gal_options_common_child, 0, NULL, 0},
@@ -190,6 +88,6 @@ children[]=
 };
 
 /* Set all the necessary argp parameters. */
-static struct argp
-thisargp = {options, parse_opt, args_doc, doc, children, NULL, NULL};
+struct argp
+thisargp = {program_options, parse_opt, args_doc, doc, children, NULL, NULL};
 #endif
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index c392e10..afadb03 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -34,11 +34,82 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <timing.h>
 #include <options.h>
 #include <checkset.h>
+#include <fixedstringmacros.h>
 
 #include "main.h"
 
 #include "ui.h"
-#include "args.h"
+#include "authors-cite.h"
+
+
+
+
+
+/**************************************************************/
+/*********      Argp necessary global entities     ************/
+/**************************************************************/
+/* Definition parameters for the argp: */
+const char *
+argp_program_version = PROGRAM_STRING "\n"
+                       GAL_STRINGS_COPYRIGHT
+                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
+
+const char *
+argp_program_bug_address = PACKAGE_BUGREPORT;
+
+static char
+args_doc[] = "ASTRdata or number [ASTRdata] OPERATOR ...";
+
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" will do arithmetic "
+  "operations on one or multiple images and numbers. Simply put, the name "
+  "of the image along with the arithmetic operators and possible numbers "
+  "are given as arguments. The extensions of each input are specified with "
+  "(possibly multiple) calls to the `--hdu' option."
+  "\n\nCurrently "PROGRAM_NAME" only supports postfix or reverse polish "
+  "notation. For example to get the result of `5+6', you should write "
+  "`5 6 +', or to get the average of two images, you should write `a.fits "
+  "b.fits + 2 /' (or more simply use the `average' operator with "
+  "`a.fits b.fits average'). Please see the manual for more information. "
+  "\n\nThe operators/functions recognized by "PROGRAM_NAME" are: +, -, *, "
+  "/, abs, pow, sqrt, log, log10, minvalue, maxvalue, min, max, average, "
+  "median, lt, le, gt, ge, eq, ne, and, or, not, isblank, and the full set "
+  "of bitwise operators. Please run `info gnuastro \"Arithmetic "
+  "operators\"' for detailed information on each operator. Note that "
+  "multiplication should be quoted (like \"*\", or '*') to avoid shell "
+  "expansion.\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
+
+
+
+
+
+/* Available letters for short options:
+
+   a b c d e f g i j k l m n p r s t u v w x y z
+   A B C E F G H I J L M O Q R T U W X Y Z                */
+enum option_keys_enum
+{
+  /* With short-option version. */
+  ARGS_OPTION_KEY_HDU        = 'h',
+
+  /* Only with long version (start with a value 1000, the rest will be set
+     automatically). */
+};
+
+
+
+
+
+
+
+
+
+
+
 
 
 
@@ -49,70 +120,95 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /**************************************************************/
-/***************       Sanity Check         *******************/
+/*********    Initialize & Parse command-line    **************/
 /**************************************************************/
-/* Read the options into the main program structure. When an option wasn't
-   given, it will not be given a value here, so it will have the
-   initialized value of 0 (or NULL for pointers) after this function. If
-   the value of `0' is meaningful in the context of the option, then it
-   must be given the blank value for the type of the variable IN THIS
-   FUNCTION.
-
-   When the option is necessary for the program to run (independent of any
-   arguments) but it wasn't given, call the `gal_options_add_to_not_given'
-   function. The role of the final `gal_options_abort_if_mandatory_missing'
-   function at the end of this function is to print the full list of
-   mandatory options that were gathered by that function and abort with one
-   error message to help the user. */
 static void
-ui_read_options(struct imgarithparams *p)
+ui_initialize_options(struct imgarithparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
 {
-  size_t i;
-
-  /* Put the program's option values into the structure. */
-  for(i=0; !gal_options_is_last(&options[i]); ++i)
-    if( options[i].key && options[i].name )
-      switch(options[i].key)
-        {
-        /* Inputs */
-        case ARGS_OPTION_HDU_KEY:
-          gal_linked_list_copy_stll(options[i].value, &p->hdus);
-          break;
+  struct gal_options_common_params *cp=&p->cp;
 
+  /* Set the necessary common parameters structure. */
+  cp->poptions           = program_options;
+  cp->program_name       = PROGRAM_NAME;
+  cp->program_exec       = PROGRAM_EXEC;
+  cp->program_bibtex     = PROGRAM_BIBTEX;
+  cp->program_authors    = PROGRAM_AUTHORS;
+  cp->coptions           = gal_commonopts_options;
+}
 
 
-        /* Output */
 
 
 
-        /* Operating mode */
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
+{
+  struct imgarithparams *p = state->input;
+
+  /* Pass `gal_options_common_params' into the child parser.  */
+  state->child_inputs[0] = &p->cp;
+
+  /* In case the user incorrectly uses the equal sign (for example
+     with a short format or with space in the long format, then `arg`
+     start with (if the short version was called) or be (if the long
+     version was called with a space) the equal sign. So, here we
+     check if the first character of arg is the equal sign, then the
+     user is warned and the program is stopped: */
+  if(arg && arg[0]=='=')
+    argp_error(state, "incorrect use of the equal sign (`=`). For short "
+               "options, `=` should not be used and for long options, "
+               "there should be no space between the option, equal sign "
+               "and value");
+
+  /* Set the key to this option. */
+  switch(key)
+    {
 
+    /* Read the non-option tokens (arguments): */
+    case ARGP_KEY_ARG:
+      gal_linkedlist_add_to_stll(&p->tokens, arg, 0);
+      break;
 
 
-        default:
-          error(EXIT_FAILURE, 0, "option key %d not recognized in "
-                "`ui_read_check_only_options'", options[i].key);
-        }
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
 
-  /* If any of the mandatory options were not given, then print an error
-     listing them and abort. */
-  gal_options_abort_if_mandatory_missing(&p->cp);
+  return 0;
 }
 
 
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/***************       Sanity Check         *******************/
+/**************************************************************/
 /* Read and check ONLY the options. When arguments are involved, do the
    check in `ui_check_options_and_arguments'. */
 static void
 ui_read_check_only_options(struct imgarithparams *p)
 {
 
-  /* Read all the options from the `argp_option' array into the main
-     program structure to facilitate checks and running the program. */
-  ui_read_options(p);
-
 }
 
 
@@ -128,10 +224,10 @@ ui_check_options_and_arguments(struct imgarithparams *p)
   size_t numfits=0, numhdus=0;
   struct gal_linkedlist_stll *token, *hdu;
 
-  /* The inputs are put in a lastin-firstout (simple) linked list, so
+  /* The input tokens are put in a lastin-firstout (simple) linked list, so
      change them to the correct order so the order we pop a token is the
-     same order that the user input a value. */
-  gal_linkedlist_reverse_stll(&p->hdus);
+     same order that the user input a value. Note that for the options this
+     was done in `gal_options_read_config_set'. */
   gal_linkedlist_reverse_stll(&p->tokens);
 
   /* Set the output file name (if any is needed). Note that since the
@@ -207,14 +303,18 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
imgarithparams *p)
   struct gal_options_common_params *cp=&p->cp;
 
 
-  /* Set the non-zero initial values, the structure was initialized to
-     have a zero/NULL value for all elements. */
-  cp->poptions        = options;
-  cp->program_name    = PROGRAM_NAME;
-  cp->program_exec    = PROGRAM_EXEC;
-  cp->program_bibtex  = PROGRAM_BIBTEX;
-  cp->program_authors = PROGRAM_AUTHORS;
-  cp->coptions        = gal_commonopts_options;
+  /* Include the parameters necessary for argp from this program (`args.h')
+     and for the common options to all Gnuastro (`commonopts.h'). We want
+     to directly put the pointers to the fields in `p' and `cp', so we are
+     simply including the header here to not have to use long macros in
+     those headers which make them hard to read. */
+#define NOT_COMMON_HDU_PARSER 1
+#include <commonopts.h>
+#include "args.h"
+
+
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
 
 
   /* The dash of a negative number will cause problems with the option
@@ -233,7 +333,7 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
imgarithparams *p)
 
 
   /* Read the configuration files. */
-  gal_options_read_config_set_common(cp);
+  gal_options_read_config_set(cp);
 
 
   /* Read the options into the program's structure, and check them and
@@ -251,12 +351,6 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
imgarithparams *p)
      that arguments don't go in a configuration file. So this test should
      be done after (possibly) printing the option values. */
   ui_check_options_and_arguments(p);
-
-
-  /* Free all the allocated spaces in the option structures. */
-  gal_options_free(options);
-  gal_options_free(gal_commonopts_options);
-  gal_linkedlist_free_ill(cp->mand_common);
 }
 
 
diff --git a/bin/arithmetic/ui.h b/bin/arithmetic/ui.h
index 9eeb6e7..169b51b 100644
--- a/bin/arithmetic/ui.h
+++ b/bin/arithmetic/ui.h
@@ -20,8 +20,8 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#ifndef IMCROPUI_H
-#define IMCROPUI_H
+#ifndef UI_H
+#define UI_H
 
 void
 ui_read_check_inputs_setup(int argc, char *argv[], struct imgarithparams *p);
diff --git a/bin/imgwarp/ui.h b/bin/imgwarp/ui.h
index 6344265..3c6aaa1 100644
--- a/bin/imgwarp/ui.h
+++ b/bin/imgwarp/ui.h
@@ -26,15 +26,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 /* Macros for various types of standard transformation.*/
 enum standard_warps
-  {
-    ALIGN_WARP,
-    ROTATE_WARP,
-    SCALE_WARP,
-    FLIP_WARP,
-    SHEAR_WARP,
-    TRANSLATE_WARP,
-    PROJECT_WARP,
-  };
+{
+  UI_WARP_INVALID,
+
+  UI_WARP_ALIGN,
+  UI_WARP_ROTATE,
+  UI_WARP_SCALE,
+  UI_WARP_FLIP,
+  UI_WARP_SHEAR,
+  UI_WARP_TRANSLATE,
+  UI_WARP_PROJECT,
+};
 
 
 /* Functions */
diff --git a/bin/mkprof/args.h b/bin/mkprof/args.h
index a7c8604..cd7bb62 100644
--- a/bin/mkprof/args.h
+++ b/bin/mkprof/args.h
@@ -27,98 +27,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-/* Include necessary headers. */
-#include <commonopts.h>
-#include <authors-cite.h>
-#include <fixedstringmacros.h>
-
-
-
-
-
-/* Definition parameters for the argp: */
-const char *
-argp_program_version = PROGRAM_STRING "\n"
-                       GAL_STRINGS_COPYRIGHT
-                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
-
-const char *
-argp_program_bug_address = PACKAGE_BUGREPORT;
-
-static char
-args_doc[] = "[BackgroundImage] Catalog";
-
-const char
-doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" will create a FITS image "
-  "containing any number of mock astronomical profiles based on an input "
-  "catalog. All the profiles will be built from the center outwards. First "
-  "by Monte Carlo integration, then using the central pixel position. The "
-  "tolerance level specifies when to switch to a latter.\n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Keys for each option.
-
-   Available letters (-V which is used by GNU is also removed):
-
-   a d f g j k l u v
-   A E G H I J L M O Q U W Z     */
-enum option_keys_enum
-{
-  /* With short-option version. */
-  ARGS_OPTION_BACKHDU_KEY         = 'B',
-  ARGS_OPTION_NAXIS1_KEY          = 'x',
-  ARGS_OPTION_NAXIS2_KEY          = 'y',
-  ARGS_OPTION_INPUTASCANVAS_KEY   = 'C',
-  ARGS_OPTION_OVERSAMPLE_KEY      = 's',
-  ARGS_OPTION_INDIVIDUAL_KEY      = 'i',
-  ARGS_OPTION_NOMERGED_KEY        = 'm',
-  ARGS_OPTION_TYPE_KEY            = 'T',
-  ARGS_OPTION_NUMRANDOM_KEY       = 'r',
-  ARGS_OPTION_TOLERANCE_KEY       = 't',
-  ARGS_OPTION_TUNITINP_KEY        = 'p',
-  ARGS_OPTION_XSHIFT_KEY          = 'X',
-  ARGS_OPTION_YSHIFT_KEY          = 'Y',
-  ARGS_OPTION_PREPFORCONV_KEY     = 'c',
-  ARGS_OPTION_ZEROPOINT_KEY       = 'z',
-  ARGS_OPTION_CIRCUMWIDTH_KEY     = 'w',
-  ARGS_OPTION_REPLACE_KEY         = 'R',
-  ARGS_OPTION_ENVSEED_KEY         = 'e',
-  ARGS_OPTION_MFORFLATPIX_KEY     = 'F',
-
-  /* Only with long version. */
-  ARGS_OPTION_PSFINIMG_KEY        = 1000,
-  ARGS_OPTION_MAGATPEAK_KEY,
-  ARGS_OPTION_XCOL_KEY,
-  ARGS_OPTION_YCOL_KEY,
-  ARGS_OPTION_RACOL_KEY,
-  ARGS_OPTION_DECCOL_KEY,
-  ARGS_OPTION_FCOL_KEY,
-  ARGS_OPTION_RCOL_KEY,
-  ARGS_OPTION_NCOL_KEY,
-  ARGS_OPTION_PCOL_KEY,
-  ARGS_OPTION_QCOL_KEY,
-  ARGS_OPTION_MCOL_KEY,
-  ARGS_OPTION_TCOL_KEY,
-  ARGS_OPTION_CRPIX1_KEY,
-  ARGS_OPTION_CRPIX2_KEY,
-  ARGS_OPTION_CRVAL1_KEY,
-  ARGS_OPTION_CRVAL2_KEY,
-  ARGS_OPTION_RESOLUTION_KEY,
-};
-
-
-
-
-
 /* Option definition array. */
-static struct argp_option options[] =
+struct argp_option program_options[] =
   {
     {
       0, 0, 0, 0,
@@ -133,18 +43,20 @@ static struct argp_option options[] =
     {
       0, 0, 0, 0,
       "Input:",
-      1
+      GAL_OPTIONS_GROUP_INPUT
     },
     {
       "backhdu",
-      ARGS_OPTION_BACKHDU_KEY,
+      ARGS_OPTION_KEY_BACKHDU,
       "INT/STR",
       0,
       "HDU of background image.",
-      1,
-      NULL,
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->backhdu,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -152,95 +64,111 @@ static struct argp_option options[] =
     {
       0, 0, 0, 0,
       "Output:",
-      2
+      GAL_OPTIONS_GROUP_OUTPUT
     },
     {
       "naxis1",
-      ARGS_OPTION_NAXIS1_KEY,
+      ARGS_OPTION_KEY_NAXIS1,
       "INT",
       0,
       "Number of pixels along first FITS axis.",
-      2,
-      NULL,
-      GAL_DATA_TYPE_ULONG,
-      GAL_OPTIONS_RANGE_GT_0
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->naxes[0],
+      GAL_DATA_TYPE_LONG,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "naxis2",
-      ARGS_OPTION_NAXIS2_KEY,
+      ARGS_OPTION_KEY_NAXIS2,
       "INT",
       0,
       "Number of pixels along second FITS axis.",
-      2,
-      NULL,
-      GAL_DATA_TYPE_ULONG,
-      GAL_OPTIONS_RANGE_GT_0
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->naxes[1],
+      GAL_DATA_TYPE_LONG,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "inputascanvas",
-      ARGS_OPTION_INPUTASCANVAS_KEY,
+      ARGS_OPTION_KEY_INPUTASCANVAS,
       0,
       0,
       "Use input image for output size and WCS.",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->inputascanvas,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "oversample",
-      ARGS_OPTION_OVERSAMPLE_KEY,
+      ARGS_OPTION_KEY_OVERSAMPLE,
       "INT",
       0,
       "Scale of oversampling (>0 and odd).",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->oversample,
       GAL_DATA_TYPE_UCHAR,
       GAL_OPTIONS_RANGE_GT_0_ODD,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "psfinimg",
-      ARGS_OPTION_PSFINIMG_KEY,
+      ARGS_OPTION_KEY_PSFINIMG,
       0,
       0,
       "PSF profiles made with all in output image.",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->psfinimg,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "individual",
-      ARGS_OPTION_INDIVIDUAL_KEY,
+      ARGS_OPTION_KEY_INDIVIDUAL,
       0,
       0,
       "Build all profiles separately.",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->individual,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "nomerged",
-      ARGS_OPTION_NOMERGED_KEY,
+      ARGS_OPTION_KEY_NOMERGED,
       0,
       0,
       "Do not create a merged image of all profiles.",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->nomerged,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "type",
-      ARGS_OPTION_TYPE_KEY,
+      ARGS_OPTION_KEY_TYPE,
       "STR",
       0,
       "uchar, short, long, longlong, float, double.",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->typestr,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -250,128 +178,150 @@ static struct argp_option options[] =
     {
       0, 0, 0, 0,
       "Profiles:",
-      3
+      ARGS_GROUP_PROFILES
     },
     {
       "numrandom",
-      ARGS_OPTION_NUMRANDOM_KEY,
+      ARGS_OPTION_KEY_NUMRANDOM,
       "INT",
       0,
       "No. of random points in Monte Carlo integration.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->numrandom,
       GAL_DATA_TYPE_ULONG,
-      GAL_OPTIONS_RANGE_GT_0
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "tolerance",
-      ARGS_OPTION_TOLERANCE_KEY,
+      ARGS_OPTION_KEY_TOLERANCE,
       "FLT",
       0,
       "Tolerance to switch to less accurate method.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->tolerance,
       GAL_DATA_TYPE_FLOAT,
-      GAL_OPTIONS_RANGE_GE_0_LE_1
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "tunitinp",
-      ARGS_OPTION_TUNITINP_KEY,
+      ARGS_OPTION_KEY_TUNITINP,
       0,
       0,
       "Truncation is in units of pixels, not radius.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->tunitinp,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "xshift",
-      ARGS_OPTION_XSHIFT_KEY,
+      ARGS_OPTION_KEY_XSHIFT,
       "FLT",
       0,
       "Shift profile centers and enlarge image, X axis.",
-      3,
-      NULL,
-      GAL_DATA_TYPE_FLOAT,
-      GAL_OPTIONS_RANGE_GE_0
+      ARGS_GROUP_PROFILES,
+      &p->shift[0],
+      GAL_DATA_TYPE_LONG,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "yshift",
-      ARGS_OPTION_YSHIFT_KEY,
+      ARGS_OPTION_KEY_YSHIFT,
       "FLT",
       0,
       "Shift profile centers and enlarge image, Y axis.",
-      3,
-      NULL,
-      GAL_DATA_TYPE_FLOAT,
-      GAL_OPTIONS_RANGE_GE_0
+      ARGS_GROUP_PROFILES,
+      &p->shift[1],
+      GAL_DATA_TYPE_LONG,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "prepforconv",
-      ARGS_OPTION_PREPFORCONV_KEY,
+      ARGS_OPTION_KEY_PREPFORCONV,
       0,
       0,
       "Shift and expand based on first catalog PSF.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->prepforconv,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "zeropoint",
-      ARGS_OPTION_ZEROPOINT_KEY,
+      ARGS_OPTION_KEY_ZEROPOINT,
       "FLT",
       0,
       "Magnitude zero point.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->zeropoint,
       GAL_DATA_TYPE_FLOAT,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "circumwidth",
-      ARGS_OPTION_CIRCUMWIDTH_KEY,
+      ARGS_OPTION_KEY_CIRCUMWIDTH,
       "FLT",
       0,
       "Width of circumference (inward) profiles",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->circumwidth,
       GAL_DATA_TYPE_FLOAT,
-      GAL_OPTIONS_RANGE_GT_0
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "replace",
-      ARGS_OPTION_REPLACE_KEY,
+      ARGS_OPTION_KEY_REPLACE,
       0,
       0,
       "Replace overlapping profile pixels, don't add.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->replace,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "magatpeak",
-      ARGS_OPTION_MAGATPEAK_KEY,
+      ARGS_OPTION_KEY_MAGATPEAK,
       0,
       0,
       "Magnitude is for peak pixel, not full profile.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->magatpeak,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "envseed",
-      ARGS_OPTION_ENVSEED_KEY,
+      ARGS_OPTION_KEY_ENVSEED,
       0,
       0,
       "Use GSL_RNG_SEED environment variable for seed.",
-      3,
-      NULL,
+      ARGS_GROUP_PROFILES,
+      &p->envseed,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -380,141 +330,165 @@ static struct argp_option options[] =
 
     {
       0, 0, 0, 0,
-      "Catalog (column number, starting from zero):",
-      4
+      "Catalog (column name or number, starting from 1):",
+      ARGS_GROUP_CATALOG
     },
     {
       "xcol",
-      ARGS_OPTION_XCOL_KEY,
+      ARGS_OPTION_KEY_XCOL,
       "INT/STR",
       0,
       "Center along first FITS axis (horizontal).",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->xcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "ycol",
-      ARGS_OPTION_YCOL_KEY,
+      ARGS_OPTION_KEY_YCOL,
       "INT/STR",
       0,
       "Center along second FITS axis (vertical).",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->ycol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "racol",
-      ARGS_OPTION_RACOL_KEY,
+      ARGS_OPTION_KEY_RACOL,
       "INT/STR",
       0,
       "Center right ascension.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->racol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "deccol",
-      ARGS_OPTION_DECCOL_KEY,
+      ARGS_OPTION_KEY_DECCOL,
       "INT/STR",
       0,
       "Center declination.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->deccol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "fcol",
-      ARGS_OPTION_FCOL_KEY,
+      ARGS_OPTION_KEY_FCOL,
       "INT/STR",
       0,
       "Sersic (0), Moffat (1), Gaussian (2), Point (3),\n"
       "Flat (4), Circumference (5).",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->fcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "rcol",
-      ARGS_OPTION_RCOL_KEY,
+      ARGS_OPTION_KEY_RCOL,
       "INT/STR",
       0,
       "Effective radius or FWHM in pixels.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->rcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "ncol",
-      ARGS_OPTION_NCOL_KEY,
+      ARGS_OPTION_KEY_NCOL,
       "INT/STR",
       0,
       "Sersic index or Moffat beta.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->ncol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "pcol",
-      ARGS_OPTION_PCOL_KEY,
+      ARGS_OPTION_KEY_PCOL,
       "INT/STR",
       0,
       "Position angle.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->pcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "qcol",
-      ARGS_OPTION_QCOL_KEY,
+      ARGS_OPTION_KEY_QCOL,
       "INT/STR",
       0,
       "Axis ratio.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->qcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "mcol",
-      ARGS_OPTION_MCOL_KEY,
+      ARGS_OPTION_KEY_MCOL,
       "INT/STR",
       0,
       "Magnitude.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->mcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "tcol",
-      ARGS_OPTION_TCOL_KEY,
+      ARGS_OPTION_KEY_TCOL,
       "INT/STR",
       0,
       "Truncation in units of --rcol, unless --tunitinp.",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->tcol,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "mforflatpix",
-      ARGS_OPTION_MFORFLATPIX_KEY,
+      ARGS_OPTION_KEY_MFORFLATPIX,
       0,
       0,
       "mcol is flat pixel value (when fcol is 4 or 5)",
-      4,
-      NULL,
+      ARGS_GROUP_CATALOG,
+      &p->mforflatpix,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -524,62 +498,72 @@ static struct argp_option options[] =
     {
       0, 0, 0, 0,
       "WCS parameters:",
-      5
+      ARGS_GROUP_WCS
     },
     {
       "crpix1",
-      ARGS_OPTION_CRPIX1_KEY,
+      ARGS_OPTION_KEY_CRPIX1,
       "FLT",
       0,
       "Pixel coordinate of reference point (axis 1).",
-      5,
-      NULL,
+      ARGS_GROUP_WCS,
+      &p->crpix[0],
       GAL_DATA_TYPE_DOUBLE,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "crpix2",
-      ARGS_OPTION_CRPIX2_KEY,
+      ARGS_OPTION_KEY_CRPIX2,
       "FLT",
       0,
       "Pixel coordinate of reference point (axis 2).",
-      5,
-      NULL,
+      ARGS_GROUP_WCS,
+      &p->crpix[1],
       GAL_DATA_TYPE_DOUBLE,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "crval1",
-      ARGS_OPTION_CRVAL1_KEY,
+      ARGS_OPTION_KEY_CRVAL1,
       "FLT",
       0,
       "Right ascension at reference point (degrees).",
-      5,
-      NULL,
+      ARGS_GROUP_WCS,
+      &p->crval[0],
       GAL_DATA_TYPE_DOUBLE,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "crval2",
-      ARGS_OPTION_CRVAL2_KEY,
+      ARGS_OPTION_KEY_CRVAL2,
       "FLT",
       0,
       "Declination at reference point (degrees).",
-      5,
-      NULL,
+      ARGS_GROUP_WCS,
+      &p->crval[1],
       GAL_DATA_TYPE_DOUBLE,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "resolution",
-      ARGS_OPTION_RESOLUTION_KEY,
+      ARGS_OPTION_KEY_RESOLUTION,
       "FLT",
       0,
       "Resolution of image (arcseconds/pixel).",
-      5,
-      NULL,
+      ARGS_GROUP_WCS,
+      &p->resolution,
       GAL_DATA_TYPE_DOUBLE,
-      GAL_OPTIONS_RANGE_GT_0
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -590,57 +574,14 @@ static struct argp_option options[] =
 
 
 
-/* Parse a single option: */
-error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-  struct mkprofparams *p = state->input;
-
-  /* Pass `gal_options_common_params' into the child parser.  */
-  state->child_inputs[0] = &p->cp;
-
-  /* In case the user incorrectly uses the equal sign (for example
-     with a short format or with space in the long format, then `arg`
-     start with (if the short version was called) or be (if the long
-     version was called with a space) the equal sign. So, here we
-     check if the first character of arg is the equal sign, then the
-     user is warned and the program is stopped: */
-  if(arg && arg[0]=='=')
-    argp_error(state, "incorrect use of the equal sign (`=`). For short "
-               "options, `=` should not be used and for long options, "
-               "there should be no space between the option, equal sign "
-               "and value");
-
-  /* Set the key to this option. */
-  switch(key)
-    {
-
-    /* Read the non-option tokens (arguments): */
-    case ARGP_KEY_ARG:
-      gal_linkedlist_add_to_stll(&p->allargs, arg, 0);
-      break;
-
-
-    /* This is an option, set its value. */
-    default:
-      return gal_options_set_from_key(key, arg, options, &p->cp);
-    }
-
-  return 0;
-}
-
-
-
-
-
 /* Define the child argp structure. */
-static struct argp
+struct argp
 gal_options_common_child = {gal_commonopts_options,
                             gal_options_common_argp_parse,
                             NULL, NULL, NULL, NULL, NULL};
 
 /* Use the child argp structure in list of children (only one for now). */
-static struct argp_child
+struct argp_child
 children[]=
 {
   {&gal_options_common_child, 0, NULL, 0},
@@ -648,6 +589,8 @@ children[]=
 };
 
 /* Set all the necessary argp parameters. */
-static struct argp
-thisargp = {options, parse_opt, args_doc, doc, children, NULL, NULL};
+struct argp
+thisargp = {program_options, parse_opt, args_doc, doc, children, NULL, NULL};
+
+
 #endif
diff --git a/bin/mkprof/astmkprof.conf b/bin/mkprof/astmkprof.conf
index e7dcffd..04b0050 100644
--- a/bin/mkprof/astmkprof.conf
+++ b/bin/mkprof/astmkprof.conf
@@ -53,3 +53,4 @@
 
 # Common options
  hdu                   0
+ minmapsize    100000000
diff --git a/bin/mkprof/main.h b/bin/mkprof/main.h
index a07e932..e14eae8 100644
--- a/bin/mkprof/main.h
+++ b/bin/mkprof/main.h
@@ -47,14 +47,16 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Types of profiles. */
 enum profile_types
 {
-  PROFILE_SERSIC,               /* Sersic profile.           */
-  PROFILE_MOFFAT,               /* Moffat Profile.           */
-  PROFILE_GAUSSIAN,             /* Gaussian Profile.         */
-  PROFILE_POINT,                /* Point profile.            */
-  PROFILE_FLAT,                 /* Flat profile.             */
-  PROFILE_CIRCUMFERENCE,        /* Circumference profile.    */
-
-  MAXIMUM_PROFILE_CODE,         /* Just for a sanity checck. */
+  PROFILE_INVALID,              /* Invalid (=0 by C standard). */
+
+  PROFILE_SERSIC,               /* Sersic profile.             */
+  PROFILE_MOFFAT,               /* Moffat Profile.             */
+  PROFILE_GAUSSIAN,             /* Gaussian Profile.           */
+  PROFILE_POINT,                /* Point profile.              */
+  PROFILE_FLAT,                 /* Flat profile.               */
+  PROFILE_CIRCUMFERENCE,        /* Circumference profile.      */
+
+  MAXIMUM_PROFILE_CODE,         /* Just for a sanity check.    */
 };
 #define MINCIRCUMWIDTH       0.5f
 
@@ -99,84 +101,70 @@ struct builtqueue
 
 struct mkprofparams
 {
-  /* Common parameters structure. */
-  struct gal_options_common_params cp; /* Common parameters.           */
-
-  /* Operating modes */
-  int           psfinimg;  /* ==1: Build PSF profiles in image.        */
-  int         individual;  /* ==1: Build all catalog separately.       */
-
-
-  /* Profiles */
-  int            replace;  /* Replace overlaping profile pixel values. */
-  size_t       numrandom;  /* Number of radom points for integration.  */
-  float        tolerance;  /* Accuracy to stop integration.            */
-  float        zeropoint;  /* Magnitude of zero point flux.            */
-  double     circumwidth;  /* Width of circumference (inward).         */
-  int          magatpeak;  /* Mag only for peak pixel, not all profile.*/
-  int            envseed;  /* Use GSL_RNG_SEED for random seed.        */
-  int        mforflatpix;  /* mcol is flat pixel value (f is 4 or 5).  */
-  int           tunitinp;  /* ==1: Truncation unit is in pixels.       */
-                           /* ==0: It is in radial parameter.          */
-
-  /* Random number generator */
-  gsl_rng           *rng;  /* Main instance of random number generator.*/
+  /* From command-line */
+  struct gal_options_common_params cp; /* Common parameters.              */
+  char            *backname;  /* Name of background image file name.      */
+  char             *catname;  /* Name of catalog of parameters.           */
+  char             *backhdu;  /* HDU of background image.                 */
+  long             naxes[2];  /* Size of the output image.                */
+  unsigned char inputascanvas;/* Input image's header for size and WCS.   */
+  unsigned char  oversample;  /* Oversampling scale.                      */
+  unsigned char    psfinimg;  /* ==1: Build PSF profiles in image.        */
+  unsigned char  individual;  /* ==1: Build all catalog separately.       */
+  unsigned char    nomerged;  /* ==1: Don't make a merged image of all.   */
+  char             *typestr;  /* Type of finally merged output image.     */
+  size_t          numrandom;  /* Number of radom points for integration.  */
+  float           tolerance;  /* Accuracy to stop integration.            */
+  unsigned char    tunitinp;  /* ==1: Truncation is in pixels, not radial.*/
+  long             shift[2];  /* Shift along axeses position of profiles. */
+  unsigned char prepforconv;  /* Shift and expand by size of first psf.   */
+  float           zeropoint;  /* Magnitude of zero point flux.            */
+  double        circumwidth;  /* Width of circumference (inward).         */
+  unsigned char     replace;  /* Replace overlaping profile pixel values. */
+  unsigned char   magatpeak;  /* Mag only for peak pixel, not all profile.*/
+  unsigned char     envseed;  /* Use GSL_RNG_SEED for random seed.        */
+  char                *xcol;  /* X column of profile center.              */
+  char                *ycol;  /* Y column of profile center.              */
+  char               *racol;  /* RA column of profile center.             */
+  char              *deccol;  /* Dec column of profile center.            */
+  char                *fcol;  /* Column specifying profile function.      */
+  char                *rcol;  /* Effective radius of profile.             */
+  char                *ncol;  /* Sersic index column of profile.          */
+  char                *pcol;  /* Position angle column of profile.        */
+  char                *qcol;  /* Axis ratio column of profile.            */
+  char                *mcol;  /* Magnitude column.                        */
+  char                *tcol;  /* Truncation of the profiles.              */
+  unsigned char mforflatpix;  /* mcol is flat pixel value (f is 4 or 5).  */
+  double           crpix[2];  /* CRPIX FITS header keywords.              */
+  double           crval[2];  /* CRVAL FITS header keywords.              */
+  float          resolution;  /* PC1_1 and PC2_2 FITS header keywords.    */
 
 
   /* Output */
-  char         *basename;  /* Merged image name with no directory.     */
-  char           *outdir;  /* Output directory.                        */
-  int           anyblank;  /* ==1: there are blanks in back.           */
-  int           nomerged;  /* ==1: Don't make a merged image of all.   */
-  long          naxes[2];  /* Size of the output image.                */
-  long          shift[2];  /* Shift along axeses position of profiles. */
-  size_t      oversample;  /* Oversampling scale.                      */
-  int               nwcs;  /* Number of WCS.                           */
-  struct wcsprm     *wcs;  /* WCSparam structure.                      */
-
-
-  /* WCS: */
-  double        crpix[2];  /* CRPIX FITS header keywords.              */
-  double        crval[2];  /* CRVAL FITS header keywords.              */
-  float       resolution;  /* PC1_1 and PC2_2 FITS header keywords.    */
-
-
-  /* User interface variables. */
-  struct gal_linkedlist_stll *allargs; /* Keep all input arguments.    */
-  int               type;  /* User's desired output bitpix.            */
-  char         *backname;  /* Name of background image file name.      */
-  char          *backhdu;  /* HDU of background image.                 */
-  char          *catname;  /* Name of catalog of parameters.           */
-  int        prepforconv;  /* Shift and expand by size of first psf.   */
-  int      inputascanvas;  /* Input image's header for size and WCS.   */
-  size_t            fcol;  /* Column specifying profile function.      */
-  size_t            xcol;  /* X column of profile center.              */
-  size_t            ycol;  /* Y column of profile center.              */
-  size_t           racol;  /* RA column of profile center.             */
-  size_t          deccol;  /* Dec column of profile center.            */
-  size_t            rcol;  /* Effective radius of profile.             */
-  size_t            ncol;  /* Sersic index column of profile.          */
-  size_t            pcol;  /* Position angle column of profile.        */
-  size_t            qcol;  /* Axis ratio column of profile.            */
-  size_t            mcol;  /* Magnitude column.                        */
-  size_t            tcol;  /* Truncation of the profiles.              */
+  int                  type;  /* User's desired output type.              */
+  char            *basename;  /* Merged image name with no directory.     */
+  char              *outdir;  /* Output directory.                        */
+  int              anyblank;  /* ==1: there are blanks in back.           */
+  int                  nwcs;  /* Number of WCS.                           */
+  struct wcsprm        *wcs;  /* WCSparam structure.                      */
 
 
   /* Processing parameters: */
-  time_t         rawtime;  /* Starting time of the program.            */
-  gal_data_t        *out;  /* Output image.                            */
-  double            *cat;  /* Input catalog.                           */
-  size_t             cs0;  /* Number of rows in input catalog.         */
-  size_t             cs1;  /* Number of columns in input catalog.      */
-  double            *log;  /* Log data to be printed.                  */
-  struct builtqueue  *bq;  /* Top (last) elem of build queue.          */
-  pthread_cond_t  qready;  /* bq is ready to be written.               */
-  pthread_mutex_t  qlock;  /* Mutex lock to change builtq.             */
-  double       halfpixel;  /* Half pixel in oversampled image.         */
-  int            outtype;  /* Type of finally merged output image.     */
-  char        *wcsheader;  /* The WCS header information for main img. */
-  int         wcsnkeyrec;  /* The number of keywords in the WCS header.*/
-  char    *mergedimgname;  /* Name of merged image.                    */
+  gsl_rng              *rng;  /* Main instance of random number generator.*/
+  time_t            rawtime;  /* Starting time of the program.            */
+  gal_data_t           *out;  /* Output image.                            */
+  double               *cat;  /* Input catalog.                           */
+  size_t                cs0;  /* Number of rows in input catalog.         */
+  size_t                cs1;  /* Number of columns in input catalog.      */
+  double               *log;  /* Log data to be printed.                  */
+  struct builtqueue     *bq;  /* Top (last) elem of build queue.          */
+  pthread_cond_t     qready;  /* bq is ready to be written.               */
+  pthread_mutex_t     qlock;  /* Mutex lock to change builtq.             */
+  double          halfpixel;  /* Half pixel in oversampled image.         */
+  char           *wcsheader;  /* The WCS header information for main img. */
+  int            wcsnkeyrec;  /* The number of keywords in the WCS header.*/
+  char       *mergedimgname;  /* Name of merged image.                    */
+  struct gal_linkedlist_stll *allargs; /* Keep all input arguments.       */
 };
 
 #endif
diff --git a/bin/mkprof/mkprof.c b/bin/mkprof/mkprof.c
index 67ecc2a..e482a74 100644
--- a/bin/mkprof/mkprof.c
+++ b/bin/mkprof/mkprof.c
@@ -215,6 +215,10 @@ saveindividual(struct mkonthread *mkp)
 void *
 build(void *inparam)
 {
+  printf("\n... build needs to be corrected ... \n");
+  exit(0);
+#if 0
+
   struct mkonthread *mkp=(struct mkonthread *)inparam;
   struct mkprofparams *p=mkp->p;
 
@@ -346,6 +350,7 @@ build(void *inparam)
     pthread_barrier_wait(mkp->b);
 
   return NULL;
+#endif
 }
 
 
@@ -544,13 +549,12 @@ write(struct mkprofparams *p)
       /* Get the current time for verbose output. */
       if(!p->cp.quiet) gettimeofday(&t1, NULL);
 
-      /* Make a temporary array of the desired type for writing the
-         output. */
-      if(out->type==GAL_DATA_TYPE_FLOAT)
+      /* Prepare type of output. */
+      if(out->type==p->type)
         towrite=out;
       else
         {
-          towrite=gal_data_copy_to_new_type(out, p->outtype);
+          towrite=gal_data_copy_to_new_type(out, p->type);
           free(out);
         }
 
diff --git a/bin/mkprof/oneprofile.c b/bin/mkprof/oneprofile.c
index 0f70e36..103bd87 100644
--- a/bin/mkprof/oneprofile.c
+++ b/bin/mkprof/oneprofile.c
@@ -420,6 +420,10 @@ ispsf(double fcolvalue)
 void
 setprofparams(struct mkonthread *mkp)
 {
+  printf("\n ... setprofparams needs to be corrected ...\n");
+  exit(0);
+
+#if 0
   struct mkprofparams *p=mkp->p;
 
   double *cat, sigma;
@@ -536,7 +540,7 @@ setprofparams(struct mkonthread *mkp)
             "seen and reported prior to this step. Please contact us so "
             "we can correct this");
     }
-
+#endif
 }
 
 
@@ -564,6 +568,10 @@ setprofparams(struct mkonthread *mkp)
 void
 makeoneprofile(struct mkonthread *mkp)
 {
+  printf("\n ... makeoneprofile needs to be corrected ...\n");
+  exit(0);
+
+#if 0
   struct mkprofparams *p=mkp->p;
 
   float sum;
@@ -627,4 +635,5 @@ makeoneprofile(struct mkonthread *mkp)
         gal_array_fmultip_const(mkp->ibq->img, size,
                                 mkp->brightness/sum);
     }
+#endif
 }
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index f9fe51a..46675fd 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -34,11 +34,118 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <timing.h>
 #include <options.h>
 #include <checkset.h>
+#include <fixedstringmacros.h>
 
 #include "main.h"
 
 #include "ui.h"
-#include "args.h"
+#include "authors-cite.h"
+
+
+
+
+
+/**************************************************************/
+/*********      Argp necessary global entities     ************/
+/**************************************************************/
+/* Definition parameters for the argp: */
+const char *
+argp_program_version = PROGRAM_STRING "\n"
+                       GAL_STRINGS_COPYRIGHT
+                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
+
+const char *
+argp_program_bug_address = PACKAGE_BUGREPORT;
+
+static char
+args_doc[] = "[BackgroundImage] Catalog";
+
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" will create a FITS image "
+  "containing any number of mock astronomical profiles based on an input "
+  "catalog. All the profiles will be built from the center outwards. First "
+  "by Monte Carlo integration, then using the central pixel position. The "
+  "tolerance level specifies when to switch to a latter.\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
+
+
+
+
+/* Option groups particular to this program. */
+enum program_args_groups
+{
+  ARGS_GROUP_PROFILES = GAL_OPTIONS_GROUP_AFTER_COMMON,
+  ARGS_GROUP_CATALOG,
+  ARGS_GROUP_WCS,
+};
+
+
+
+
+
+/* Keys for each option.
+
+   Available letters (-V which is used by GNU is also removed):
+
+   a d f g j k l u v
+   A E G H I J L M O Q U W Z     */
+enum option_keys_enum
+{
+  /* With short-option version. */
+  ARGS_OPTION_KEY_BACKHDU         = 'B',
+  ARGS_OPTION_KEY_NAXIS1          = 'x',
+  ARGS_OPTION_KEY_NAXIS2          = 'y',
+  ARGS_OPTION_KEY_INPUTASCANVAS   = 'C',
+  ARGS_OPTION_KEY_OVERSAMPLE      = 's',
+  ARGS_OPTION_KEY_INDIVIDUAL      = 'i',
+  ARGS_OPTION_KEY_NOMERGED        = 'm',
+  ARGS_OPTION_KEY_TYPE            = 'T',
+  ARGS_OPTION_KEY_NUMRANDOM       = 'r',
+  ARGS_OPTION_KEY_TOLERANCE       = 't',
+  ARGS_OPTION_KEY_TUNITINP        = 'p',
+  ARGS_OPTION_KEY_XSHIFT          = 'X',
+  ARGS_OPTION_KEY_YSHIFT          = 'Y',
+  ARGS_OPTION_KEY_PREPFORCONV     = 'c',
+  ARGS_OPTION_KEY_ZEROPOINT       = 'z',
+  ARGS_OPTION_KEY_CIRCUMWIDTH     = 'w',
+  ARGS_OPTION_KEY_REPLACE         = 'R',
+  ARGS_OPTION_KEY_ENVSEED         = 'e',
+  ARGS_OPTION_KEY_MFORFLATPIX     = 'F',
+
+  /* Only with long version. */
+  ARGS_OPTION_KEY_PSFINIMG        = 1000,
+  ARGS_OPTION_KEY_MAGATPEAK,
+  ARGS_OPTION_KEY_XCOL,
+  ARGS_OPTION_KEY_YCOL,
+  ARGS_OPTION_KEY_RACOL,
+  ARGS_OPTION_KEY_DECCOL,
+  ARGS_OPTION_KEY_FCOL,
+  ARGS_OPTION_KEY_RCOL,
+  ARGS_OPTION_KEY_NCOL,
+  ARGS_OPTION_KEY_PCOL,
+  ARGS_OPTION_KEY_QCOL,
+  ARGS_OPTION_KEY_MCOL,
+  ARGS_OPTION_KEY_TCOL,
+  ARGS_OPTION_KEY_CRPIX1,
+  ARGS_OPTION_KEY_CRPIX2,
+  ARGS_OPTION_KEY_CRVAL1,
+  ARGS_OPTION_KEY_CRVAL2,
+  ARGS_OPTION_KEY_RESOLUTION,
+};
+
+
+
+
+
+
+
+
+
+
+
 
 
 
@@ -49,82 +156,122 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /**************************************************************/
-/***************       Sanity Check         *******************/
+/*********    Initialize & Parse command-line    **************/
 /**************************************************************/
-/* Read the options into the main program structure. When an option wasn't
-   given, it will not be given a value here, so it will have the
-   initialized value of 0 (or NULL for pointers) after this function. If
-   the value of `0' is meaningful in the context of the option, then it
-   must be given the blank value for the type of the variable IN THIS
-   FUNCTION.
-
-   When the option is necessary for the program to run (independent of any
-   arguments) but it wasn't given, call the `gal_options_add_to_not_given'
-   function. The role of the final `gal_options_abort_if_mandatory_missing'
-   function at the end of this function is to print the full list of
-   mandatory options that were gathered by that function and abort with one
-   error message to help the user. */
 static void
-ui_read_options(struct mkprofparams *p)
+ui_initialize_options(struct mkprofparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
 {
   size_t i;
+  struct gal_options_common_params *cp=&p->cp;
 
-  /* Put the program's option values into the structure. */
-  for(i=0; !gal_options_is_last(&options[i]); ++i)
-    if( options[i].key && options[i].name )
-      switch(options[i].key)
-        {
+  /* Set the necessary common parameters structure. */
+  cp->poptions           = program_options;
+  cp->program_name       = PROGRAM_NAME;
+  cp->program_exec       = PROGRAM_EXEC;
+  cp->program_bibtex     = PROGRAM_BIBTEX;
+  cp->program_authors    = PROGRAM_AUTHORS;
+  cp->coptions           = gal_commonopts_options;
 
-          /* Input */
-        case ARGS_OPTION_BACKHDU_KEY:
-          gal_checkset_allocate_copy(options[i].value, &p->backhdu);
-          break;
 
+  /* Set the mandatory common options. */
+  for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
+    switch(cp->coptions[i].key)
+      {
+      case GAL_OPTIONS_KEY_MINMAPSIZE:
+        cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
+        break;
+      }
 
-          /* Output */
 
-          /* naxis1 and naxis2 are only mandatory when a background is not
-             given and `individual' is not called.  */
-        case ARGS_OPTION_NAXIS1_KEY:
-          printf("\n... just before checking `naxis1' ...\n");
-          exit(0);
-          break;
+  /* Read the number of threads available to the user, this should be done
+     before reading command-line and configuration file options, since they
+     can change it.  */
+  gal_options_initialize_numthreads(cp);
 
-        case ARGS_OPTION_NAXIS2_KEY:
 
-          break;
+  /* Set the non-zero initial values, the structure was initialized to have
+     a zero/NULL value for all elements. So, this is necessary only when
+     `0' is meaningful in the context of the variable. */
+  p->type=GAL_DATA_TYPE_INVALID;
+  p->crpix[0]=p->crpix[1]=p->crval[0]=p->crval[1]=NAN;
+}
+
 
 
 
-          /* Operating mode */
 
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
+{
+  struct mkprofparams *p = state->input;
+
+  /* Pass `gal_options_common_params' into the child parser.  */
+  state->child_inputs[0] = &p->cp;
+
+  /* In case the user incorrectly uses the equal sign (for example
+     with a short format or with space in the long format, then `arg`
+     start with (if the short version was called) or be (if the long
+     version was called with a space) the equal sign. So, here we
+     check if the first character of arg is the equal sign, then the
+     user is warned and the program is stopped: */
+  if(arg && arg[0]=='=')
+    argp_error(state, "incorrect use of the equal sign (`=`). For short "
+               "options, `=` should not be used and for long options, "
+               "there should be no space between the option, equal sign "
+               "and value");
+
+  /* Set the key to this option. */
+  switch(key)
+    {
 
+    /* Read the non-option tokens (arguments): */
+    case ARGP_KEY_ARG:
+      gal_linkedlist_add_to_stll(&p->allargs, arg, 0);
+      break;
 
-        default:
-          error(EXIT_FAILURE, 0, "option key %d not recognized in "
-                "`ui_read_check_only_options'", options[i].key);
-        }
 
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
 
-  /* If any of the mandatory options were not given, then print an error
-     listing them and abort. */
-  gal_options_abort_if_mandatory_missing(&p->cp);
+  return 0;
 }
 
 
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/***************       Sanity Check         *******************/
+/**************************************************************/
 /* Read and check ONLY the options. When arguments are involved, do the
    check in `ui_check_options_and_arguments'. */
 static void
 ui_read_check_only_options(struct mkprofparams *p)
 {
-
-  /* Read all the options from the `argp_option' array into the main
-     program structure to facilitate checks and running the program. */
-  ui_read_options(p);
-
+  /* When a no-merged image is to be created, type is necessary. */
+  if( p->type==GAL_DATA_TYPE_INVALID && p->nomerged==0)
+    error(EXIT_FAILURE, 0, "an output type `--type' is necessary when a "
+          "merged image is to be built.");
 }
 
 
@@ -159,6 +306,34 @@ ui_check_options_and_arguments(struct mkprofparams *p)
 
 
 /**************************************************************/
+/***************       Preparations         *******************/
+/**************************************************************/
+static void
+ui_preparations(struct mkprofparams *p)
+{
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
 /************         Set the parameters          *************/
 /**************************************************************/
 void
@@ -167,27 +342,17 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
mkprofparams *p)
   struct gal_options_common_params *cp=&p->cp;
 
 
-  /* Set the non-zero initial values, the structure was initialized to
-     have a zero/NULL value for all elements. */
-  cp->poptions        = options;
-  cp->program_name    = PROGRAM_NAME;
-  cp->program_exec    = PROGRAM_EXEC;
-  cp->program_bibtex  = PROGRAM_BIBTEX;
-  cp->program_authors = PROGRAM_AUTHORS;
-  cp->coptions        = gal_commonopts_options;
-
-
-  /* Read the number of threads available to the user, this should be done
-     before reading command-line and configuration file options, since they
-     can change it.  */
-  gal_options_initialize_numthreads(cp);
+  /* Include the parameters necessary for argp from this program (`args.h')
+     and for the common options to all Gnuastro (`commonopts.h'). We want
+     to directly put the pointers to the fields in `p' and `cp', so we are
+     simply including the header here to not have to use long macros in
+     those headers which make them hard to read. */
+#include <commonopts.h>
+#include "args.h"
 
 
-  /* If there are mandatory common options, add them to this list. The
-     mandatory options for this program will be checked in
-     `ui_read_check_only_options' and finally they will all be reported
-     together if any of them are not given a value. */
-  gal_linkedlist_add_to_ill(&cp->mand_common, GAL_OPTIONS_MINMAPSIZE_KEY);
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
 
 
   /* Read the command-line options and arguments. */
@@ -197,7 +362,7 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
mkprofparams *p)
 
 
   /* Read the configuration files. */
-  gal_options_read_config_set_common(cp);
+  gal_options_read_config_set(&p->cp);
 
 
   /* Read the options into the program's structure, and check them and
@@ -208,7 +373,7 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
mkprofparams *p)
   /* Print the option values if asked. Note that this needs to be done
      after the sanity check so un-sane values are not printed in the output
      state. */
-  gal_options_print_state(cp);
+  gal_options_print_state(&p->cp);
 
 
   /* Check that the options and arguments fit well with each other. Note
@@ -217,10 +382,11 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
mkprofparams *p)
   ui_check_options_and_arguments(p);
 
 
-  /* Free all the allocated spaces in the option structures. */
-  gal_options_free(options);
-  gal_options_free(gal_commonopts_options);
-  gal_linkedlist_free_ill(cp->mand_common);
+  /* Read/allocate all the necessary starting arrays. */
+  ui_preparations(p);
+
+  printf("\n... End of ui.c ...\n");
+  exit(0);
 }
 
 
diff --git a/bin/table/args.h b/bin/table/args.h
index f3afbf3..70fe0e0 100644
--- a/bin/table/args.h
+++ b/bin/table/args.h
@@ -27,102 +27,53 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-/* Include necessary headers. */
-#include <commonopts.h>
-#include <authors-cite.h>
-#include <fixedstringmacros.h>
-
-
-
-
-
-/* Definition parameters for the Argp: */
-const char *
-argp_program_version = PROGRAM_STRING "\n"
-                       GAL_STRINGS_COPYRIGHT
-                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
-
-const char *
-argp_program_bug_address = PACKAGE_BUGREPORT;
-
-static char
-args_doc[] = "ASTRdata";
-
-const char
-doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" can be used to view the "
-  "information, select columns, or convert tables. The inputs and outputs "
-  "can be plain text (with whitespace or comma as delimiters), FITS ascii, "
-  "or FITS binary tables. The output columns can either be selected by "
-  "number (counting from 1), name or using regular expressions. For regular "
-  "expressions, enclose the value to the `--column' (`-c') option in "
-  "slashes (`\\', as in `-c\\^mag\\'). To print the selected columns on the "
-  "command-line, don't specify an output file.\n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Available letters for short options:
-
-   a b d e f g j k l m n p r u v w x y z
-   A B C E F G H J L M O Q R T U W X Y Z  */
-enum option_keys_enum
-{
-  /* With short-option version. */
-  ARGS_OPTION_COLUMN_KEY      = 'c',
-  ARGS_OPTION_SEARCHIN_KEY    = 's',
-  ARGS_OPTION_IGNORECASE_KEY  = 'I',
-  ARGS_OPTION_TABLETYPE_KEY   = 't',
-  ARGS_OPTION_INFORMATION_KEY = 'i',
-
-  /* Only with long version (start with a value 1000, the rest will be set
-     automatically). */
-};
 
 /* Array of acceptable options. */
-struct argp_option options[] =
+struct argp_option program_options[] =
   {
     {
       0, 0, 0, 0,
       "Input:",
-      1
+      GAL_OPTIONS_GROUP_INPUT
     },
     {
       "column",
-      ARGS_OPTION_COLUMN_KEY,
+      ARGS_OPTION_KEY_COLUMN,
       "STR",
       0,
       "Column number (counting from 1) or search string.",
-      1,
-      NULL,
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->columns,
       GAL_DATA_TYPE_STRLL,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "searchin",
-      ARGS_OPTION_SEARCHIN_KEY,
+      ARGS_OPTION_KEY_SEARCHIN,
       "STR",
       0,
       "Search in column `name', `units', or `comments'.",
-      1,
-      NULL,
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->searchinstr,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "ignorecase",
-      ARGS_OPTION_IGNORECASE_KEY,
+      ARGS_OPTION_KEY_IGNORECASE,
       0,
       0,
       "Ignore case when matching column information.",
-      1,
-      NULL,
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->ignorecase,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -135,14 +86,16 @@ struct argp_option options[] =
     },
     {
       "tabletype",
-      ARGS_OPTION_TABLETYPE_KEY,
+      ARGS_OPTION_KEY_TABLETYPE,
       "STR",
       0,
       "Output table type: `fits-ascii', `fits-binary'.",
-      2,
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->tabletypestr,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -151,18 +104,20 @@ struct argp_option options[] =
     {
       0, 0, 0, 0,
       "Operating modes:",
-      -1
+      GAL_OPTIONS_GROUP_OPERATING_MODE
     },
     {
       "information",
-      ARGS_OPTION_INFORMATION_KEY,
+      ARGS_OPTION_KEY_INFORMATION,
       0,
       0,
       "Only print table and column information.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &p->information,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -173,58 +128,14 @@ struct argp_option options[] =
 
 
 
-/* Parse a single option: */
-error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-  struct tableparams *p = state->input;
-
-  /* Pass `gal_options_common_params' into the child parser.  */
-  state->child_inputs[0] = &p->cp;
-
-  /* In case the user incorrectly uses the equal sign (for example
-     with a short format or with space in the long format, then `arg`
-     start with (if the short version was called) or be (if the long
-     version was called with a space) the equal sign. So, here we
-     check if the first character of arg is the equal sign, then the
-     user is warned and the program is stopped: */
-  if(arg && arg[0]=='=')
-    argp_error(state, "incorrect use of the equal sign (`=`). For short "
-               "options, `=` should not be used and for long options, "
-               "there should be no space between the option, equal sign "
-               "and value");
-
-  /* Set the key to this option. */
-  switch(key)
-    {
-
-    /* Read the non-option tokens (arguments): */
-    case ARGP_KEY_ARG:
-      if(p->up.filename)
-        argp_error(state, "only one argument (input file) should be given");
-      else
-        p->up.filename=arg;
-      break;
-
-
-    /* This is an option, set its value. */
-    default:
-      return gal_options_set_from_key(key, arg, options, &p->cp);
-    }
-
-  return 0;
-}
-
-
-
 /* Define the child argp structure. */
-static struct argp
+struct argp
 gal_options_common_child = {gal_commonopts_options,
                             gal_options_common_argp_parse,
                             NULL, NULL, NULL, NULL, NULL};
 
 /* Use the child argp structure in list of children (only one for now). */
-static struct argp_child
+struct argp_child
 children[]=
 {
   {&gal_options_common_child, 0, NULL, 0},
@@ -232,6 +143,6 @@ children[]=
 };
 
 /* Set all the necessary argp parameters. */
-static struct argp
-thisargp = {options, parse_opt, args_doc, doc, children, NULL, NULL};
+struct argp
+thisargp = {program_options, parse_opt, args_doc, doc, children, NULL, NULL};
 #endif
diff --git a/bin/table/asttable.conf b/bin/table/asttable.conf
index 4ce41c6..5ae10ad 100644
--- a/bin/table/asttable.conf
+++ b/bin/table/asttable.conf
@@ -23,4 +23,7 @@
  ignorecase       0
 
 # Output:
- tabletype        fits-binary
\ No newline at end of file
+ tabletype        fits-binary
+
+# Common options
+ minmapsize       1000000000
\ No newline at end of file
diff --git a/bin/table/main.c b/bin/table/main.c
index ec46fb1..d34ebd1 100644
--- a/bin/table/main.c
+++ b/bin/table/main.c
@@ -37,7 +37,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 int
 main (int argc, char *argv[])
 {
-  struct tableparams p={{0}, {0}, 0};
+  struct tableparams p={{0}, 0};
 
   /* Set they starting time. */
   time(&p.rawtime);
diff --git a/bin/table/main.h b/bin/table/main.h
index bc51615..5fbab85 100644
--- a/bin/table/main.h
+++ b/bin/table/main.h
@@ -36,38 +36,26 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-/* User interface structure. */
-struct uiparams
-{
-  char              *filename;
-  gal_data_t      *allcolinfo;
-};
-
-
 
 
 
 /* Main program parameters structure */
 struct tableparams
 {
-  /* Other structures: */
-  struct uiparams          up;  /* User interface parameters.           */
+  /* From command-line */
   struct gal_options_common_params cp; /* Common parameters.            */
-
-  /* Input */
+  char              *filename;  /* Input filename.                      */
   struct gal_linkedlist_stll *columns; /* List of given columns.        */
+  char           *searchinstr;  /* Value to the `searchin' option.      */
+  unsigned char    ignorecase;  /* Ignore case matching column names.   */
+  char          *tabletypestr;  /* The type of the table as a string.   */
+  unsigned char   information;  /* ==1, only print FITS information.    */
 
   /* Output: */
+  unsigned char      searchin;  /* Where to search in column info.      */
   int               tabletype;  /* Type of output table (FITS, txt).    */
   gal_data_t           *table;  /* Linked list of output table columns. */
-
-  /* Operating modes */
-  int             information;  /* ==1, only print FITS information.    */
-  int              ignorecase;  /* Ignore case matching column names.   */
-  int                searchin;  /* Where to search in column info.      */
-
-  /* Internal: */
-  int                onlyview;
+  gal_data_t      *allcolinfo;  /* Information of all the columns.      */
   time_t              rawtime;  /* Starting time of the program.        */
 };
 
diff --git a/bin/table/ui.c b/bin/table/ui.c
index 8dfaf32..6a9ab11 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -33,11 +33,76 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <timing.h>
 #include <options.h>
+#include <checkset.h>
+#include <fixedstringmacros.h>
 
 #include "main.h"
 
 #include "ui.h"
-#include "args.h"
+#include "authors-cite.h"
+
+
+
+
+
+/**************************************************************/
+/*********      Argp necessary global entities     ************/
+/**************************************************************/
+/* Definition parameters for the Argp: */
+const char *
+argp_program_version = PROGRAM_STRING "\n"
+                       GAL_STRINGS_COPYRIGHT
+                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
+
+const char *
+argp_program_bug_address = PACKAGE_BUGREPORT;
+
+static char
+args_doc[] = "ASTRdata";
+
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" can be used to view the "
+  "information, select columns, or convert tables. The inputs and outputs "
+  "can be plain text (with whitespace or comma as delimiters), FITS ascii, "
+  "or FITS binary tables. The output columns can either be selected by "
+  "number (counting from 1), name or using regular expressions. For regular "
+  "expressions, enclose the value to the `--column' (`-c') option in "
+  "slashes (`\\', as in `-c\\^mag\\'). To print the selected columns on the "
+  "command-line, don't specify an output file.\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
+
+
+
+
+
+/* Available letters for short options:
+
+   a b d e f g j k l m n p r u v w x y z
+   A B C E F G H J L M O Q R T U W X Y Z  */
+enum option_keys_enum
+{
+  /* With short-option version. */
+  ARGS_OPTION_KEY_COLUMN      = 'c',
+  ARGS_OPTION_KEY_SEARCHIN    = 's',
+  ARGS_OPTION_KEY_IGNORECASE  = 'I',
+  ARGS_OPTION_KEY_TABLETYPE   = 't',
+  ARGS_OPTION_KEY_INFORMATION = 'i',
+
+  /* Only with long version (start with a value 1000, the rest will be set
+     automatically). */
+};
+
+
+
+
+
+
+
+
+
 
 
 
@@ -49,92 +114,117 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /**************************************************************/
-/***************       Sanity Check         *******************/
+/*********    Initialize & Parse command-line    **************/
 /**************************************************************/
-/* Read the options into the main program structure. When an option wasn't
-   given, it will not be given a value here, so it will have the
-   initialized value of 0 (or NULL for pointers) after this function. If
-   the value of `0' is meaningful in the context of the option, then it
-   must be given the blank value for the type of the variable IN THIS
-   FUNCTION.
-
-   When the option is necessary for the program to run (independent of any
-   arguments) but it wasn't given, call the `gal_options_add_to_not_given'
-   function. The role of the final `gal_options_abort_if_mandatory_missing'
-   function at the end of this function is to print the full list of
-   mandatory options that were gathered by that function and abort with one
-   error message to help the user. */
 static void
-ui_read_options(struct tableparams *p)
+ui_initialize_options(struct tableparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
 {
   size_t i;
-
-  /* Put the program's option values into the structure. */
-  for(i=0; !gal_options_is_last(&options[i]); ++i)
-    if( options[i].key && options[i].name )
-      switch(options[i].key)
-        {
-        /* Inputs */
-        case ARGS_OPTION_COLUMN_KEY:
-          gal_linked_list_copy_stll(options[i].value, &p->columns);
-          break;
+  struct gal_options_common_params *cp=&p->cp;
 
 
-        case ARGS_OPTION_SEARCHIN_KEY:
-          if(options[i].value)
-            p->searchin=gal_table_string_to_searchin(options[i].value);
-          else
-            gal_options_add_to_not_given(&p->cp, &options[i]);
-          break;
+  /* Set the necessary common parameters structure. */
+  cp->poptions           = program_options;
+  cp->program_name       = PROGRAM_NAME;
+  cp->program_exec       = PROGRAM_EXEC;
+  cp->program_bibtex     = PROGRAM_BIBTEX;
+  cp->program_authors    = PROGRAM_AUTHORS;
+  cp->coptions           = gal_commonopts_options;
 
 
-        case ARGS_OPTION_IGNORECASE_KEY:
-          p->ignorecase = *(unsigned char *)options[i].value;
-          break;
+  /* Set the mandatory common options. */
+  for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
+    switch(cp->coptions[i].key)
+      {
+      case GAL_OPTIONS_KEY_MINMAPSIZE:
+        cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
+        break;
+      }
+}
 
 
 
-        /* Output */
-        case ARGS_OPTION_TABLETYPE_KEY:
-          p->tabletype = ( options[i].value
-                           ? gal_table_string_to_type(options[i].value)
-                           : GAL_TABLE_TYPE_INVALID );
-         break;
 
 
-        /* Operating mode */
-        case ARGS_OPTION_INFORMATION_KEY:
-          if(options[i].value)
-            p->information = *(unsigned char *)options[i].value;
-          break;
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
+{
+  struct tableparams *p = state->input;
+
+  /* Pass `gal_options_common_params' into the child parser.  */
+  state->child_inputs[0] = &p->cp;
+
+  /* In case the user incorrectly uses the equal sign (for example
+     with a short format or with space in the long format, then `arg`
+     start with (if the short version was called) or be (if the long
+     version was called with a space) the equal sign. So, here we
+     check if the first character of arg is the equal sign, then the
+     user is warned and the program is stopped: */
+  if(arg && arg[0]=='=')
+    argp_error(state, "incorrect use of the equal sign (`=`). For short "
+               "options, `=` should not be used and for long options, "
+               "there should be no space between the option, equal sign "
+               "and value");
+
+  /* Set the key to this option. */
+  switch(key)
+    {
 
+    /* Read the non-option tokens (arguments): */
+    case ARGP_KEY_ARG:
+      if(p->filename)
+        argp_error(state, "only one argument (input file) should be given");
+      else
+        p->filename=arg;
+      break;
 
 
-        default:
-          error(EXIT_FAILURE, 0, "option key %d not recognized in "
-                "`ui_read_check_only_options'", options[i].key);
-        }
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
 
-  /* If any of the mandatory options were not given, then print an error
-     listing them and abort. */
-  gal_options_abort_if_mandatory_missing(&p->cp);
+  return 0;
 }
 
 
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/***************       Sanity Check         *******************/
+/**************************************************************/
 /* Read and check ONLY the options. When arguments are involved, do the
    check in `ui_check_options_and_arguments'. */
 static void
 ui_read_check_only_options(struct tableparams *p)
 {
 
-  /* Read all the options from the `argp_option' array into the main
-     program structure to facilitate checks and running the program. */
-  ui_read_options(p);
+  /* Read the searchin and table type strings as internal codes. */
+  p->searchin=gal_table_string_to_searchin(p->searchinstr);
+  p->tabletype=gal_table_string_to_type(p->tabletypestr);
+
 
-  /* Check if the type of the output table is valid. */
+  /* Check if the type of the output table is valid, given the type of the
+     output. */
   gal_table_check_fits_type(p->cp.output, p->tabletype);
 
 }
@@ -148,9 +238,9 @@ ui_check_options_and_arguments(struct tableparams *p)
 {
   /* Make sure an input file name was given and if it was a FITS file, that
      a HDU is also given. */
-  if(p->up.filename)
+  if(p->filename)
     {
-      if( gal_fits_name_is_fits(p->up.filename) && p->cp.hdu==NULL )
+      if( gal_fits_name_is_fits(p->filename) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
               "file, a HDU must also be specified, you can use the `--hdu' "
               "(`-h') option and give it the HDU number (starting from "
@@ -196,12 +286,12 @@ ui_preparations(struct tableparams *p)
   if(p->columns==NULL)
     {
       /* Read the table information for the number of columns and rows. */
-      allcols=gal_table_info(p->up.filename, p->cp.hdu, &numcols,
+      allcols=gal_table_info(p->filename, p->cp.hdu, &numcols,
                              &numrows, &tabletype);
 
       /* If there was no actual data in the file, then inform the user */
       if(allcols==NULL)
-        error(EXIT_FAILURE, 0, "%s: no usable data rows", p->up.filename);
+        error(EXIT_FAILURE, 0, "%s: no usable data rows", p->filename);
 
 
       /* If the user just wanted information, then print it. */
@@ -209,8 +299,8 @@ ui_preparations(struct tableparams *p)
         {
           /* Print the file information. */
           printf("--------\n");
-          printf("%s", p->up.filename);
-          if(gal_fits_name_is_fits(p->up.filename))
+          printf("%s", p->filename);
+          if(gal_fits_name_is_fits(p->filename))
             printf(" (hdu: %s)\n", p->cp.hdu);
           else
             printf("\n");
@@ -248,14 +338,14 @@ ui_preparations(struct tableparams *p)
      elements were added to the list is the reverse of the order that they
      will be popped). */
   gal_linkedlist_reverse_stll(&p->columns);
-  p->table=gal_table_read(p->up.filename, p->cp.hdu, p->columns,
+  p->table=gal_table_read(p->filename, p->cp.hdu, p->columns,
                           p->searchin, p->ignorecase, p->cp.minmapsize);
 
   /* If there was no actual data in the file, then inform the user and
      abort. */
   if(p->table==NULL)
     error(EXIT_FAILURE, 0, "%s: no usable data rows (non-commented and "
-          "non-blank lines)", p->up.filename);
+          "non-blank lines)", p->filename);
 
   /* Now that the data columns are ready, we can free the string linked
      list. */
@@ -289,14 +379,18 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
tableparams *p)
 {
   struct gal_options_common_params *cp=&p->cp;
 
-  /* Set the non-zero initial values, the structure was initialized to
-     have a zero/NULL value for all elements. */
-  cp->poptions        = options;
-  cp->program_name    = PROGRAM_NAME;
-  cp->program_exec    = PROGRAM_EXEC;
-  cp->program_bibtex  = PROGRAM_BIBTEX;
-  cp->program_authors = PROGRAM_AUTHORS;
-  cp->coptions        = gal_commonopts_options;
+
+  /* Include the parameters necessary for argp from this program (`args.h')
+     and for the common options to all Gnuastro (`commonopts.h'). We want
+     to directly put the pointers to the fields in `p' and `cp', so we are
+     simply including the header here to not have to use long macros in
+     those headers which make them hard to read. */
+#include <commonopts.h>
+#include "args.h"
+
+
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
 
 
   /* Read the command-line options and arguments. */
@@ -306,7 +400,7 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
tableparams *p)
 
 
   /* Read the configuration files and set the common values. */
-  gal_options_read_config_set_common(cp);
+  gal_options_read_config_set(&p->cp);
 
 
   /* Read the options into the program's structure, and check them and
@@ -317,7 +411,7 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
tableparams *p)
   /* Print the option values if asked. Note that this needs to be done
      after the option checks so un-sane values are not printed in the
      output state. */
-  gal_options_print_state(cp);
+  gal_options_print_state(&p->cp);
 
 
   /* Check that the options and arguments fit well with each other. Note
@@ -328,11 +422,6 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
tableparams *p)
 
   /* Read/allocate all the necessary starting arrays. */
   ui_preparations(p);
-
-
-  /* Free all the allocated spaces in the option structures. */
-  gal_options_free(options);
-  gal_options_free(gal_commonopts_options);
 }
 
 
@@ -363,5 +452,7 @@ freeandreport(struct tableparams *p)
   /* Free the allocated arrays: */
   free(p->cp.hdu);
   free(p->cp.output);
+  free(p->searchinstr);
+  free(p->tabletypestr);
   gal_data_free_ll(p->table);
 }
diff --git a/bootstrap.conf b/bootstrap.conf
index f496e6d..3de3888 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -127,34 +127,44 @@ bootstrap_post_import_hook()
   fi
 
   # Add a value pointer to `argp_option' for easy setting of option values.
-  awk '{                                            \
-         if($1=="struct" && $2=="argp_option")      \
-           inargp=1;                                \
-                                                    \
-         if(inargp==0)                              \
-           print;                                   \
-         else if($1=="};")                          \
-           {                                        \
-             printf "\n";                           \
-             print "  /* Pointer to value.";        \
-             print "     IMPORTANT: currently ONLY a Gnuastro addition. */"; \
-             print "  void *value;";                \
-                                                    \
-             printf "\n";                           \
-             print "  /* Type of value (see lib/gnuastro/data.h).";          \
-             print "     IMPORTANT: currently ONLY a Gnuastro addition. */"; \
-             print "  int type;";                   \
-                                                    \
-             printf "\n";                           \
-             print "  /* Acceptable range of value (see lib/options.h).";    \
-             print "     IMPORTANT: currently ONLY a Gnuastro addition. */"; \
-             print "  int range;";                  \
-                                                    \
-             print;                                 \
-             inargp=0;                              \
-          }                                         \
-         else                                       \
-          print;                                    \
+  awk '{                                                                    \
+         if($1=="struct" && $2=="argp_option")                              \
+           inargp=1;                                                        \
+                                                                            \
+         if(inargp==0)                                                      \
+           print;                                                           \
+         else if($1=="};")                                                  \
+           {                                                                \
+             printf "\n";                                                   \
+             print "  /* Pointer to value.";                                \
+             print "     IMPORTANT: A Gnuastro addition. */";               \
+             print "  void *value;";                                        \
+                                                                            \
+             printf "\n";                                                   \
+             print "  /* Type of value (see lib/gnuastro/data.h).";         \
+             print "     IMPORTANT: A Gnuastro addition. */";               \
+             print "  int type;";                                           \
+                                                                            \
+             printf "\n";                                                   \
+             print "  /* Acceptable range of value (see lib/options.h).";   \
+             print "     IMPORTANT: A Gnuastro addition. */";               \
+             print "  int range;";                                          \
+                                                                            \
+             printf "\n";                                                   \
+             print "  /* Is this option mandatory? (see lib/options.h).";   \
+             print "     IMPORTANT: A Gnuastro addition. */";               \
+             print "  unsigned char mandatory;";                            \
+                                                                            \
+             printf "\n";                                                   \
+             print "  /* Is value already set or not? (see lib/options.h).";\
+             print "     IMPORTANT: A Gnuastro addition. */";               \
+             print "  unsigned char set;";                                  \
+                                                                            \
+             print;                                                         \
+             inargp=0;                                                      \
+          }                                                                 \
+         else                                                               \
+          print;                                                            \
        }' bootstrapped/lib/argp.h > argp_tmp.h
   mv argp_tmp.h bootstrapped/lib/argp.h
 }
diff --git a/lib/commonopts.h b/lib/commonopts.h
index c0a984b..7bbff58 100644
--- a/lib/commonopts.h
+++ b/lib/commonopts.h
@@ -24,7 +24,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef __GAL_COMMONOPTS_H__
 #define __GAL_COMMONOPTS_H__
 
-#include <gnuastro/data.h>
+
 
 /* Common options for all programs.
 
@@ -41,48 +41,56 @@ struct argp_option gal_commonopts_options[] =
 #ifndef NOT_COMMON_HDU_PARSER
     {                           /* Some utilities need to parse `hdu' them-*/
       "hdu",                    /* selves. In this case, they will define  */
-      GAL_OPTIONS_HDU_KEY,      /* `NOT_COMMON_HDU_PARSER' and set their   */
+      GAL_OPTIONS_KEY_HDU,      /* `NOT_COMMON_HDU_PARSER' and set their   */
       "STR",                    /* own `hdu' option structure. */
       0,
       "Extension name or number of input data.",
-      1,                        /* Input. */
-      NULL,
+      GAL_OPTIONS_GROUP_INPUT,
+      &cp->hdu,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 #endif
     {
       "output",
-      GAL_OPTIONS_OUTPUT_KEY,
+      GAL_OPTIONS_KEY_OUTPUT,
       "STR",
       0,
       "Output file or directory name.",
-      2,                        /* Output. */
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &cp->output,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "dontdelete",
-      GAL_OPTIONS_DONTDELETE_KEY,
+      GAL_OPTIONS_KEY_DONTDELETE,
       0,
       0,
       "Don't delete output if it exists.",
-      2,                        /* Output. */
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &cp->dontdelete,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "keepinputdir",
-      GAL_OPTIONS_KEEPINPUTDIR_KEY,
+      GAL_OPTIONS_KEY_KEEPINPUTDIR,
       0,
       0,
       "Keep input directory for automatic output.",
-      2,                        /* Output. */
-      NULL,
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &cp->keepinputdir,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -90,47 +98,55 @@ struct argp_option gal_commonopts_options[] =
     /* Operating mode. */
     {
       "quiet",
-      GAL_OPTIONS_QUIET_KEY,
+      GAL_OPTIONS_KEY_QUIET,
       0,
       0,
       "Only report errors, remain quiet about steps.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->quiet,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "numthreads",
-      GAL_OPTIONS_NUMTHREADS_KEY,
+      GAL_OPTIONS_KEY_NUMTHREADS,
       "INT",
       0,
       "Number of CPU threads to use.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->numthreads,
       GAL_DATA_TYPE_ULONG,
-      GAL_OPTIONS_RANGE_GT_0
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "minmapsize",
-      GAL_OPTIONS_MINMAPSIZE_KEY,
+      GAL_OPTIONS_KEY_MINMAPSIZE,
       "INT",
       0,
       "Minimum no. bytes to map arrays to hdd/ssd.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->minmapsize,
       GAL_DATA_TYPE_ULONG,
-      GAL_OPTIONS_RANGE_GE_0
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "log",
-      GAL_OPTIONS_LOG_KEY,
+      GAL_OPTIONS_KEY_LOG,
       0,
       0,
       "No log file for programs which make one.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->log,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -138,80 +154,94 @@ struct argp_option gal_commonopts_options[] =
     /* Internal (before control goes back to the program). */
     {
       "cite",
-      GAL_OPTIONS_CITE_KEY,
+      GAL_OPTIONS_KEY_CITE,
       0,
       0,
       "BibTeX citation for this program.",
-      -1,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
       NULL,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "printparams",
-      GAL_OPTIONS_PRINTPARAMS_KEY,
+      GAL_OPTIONS_KEY_PRINTPARAMS,
       0,
       0,
       "Print parameter values to be used and abort.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->printparams,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "config",
-      GAL_OPTIONS_CONFIG_KEY,
+      GAL_OPTIONS_KEY_CONFIG,
       "STR",
       0,
       "Read file STR before continuing.",
-      -1,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
       NULL,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "setdirconf",
-      GAL_OPTIONS_SETDIRCONF_KEY,
+      GAL_OPTIONS_KEY_SETDIRCONF,
       0,
       0,
       "Set default values for this directory and abort.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->setdirconf,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "setusrconf",
-      GAL_OPTIONS_SETUSRCONF_KEY,
+      GAL_OPTIONS_KEY_SETUSRCONF,
       0,
       0,
       "Set default values for this user and abort.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->setusrconf,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "lastconfig",
-      GAL_OPTIONS_LASTCONFIG_KEY,
+      GAL_OPTIONS_KEY_LASTCONFIG,
       0,
       0,
       "Do not parse any more configuration files.",
-      -1,
-      NULL,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &cp->lastconfig,
       GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "onlyversion",
-      GAL_OPTIONS_ONLYVERSION_KEY,
+      GAL_OPTIONS_KEY_ONLYVERSION,
       "STR",
       0,
       "Only run if the program version is STR.",
-      -1,
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
       NULL,
       GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_0_OR_1
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
diff --git a/lib/data.c b/lib/data.c
index 7572d47..297ec3a 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -826,6 +826,10 @@ gal_data_string_fixed_alloc_size(gal_data_t *data)
 void
 gal_data_free_contents(gal_data_t *data)
 {
+  if(data==NULL)
+    error(EXIT_FAILURE, 0, "the input data structure to "
+          "`gal_data_free_contents' was a NULL pointer");
+
   /* Free all the possible allocations. */
   if(data->name)    free(data->name);
   if(data->unit)    free(data->unit);
@@ -865,8 +869,11 @@ gal_data_free_contents(gal_data_t *data)
 void
 gal_data_free(gal_data_t *data)
 {
-  gal_data_free_contents(data);
-  free(data);
+  if(data)
+    {
+      gal_data_free_contents(data);
+      free(data);
+    }
 }
 
 
@@ -2138,11 +2145,11 @@ gal_data_string_to_number(char *string)
    *out. When the input `*out!=NULL', then it is assumed to be allocated
    and the value will be simply put there. If `*out==NULL', then space will
    be allocated for the given type and the string's value (in the given
-   type) will be sored there.
+   type) will be stored there.
 
    Note that when we are dealing with a string type, `*out' should be
    interpretted as `char **' (one element in an array of pointers to
-   different strings).
+   different strings). In other words, `out' should be `char ***'.
 
    This function can be used to fill in arrays of numbers from strings (in
    an already allocated data structure), or add nodes to a linked list. For
@@ -2150,8 +2157,7 @@ gal_data_string_to_number(char *string)
    want the value to be stored, for example &(array[i]).
 
    If parsing was successful, it will return a 0. If there was a problem,
-   it will return 1.
- */
+   it will return 1.  */
 int
 gal_data_string_to_type(void **out, char *string, int type)
 {
diff --git a/lib/gnuastro/arithmetic.h b/lib/gnuastro/arithmetic.h
index 850e224..0f39bf3 100644
--- a/lib/gnuastro/arithmetic.h
+++ b/lib/gnuastro/arithmetic.h
@@ -71,6 +71,8 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 /* Identifiers for each operator. */
 enum gal_arithmetic_operators
 {
+  GAL_ARITHMETIC_OP_INVALID,      /* Invalid (=0 by C standard).  */
+
   GAL_ARITHMETIC_OP_PLUS,         /*   +     */
   GAL_ARITHMETIC_OP_MINUS,        /*   -     */
   GAL_ARITHMETIC_OP_MULTIPLY,     /*   *     */
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 4de3729..6e4928e 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -86,9 +86,10 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 /* Macros to identify the type of data. The macros in the comment
    parenthesis is the equivalent macro in CFITSIO. */
-#define GAL_DATA_TYPE_INVALID     -1
 enum gal_data_types
 {
+  GAL_DATA_TYPE_INVALID,   /* Invalid (=0 by C standard).    */
+
   GAL_DATA_TYPE_BIT,       /* Bit              (TBIT).        */
   GAL_DATA_TYPE_UCHAR,     /* unsigned char    (TBYTE).       */
   GAL_DATA_TYPE_CHAR,      /* char             (TSBYTE).      */
diff --git a/lib/gnuastro/table.h b/lib/gnuastro/table.h
index 917d564..2f2e811 100644
--- a/lib/gnuastro/table.h
+++ b/lib/gnuastro/table.h
@@ -74,11 +74,11 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 #define GAL_TABLE_STRING_TYPE_BFITS "fits-binary"
 enum gal_table_types
 {
-  GAL_TABLE_TYPE_TXT,                     /* Plain text table.  */
-  GAL_TABLE_TYPE_AFITS,                   /* FITS ASCII table.  */
-  GAL_TABLE_TYPE_BFITS,                   /* FITS binary table. */
+  GAL_TABLE_TYPE_INVALID,       /* Invalid (=0 by C standard).       */
 
-  GAL_TABLE_TYPE_INVALID,                 /* For sanity checks. */
+  GAL_TABLE_TYPE_TXT,           /* Plain text table.                 */
+  GAL_TABLE_TYPE_AFITS,         /* FITS ASCII table.                 */
+  GAL_TABLE_TYPE_BFITS,         /* FITS binary table.                */
 };
 
 
@@ -93,11 +93,11 @@ enum gal_table_types
 #define GAL_TABLE_STRING_SEARCH_COMMENT "comment"
 enum gal_table_where_to_search
 {
-  GAL_TABLE_SEARCH_NAME,                   /* Match/search in names.    */
-  GAL_TABLE_SEARCH_UNIT,                   /* Match/search in units.    */
-  GAL_TABLE_SEARCH_COMMENT,                /* Match/search in comments. */
+  GAL_TABLE_SEARCH_INVALID,       /* Invalid (=0 by C standard).     */
 
-  GAL_TABLE_SEARCH_INVALID,                /* For sanity checks.        */
+  GAL_TABLE_SEARCH_NAME,          /* Match/search in names.          */
+  GAL_TABLE_SEARCH_UNIT,          /* Match/search in units.          */
+  GAL_TABLE_SEARCH_COMMENT,       /* Match/search in comments.       */
 };
 
 
@@ -110,6 +110,8 @@ enum gal_table_where_to_search
    data.*/
 enum gal_table_diplay_formats
 {
+  GAL_TABLE_DISPLAY_FMT_INVALID,        /* Invalid (=0 by C standard). */
+
   GAL_TABLE_DISPLAY_FMT_STRING,         /* String/Character.           */
   GAL_TABLE_DISPLAY_FMT_DECIMAL,        /* Integers: signed decimal.   */
   GAL_TABLE_DISPLAY_FMT_UDECIMAL,       /* Integers: unsigned decimal. */
@@ -118,8 +120,6 @@ enum gal_table_diplay_formats
   GAL_TABLE_DISPLAY_FMT_FLOAT,          /* Floats: with decimal point. */
   GAL_TABLE_DISPLAY_FMT_EXP,            /* Floats: as exponential.     */
   GAL_TABLE_DISPLAY_FMT_GENERAL,        /* Floats: general (%g in C).  */
-
-  GAL_TABLE_DISPLAY_FMT_INVALID,        /* Floats: general (%g in C).  */
 };
 
 
diff --git a/lib/linkedlist.c b/lib/linkedlist.c
index 9ed667f..7795ec4 100644
--- a/lib/linkedlist.c
+++ b/lib/linkedlist.c
@@ -373,7 +373,7 @@ gal_linkedlist_reverse_stll(struct gal_linkedlist_stll 
**list)
       while(*list!=NULL)
         {
           gal_linkedlist_pop_from_stll(list, &thisstring);
-          gal_linkedlist_add_to_stll(&correctorder, thisstring, 1);
+          gal_linkedlist_add_to_stll(&correctorder, thisstring, 0);
         }
       *list=correctorder;
     }
diff --git a/lib/options.c b/lib/options.c
index 438c6d7..413be9b 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -106,9 +106,9 @@ gal_options_abort_if_mandatory_missing(struct 
gal_options_common_params *cp)
     if( strlen(tmp->v) > namewidth ) namewidth=strlen(tmp->v);
 
   /* Print the introductory information. */
-  sprintf(info, "to continue, the following options need a value:\n");
+  sprintf(info, "to continue, the following options need a value ");
   sprintf(info+strlen(info), "(parenthesis after option name contain its "
-          "description)\n\n");
+          "description):\n\n");
 
   /* Print the list of options along with their description. */
   while(cp->novalue_name!=NULL)
@@ -136,29 +136,6 @@ gal_options_abort_if_mandatory_missing(struct 
gal_options_common_params *cp)
 
 
 
-/* The modified `argp_option' structure contains a void pointer, depending
-   on the type of value inside it, you need to the pointer differently. */
-void
-gal_options_free(struct argp_option *options)
-{
-  size_t i;
-
-  /* Go over all the options and free those that are allocated. After
-     freeing, set them to NULL, so they are not mistakenly used later. */
-  for(i=0; !gal_options_is_last(&options[i]); ++i)
-    if(options[i].value)
-      {
-        if(options[i].type==GAL_DATA_TYPE_STRLL)
-          gal_linkedlist_free_stll(options[i].value, 1);
-        else
-          free(options[i].value);
-        options[i].value=NULL;
-      }
-}
-
-
-
-
 
 static char *
 options_get_home()
@@ -298,18 +275,18 @@ options_immediate(int key, char *arg, struct 
gal_options_common_params *cp)
     {
     /* We don't want later options that were set for the given version to
        cause errors if this option was given. */
-    case GAL_OPTIONS_ONLYVERSION_KEY:
+    case GAL_OPTIONS_KEY_ONLYVERSION:
       options_check_version(arg);
       break;
 
     /* This option is completely independent of anything and doesn't need
        out attention later. */
-    case GAL_OPTIONS_CITE_KEY:
+    case GAL_OPTIONS_KEY_CITE:
       options_print_citation_exit(cp);
       break;
 
     /* Read the given configuration file. */
-    case GAL_OPTIONS_CONFIG_KEY:
+    case GAL_OPTIONS_KEY_CONFIG:
       options_parse_file(arg, cp, 1);
       break;
     }
@@ -320,20 +297,20 @@ options_immediate(int key, char *arg, struct 
gal_options_common_params *cp)
 
 
 /* The option value has been read and put into the `value' field of the
-   `argp_option' structure. This function will use the `range' field to and
-   abort with an error if the value is not in the given range. It also
-   takes the `value_in_str' so it can be used for good error message
-   (showing the value that could not be read). Note that for strings, this
-   option will not do any checks. */
+   `argp_option' structure. This function will use the `range' field to
+   define a check and abort with an error if the value is not in the given
+   range. It also takes the `arg' so it can be used for good error message
+   (showing the value that could not be read). */
 static void
 options_sanity_check(struct argp_option *option, char *arg,
                      char *filename, size_t lineno)
 {
-  char *message;
   size_t dsize=1;
-  int multicheckop;
-  int operator1, operator2;
-  gal_data_t *value, *ref1, *ref2, *check1, *check2;
+  char *message=NULL;
+  int operator1=GAL_ARITHMETIC_OP_INVALID;
+  int operator2=GAL_ARITHMETIC_OP_INVALID;
+  int multicheckop=GAL_ARITHMETIC_OP_INVALID;
+  gal_data_t *value, *ref1=NULL, *ref2=NULL, *check1, *check2;
   int mcflag = ( GAL_ARITHMETIC_NUMOK
                  | GAL_ARITHMETIC_FREE
                  | GAL_ARITHMETIC_INPLACE );
@@ -451,6 +428,8 @@ options_sanity_check(struct argp_option *option, char *arg,
      doesn't free it, we need it for later (for example to print the option
      values). */
   value->array=NULL;
+  gal_data_free(ref1);
+  gal_data_free(ref2);
   gal_data_free(value);
   gal_data_free(check1);
 }
@@ -463,25 +442,12 @@ static void
 gal_options_read_check(struct argp_option *option, char *arg, char *filename,
                        size_t lineno)
 {
-  char **strarr=NULL;
-
-  /* For strings, `gal_data_string_to_type' is going to return an allocated
-     pointer to an allocated string (`char **'). In this context, we are
-     just dealing with one string, and arrays of strings are never used (a
-     linked list is defined when multiple strings must be read). So only
-     keep the actual string and free the one that kept it. */
-  if(option->type==GAL_DATA_TYPE_STRING)
-    {
-      gal_data_string_to_type((void **)(&strarr), arg,
-                              option->type);
-      option->value=strarr[0];
-      free(strarr);
-    }
+  if(option->type==GAL_DATA_TYPE_STRLL)
+    gal_linkedlist_add_to_stll(option->value, arg, 1);
   else
     {
-      /* Read in the value. */
-      if( gal_data_string_to_type(&option->value, arg,
-                                  option->type) )
+      /* Read the string argument into the value. */
+      if( gal_data_string_to_type(&option->value, arg, option->type) )
 
         /* Fortunately `error_at_line' will behave like `error' when the
            filename is NULL (the option was read from a command-line). */
@@ -494,10 +460,14 @@ gal_options_read_check(struct argp_option *option, char 
*arg, char *filename,
                       "positive\n"
                       "  - It is floating point, but the expected value "
                       "is an integer\n", arg, option->name);
-
-      /* Do a sanity check. */
-      options_sanity_check(option, arg, filename, lineno);
     }
+
+  /* Do a sanity check. */
+  options_sanity_check(option, arg, filename, lineno);
+
+
+  /* Flip the `set' flag to `GAL_OPTIONS_SET'. */
+  option->set=GAL_OPTIONS_SET;
 }
 
 
@@ -552,11 +522,8 @@ gal_options_set_from_key(int key, char *arg, struct 
argp_option *options,
              As a result, only when searching for options on the
              command-line, a second value to the same option will replace
              the first one. This will not happen in configuration files. */
-          if(options[i].value && gal_data_is_linked_list(options[i].type)==0)
-            {
-              free(options[i].value);
-              options[i].value=NULL;
-            }
+          if(options[i].set && gal_data_is_linked_list(options[i].type)==0)
+            options[i].set=GAL_OPTIONS_NOT_SET;
 
           /* We have two types of options: those which need an argument and
              those that don't. For those that don't `arg' will be
@@ -569,8 +536,10 @@ gal_options_set_from_key(int key, char *arg, struct 
argp_option *options,
               /* Make sure the option has the type set for options with no
                  argument. So, give it a value of 1. */
               if(options[i].type==GAL_OPTIONS_NO_ARG_TYPE)
-                gal_data_string_to_type(&(options[i].value), "1",
-                                        options[i].type);
+                {
+                  *(unsigned char *)(options[i].value)=1;
+                  options[i].set=GAL_OPTIONS_SET;
+                }
               else
                 error(EXIT_FAILURE, 0, "A bug! Please contact us at %s to "
                       "correct it. Options with no arguments, must have "
@@ -744,7 +713,7 @@ options_set_from_name(char *name, char *arg,  struct 
argp_option *options,
         {
           /* If the option already has a value and it isn't a linked
              list, then ignore it. */
-          if(options[i].value && !gal_data_is_linked_list(options[i].type))
+          if(options[i].set && !gal_data_is_linked_list(options[i].type))
             return 0;
 
           /* For options that need immediate attention. */
@@ -778,8 +747,8 @@ options_lastconfig_has_been_called(struct argp_option 
*coptions)
 {
   size_t i;
   for(i=0; !gal_options_is_last(&coptions[i]); ++i)
-    if( coptions[i].key == GAL_OPTIONS_LASTCONFIG_KEY
-        && coptions[i].value
+    if( coptions[i].key == GAL_OPTIONS_KEY_LASTCONFIG
+        && coptions[i].set
         && *((unsigned char *)(coptions[i].value)) )
       return 1;
   return 0;
@@ -934,44 +903,27 @@ gal_options_parse_config_files(struct 
gal_options_common_params *cp)
 
 
 static void
-options_reverse_lists(struct argp_option *options)
+options_reverse_lists_check_mandatory(struct gal_options_common_params *cp,
+                                      struct argp_option *options)
 {
   size_t i;
 
   for(i=0; !gal_options_is_last(&options[i]); ++i)
-    if(options[i].value && gal_data_is_linked_list(options[i].type) )
-      switch(options[i].type)
+    {
+      if(options[i].set)
         {
-        case GAL_DATA_TYPE_STRLL:
-          gal_linkedlist_reverse_stll(
-                 (struct gal_linkedlist_stll **)(&options[i].value) );
-          break;
-
-        default:
-          error(EXIT_FAILURE, 0, "type code %d isn't recognized as a "
-                "linked list in `options_reverse_lists'", options[i].type);
+          if( gal_data_is_linked_list(options[i].type) )
+            switch(options[i].type)
+              {
+              case GAL_DATA_TYPE_STRLL:
+                gal_linkedlist_reverse_stll(
+                    (struct gal_linkedlist_stll **)(options[i].value) );
+                break;
+              }
         }
-}
-
-
-
-
-
-/* The full list of common options is not necessarily for all the programs,
-   before calling `gal_options_read_config_files', the programs can add the
-   keys of any common options they need to the `mand_common' field of the
-   `gal_options_common_params' structure, then those common options that
-   might be necessary will call this function to check. */
-static void
-options_check_if_mandatory(struct gal_options_common_params *cp,
-                           struct argp_option *option)
-{
-  struct gal_linkedlist_ill *tmp;
-
-  if(option->value==NULL)       /* Only necessary when there is no value. */
-    for(tmp=cp->mand_common; tmp!=NULL; tmp=tmp->next)
-      if(option->key==tmp->v)
-        gal_options_add_to_not_given(cp, option);
+      else if(options[i].mandatory==GAL_OPTIONS_MANDATORY)
+        gal_options_add_to_not_given(cp, &options[i]);
+    }
 }
 
 
@@ -980,64 +932,19 @@ options_check_if_mandatory(struct 
gal_options_common_params *cp,
 
 /* Read all configuration files and set common options */
 void
-gal_options_read_config_set_common(struct gal_options_common_params *cp)
+gal_options_read_config_set(struct gal_options_common_params *cp)
 {
-  size_t i;
-
   /* Parse all the configuration files. */
   gal_options_parse_config_files(cp);
 
   /* Reverse the order of all linked list type options so the popping order
      is the same as the user's input order. We need to do this here because
      when printing those options, their order matters.*/
-  options_reverse_lists(cp->poptions);
-  options_reverse_lists(cp->coptions);
-
-  /* Put the common option values into the structure. */
-  for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
-    if( cp->coptions[i].key && cp->coptions[i].name )
-      switch(cp->coptions[i].key)
-        {
-        case GAL_OPTIONS_HDU_KEY:
-          gal_checkset_allocate_copy(cp->coptions[i].value, &cp->hdu);
-          break;
-
-        case GAL_OPTIONS_OUTPUT_KEY:
-          gal_checkset_allocate_copy(cp->coptions[i].value, &cp->output);
-          break;
-
-        case GAL_OPTIONS_DONTDELETE_KEY:
-          if(cp->coptions[i].value)
-            cp->dontdelete = *(unsigned char *)(cp->coptions[i].value);
-          break;
-
-        case GAL_OPTIONS_KEEPINPUTDIR_KEY:
-          if(cp->coptions[i].value)
-            cp->keepinputdir = *(unsigned char *)(cp->coptions[i].value);
-          break;
-
-        case GAL_OPTIONS_QUIET_KEY:
-          if(cp->coptions[i].value)
-            cp->quiet = *(unsigned char *)(cp->coptions[i].value);
-          break;
+  options_reverse_lists_check_mandatory(cp, cp->poptions);
+  options_reverse_lists_check_mandatory(cp, cp->coptions);
 
-        case GAL_OPTIONS_NUMTHREADS_KEY:
-          if(cp->coptions[i].value)
-            cp->numthreads = *(unsigned long *)(cp->coptions[i].value);
-          break;
-
-        case GAL_OPTIONS_MINMAPSIZE_KEY:
-          if(cp->coptions[i].value)
-            cp->minmapsize = *(unsigned long *)(cp->coptions[i].value);
-          else
-            options_check_if_mandatory(cp, &cp->coptions[i]);
-          break;
-
-        case GAL_OPTIONS_LOG_KEY:
-          if(cp->coptions[i].value)
-            cp->log = *(unsigned char *)(cp->coptions[i].value);
-          break;
-        }
+  /* Abort if any of the mandatory options are not set. */
+  gal_options_abort_if_mandatory_missing(cp);
 }
 
 
@@ -1071,13 +978,13 @@ option_is_printable(struct argp_option *option)
 {
   switch(option->key)
     {
-    case GAL_OPTIONS_OUTPUT_KEY:
-    case GAL_OPTIONS_CITE_KEY:
-    case GAL_OPTIONS_PRINTPARAMS_KEY:
-    case GAL_OPTIONS_CONFIG_KEY:
-    case GAL_OPTIONS_SETDIRCONF_KEY:
-    case GAL_OPTIONS_SETUSRCONF_KEY:
-    case GAL_OPTIONS_LASTCONFIG_KEY:
+    case GAL_OPTIONS_KEY_OUTPUT:
+    case GAL_OPTIONS_KEY_CITE:
+    case GAL_OPTIONS_KEY_PRINTPARAMS:
+    case GAL_OPTIONS_KEY_CONFIG:
+    case GAL_OPTIONS_KEY_SETDIRCONF:
+    case GAL_OPTIONS_KEY_SETUSRCONF:
+    case GAL_OPTIONS_KEY_LASTCONFIG:
       return 0;
     }
   return 1;
@@ -1099,9 +1006,9 @@ options_print_any_type(void *ptr, int type, int width, 
FILE *fp)
     /* For a string we need to make sure it has no white space characters,
        if it does, it should be printed it within quotation signs. */
     case GAL_DATA_TYPE_STRING:
-      c=ptr; while(*c!='\0') if(isspace(*c++)) break;
-      if(*c=='\0') asprintf(&str, "%s",      (char *)ptr);
-      else         asprintf(&str, "\"%s\" ", (char *)ptr);
+      c=*(char **)ptr; while(*c!='\0') if(isspace(*c++)) break;
+      if(*c=='\0') asprintf(&str, "%s",      *(char **)ptr);
+      else         asprintf(&str, "\"%s\" ", *(char **)ptr);
       break;
 
     case GAL_DATA_TYPE_UCHAR:
@@ -1145,7 +1052,7 @@ options_print_any_type(void *ptr, int type, int width, 
FILE *fp)
       break;
 
     case GAL_DATA_TYPE_DOUBLE:
-      asprintf(&str, "%.14f", *(double *)ptr);
+      asprintf(&str, "%.10f", *(double *)ptr);
       break;
 
     default:
@@ -1180,12 +1087,13 @@ options_set_lengths(struct argp_option *poptions,
 
   /* For program specific options. */
   for(i=0; !gal_options_is_last(&poptions[i]); ++i)
-    if(poptions[i].name && poptions[i].value)
+    if(poptions[i].name && poptions[i].set)
       {
         /* Get the length of the value and save its length length if its
            larger than the widest value. */
         if(gal_data_is_linked_list(poptions[i].type))
-          for(tmp=poptions[i].value; tmp!=NULL; tmp=tmp->next)
+          for(tmp=*(struct gal_linkedlist_stll **)(poptions[i].value);
+              tmp!=NULL; tmp=tmp->next)
             {
               /* A small sanity check. */
               if(poptions[i].type!=GAL_DATA_TYPE_STRLL)
@@ -1193,7 +1101,7 @@ options_set_lengths(struct argp_option *poptions,
                       "are acceptable for printing");
 
               /* Get the maximum lengths of each node: */
-              tvlen=options_print_any_type(tmp->v, GAL_DATA_TYPE_STRING,
+              tvlen=options_print_any_type(&tmp->v, GAL_DATA_TYPE_STRING,
                                            0, NULL);
               if( tvlen>vlen )
                 vlen=tvlen;
@@ -1216,7 +1124,7 @@ options_set_lengths(struct argp_option *poptions,
      in this category, so we also need to check them. The detailed steps
      are the same as before. */
   for(i=0; !gal_options_is_last(&coptions[i]); ++i)
-    if( coptions[i].name && coptions[i].value
+    if( coptions[i].name && coptions[i].set
         && option_is_printable(&coptions[i]) )
       {
         tvlen=options_print_any_type(coptions[i].value, coptions[i].type,
@@ -1248,15 +1156,16 @@ options_print_all_in_group(struct argp_option *options, 
int groupint,
   /* Go over all the options. */
   for(i=0; !gal_options_is_last(&options[i]); ++i)
     if( options[i].group == groupint          /* Is in this group.        */
-        && options[i].value                   /* Has been given a value.  */
+        && options[i].set                     /* Has been given a value.  */
         && option_is_printable(&options[i]) ) /* Is relevant for printing.*/
       {
         /* Linked lists */
         if(gal_data_is_linked_list(options[i].type))
-          for(tmp=options[i].value; tmp!=NULL; tmp=tmp->next)
+          for(tmp=*(struct gal_linkedlist_stll **)(options[i].value);
+              tmp!=NULL; tmp=tmp->next)
             {
               fprintf(fp, " %-*s ", namewidth, options[i].name);
-              options_print_any_type(tmp->v, GAL_DATA_TYPE_STRING,
+              options_print_any_type(&tmp->v, GAL_DATA_TYPE_STRING,
                                      valuewidth, fp);
               fprintf(fp, "(%s\b)\n", options[i].doc);
             }
@@ -1395,12 +1304,12 @@ gal_options_print_state(struct 
gal_options_common_params *cp)
   /* A sanity check is necessary first. We want to make sure that the user
      hasn't called more than one of these options. */
   for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
-    if(cp->coptions[i].value)
+    if(cp->coptions[i].set)
       switch(cp->coptions[i].key)
         {
-        case GAL_OPTIONS_PRINTPARAMS_KEY:
-        case GAL_OPTIONS_SETDIRCONF_KEY:
-        case GAL_OPTIONS_SETUSRCONF_KEY:
+        case GAL_OPTIONS_KEY_PRINTPARAMS:
+        case GAL_OPTIONS_KEY_SETDIRCONF:
+        case GAL_OPTIONS_KEY_SETUSRCONF:
           sum += OPTIONS_UCHARVAL;
         }
   if(sum>1)
@@ -1412,20 +1321,20 @@ gal_options_print_state(struct 
gal_options_common_params *cp)
      non-NULL value is not enough. They can have a value of 1 or 0, and the
      respective file should only be created if we have a value of 1. */
   for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
-    if(cp->coptions[i].value && OPTIONS_UCHARVAL)
+    if(cp->coptions[i].set && OPTIONS_UCHARVAL)
       switch(cp->coptions[i].key)
         {
-        case GAL_OPTIONS_PRINTPARAMS_KEY:
+        case GAL_OPTIONS_KEY_PRINTPARAMS:
           options_print_all(cp, NULL, NULL);
           break;
 
-        case GAL_OPTIONS_SETDIRCONF_KEY:
+        case GAL_OPTIONS_KEY_SETDIRCONF:
           asprintf(&dirname, ".%s", PACKAGE);
           options_print_all(cp, dirname, cp->coptions[i].name);
           free(dirname);
           break;
 
-        case GAL_OPTIONS_SETUSRCONF_KEY:
+        case GAL_OPTIONS_KEY_SETUSRCONF:
           home=options_get_home();
           asprintf(&dirname, "%s/%s", home, USERCONFIG_DIR);
           options_print_all(cp, dirname, cp->coptions[i].name);
diff --git a/lib/options.h b/lib/options.h
index 530d243..b98d8de 100644
--- a/lib/options.h
+++ b/lib/options.h
@@ -43,6 +43,30 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+/* Standard groups of options. From the Argp manual (in GNU C Library): "In
+   a long help message, options are sorted alphabetically within each
+   group, and the groups presented in the order 0, 1, 2, ..., N, -M, ...,
+   -2, -1."
+
+   We want the Operating mode group of options to be the last and the input
+   and output groups to the be the first. So first we set the operating
+   mdoe group code to `-1', and benefit from the definition of the
+   Enumerator type in C, so each field afterwards will be one integer
+   larger than the previous. The largest common option group is then used
+   to build the codes of program-specific option groups. */
+enum options_standard_groups
+{
+  GAL_OPTIONS_GROUP_OPERATING_MODE = -1,
+  GAL_OPTIONS_GROUP_INPUT,
+  GAL_OPTIONS_GROUP_OUTPUT,
+
+  GAL_OPTIONS_GROUP_AFTER_COMMON,
+};
+
+
+
+
+
 /* Key values for the common options, the free alphabetical keys are listed
    below. You can use any of the free letters for an option in a
    program. Note that `-V', which is used by GNU and implemented by Argp,
@@ -54,28 +78,31 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 enum options_common_keys
 {
   /* With short-option version */
-  GAL_OPTIONS_HDU_KEY          = 'h',
-  GAL_OPTIONS_OUTPUT_KEY       = 'o',
-  GAL_OPTIONS_DONTDELETE_KEY   = 'D',
-  GAL_OPTIONS_KEEPINPUTDIR_KEY = 'K',
-  GAL_OPTIONS_QUIET_KEY        = 'q',
-  GAL_OPTIONS_NUMTHREADS_KEY   = 'N',
-  GAL_OPTIONS_PRINTPARAMS_KEY  = 'P',
-  GAL_OPTIONS_SETDIRCONF_KEY   = 'S',
-  GAL_OPTIONS_SETUSRCONF_KEY   = 'U',
+  GAL_OPTIONS_KEY_HDU          = 'h',
+  GAL_OPTIONS_KEY_OUTPUT       = 'o',
+  GAL_OPTIONS_KEY_DONTDELETE   = 'D',
+  GAL_OPTIONS_KEY_KEEPINPUTDIR = 'K',
+  GAL_OPTIONS_KEY_QUIET        = 'q',
+  GAL_OPTIONS_KEY_NUMTHREADS   = 'N',
+  GAL_OPTIONS_KEY_PRINTPARAMS  = 'P',
+  GAL_OPTIONS_KEY_SETDIRCONF   = 'S',
+  GAL_OPTIONS_KEY_SETUSRCONF   = 'U',
 
   /* Only long option (integers for keywords). */
-  GAL_OPTIONS_MINMAPSIZE_KEY   = 500,
-  GAL_OPTIONS_LOG_KEY,
-  GAL_OPTIONS_CITE_KEY,
-  GAL_OPTIONS_CONFIG_KEY,
-  GAL_OPTIONS_LASTCONFIG_KEY,
-  GAL_OPTIONS_ONLYVERSION_KEY,
+  GAL_OPTIONS_KEY_MINMAPSIZE   = 500,
+  GAL_OPTIONS_KEY_LOG,
+  GAL_OPTIONS_KEY_CITE,
+  GAL_OPTIONS_KEY_CONFIG,
+  GAL_OPTIONS_KEY_LASTCONFIG,
+  GAL_OPTIONS_KEY_ONLYVERSION,
 };
 
 
+
+
+
 /* Conditions to check */
-enum gal_options_check_values
+enum gal_options_range_values
 {
   GAL_OPTIONS_RANGE_ANY,
 
@@ -88,22 +115,55 @@ enum gal_options_check_values
 };
 
 
+
+
+
+/* What to do if option isn't given. Note that in each program's `main.c'
+   the main program structure is initialized to zero (or NULL for
+   pointers). */
+enum gal_options_mandatory_values
+{
+  GAL_OPTIONS_NOT_MANDATORY,     /* =0 in C standard. */
+  GAL_OPTIONS_MANDATORY,
+};
+
+
+
+
+
+/* If the option has already been given a value or not. */
+enum gal_options_set_values
+{
+  GAL_OPTIONS_NOT_SET,           /* =0 in C standard. */
+  GAL_OPTIONS_SET,
+};
+
+
+
+
+
 /* The structure keeping all the values of the common options in Gnuastro's
    programs. */
 struct gal_options_common_params
 {
-  /* Input/Output: */
+  /* Input/Output. */
   char                    *hdu; /* Image extension.                      */
   char                 *output; /* Directory containg output.            */
   int               dontdelete; /* ==1: Don't delete existing file.      */
   int             keepinputdir; /* Keep input directory for auto output. */
 
-  /* Operating modes: */
+  /* Operating modes. */
   int                    quiet; /* Only print errors.                    */
   size_t            numthreads; /* Number of threads to use.             */
   size_t            minmapsize; /* Minimum bytes necessary to use mmap.  */
   int                      log; /* Make a log file.                      */
 
+  /* Configuration files. */
+  unsigned char    printparams; /* To print the full list of parameters. */
+  unsigned char     setdirconf; /* To write the directory config file.   */
+  unsigned char     setusrconf; /* To write teh user config config file. */
+  unsigned char     lastconfig; /* This is the last configuration file.  */
+
   /* For internal purposes. */
   char           *program_name; /* Official name to be used in text.     */
   char           *program_exec; /* Program's executable name.            */
@@ -161,7 +221,7 @@ gal_options_common_argp_parse(int key, char *arg, struct 
argp_state *state);
 /************            Configuration files            ***************/
 /**********************************************************************/
 void
-gal_options_read_config_set_common(struct gal_options_common_params *cp);
+gal_options_read_config_set(struct gal_options_common_params *cp);
 
 
 void
diff --git a/lib/table.c b/lib/table.c
index 200d819..15b18f3 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -226,7 +226,7 @@ gal_table_col_print_info(gal_data_t *col, int tabletype, 
char *fmt, char *lng)
 {
   size_t j;
   char **strarr;
-  int maxstrlen, width, precision;
+  int maxstrlen, width=0, precision=0;
 
 
   /* First do a sanity check, so we can safly stop checking in the steps



reply via email to

[Prev in Thread] Current Thread [Next in Thread]