gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master e978d44 068/125: Numeric option sanity checks


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e978d44 068/125: Numeric option sanity checks
Date: Sun, 23 Apr 2017 22:36:39 -0400 (EDT)

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

    Numeric option sanity checks
    
    MakeProfiles is being ported to the new option management system and
    `gal_data_t'. After Arithmetic and Table, it is the first program that
    deals with a lot of options of various types (especially numeric
    options). Hence, several changes were necessary in the infra-structure to
    make it more generic and accommodate all these options and values. So the
    changes are relatively diverse as described below:
    
     - Until now, Gnulib's `num_processors' function would be called
       individually in each program, forcing us to include the `nproc.h' header
       in each program's `ui.c'. This could be confusing for users who want to
       read the programs and also for developers. Since this header is not
       available on any system (its only part of Gnulib). So, the new
       `gal_options_initialize_numthreads' was defined to call this function in
       the options library and make things more clear in the code of each
       program.
    
     - In order to call Gnulib's `num_processors' function within the library,
       it was necessary to link Gnuastro's library with Gnulib. This removed
       the need for all the programs to link with Gnulib separately and the
       great features of Gnulib can now also be used by the library
       users. Although the headers are not available, but we can write wrappers
       for them if necessary later.
    
     - Since the long linking line to Gnulib was removed in each program's
       `Makefile.am', all the program `Makefile.am's were also reviewed and
       re-ordered to be more clear and easily readable. In particular, the
       headers (`.h') are now separated from the program sources (`.c' files)
       through automake's `EXTRA_DIST' variable, as in the libraries.
    
     - The option values are now checked to fit into the desired range
       immediately when read with the new `options_sanity_check' function.
       This mandated the addition of a new field in the `argp_option' structure
       called `range' and a new enumerator type in `option.h' to define
       specific ranges to check for. This greatly simplifies the life of
       program developers, now they just have to check for the existance of the
       value, not that it is in the correct range.
    
     - The `doc[]' string for Arithmetic still assumed different HDU options
       (like `--hdu1', `--hdu2' and etc). This has been corrected.
    
     - The old `setparams' function in `ui.c' which was called from the
       program's `main' function now has the more clear name
       `ui_read_check_inputs_setup' in all the programs (that are currently
       built, and will also be used for other programs as they are adopt this
       new system).
    
     - A system was devised to manage mandatory options (and errors if they are
       not given), including both common options and program specific
       options. In particular, the two linked lists that were previous called
       in `ui_read_check_only_options' are now taken into the
       `gal_options_common_params' structure, and programs can now specify the
       list of mandatory common options for the
       `gal_options_read_config_set_common' to check as soon as all the
       configuration files are read and the program doesn't have to worry about
       them being given or not any more.
    
     - The values of the `value' and `type' fields of the option definitions
       were written in one line until now. But with the addition of the `range'
       field in the `argp_option' strcuture, they are all in a separate line
       now.
    
     - Thanks to the range checks being done during the reading of the option
       values, the new `ui_read_options' function in each program's `ui.c' is
       now only in charge of reading the values of the given options and to
       take the necessary step if they were not given. The function that calls
       it (`ui_read_check_only_options') is now in charge of higher-level
       option value checking, for example if the option values do not conflict
       with each other, or if the string values are reasonable.
    
     - Since tables will be used a lot by various programs, a new function
       `gal_table_check_fits_type' was defined to check the types of FITS
       tables (from a string).
    
     - The acceptable string values to `tabletype' and `searchin' are now
       macros to be safely used when-ever they are needed.
    
     - The new `gal_data_set_blank' is now in charge of writing in a blank
       value into an already allocated space. This greatly simplified the
       `gal_data_alloc_blank' function and will be useful in some contexts.
    
     - The process of reading of option values was almost identical between the
       command-line and configuration files. So the new function
       `gal_options_read_check' was defined to make things more clear.
    
     - The larger copyright date when users run `--version' has been updated.
---
 bin/TEMPLATE/Makefile.am      |  12 +-
 bin/arithmetic/Makefile.am    |  10 +-
 bin/arithmetic/args.h         |  18 +-
 bin/arithmetic/authors-cite.h |   2 +-
 bin/arithmetic/main.c         |   2 +-
 bin/arithmetic/ui.c           |  52 ++++-
 bin/arithmetic/ui.h           |   2 +-
 bin/convertt/Makefile.am      |  10 +-
 bin/convolve/Makefile.am      |  10 +-
 bin/cosmiccal/Makefile.am     |  10 +-
 bin/header/Makefile.am        |  10 +-
 bin/imgcrop/Makefile.am       |  10 +-
 bin/imgstat/Makefile.am       |  11 +-
 bin/imgwarp/Makefile.am       |  10 +-
 bin/mkcatalog/Makefile.am     |  11 +-
 bin/mknoise/Makefile.am       |  11 +-
 bin/mkprof/Makefile.am        |  11 +-
 bin/mkprof/args.h             | 150 +++++++++----
 bin/mkprof/astmkprof.conf     |   8 +-
 bin/mkprof/authors-cite.h     |   2 +-
 bin/mkprof/main.c             |   2 +-
 bin/mkprof/main.h             |   4 +-
 bin/mkprof/ui.c               |  85 +++++--
 bin/mkprof/ui.h               |   5 +-
 bin/noisechisel/Makefile.am   |  14 +-
 bin/subtractsky/Makefile.am   |  10 +-
 bin/table/Makefile.am         |  10 +-
 bin/table/args.h              |  20 +-
 bin/table/authors-cite.h      |   4 +-
 bin/table/main.c              |   2 +-
 bin/table/ui.c                |  96 ++++----
 bin/table/ui.h                |   9 +-
 lib/Makefile.am               |   8 +-
 lib/commonopts.h              |  60 +++--
 lib/data.c                    | 122 +++++-----
 lib/fixedstringmacros.h       |   2 +-
 lib/gnuastro/data.h           |   3 +
 lib/gnuastro/linkedlist.h     |   2 +
 lib/gnuastro/table.h          |  17 +-
 lib/linkedlist.c              |  17 ++
 lib/options.c                 | 512 ++++++++++++++++++++----------------------
 lib/options.h                 |  31 ++-
 lib/table.c                   |  57 ++++-
 43 files changed, 852 insertions(+), 602 deletions(-)

diff --git a/bin/TEMPLATE/Makefile.am b/bin/TEMPLATE/Makefile.am
index 5aacadd..54a99a5 100644
--- a/bin/TEMPLATE/Makefile.am
+++ b/bin/TEMPLATE/Makefile.am
@@ -25,16 +25,16 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astTEMPLATE
 
-astTEMPLATE_SOURCES = main.c main.h cite.h ui.c ui.h args.h    \
-TEMPLATE.c TEMPLATE.h
+astTEMPLATE_LDADD = -lgnuastro
 
-astTEMPLATE_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la         \
--lgnuastro
+astTEMPLATE_SOURCES = main.c ui.c TEMPLATE.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h TEMPLATE.h
 
 
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
-dist_sysconf_DATA = asttable.conf
+dist_sysconf_DATA = astTEMPLATE.conf
diff --git a/bin/arithmetic/Makefile.am b/bin/arithmetic/Makefile.am
index 0b50fa5..9426846 100644
--- a/bin/arithmetic/Makefile.am
+++ b/bin/arithmetic/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astarithmetic
 
-astarithmetic_SOURCES = main.c main.h authors-cite.h ui.c ui.h args.h  \
-arithmetic.c arithmetic.h operands.c operands.h
+astarithmetic_LDADD = -lgnuastro
 
-astarithmetic_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la       \
--lgnuastro
+astarithmetic_SOURCES = main.c ui.c arithmetic.c operands.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h arithmetic.h operands.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/arithmetic/args.h b/bin/arithmetic/args.h
index 73ffb65..d984fea 100644
--- a/bin/arithmetic/args.h
+++ b/bin/arithmetic/args.h
@@ -51,13 +51,13 @@ 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 image are expected "
-  "as options (starting with `hdu') listed below. Please note that currently "
-  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 a.fits b.fits average). Please see the manual for more "
-  "information. "
+  "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 "
@@ -101,7 +101,9 @@ static struct argp_option options[] =
       0,
       "Nth call of this option, used for Nth input FITS.",
       1,
-      NULL, GAL_DATA_TYPE_STRLL
+      NULL,
+      GAL_DATA_TYPE_STRLL,
+      GAL_OPTIONS_RANGE_ANY
     },
 
 
diff --git a/bin/arithmetic/authors-cite.h b/bin/arithmetic/authors-cite.h
index 4867cfb..2c56a91 100644
--- a/bin/arithmetic/authors-cite.h
+++ b/bin/arithmetic/authors-cite.h
@@ -21,7 +21,7 @@ You should have received a copy of the GNU General Public 
License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
 #ifndef AUTHORS_CITE_H
-#define AUTHORS_CITS_H
+#define AUTHORS_CITE_H
 
 /* When any specific citation is necessary, please add its BibTeX (from ADS
    hopefully) to this variable along with a title decribing what this
diff --git a/bin/arithmetic/main.c b/bin/arithmetic/main.c
index 59fdafd..3f1b1f5 100644
--- a/bin/arithmetic/main.c
+++ b/bin/arithmetic/main.c
@@ -43,7 +43,7 @@ main (int argc, char *argv[])
   gettimeofday(&t1, NULL);
 
   /* Read the input parameters. */
-  setparams(argc, argv, &p);
+  ui_read_check_inputs_setup(argc, argv, &p);
 
   /* Run MakeProfiles */
   imgarith(&p);
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 0585473..c392e10 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -31,7 +31,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/table.h>
 #include <gnuastro/linkedlist.h>
 
-#include <nproc.h>  /* from Gnulib, in Gnuastro's source */
 #include <timing.h>
 #include <options.h>
 #include <checkset.h>
@@ -52,13 +51,23 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
-/* Sanity check ONLY on options. When arguments are involved, do the check
-   in `ui_check_options_and_arguments'. */
+/* 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_check_only_options(struct imgarithparams *p)
+ui_read_options(struct imgarithparams *p)
 {
   size_t i;
-  struct gal_linkedlist_stll *namell=NULL, *docll=NULL;
 
   /* Put the program's option values into the structure. */
   for(i=0; !gal_options_is_last(&options[i]); ++i)
@@ -87,8 +96,23 @@ ui_read_check_only_options(struct imgarithparams *p)
 
   /* If any of the mandatory options were not given, then print an error
      listing them and abort. */
-  if(namell)
-    gal_options_mandatory_error(namell, docll);
+  gal_options_abort_if_mandatory_missing(&p->cp);
+}
+
+
+
+
+
+/* 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);
+
 }
 
 
@@ -177,11 +201,12 @@ ui_check_options_and_arguments(struct imgarithparams *p)
 /************         Set the parameters          *************/
 /**************************************************************/
 void
-setparams(int argc, char *argv[], struct imgarithparams *p)
+ui_read_check_inputs_setup(int argc, char *argv[], struct imgarithparams *p)
 {
   size_t i;
   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;
@@ -190,7 +215,7 @@ setparams(int argc, char *argv[], struct imgarithparams *p)
   cp->program_bibtex  = PROGRAM_BIBTEX;
   cp->program_authors = PROGRAM_AUTHORS;
   cp->coptions        = gal_commonopts_options;
-  cp->numthreads      = num_processors(NPROC_CURRENT);
+
 
   /* The dash of a negative number will cause problems with the option
      readin. To work properly we will go over all the options/arguments and
@@ -200,31 +225,38 @@ setparams(int argc, char *argv[], struct imgarithparams 
*p)
     if(argv[i][0]=='-' && isdigit(argv[i][1]))
       argv[i][0]=NEG_DASH_REPLACE;
 
+
   /* Read the command-line options and arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
+
   /* Read the configuration files. */
-  gal_options_read_config_files(cp);
+  gal_options_read_config_set_common(cp);
+
 
   /* Read the options into the program's structure, and check them and
      their relations prior to printing. */
   ui_read_check_only_options(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);
 
+
   /* Check that the options and arguments fit well with each other. Note
      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 f327640..9eeb6e7 100644
--- a/bin/arithmetic/ui.h
+++ b/bin/arithmetic/ui.h
@@ -24,7 +24,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define IMCROPUI_H
 
 void
-setparams(int argc, char *argv[], struct imgarithparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct imgarithparams *p);
 
 void
 freeandreport(struct imgarithparams *p, struct timeval *t1);
diff --git a/bin/convertt/Makefile.am b/bin/convertt/Makefile.am
index 19fd691..504f073 100644
--- a/bin/convertt/Makefile.am
+++ b/bin/convertt/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astconvertt
 
-astconvertt_SOURCES = main.c main.h args.h cite.h ui.c ui.h eps.c      \
-eps.h jpeg.c jpeg.h convertt.c convertt.h
+astconvertt_LDADD = -lgnuastro
 
-astconvertt_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la         \
--lgnuastro
+astconvertt_SOURCES = main.c ui.c convertt.c eps.c jpeg.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h convertt.h eps.h jpeg.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/convolve/Makefile.am b/bin/convolve/Makefile.am
index 14f1945..a30872f 100644
--- a/bin/convolve/Makefile.am
+++ b/bin/convolve/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astconvolve
 
-astconvolve_SOURCES = main.c main.h args.h ui.c ui.h convolve.c        \
-convolve.h cite.h
+astconvolve_LDADD = -lgnuastro
 
-astconvolve_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la            \
--lgnuastro
+astconvolve_SOURCES = main.c ui.c convolve.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h convolve.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/cosmiccal/Makefile.am b/bin/cosmiccal/Makefile.am
index 03e46e6..97a6124 100644
--- a/bin/cosmiccal/Makefile.am
+++ b/bin/cosmiccal/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astcosmiccal
 
-astcosmiccal_SOURCES = main.c main.h cite.h ui.c ui.h args.h   \
-cosmiccal.c cosmiccal.h
+astcosmiccal_LDADD = -lgnuastro
 
-astcosmiccal_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la                
\
--lgnuastro
+astcosmiccal_SOURCES = main.c ui.c cosmiccal.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h cosmiccal.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/header/Makefile.am b/bin/header/Makefile.am
index d98b594..57a34b7 100644
--- a/bin/header/Makefile.am
+++ b/bin/header/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astheader
 
-astheader_SOURCES = main.c main.h cite.h ui.c ui.h args.h      \
-header.c header.h
+astheader_LDADD = -lgnuastro
 
-astheader_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la           \
--lgnuastro
+astheader_SOURCES = main.c ui.c header.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h header.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/imgcrop/Makefile.am b/bin/imgcrop/Makefile.am
index 4552260..c3a5b11 100644
--- a/bin/imgcrop/Makefile.am
+++ b/bin/imgcrop/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astimgcrop
 
-astimgcrop_SOURCES = main.c main.h cite.h ui.c ui.h args.h imgcrop.c   \
-imgcrop.h wcsmode.c wcsmode.h crop.c crop.h
+astimgcrop_LDADD = -lgnuastro
 
-astimgcrop_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la  \
--lgnuastro
+astimgcrop_SOURCES = main.c ui.c imgcrop.c wcsmode.c crop.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h imgcrop.h wcsmode.h crop.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/imgstat/Makefile.am b/bin/imgstat/Makefile.am
index 99c5f75..16e1c50 100644
--- a/bin/imgstat/Makefile.am
+++ b/bin/imgstat/Makefile.am
@@ -25,14 +25,15 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astimgstat
 
-astimgstat_SOURCES = main.c main.h cite.h ui.c ui.h args.h     \
-imgstat.c imgstat.h
+astimgstat_LDADD = -lgnuastro
+
+astimgstat_SOURCES = main.c ui.c imgstat.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h imgstat.h
 
-astimgstat_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la          \
--lgnuastro
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/imgwarp/Makefile.am b/bin/imgwarp/Makefile.am
index 8ce76e2..d2d3235 100644
--- a/bin/imgwarp/Makefile.am
+++ b/bin/imgwarp/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astimgwarp
 
-astimgwarp_SOURCES = main.c main.h cite.h ui.c ui.h args.h     \
-imgwarp.c imgwarp.h
+astimgwarp_LDADD = -lgnuastro
 
-astimgwarp_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la          \
--lgnuastro
+astimgwarp_SOURCES = main.c ui.c imgwarp.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h imgwarp.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/mkcatalog/Makefile.am b/bin/mkcatalog/Makefile.am
index fcc7bcd..f9b6f71 100644
--- a/bin/mkcatalog/Makefile.am
+++ b/bin/mkcatalog/Makefile.am
@@ -25,14 +25,15 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astmkcatalog
 
-astmkcatalog_SOURCES = main.c main.h cite.h ui.c ui.h args.h          \
-mkcatalog.c mkcatalog.h columns.c columns.h upperlimit.c upperlimit.h
+astmkcatalog_LDADD = -lgnuastro
 
-astmkcatalog_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la       \
--lgnuastro
+astmkcatalog_SOURCES = main.c ui.c mkcatalog.c columns.c upperlimit.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h mkcatalog.h columns.h    \
+  upperlimit.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/mknoise/Makefile.am b/bin/mknoise/Makefile.am
index 37c8558..93ef35a 100644
--- a/bin/mknoise/Makefile.am
+++ b/bin/mknoise/Makefile.am
@@ -25,14 +25,15 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astmknoise
 
-astmknoise_SOURCES = main.c main.h cite.h ui.c ui.h args.h     \
-mknoise.c mknoise.h
+astmknoise_LDADD = -lgnuastro
+
+astmknoise_SOURCES = main.c ui.c mknoise.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h mknoise.h
 
-astmknoise_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la          \
--lgnuastro
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/mkprof/Makefile.am b/bin/mkprof/Makefile.am
index 776569c..e78db15 100644
--- a/bin/mkprof/Makefile.am
+++ b/bin/mkprof/Makefile.am
@@ -25,14 +25,15 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-# Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astmkprof
 
-astmkprof_SOURCES = main.c main.h ui.c ui.h mkprof.c mkprof.h args.h   \
-oneprofile.c oneprofile.h profiles.c profiles.h authors-cite.h
+astmkprof_LDADD = -lgnuastro
 
-astmkprof_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la            \
--lgnuastro
+astmkprof_SOURCES = main.c ui.c mkprof.c oneprofile.c profiles.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h mkprof.h oneprofile.h    \
+  profiles.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/mkprof/args.h b/bin/mkprof/args.h
index 0bfc5f1..a7c8604 100644
--- a/bin/mkprof/args.h
+++ b/bin/mkprof/args.h
@@ -142,7 +142,9 @@ static struct argp_option options[] =
       0,
       "HDU of background image.",
       1,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
 
 
@@ -159,7 +161,9 @@ static struct argp_option options[] =
       0,
       "Number of pixels along first FITS axis.",
       2,
-      NULL, GAL_DATA_TYPE_ULONG
+      NULL,
+      GAL_DATA_TYPE_ULONG,
+      GAL_OPTIONS_RANGE_GT_0
     },
     {
       "naxis2",
@@ -168,7 +172,9 @@ static struct argp_option options[] =
       0,
       "Number of pixels along second FITS axis.",
       2,
-      NULL, GAL_DATA_TYPE_ULONG
+      NULL,
+      GAL_DATA_TYPE_ULONG,
+      GAL_OPTIONS_RANGE_GT_0
     },
     {
       "inputascanvas",
@@ -177,16 +183,20 @@ static struct argp_option options[] =
       0,
       "Use input image for output size and WCS.",
       2,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "oversample",
       ARGS_OPTION_OVERSAMPLE_KEY,
       "INT",
       0,
-      "Scale of oversampling.",
+      "Scale of oversampling (>0 and odd).",
       2,
-      NULL, GAL_DATA_TYPE_ULONG
+      NULL,
+      GAL_DATA_TYPE_UCHAR,
+      GAL_OPTIONS_RANGE_GT_0_ODD,
     },
     {
       "psfinimg",
@@ -195,7 +205,9 @@ static struct argp_option options[] =
       0,
       "PSF profiles made with all in output image.",
       2,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "individual",
@@ -204,7 +216,9 @@ static struct argp_option options[] =
       0,
       "Build all profiles separately.",
       2,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "nomerged",
@@ -213,7 +227,9 @@ static struct argp_option options[] =
       0,
       "Do not create a merged image of all profiles.",
       2,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "type",
@@ -222,7 +238,9 @@ static struct argp_option options[] =
       0,
       "uchar, short, long, longlong, float, double.",
       2,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
 
 
@@ -241,7 +259,9 @@ static struct argp_option options[] =
       0,
       "No. of random points in Monte Carlo integration.",
       3,
-      NULL, GAL_DATA_TYPE_ULONG
+      NULL,
+      GAL_DATA_TYPE_ULONG,
+      GAL_OPTIONS_RANGE_GT_0
     },
     {
       "tolerance",
@@ -250,7 +270,9 @@ static struct argp_option options[] =
       0,
       "Tolerance to switch to less accurate method.",
       3,
-      NULL, GAL_DATA_TYPE_FLOAT
+      NULL,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GE_0_LE_1
     },
     {
       "tunitinp",
@@ -259,7 +281,9 @@ static struct argp_option options[] =
       0,
       "Truncation is in units of pixels, not radius.",
       3,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "xshift",
@@ -268,7 +292,9 @@ static struct argp_option options[] =
       0,
       "Shift profile centers and enlarge image, X axis.",
       3,
-      NULL, GAL_DATA_TYPE_FLOAT
+      NULL,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GE_0
     },
     {
       "yshift",
@@ -277,7 +303,9 @@ static struct argp_option options[] =
       0,
       "Shift profile centers and enlarge image, Y axis.",
       3,
-      NULL, GAL_DATA_TYPE_FLOAT
+      NULL,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GE_0
     },
     {
       "prepforconv",
@@ -286,7 +314,9 @@ static struct argp_option options[] =
       0,
       "Shift and expand based on first catalog PSF.",
       3,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "zeropoint",
@@ -295,7 +325,9 @@ static struct argp_option options[] =
       0,
       "Magnitude zero point.",
       3,
-      NULL, GAL_DATA_TYPE_FLOAT
+      NULL,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "circumwidth",
@@ -304,7 +336,9 @@ static struct argp_option options[] =
       0,
       "Width of circumference (inward) profiles",
       3,
-      NULL, GAL_DATA_TYPE_FLOAT
+      NULL,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GT_0
     },
     {
       "replace",
@@ -313,7 +347,9 @@ static struct argp_option options[] =
       0,
       "Replace overlapping profile pixels, don't add.",
       3,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "magatpeak",
@@ -322,7 +358,9 @@ static struct argp_option options[] =
       0,
       "Magnitude is for peak pixel, not full profile.",
       3,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "envseed",
@@ -331,7 +369,9 @@ static struct argp_option options[] =
       0,
       "Use GSL_RNG_SEED environment variable for seed.",
       3,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
@@ -350,7 +390,9 @@ static struct argp_option options[] =
       0,
       "Center along first FITS axis (horizontal).",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "ycol",
@@ -359,7 +401,9 @@ static struct argp_option options[] =
       0,
       "Center along second FITS axis (vertical).",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "racol",
@@ -368,7 +412,9 @@ static struct argp_option options[] =
       0,
       "Center right ascension.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "deccol",
@@ -377,7 +423,9 @@ static struct argp_option options[] =
       0,
       "Center declination.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "fcol",
@@ -387,7 +435,9 @@ static struct argp_option options[] =
       "Sersic (0), Moffat (1), Gaussian (2), Point (3),\n"
       "Flat (4), Circumference (5).",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "rcol",
@@ -396,7 +446,9 @@ static struct argp_option options[] =
       0,
       "Effective radius or FWHM in pixels.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "ncol",
@@ -405,7 +457,9 @@ static struct argp_option options[] =
       0,
       "Sersic index or Moffat beta.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "pcol",
@@ -414,7 +468,9 @@ static struct argp_option options[] =
       0,
       "Position angle.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "qcol",
@@ -423,7 +479,9 @@ static struct argp_option options[] =
       0,
       "Axis ratio.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "mcol",
@@ -432,7 +490,9 @@ static struct argp_option options[] =
       0,
       "Magnitude.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "tcol",
@@ -441,7 +501,9 @@ static struct argp_option options[] =
       0,
       "Truncation in units of --rcol, unless --tunitinp.",
       4,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "mforflatpix",
@@ -450,7 +512,9 @@ static struct argp_option options[] =
       0,
       "mcol is flat pixel value (when fcol is 4 or 5)",
       4,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
@@ -469,7 +533,9 @@ static struct argp_option options[] =
       0,
       "Pixel coordinate of reference point (axis 1).",
       5,
-      NULL, GAL_DATA_TYPE_DOUBLE
+      NULL,
+      GAL_DATA_TYPE_DOUBLE,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "crpix2",
@@ -478,7 +544,9 @@ static struct argp_option options[] =
       0,
       "Pixel coordinate of reference point (axis 2).",
       5,
-      NULL, GAL_DATA_TYPE_DOUBLE
+      NULL,
+      GAL_DATA_TYPE_DOUBLE,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "crval1",
@@ -487,7 +555,9 @@ static struct argp_option options[] =
       0,
       "Right ascension at reference point (degrees).",
       5,
-      NULL, GAL_DATA_TYPE_DOUBLE
+      NULL,
+      GAL_DATA_TYPE_DOUBLE,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "crval2",
@@ -496,7 +566,9 @@ static struct argp_option options[] =
       0,
       "Declination at reference point (degrees).",
       5,
-      NULL, GAL_DATA_TYPE_DOUBLE
+      NULL,
+      GAL_DATA_TYPE_DOUBLE,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "resolution",
@@ -505,7 +577,9 @@ static struct argp_option options[] =
       0,
       "Resolution of image (arcseconds/pixel).",
       5,
-      NULL, GAL_DATA_TYPE_DOUBLE
+      NULL,
+      GAL_DATA_TYPE_DOUBLE,
+      GAL_OPTIONS_RANGE_GT_0
     },
 
 
diff --git a/bin/mkprof/astmkprof.conf b/bin/mkprof/astmkprof.conf
index 7b5aee2..e7dcffd 100644
--- a/bin/mkprof/astmkprof.conf
+++ b/bin/mkprof/astmkprof.conf
@@ -17,9 +17,6 @@
 # notice and this notice are preserved.  This file is offered as-is,
 # without any warranty.
 
-# Input:
- hdu                   0
-
 # Output:
  naxis1             1000
  naxis2             1000
@@ -52,4 +49,7 @@
  crpix2                1
  crval1                1
  crval2                1
- resolution         0.03
\ No newline at end of file
+ resolution         0.03
+
+# Common options
+ hdu                   0
diff --git a/bin/mkprof/authors-cite.h b/bin/mkprof/authors-cite.h
index 5c37dd5..f65b516 100644
--- a/bin/mkprof/authors-cite.h
+++ b/bin/mkprof/authors-cite.h
@@ -5,7 +5,7 @@ MakeProfiles is part of GNU Astronomy Utilities (Gnuastro) 
package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2015, Free Software Foundation, Inc.
+Copyright (C) 2017, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
diff --git a/bin/mkprof/main.c b/bin/mkprof/main.c
index 1bfe637..a3a530a 100644
--- a/bin/mkprof/main.c
+++ b/bin/mkprof/main.c
@@ -43,7 +43,7 @@ main (int argc, char *argv[])
   gettimeofday(&t1, NULL);
 
   /* Read the input parameters. */
-  setparams(argc, argv, &p);
+  ui_read_check_inputs_setup(argc, argv, &p);
 
   /* Run MakeProfiles */
   mkprof(&p);
diff --git a/bin/mkprof/main.h b/bin/mkprof/main.h
index 0d382f4..a07e932 100644
--- a/bin/mkprof/main.h
+++ b/bin/mkprof/main.h
@@ -32,8 +32,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /* Progarm name macros: */
-#define PROGRAM_NAME "Arithmetic"      /* Program full name.       */
-#define PROGRAM_EXEC "astarithmetic"   /* Program executable name. */
+#define PROGRAM_NAME "MakeProfiles"      /* Program full name.       */
+#define PROGRAM_EXEC "astmkprof"         /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 7c11fd5..f9fe51a 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -31,7 +31,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/table.h>
 #include <gnuastro/linkedlist.h>
 
-#include <nproc.h>  /* from Gnulib, in Gnuastro's source */
 #include <timing.h>
 #include <options.h>
 #include <checkset.h>
@@ -52,35 +51,47 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
-/* ONLY check options. When arguments are involved, do the check in
-   `ui_check_options_and_arguments'. */
+/* 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_check_only_options(struct mkprofparams *p)
+ui_read_options(struct mkprofparams *p)
 {
   size_t i;
-  struct argp_option *o=options;
-  struct gal_linkedlist_stll *namell=NULL, *docll=NULL;
 
   /* Put the program's option values into the structure. */
-  for(i=0; !gal_options_is_last(&o[i]); ++i)
-    if( o[i].key && o[i].name )
-      switch(o[i].key)
+  for(i=0; !gal_options_is_last(&options[i]); ++i)
+    if( options[i].key && options[i].name )
+      switch(options[i].key)
         {
 
           /* Input */
         case ARGS_OPTION_BACKHDU_KEY:
-          gal_checkset_allocate_copy(o[i].value, &p->backhdu);
+          gal_checkset_allocate_copy(options[i].value, &p->backhdu);
           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("\nJust before checking value to naxis1.\n"); exit(0);
-          gal_options_check_set(&o[i], &p->naxes[0], GAL_OPTIONS_RANGE_GT_0);
+          printf("\n... just before checking `naxis1' ...\n");
+          exit(0);
           break;
 
         case ARGS_OPTION_NAXIS2_KEY:
-          gal_options_check_set(&o[i], &p->naxes[1], GAL_OPTIONS_RANGE_GT_0);
+
           break;
 
 
@@ -91,13 +102,29 @@ ui_read_check_only_options(struct mkprofparams *p)
 
         default:
           error(EXIT_FAILURE, 0, "option key %d not recognized in "
-                "`ui_read_check_only_options'", o[i].key);
+                "`ui_read_check_only_options'", options[i].key);
         }
 
+
   /* If any of the mandatory options were not given, then print an error
      listing them and abort. */
-  if(namell)
-    gal_options_mandatory_error(namell, docll);
+  gal_options_abort_if_mandatory_missing(&p->cp);
+}
+
+
+
+
+
+/* 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);
+
 }
 
 
@@ -135,10 +162,11 @@ ui_check_options_and_arguments(struct mkprofparams *p)
 /************         Set the parameters          *************/
 /**************************************************************/
 void
-setparams(int argc, char *argv[], struct mkprofparams *p)
+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;
@@ -147,33 +175,52 @@ setparams(int argc, char *argv[], struct mkprofparams *p)
   cp->program_bibtex  = PROGRAM_BIBTEX;
   cp->program_authors = PROGRAM_AUTHORS;
   cp->coptions        = gal_commonopts_options;
-  cp->numthreads      = num_processors(NPROC_CURRENT);
+
+
+  /* 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);
+
+
+  /* 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);
+
 
   /* Read the command-line options and arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
+
   /* Read the configuration files. */
-  gal_options_read_config_files(cp);
+  gal_options_read_config_set_common(cp);
+
 
   /* Read the options into the program's structure, and check them and
      their relations prior to printing. */
   ui_read_check_only_options(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);
 
+
   /* Check that the options and arguments fit well with each other. Note
      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/mkprof/ui.h b/bin/mkprof/ui.h
index 7b5af23..fcabe30 100644
--- a/bin/mkprof/ui.h
+++ b/bin/mkprof/ui.h
@@ -24,10 +24,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define UI_H
 
 void
-checksaveouttype(struct mkprofparams *p, char *arg);
-
-void
-setparams(int argc, char *argv[], struct mkprofparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct mkprofparams *p);
 
 void
 freeandreport(struct mkprofparams *p, struct timeval *t1);
diff --git a/bin/noisechisel/Makefile.am b/bin/noisechisel/Makefile.am
index b3e3d4d..855c804 100644
--- a/bin/noisechisel/Makefile.am
+++ b/bin/noisechisel/Makefile.am
@@ -25,16 +25,16 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astnoisechisel
 
-astnoisechisel_SOURCES = main.c main.h cite.h ui.c ui.h args.h         \
-noisechisel.c noisechisel.h thresh.c thresh.h binary.c binary.h                
\
-label.c label.h detection.c detection.h sky.c sky.h segmentation.c     \
-segmentation.h clumps.c clumps.h
+astnoisechisel_LDADD = -lgnuastro
 
-astnoisechisel_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la      \
--lgnuastro
+astnoisechisel_SOURCES = main.c ui.c noisechisel.c thresh.c binary.c    \
+  label.c detection.c sky.c segmentation.c clumps.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h noisechisel.h thresh.h   \
+  binary.h label.h detection.h sky.h segmentation.h clumps.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/subtractsky/Makefile.am b/bin/subtractsky/Makefile.am
index 56be351..f56a27d 100644
--- a/bin/subtractsky/Makefile.am
+++ b/bin/subtractsky/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = astsubtractsky
 
-astsubtractsky_SOURCES = main.c main.h cite.h ui.c ui.h args.h \
-subtractsky.c subtractsky.h
+astsubtractsky_LDADD = -lgnuastro
 
-astsubtractsky_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la      \
--lgnuastro
+astsubtractsky_SOURCES = main.c ui.c subtractsky.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h subtractsky.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/table/Makefile.am b/bin/table/Makefile.am
index 8df496b..d5d00da 100644
--- a/bin/table/Makefile.am
+++ b/bin/table/Makefile.am
@@ -25,14 +25,14 @@
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
-## Utility and its sources
+## Program definition (name, linking, sources and headers)
 bin_PROGRAMS = asttable
 
-asttable_SOURCES = main.c main.h authors-cite.h ui.c ui.h args.h       \
-table.c table.h
+asttable_LDADD = -lgnuastro
 
-asttable_LDADD = $(top_builddir)/bootstrapped/lib/libgnu.la             \
--lgnuastro
+asttable_SOURCES = main.c ui.c table.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h table.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/table/args.h b/bin/table/args.h
index 4048599..f3afbf3 100644
--- a/bin/table/args.h
+++ b/bin/table/args.h
@@ -98,7 +98,9 @@ struct argp_option options[] =
       0,
       "Column number (counting from 1) or search string.",
       1,
-      NULL, GAL_DATA_TYPE_STRLL
+      NULL,
+      GAL_DATA_TYPE_STRLL,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "searchin",
@@ -107,7 +109,9 @@ struct argp_option options[] =
       0,
       "Search in column `name', `units', or `comments'.",
       1,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "ignorecase",
@@ -116,7 +120,9 @@ struct argp_option options[] =
       0,
       "Ignore case when matching column information.",
       1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
@@ -134,7 +140,9 @@ struct argp_option options[] =
       0,
       "Output table type: `fits-ascii', `fits-binary'.",
       2,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
 
 
@@ -152,7 +160,9 @@ struct argp_option options[] =
       0,
       "Only print table and column information.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
diff --git a/bin/table/authors-cite.h b/bin/table/authors-cite.h
index a2a4b0f..d3bc2a0 100644
--- a/bin/table/authors-cite.h
+++ b/bin/table/authors-cite.h
@@ -5,7 +5,7 @@ Table is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
+Copyright (C) 2017, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -21,7 +21,7 @@ You should have received a copy of the GNU General Public 
License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
 #ifndef AUTHORS_CITE_H
-#define AUTHORS_CITS_H
+#define AUTHORS_CITE_H
 
 /* When any specific citation is necessary, please add its BibTeX (from ADS
    hopefully) to this variable along with a title decribing what this
diff --git a/bin/table/main.c b/bin/table/main.c
index b5fe161..ec46fb1 100644
--- a/bin/table/main.c
+++ b/bin/table/main.c
@@ -43,7 +43,7 @@ main (int argc, char *argv[])
   time(&p.rawtime);
 
   /* Read the input parameters. */
-  setparams(argc, argv, &p);
+  ui_read_check_inputs_setup(argc, argv, &p);
 
   /* Run MakeProfiles */
   table(&p);
diff --git a/bin/table/ui.c b/bin/table/ui.c
index aff168d..8dfaf32 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -31,7 +31,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/table.h>
 #include <gnuastro/linkedlist.h>
 
-#include <nproc.h> /* from Gnulib, in Gnuastro's source */
 #include <timing.h>
 #include <options.h>
 
@@ -52,27 +51,23 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
-
-/* This function is in charge of reading the option values from the arrays
-   of the `argp_option' structure and put them into each program's own data
-   structure.
-
-   IMPORTANT: DO NOT USE THE SAME POINTERS. When the types are pointers
-   (like stirings or linked lists), do not use the same pointers, allocate
-   and keep a new copy. This is because the printing of options will take
-   place after this sanity check, so users can be sure that the values that
-   are printed and used as configuration files later have no non-sane
-   values. Thus the poitners in `argp_option' will be freed after printing,
-   but the program's pointers must stay to the end.
-
-   After setting all the values, do other forms of sanity checks that
-   involve more than one option.
-*/
+/* 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_check_only_options(struct tableparams *p)
+ui_read_options(struct tableparams *p)
 {
   size_t i;
-  struct gal_linkedlist_stll *namell=NULL, *docll=NULL;
 
   /* Put the program's option values into the structure. */
   for(i=0; !gal_options_is_last(&options[i]); ++i)
@@ -89,7 +84,7 @@ ui_read_check_only_options(struct tableparams *p)
           if(options[i].value)
             p->searchin=gal_table_string_to_searchin(options[i].value);
           else
-            gal_options_add_to_not_given(&options[i], &namell, &docll);
+            gal_options_add_to_not_given(&p->cp, &options[i]);
           break;
 
 
@@ -101,28 +96,9 @@ ui_read_check_only_options(struct tableparams *p)
 
         /* Output */
         case ARGS_OPTION_TABLETYPE_KEY:
-
-          /* If `tabletype' has a value, put it in. */
-          if(options[i].value)
-            {
-              /* Set the value into the structure. */
-              p->tabletype=gal_table_string_to_type(options[i].value);
-
-              /* If the output name was set and is a FITS file, make sure
-                 that the type of the table is not a `txt'. */
-              if( p->cp.output && gal_fits_name_is_fits(p->cp.output)
-                 && ( p->tabletype != GAL_TABLE_TYPE_AFITS
-                       && p->tabletype != GAL_TABLE_TYPE_BFITS ) )
-                error(EXIT_FAILURE, 0, "desired output file `%s' is a FITS "
-                      "file, but `tabletype' is not a FITS table type. "
-                      "Please set it to `fits-ascii', or `fits-binary'",
-                      p->cp.output);
-            }
-
-          /* In Table, `tabletype' is only mandatory when the output is a
-             FITS file, A text table output only has one possible type. */
-          else if( gal_fits_name_is_fits(p->cp.output) )
-            gal_options_add_to_not_given(&options[i], &namell, &docll);
+          p->tabletype = ( options[i].value
+                           ? gal_table_string_to_type(options[i].value)
+                           : GAL_TABLE_TYPE_INVALID );
          break;
 
 
@@ -141,8 +117,26 @@ ui_read_check_only_options(struct tableparams *p)
 
   /* If any of the mandatory options were not given, then print an error
      listing them and abort. */
-  if(namell)
-    gal_options_mandatory_error(namell, docll);
+  gal_options_abort_if_mandatory_missing(&p->cp);
+}
+
+
+
+
+
+/* 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);
+
+  /* Check if the type of the output table is valid. */
+  gal_table_check_fits_type(p->cp.output, p->tabletype);
+
 }
 
 
@@ -291,7 +285,7 @@ ui_preparations(struct tableparams *p)
 /**************************************************************/
 
 void
-setparams(int argc, char *argv[], struct tableparams *p)
+ui_read_check_inputs_setup(int argc, char *argv[], struct tableparams *p)
 {
   struct gal_options_common_params *cp=&p->cp;
 
@@ -303,33 +297,39 @@ setparams(int argc, char *argv[], struct tableparams *p)
   cp->program_bibtex  = PROGRAM_BIBTEX;
   cp->program_authors = PROGRAM_AUTHORS;
   cp->coptions        = gal_commonopts_options;
-  cp->numthreads      = num_processors(NPROC_CURRENT);
+
 
   /* Read the command-line options and arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
-  /* Read the configuration files. */
-  gal_options_read_config_files(cp);
+
+  /* Read the configuration files and set the common values. */
+  gal_options_read_config_set_common(cp);
+
 
   /* Read the options into the program's structure, and check them and
      their relations prior to printing. */
   ui_read_check_only_options(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);
 
+
   /* Check that the options and arguments fit well with each other. Note
      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);
 
+
   /* 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);
diff --git a/bin/table/ui.h b/bin/table/ui.h
index 1b949be..471948d 100644
--- a/bin/table/ui.h
+++ b/bin/table/ui.h
@@ -24,14 +24,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define UI_H
 
 void
-checksetfge(char *optarg, int *fge, char *filename, size_t lineno);
-
-void
-checksetfitstabletype(char *optarg, int *fitstabletype, char *filename,
-                   size_t lineno);
-
-void
-setparams(int argc, char *argv[], struct tableparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct tableparams *p);
 
 void
 freeandreport(struct tableparams *p);
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f613e10..9d32013 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -34,10 +34,14 @@ AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib      \
 
 
 
-# Define the main compiled library file and its Libtool version.
+# Define the main compiled library file, its Libtool version and also link
+# with Gnulib's compiled library for this system. We are doing this so the
+# Gnuastro library functions can also benefit from Gnulib's many great
+# features. This also avoids the need for the programs to link separately
+# with Gnulib, they only need to link with the Gnuastro library.
 lib_LTLIBRARIES = libgnuastro.la
 libgnuastro_la_LDFLAGS = -version-info $(GAL_LT_VERSION)
-
+libgnuastro_la_LIBADD = $(top_builddir)/bootstrapped/lib/libgnu.la
 
 
 
diff --git a/lib/commonopts.h b/lib/commonopts.h
index b529f96..c0a984b 100644
--- a/lib/commonopts.h
+++ b/lib/commonopts.h
@@ -46,7 +46,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Extension name or number of input data.",
       1,                        /* Input. */
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
 #endif
     {
@@ -56,7 +58,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Output file or directory name.",
       2,                        /* Output. */
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "dontdelete",
@@ -65,7 +69,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Don't delete output if it exists.",
       2,                        /* Output. */
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "keepinputdir",
@@ -74,7 +80,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Keep input directory for automatic output.",
       2,                        /* Output. */
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
@@ -87,7 +95,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Only report errors, remain quiet about steps.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "numthreads",
@@ -96,7 +106,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Number of CPU threads to use.",
       -1,
-      NULL, GAL_DATA_TYPE_ULONG
+      NULL,
+      GAL_DATA_TYPE_ULONG,
+      GAL_OPTIONS_RANGE_GT_0
     },
     {
       "minmapsize",
@@ -105,7 +117,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Minimum no. bytes to map arrays to hdd/ssd.",
       -1,
-      NULL, GAL_DATA_TYPE_ULONG
+      NULL,
+      GAL_DATA_TYPE_ULONG,
+      GAL_OPTIONS_RANGE_GE_0
     },
     {
       "log",
@@ -114,7 +128,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "No log file for programs which make one.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
@@ -127,7 +143,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "BibTeX citation for this program.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "printparams",
@@ -136,7 +154,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Print parameter values to be used and abort.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "config",
@@ -145,7 +165,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Read file STR before continuing.",
       -1,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY
     },
     {
       "setdirconf",
@@ -154,7 +176,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Set default values for this directory and abort.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "setusrconf",
@@ -163,7 +187,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Set default values for this user and abort.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "lastconfig",
@@ -172,7 +198,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Do not parse any more configuration files.",
       -1,
-      NULL, GAL_OPTIONS_NO_ARG_TYPE
+      NULL,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
     {
       "onlyversion",
@@ -181,7 +209,9 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Only run if the program version is STR.",
       -1,
-      NULL, GAL_DATA_TYPE_STRING
+      NULL,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_0_OR_1
     },
 
 
diff --git a/lib/data.c b/lib/data.c
index 94e53ea..7572d47 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -1029,87 +1029,87 @@ gal_data_free_ll(gal_data_t *list)
 /*************************************************************
  **************          Blank data            ***************
  *************************************************************/
-void *
-gal_data_alloc_blank(int type)
-{
-  /* Define the pointers. */
-  char            *str;
-  unsigned char     uc = GAL_DATA_BLANK_UCHAR;
-  char               c = GAL_DATA_BLANK_CHAR;
-  unsigned short    us = GAL_DATA_BLANK_USHORT;
-  short              s = GAL_DATA_BLANK_SHORT;
-  unsigned int      ui = GAL_DATA_BLANK_UINT;
-  int                i = GAL_DATA_BLANK_INT;
-  unsigned long     ul = GAL_DATA_BLANK_ULONG;
-  long               l = GAL_DATA_BLANK_LONG;
-  LONGLONG           L = GAL_DATA_BLANK_LONGLONG;
-  float              f = GAL_DATA_BLANK_FLOAT;
-  double             d = GAL_DATA_BLANK_DOUBLE;
-  gsl_complex_float cx;
-  gsl_complex      dcx;
+/* Write the blank value of the type into an already allocate space.
 
-  /* Put the blank value into it. */
+   Note that for strings, pointer should actually be `char **'. */
+void
+gal_data_set_blank(void *pointer, int type)
+{
   switch(type)
     {
     case GAL_DATA_TYPE_STRING:
-      gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &str);
-      return str;
-
-    case GAL_DATA_TYPE_BIT:
-      error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support blank "
-            "values for `GAL_DATA_TYPE_BIT', please get in touch with "
-            "us to see how we can implement it.");
+      gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, pointer);
+      break;
 
     case GAL_DATA_TYPE_UCHAR:
-      return gal_data_alloc_number(type, &uc);
+      *(unsigned char *)pointer  = GAL_DATA_BLANK_UCHAR;
+      break;
 
-      /* CFITSIO says "int for keywords, char for table columns". Here we
-         are only assuming table columns. So in practice this also applies
-         to TSBYTE.*/
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      return gal_data_alloc_number(type, &c);
+    case GAL_DATA_TYPE_CHAR:
+      *(char *)pointer           = GAL_DATA_BLANK_CHAR;
+      break;
 
     case GAL_DATA_TYPE_USHORT:
-      return gal_data_alloc_number(type, &us);
+      *(unsigned short *)pointer = GAL_DATA_BLANK_USHORT;
+      break;
 
     case GAL_DATA_TYPE_SHORT:
-      return gal_data_alloc_number(type, &s);
+      *(short *)pointer          = GAL_DATA_BLANK_SHORT;
+      break;
 
     case GAL_DATA_TYPE_UINT:
-      return gal_data_alloc_number(type, &ui);
+      *(unsigned int *)pointer   = GAL_DATA_BLANK_UINT;
+      break;
 
     case GAL_DATA_TYPE_INT:
-      return gal_data_alloc_number(type, &i);
+      *(int *)pointer            = GAL_DATA_BLANK_INT;
+      break;
 
     case GAL_DATA_TYPE_ULONG:
-      return gal_data_alloc_number(type, &ul);
+      *(unsigned long *)pointer  = GAL_DATA_BLANK_ULONG;
+      break;
 
     case GAL_DATA_TYPE_LONG:
-      return gal_data_alloc_number(type, &l);
+      *(long *)pointer           = GAL_DATA_BLANK_LONG;
+      break;
 
     case GAL_DATA_TYPE_LONGLONG:
-      return gal_data_alloc_number(type, &L);
+      *(LONGLONG *)pointer       = GAL_DATA_BLANK_LONGLONG;
+      break;
 
     case GAL_DATA_TYPE_FLOAT:
-      return gal_data_alloc_number(type, &f);
+      *(float *)pointer          = GAL_DATA_BLANK_FLOAT;
+      break;
 
     case GAL_DATA_TYPE_DOUBLE:
-      return gal_data_alloc_number(type, &d);
-
-    case GAL_DATA_TYPE_COMPLEX:
-      GSL_SET_COMPLEX(&cx, GAL_DATA_BLANK_FLOAT, GAL_DATA_BLANK_FLOAT);
-      return gal_data_alloc_number(type, &cx);
-
-    case GAL_DATA_TYPE_DCOMPLEX:
-      GSL_SET_COMPLEX(&dcx, GAL_DATA_BLANK_DOUBLE, GAL_DATA_BLANK_DOUBLE);
-      return gal_data_alloc_number(type, &dcx);
+      *(double *)pointer         = GAL_DATA_BLANK_DOUBLE;
+      break;
 
     default:
-      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
-            "`gal_data_alloc_blank'", type);
+      error(EXIT_FAILURE, 0, "type code %d not recognized in "
+            "`gal_data_set_blank'", type);
     }
+}
 
-  return NULL;
+
+
+
+
+/* Allocate some space for the given type and put the blank value into
+   it. */
+void *
+gal_data_alloc_blank(int type)
+{
+  void *out;
+
+  /* Allocate the space to keep the blank value. */
+  out=gal_data_malloc_array(type, 1);
+
+  /* Put the blank value in the allcated space. */
+  gal_data_set_blank(out, type);
+
+  /* Return the allocated space. */
+  return out;
 }
 
 
@@ -2134,11 +2134,11 @@ gal_data_string_to_number(char *string)
 
 
 
-/* Read a string as a given data type and return the pointer to it. When
-   `*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.
+/* Read a string as a given data type and put a the pointer to it in
+   *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.
 
    Note that when we are dealing with a string type, `*out' should be
    interpretted as `char **' (one element in an array of pointers to
@@ -2147,7 +2147,11 @@ gal_data_string_to_number(char *string)
    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
    an array, you have to pass the pointer to the `i'th element where you
-   want the value to be stored, for example &(array[i])*/
+   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.
+ */
 int
 gal_data_string_to_type(void **out, char *string, int type)
 {
@@ -2234,7 +2238,7 @@ gal_data_string_to_type(void **out, char *string, int 
type)
     }
 
   /* If reading was unsuccessful, then free the space if it was allocated,
-     then return the status. */
+     then return the status, don't touch the pointer. */
   if(status && allocated)
     {
       free(*out);
diff --git a/lib/fixedstringmacros.h b/lib/fixedstringmacros.h
index d613aad..ed0eb11 100644
--- a/lib/fixedstringmacros.h
+++ b/lib/fixedstringmacros.h
@@ -26,7 +26,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #define GAL_STRINGS_SHORT_COPYRIGHT                                     \
-  "Copyright (C) 2015-2016, Free Software Foundation, Inc."
+  "Copyright (C) 2015-2017, Free Software Foundation, Inc."
 
 
 #define GAL_STRINGS_SHORT_LICENSE                                       \
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 41ab816..4de3729 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -256,6 +256,9 @@ gal_data_free_ll(gal_data_t *list);
 /*************************************************************
  **************          Blank data            ***************
  *************************************************************/
+void
+gal_data_set_blank(void *pointer, int type);
+
 void *
 gal_data_alloc_blank(int type);
 
diff --git a/lib/gnuastro/linkedlist.h b/lib/gnuastro/linkedlist.h
index 00c8894..08a404f 100644
--- a/lib/gnuastro/linkedlist.h
+++ b/lib/gnuastro/linkedlist.h
@@ -200,6 +200,8 @@ gal_linkedlist_reverse_ill(struct gal_linkedlist_ill 
**list);
 void
 gal_linkedlist_print_ill(struct gal_linkedlist_ill *list);
 
+void
+gal_linkedlist_free_ill(struct gal_linkedlist_ill *list);
 
 
 /******************* Ordered size_t: */
diff --git a/lib/gnuastro/table.h b/lib/gnuastro/table.h
index 419e84d..917d564 100644
--- a/lib/gnuastro/table.h
+++ b/lib/gnuastro/table.h
@@ -68,12 +68,17 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
-/* Types of table storage for input or output. */
+/* Types of table storage for input or output, as strings and integers. */
+#define GAL_TABLE_STRING_TYPE_TXT "txt"
+#define GAL_TABLE_STRING_TYPE_AFITS "fits-ascii"
+#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,                 /* For sanity checks. */
 };
 
 
@@ -83,11 +88,16 @@ enum gal_table_types
 /* When the desired column is not a number, should the string match or
    regular expression search be in the name, units or comments of the
    columns? */
+#define GAL_TABLE_STRING_SEARCH_NAME    "name"
+#define GAL_TABLE_STRING_SEARCH_UNIT    "unit"
+#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,                /* For sanity checks.        */
 };
 
 
@@ -108,6 +118,8 @@ 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).  */
 };
 
 
@@ -118,6 +130,9 @@ enum gal_table_diplay_formats
 int
 gal_table_string_to_type(char *string);
 
+void
+gal_table_check_fits_type(char *filename, int tabletype);
+
 int
 gal_table_string_to_searchin(char *string);
 
diff --git a/lib/linkedlist.c b/lib/linkedlist.c
index a278b2a..9ed667f 100644
--- a/lib/linkedlist.c
+++ b/lib/linkedlist.c
@@ -655,6 +655,23 @@ gal_linkedlist_print_ill(struct gal_linkedlist_ill *list)
 
 
 
+void
+gal_linkedlist_free_ill(struct gal_linkedlist_ill *list)
+{
+  struct gal_linkedlist_ill *tmp, *ttmp;
+  tmp=list;
+  while(tmp!=NULL)
+    {
+      ttmp=tmp->next;
+      free(tmp);
+      tmp=ttmp;
+    }
+}
+
+
+
+
+
 
 
 
diff --git a/lib/options.c b/lib/options.c
index afbd4b3..438c6d7 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -33,6 +33,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/arithmetic.h>
 #include <gnuastro/linkedlist.h>
 
+#include <nproc.h>         /* from Gnulib, in Gnuastro's source */
 #include <options.h>
 #include <checkset.h>
 
@@ -47,6 +48,16 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /**********************************************************************/
 /************             Option utilities              ***************/
 /**********************************************************************/
+void
+gal_options_initialize_numthreads(struct gal_options_common_params *cp)
+{
+  cp->numthreads=num_processors(NPROC_CURRENT);
+}
+
+
+
+
+
 int
 gal_options_is_last(struct argp_option *option)
 {
@@ -68,12 +79,11 @@ gal_options_is_category_title(struct argp_option *option)
 
 
 void
-gal_options_add_to_not_given(struct argp_option *option,
-                             struct gal_linkedlist_stll **namell,
-                             struct gal_linkedlist_stll **docll)
+gal_options_add_to_not_given(struct gal_options_common_params *cp,
+                             struct argp_option *option)
 {
-  gal_linkedlist_add_to_stll(docll, (char *)option->doc, 0);
-  gal_linkedlist_add_to_stll(namell, (char *)option->name, 0);
+  gal_linkedlist_add_to_stll(&cp->novalue_doc, (char *)option->doc, 0);
+  gal_linkedlist_add_to_stll(&cp->novalue_name, (char *)option->name, 0);
 }
 
 
@@ -81,15 +91,18 @@ gal_options_add_to_not_given(struct argp_option *option,
 
 
 void
-gal_options_mandatory_error(struct gal_linkedlist_stll *namell,
-                            struct gal_linkedlist_stll *docll)
+gal_options_abort_if_mandatory_missing(struct gal_options_common_params *cp)
 {
   int namewidth=0;
-  char info[2000], *name, *doc;
+  char info[5000], *name, *doc;
   struct gal_linkedlist_stll *tmp;
 
+  /* If there is no mandatory options, then just return. */
+  if(cp->novalue_name==NULL)
+    return;
+
   /* Get the maximum width of the given names: */
-  for(tmp=namell; tmp!=NULL; tmp=tmp->next)
+  for(tmp=cp->novalue_name; tmp!=NULL; tmp=tmp->next)
     if( strlen(tmp->v) > namewidth ) namewidth=strlen(tmp->v);
 
   /* Print the introductory information. */
@@ -98,10 +111,10 @@ gal_options_mandatory_error(struct gal_linkedlist_stll 
*namell,
           "description)\n\n");
 
   /* Print the list of options along with their description. */
-  while(namell!=NULL)
+  while(cp->novalue_name!=NULL)
     {
-      gal_linkedlist_pop_from_stll(&namell, &name);
-      gal_linkedlist_pop_from_stll(&docll, &doc);
+      gal_linkedlist_pop_from_stll(&cp->novalue_doc, &doc);
+      gal_linkedlist_pop_from_stll(&cp->novalue_name, &name);
       sprintf(info+strlen(info), "  %-*s (%s\b)\n", namewidth+4, name, doc);
     }
   sprintf(info+strlen(info), "\n");
@@ -306,6 +319,191 @@ 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. */
+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;
+  int mcflag = ( GAL_ARITHMETIC_NUMOK
+                 | GAL_ARITHMETIC_FREE
+                 | GAL_ARITHMETIC_INPLACE );
+
+  /* Currently, this function is only for numeric types, so if the value is
+     string type, or its `range' field is `GAL_OPTIONS_RANGE_ANY', then
+     just return without any checks. */
+  if( option->type==GAL_DATA_TYPE_STRING
+      || option->type==GAL_DATA_TYPE_STRLL
+      || option->range==GAL_OPTIONS_RANGE_ANY )
+    return;
+
+  /* Put the option value into a data structure. */
+  value=gal_data_alloc(option->value, option->type, 1, &dsize, NULL,
+                       0, -1, NULL, NULL, NULL);
+
+  /* Set the operator(s) and operands: */
+  switch(option->range)
+    {
+
+    case GAL_OPTIONS_RANGE_GT_0:
+      message="greater than zero";
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      *(unsigned char *)(ref1->array)=0;
+      operator1=GAL_ARITHMETIC_OP_GT;
+      ref2=NULL;
+      break;
+
+
+    case GAL_OPTIONS_RANGE_GE_0:
+      message="greater or equal to zero";
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      *(unsigned char *)(ref1->array)=0;
+      operator1=GAL_ARITHMETIC_OP_GE;
+      ref2=NULL;
+      break;
+
+
+    case GAL_OPTIONS_RANGE_0_OR_1:
+      message="either 0 or 1";
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      *(unsigned char *)(ref1->array)=0;
+      *(unsigned char *)(ref2->array)=1;
+
+      operator1=GAL_ARITHMETIC_OP_EQ;
+      operator2=GAL_ARITHMETIC_OP_EQ;
+      multicheckop=GAL_ARITHMETIC_OP_OR;
+      break;
+
+
+    case GAL_OPTIONS_RANGE_GE_0_LE_1:
+      message="between zero and one";
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      *(unsigned char *)(ref1->array)=0;
+      *(unsigned char *)(ref2->array)=1;
+
+      operator1=GAL_ARITHMETIC_OP_GE;
+      operator2=GAL_ARITHMETIC_OP_LE;
+      multicheckop=GAL_ARITHMETIC_OP_AND;
+      break;
+
+
+    case GAL_OPTIONS_RANGE_GT_0_ODD:
+      message="greater than zero and odd";
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      *(unsigned char *)(ref1->array)=0;
+      *(unsigned char *)(ref2->array)=2;
+
+      operator1=GAL_ARITHMETIC_OP_GT;
+      operator2=GAL_ARITHMETIC_OP_MODULO;
+      multicheckop=GAL_ARITHMETIC_OP_AND;
+      break;
+
+    default:
+      error(EXIT_FAILURE, 0, "range code %d not recognized in "
+            "`gal_options_check_set'", option->range);
+    }
+
+
+  /* Use the arithmetic library to check for the condition. We don't want
+     to free the value or change its value, so when dealing with the value
+     directly, we won't use the `GAL_ARITHMETIC_FREE', or
+     `GAL_ARITHMETIC_INPLACE' flags. But we will do this when there are
+     multiple checks so from the two check data structures, we only have
+     one remaining. */
+  check1=gal_arithmetic(operator1, GAL_ARITHMETIC_NUMOK, value, ref1);
+  if(ref2)
+    {
+      check2=gal_arithmetic(operator2, GAL_ARITHMETIC_NUMOK, value, ref2);
+      check1=gal_arithmetic(multicheckop, mcflag, check1, check2);
+    }
+
+
+  /* If the final check is not successful, then print an error. */
+  if( *(unsigned char *)(check1->array)==0 )
+    error_at_line(EXIT_FAILURE, 0, filename, lineno,
+                  "value to option `%s' must be %s, but the given value "
+                  "is `%s'. Recall that `%s' is \"%s\"", option->name,
+                  message, arg, option->name, option->doc);
+
+
+  /* Clean up and finish. Note that we used the actual value pointer in the
+     data structure, so first we need to set it to NULL, so `gal_data_free'
+     doesn't free it, we need it for later (for example to print the option
+     values). */
+  value->array=NULL;
+  gal_data_free(value);
+  gal_data_free(check1);
+}
+
+
+
+
+
+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);
+    }
+  else
+    {
+      /* Read in 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). */
+        error_at_line(EXIT_FAILURE, 0, filename, lineno,
+                      "`%s' (value to option `%s') couldn't be read into "
+                      "the proper numerical type. Common causes for this "
+                      "error are:\n"
+                      "  - It contains non-numerical characters\n"
+                      "  - It is negative, but the expected value is "
+                      "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);
+    }
+}
+
+
+
+
+
 
 
 
@@ -330,7 +528,6 @@ gal_options_set_from_key(int key, char *arg, struct 
argp_option *options,
                          struct gal_options_common_params *cp)
 {
   size_t i;
-  char **strarr=NULL;
 
   /* Go through all the options and find the one that should keep this
      value, then put its value into the appropriate key. Note that the
@@ -344,12 +541,13 @@ gal_options_set_from_key(int key, char *arg, struct 
argp_option *options,
           /* For options that need immediate attention. */
           options_immediate(key, arg, cp);
 
-          /* When options are read from keys, they are read from the
-             command-line. On the commandline, the last invokation of the
-             option is important. Especially in contexts like scripts, this
-             is important because you can change a given command-line
-             option (that is not a linked list) by calling it a second
-             time, instead of going back and changing the first value.
+          /* When options are read from keys (by this function), they are
+             read from the command-line. On the commandline, the last
+             invokation of the option is important. Especially in contexts
+             like scripts, this is important because you can change a given
+             command-line option (that is not a linked list) by calling it
+             a second time, instead of going back and changing the first
+             value.
 
              As a result, only when searching for options on the
              command-line, a second value to the same option will replace
@@ -361,37 +559,11 @@ gal_options_set_from_key(int key, char *arg, struct 
argp_option *options,
             }
 
           /* We have two types of options: those which need an argument and
-             those that don't. When they need an argument the `value'
-             pointer will be NULL. In such cases, the option must be in
-             integer type, so just set it to 1. When an argument is given,
-             convert the given value to the appropriate type and put it in
-             the `value' element of options[i]. */
+             those that don't. For those that don't `arg' will be
+             NULL. When it accepts an argument then read itinto the option
+             structure and do a sanity check.*/
           if(arg)
-            {
-              /* 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(options[i].type==GAL_DATA_TYPE_STRING)
-                {
-                  gal_data_string_to_type((void **)(&strarr), arg,
-                                                 options[i].type);
-                  options[i].value=strarr[0];
-                  free(strarr);
-                }
-              else
-                {
-                  if( gal_data_string_to_type(&options[i].value, arg,
-                                              options[i].type) )
-                    error(EXIT_FAILURE, 0, "`%s' (value to option `%s') "
-                          "couldn't be read as a number", arg,
-                          options[i].name);
-
-                }
-            }
+            gal_options_read_check(&options[i], arg, NULL, 0);
           else
             {
               /* Make sure the option has the type set for options with no
@@ -560,7 +732,6 @@ options_set_from_name(char *name, char *arg,  struct 
argp_option *options,
                       size_t lineno)
 {
   size_t i;
-  char **strarr=NULL;
 
   /* Go through all the options and find the one that should keep this
      value, then put its value into the appropriate key. Note that the
@@ -579,38 +750,8 @@ options_set_from_name(char *name, char *arg,  struct 
argp_option *options,
           /* For options that need immediate attention. */
           options_immediate(options[i].key, arg, cp);
 
-          /* 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(options[i].type==GAL_DATA_TYPE_STRING)
-            {
-              gal_data_string_to_type((void **)(&strarr), arg,
-                                      options[i].type);
-              options[i].value=strarr[0];
-              free(strarr);
-            }
-          else
-            {
-              if( gal_data_string_to_type(&options[i].value, arg,
-                                          options[i].type) )
-                error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                              "`%s' (value to option `%s') couldn't be "
-                              "read as a number", arg, options[i].name);
-            }
-
-
-          /* If this is an on/off option (with no argument), then check if
-             the given value is 0 or 1. */
-          if( options[i].type==GAL_OPTIONS_NO_ARG_TYPE
-              && *(unsigned char *)(options[i].value) > 1 )
-            error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                          "`%s' is an on/off option, so its value can only "
-                          "be 1 (for `on'), or 0 (for `off'), it was given "
-                          "a value of `%s'", options[i].name, arg);
-
+          /* Read the value into the option and do a sanity check. */
+          gal_options_read_check(&options[i], arg, filename, lineno);
 
           /* We have found and set the value given to this option, so just
              return success (an error_t of 0 means success). */
@@ -816,9 +957,30 @@ options_reverse_lists(struct argp_option *options)
 
 
 
+/* 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);
+}
+
+
+
+
 
+/* Read all configuration files and set common options */
 void
-gal_options_read_config_files(struct gal_options_common_params *cp)
+gal_options_read_config_set_common(struct gal_options_common_params *cp)
 {
   size_t i;
 
@@ -867,6 +1029,8 @@ gal_options_read_config_files(struct 
gal_options_common_params *cp)
         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:
@@ -896,188 +1060,6 @@ gal_options_read_config_files(struct 
gal_options_common_params *cp)
 
 
 /**********************************************************************/
-/************                Sanity check               ***************/
-/**********************************************************************/
-/* All the command-line and configuration file options have been read. But
-   for the higher level steps of your program, you can't go over the
-   options array every time to find the recorded value (as a `void *'
-   pointer). Also, if the option was given, you want to make sure its value
-   is in the correct/acceptable range you expect for this option.
-
-   This function takes the argp_option structure you are checking
-   (`option') and a pointer to the (already allocated) space you want to
-   put its value in (`out'), along with the `condition' that the value to
-   this option must satisfy.
-
-   Outputs:
-
-    - If the option has a value and the condition is met, the value is put
-      into the `out' pointer and this function will return 1.
-
-    - If the option has a value and the condition isn't met, an error
-      message will be printed and the program will abort.
-
-    - If the option wasn't given a value, this function will return 0, and
-      put a blank value (depending on the type) in the value pointed by
-      `out'.  */
-int
-gal_options_check_set(struct argp_option *option, void *out, int condition)
-{
-  size_t dsize=1;
-  int operator1, operator2;
-  gal_data_t *value, *ref1, *ref2, *check1, *check2;
-  int arithflags = ( GAL_ARITHMETIC_INPLACE
-                     | GAL_ARITHMETIC_FREE
-                     | GAL_ARITHMETIC_NUMOK );
-
-
-  /* This function should only be used for numerical types. */
-  if(option->type==GAL_DATA_TYPE_STRING || option->type==GAL_DATA_TYPE_STRLL)
-    error(EXIT_FAILURE, 0, "A bug! `gal_options_check_set' should only be "
-          "used for numerical types. However it has been used for the "
-          "`%s' option, which has a type of `%s'", option->name,
-          gal_data_type_as_string(option->type, 1) );
-
-
-  /* If the option is given a value, then check it and return 1 if it is in
-     range. If its not in range, abort with an error.  */
-  if(option->value)
-    {
-      /* Put the option value into a data structure. */
-      value=gal_data_alloc(option->value, option->type, 1, &dsize, NULL,
-                           0, -1, NULL, NULL, NULL);
-
-      /* Set the operator(s): */
-      switch(condition)
-        {
-
-        case GAL_OPTIONS_RANGE_GT_0:
-          ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
-                              0, -1, NULL, NULL, NULL);
-          *(unsigned char *)(ref1->array)=0;
-          operator1=GAL_ARITHMETIC_OP_GT;
-          ref2=NULL;
-          break;
-
-
-        case GAL_OPTIONS_RANGE_GE_0:
-          ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
-                              0, -1, NULL, NULL, NULL);
-          *(unsigned char *)(ref1->array)=0;
-          operator1=GAL_ARITHMETIC_OP_GE;
-          ref2=NULL;
-          break;
-
-
-        case GAL_OPTIONS_RANGE_GE_0_LE_1:
-          ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
-                              0, -1, NULL, NULL, NULL);
-          ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
-                              0, -1, NULL, NULL, NULL);
-          *(unsigned char *)(ref1->array)=0;
-          *(unsigned char *)(ref2->array)=1;
-          operator1=GAL_ARITHMETIC_OP_GE;
-          operator1=GAL_ARITHMETIC_OP_LE;
-          break;
-
-        default:
-          error(EXIT_FAILURE, 0, "condition code %d not recognized in "
-                "`gal_options_check_set'", condition);
-        }
-
-      /* Use the arithmetic library to check for the condition. */
-      check1=gal_arithmetic(operator1, arithflags, value, ref1);
-
-      /* Clean up and return. Note that we used the actual value pointer in
-         the data structure, so first we need to set it to NULL, so
-         `gal_data_free' doesn't free it, we need it for later (for example
-         to print the option values). */
-      value->array=NULL;
-      gal_data_free(value);
-      return 1;
-    }
-
-  /* The option didn't have a value, set the output value as blank and
-     return 0. */
-  else
-    {
-      /* Set the output value. */
-      switch(option->type)
-        {
-        case GAL_DATA_TYPE_UCHAR:
-          *(unsigned char *)out = GAL_DATA_BLANK_UCHAR;
-          break;
-
-        case GAL_DATA_TYPE_CHAR:
-          *(char *)out = GAL_DATA_BLANK_CHAR;
-          break;
-
-        case GAL_DATA_TYPE_USHORT:
-          *(unsigned short *)out = GAL_DATA_BLANK_USHORT;
-          break;
-
-        case GAL_DATA_TYPE_SHORT:
-          *(short *)out = GAL_DATA_BLANK_SHORT;
-          break;
-
-        case GAL_DATA_TYPE_UINT:
-          *(unsigned int *)out = GAL_DATA_BLANK_UINT;
-          break;
-
-        case GAL_DATA_TYPE_INT:
-          *(int *)out = GAL_DATA_BLANK_INT;
-          break;
-
-        case GAL_DATA_TYPE_ULONG:
-          *(unsigned long *)out = GAL_DATA_BLANK_ULONG;
-          break;
-
-        case GAL_DATA_TYPE_LONG:
-          *(long *)out = GAL_DATA_BLANK_LONG;
-          break;
-
-        case GAL_DATA_TYPE_LONGLONG:
-          *(LONGLONG *)out = GAL_DATA_BLANK_LONGLONG;
-          break;
-
-        case GAL_DATA_TYPE_FLOAT:
-          *(float *)out = GAL_DATA_BLANK_FLOAT;
-          break;
-
-        case GAL_DATA_TYPE_DOUBLE:
-          *(double *)out = GAL_DATA_BLANK_DOUBLE;
-          break;
-
-        default:
-          error(EXIT_FAILURE, 0, "type code %d not recognized in "
-                "`gal_options_check_set'", option->type);
-        }
-
-      /* Return: */
-      return 0;
-    }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**********************************************************************/
 /************              Printing/Writing             ***************/
 /**********************************************************************/
 /* We don't want to print the values of configuration specific options and
diff --git a/lib/options.h b/lib/options.h
index d38d47b..530d243 100644
--- a/lib/options.h
+++ b/lib/options.h
@@ -51,7 +51,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    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 options_option_keys
+enum options_common_keys
 {
   /* With short-option version */
   GAL_OPTIONS_HDU_KEY          = 'h',
@@ -78,9 +78,13 @@ enum options_option_keys
 enum gal_options_check_values
 {
   GAL_OPTIONS_RANGE_ANY,
+
   GAL_OPTIONS_RANGE_GT_0,
   GAL_OPTIONS_RANGE_GE_0,
+  GAL_OPTIONS_RANGE_0_OR_1,
   GAL_OPTIONS_RANGE_GE_0_LE_1,
+
+  GAL_OPTIONS_RANGE_GT_0_ODD,
 };
 
 
@@ -107,6 +111,9 @@ struct gal_options_common_params
   char        *program_authors; /* List of the program authors.          */
   struct argp_option *coptions; /* Common options to all programs.       */
   struct argp_option *poptions; /* Program specific options.             */
+  struct gal_linkedlist_ill   *mand_common; /* Common mandatory options. */
+  struct gal_linkedlist_stll  *novalue_doc; /* Mandatory opts, no value  */
+  struct gal_linkedlist_stll *novalue_name; /* Mandatory opts, no value  */
 };
 
 
@@ -116,6 +123,8 @@ struct gal_options_common_params
 /**********************************************************************/
 /************              Option utilities             ***************/
 /**********************************************************************/
+void
+gal_options_initialize_numthreads(struct gal_options_common_params *cp);
 
 int
 gal_options_is_last(struct argp_option *option);
@@ -124,13 +133,11 @@ int
 gal_options_is_category_title(struct argp_option *option);
 
 void
-gal_options_add_to_not_given(struct argp_option *option,
-                             struct gal_linkedlist_stll **namell,
-                             struct gal_linkedlist_stll **docll);
+gal_options_add_to_not_given(struct gal_options_common_params *cp,
+                             struct argp_option *option);
 
 void
-gal_options_mandatory_error(struct gal_linkedlist_stll *namell,
-                            struct gal_linkedlist_stll *docll);
+gal_options_abort_if_mandatory_missing(struct gal_options_common_params *cp);
 
 void
 gal_options_free(struct argp_option *options);
@@ -151,19 +158,11 @@ gal_options_common_argp_parse(int key, char *arg, struct 
argp_state *state);
 
 
 /**********************************************************************/
-/************              Printing/Writing             ***************/
-/**********************************************************************/
-
-int
-gal_options_check_set(struct argp_option *option, void *out, int condition);
-
-
-
-/**********************************************************************/
 /************            Configuration files            ***************/
 /**********************************************************************/
 void
-gal_options_read_config_files(struct gal_options_common_params *cp);
+gal_options_read_config_set_common(struct gal_options_common_params *cp);
+
 
 void
 gal_options_print_state(struct gal_options_common_params *cp);
diff --git a/lib/table.c b/lib/table.c
index e39b244..200d819 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -49,19 +49,20 @@ gal_table_string_to_type(char *string)
 {
   if(string)
     {
-      if( !strcmp(string, "txt") )
+      if( !strcmp(string, GAL_TABLE_STRING_TYPE_TXT) )
         return GAL_TABLE_TYPE_TXT;
 
-      else if( !strcmp(string, "fits-ascii") )
+      else if( !strcmp(string, GAL_TABLE_STRING_TYPE_AFITS) )
         return GAL_TABLE_TYPE_AFITS;
 
-      else if( !strcmp(string, "fits-binary") )
+      else if( !strcmp(string, GAL_TABLE_STRING_TYPE_BFITS) )
         return GAL_TABLE_TYPE_BFITS;
 
       else
         error(EXIT_FAILURE, 0, "`%s' couldn't be interpretted as a valid "
-              "table type. The known types are `txt', `fits-ascii', and "
-              "`fits-binary'", string);
+              "table type. The known types are `%s', `%s', and `%s'", string,
+              GAL_TABLE_STRING_TYPE_TXT, GAL_TABLE_STRING_TYPE_AFITS,
+              GAL_TABLE_STRING_TYPE_BFITS);
     }
 
   /* If string was not NULL, this function won't reach here. */
@@ -72,6 +73,39 @@ gal_table_string_to_type(char *string)
 
 
 
+/* For programs that output tables, the `--tabletype' option will be used
+   to specify what format the output table should be in. When the output
+   file is a FITS file, there are multiple types, so to simplify the coding
+   in each program, this function will do a sanity check on the value given
+   to the `--tabletype' parameter. */
+void
+gal_table_check_fits_type(char *filename, int tabletype)
+{
+  if( filename && gal_fits_name_is_fits(filename) )
+    {
+      /* When `--tabletype' was not given. */
+      if(tabletype==GAL_TABLE_TYPE_INVALID)
+        error(EXIT_FAILURE, 0, "`%s' (output file) is a FITS file but the "
+              "desired type of the FITS table has not been specified with "
+              "the `--tabletype' option. For FITS tables, this option can "
+              "take two values: `%s', or `%s'", filename,
+              GAL_TABLE_STRING_TYPE_AFITS, GAL_TABLE_STRING_TYPE_BFITS);
+
+      /* When `--tabletype' didn't have the correct value. */
+      if( tabletype != GAL_TABLE_TYPE_AFITS
+          && tabletype != GAL_TABLE_TYPE_BFITS )
+        error(EXIT_FAILURE, 0, "`%s' (output file) is a FITS file but "
+              "is not a recognized FITS table type. For FITS tables, "
+              "`--tabletype' can take two values: `%s', or `%s'",
+              filename, GAL_TABLE_STRING_TYPE_AFITS,
+              GAL_TABLE_STRING_TYPE_BFITS);
+    }
+}
+
+
+
+
+
 /* In programs, the `searchin' variable is much more easier to type in as a
    description than an integer (which is what `gal_table_read_cols'
    needs). This function will check the string value and give the
@@ -79,24 +113,25 @@ gal_table_string_to_type(char *string)
 int
 gal_table_string_to_searchin(char *string)
 {
-  if(strcmp(string, "name")==0)
+  if(strcmp(string, GAL_TABLE_STRING_SEARCH_NAME)==0)
     return GAL_TABLE_SEARCH_NAME;
 
-  else if(strcmp(string, "unit")==0)
+  else if(strcmp(string, GAL_TABLE_STRING_SEARCH_UNIT)==0)
     return GAL_TABLE_SEARCH_UNIT;
 
-  else if(strcmp(string, "comment")==0)
+  else if(strcmp(string, GAL_TABLE_STRING_SEARCH_COMMENT)==0)
     return GAL_TABLE_SEARCH_COMMENT;
 
   else
     error(EXIT_FAILURE, 0, "`--searchin' only recognizes the values "
-          "`name', `unit', and `comment', you have asked for `%s'",
-          string);
+          "`%s', `%s', and `%s', you have asked for `%s'",
+          GAL_TABLE_STRING_SEARCH_NAME, GAL_TABLE_STRING_SEARCH_UNIT,
+          GAL_TABLE_STRING_SEARCH_COMMENT, string);
 
   /* Report an error control reaches here. */
   error(EXIT_FAILURE, 0, "A bug! please contact us at %s so we can address "
         "the problem. For some reason control has reached the end of "
-        "`gal_table_searchin_from_str'", PACKAGE_BUGREPORT);
+        "`gal_table_string_to_searchin'", PACKAGE_BUGREPORT);
   return -1;
 }
 



reply via email to

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