gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 5eb817a 052/125: Option values stored in argp_


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 5eb817a 052/125: Option values stored in argp_option
Date: Sun, 23 Apr 2017 22:36:35 -0400 (EDT)

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

    Option values stored in argp_option
    
    This commit is part of work on task #14300 ("Option management using new
    root data structure.", as in the previous commit), the option values are
    now read into the proper `argp_option' structure with the proper type. To
    do this several major changes were necessary:
    
     - The `/' infront of `USERCONFIG_DIR' was removed in `configure.ac' so it
       is added manually during the program.
    
     - In `data.c' the type information functions were moved to the start of
       the file to match the same order in `data.h' (which is more natural).
    
     - The new function `gal_data_string_to_type' was added to read a given
       string into a given type. This is used in option parsing as well as
       `gal_table_read_blank'. So the latter was also modified to allow this
       change.
    
     - The new function `gal_data_is_linked_list' was also added to allow easy
       checking if the type of the data structure is linked list or not. For
       now there is only one linked list type, but soon it will expand and this
       will be more meaningfull.
    
     - The two old `commonargs.h' and `commonparams.h' were removed. The common
       parameters structure is now placed with the other option specific
       definitions in `options.h' and `commonargs.h' is now effectively moved
       to the `commonopts.h' header. The commonopts header must be included by
       only one `.c' file in each program (its `ui.c'), since it includes the
       definition of the common options array. An `extern' version of it is
       also declared in `options.h' so everyone can use it.
    
     - The old `configfiles.[ch]' files are now also removed since they are
       being replaced by the `options.[ch]' files.
    
     - A fixed `GAL_OPTIONS_NO_ARG_TYPE' was defined to allow easy/un-buggy
       definition of options that don't accept any values.
    
     - Thanks to the new elements in `argp_option', the switch structure to
       check for key values is no longer necessary in the `parse_opt' (in
       `args.h') function of each program and the function that would go over
       the common options. A single `gal_options_set_from_key' is now in charge
       of setting the options values in the appropriate type.
    
     - The old `SPACK*' macros are now called `PROG*'. They are a remnant of
       the time each program was actually called a `sub-package'. But now we
       call them programs and also have libraries.
    
     - The old option parsing and checking functions have been removed in
       `ui.c'.
---
 bin/table/args.h        | 106 +++-------
 bin/table/main.h        |  12 +-
 bin/table/ui.c          | 219 +-------------------
 configure.ac            |   2 +-
 doc/Makefile.am         |   2 +-
 lib/Makefile.am         |  13 +-
 lib/commonargs.h        | 327 ------------------------------
 lib/commonopts.h        | 193 ++++++++++++++++++
 lib/commonparams.h      |  66 ------
 lib/configfiles.c       | 237 ----------------------
 lib/configfiles.h       | 308 ----------------------------
 lib/data.c              | 527 +++++++++++++++++++++++++++++-------------------
 lib/fixedstringmacros.h |  15 +-
 lib/gnuastro/data.h     |   6 +-
 lib/options.c           | 244 ++++++++++++++++++++++
 lib/options.h           | 111 ++++++++++
 lib/table.c             |  88 ++------
 17 files changed, 946 insertions(+), 1530 deletions(-)

diff --git a/bin/table/args.h b/bin/table/args.h
index c2e1587..3a87e7a 100644
--- a/bin/table/args.h
+++ b/bin/table/args.h
@@ -23,31 +23,20 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef ARGS_H
 #define ARGS_H
 
-#include <argp.h>
 
-#include <gnuastro/linkedlist.h>
 
-#include <commonargs.h>
-#include <fixedstringmacros.h>
 
 
-
-
-
-
-
-
-
-
-/**************************************************************/
-/**************        argp.h definitions       ***************/
-/**************************************************************/
+/* Include the common options to all Gnuastro programs. If the program has
+   its own HDU parsing procedure, then define the `NOT_COMMON_HDU_PARSER'
+   macro before including the `commonopts.h' header. */
+#include <commonopts.h>
 
 
 
 
 /* Definition parameters for the argp: */
-const char *argp_program_version=SPACK_STRING"\n"GAL_STRINGS_COPYRIGHT
+const char *argp_program_version=PROG_STRING"\n"GAL_STRINGS_COPYRIGHT
   "\n\nWritten by Mohammad Akhlaghi";
 const char *argp_program_bug_address=PACKAGE_BUGREPORT;
 static char args_doc[] = "ASTRdata";
@@ -59,13 +48,14 @@ static char args_doc[] = "ASTRdata";
 const char doc[] =
   /* Before the list of options: */
   GAL_STRINGS_TOP_HELP_INFO
-  SPACK_NAME" can be used to view the information, select columns, or convert "
-  "tables. The inputs and outputs can be plain text (with whitespace or comma "
-  "as delimiters), FITS ascii, or FITS binary tables. The output columns can "
-  "either be selected by number (counting from 1), name or using regular "
-  "expressions. For regular expressions, enclose the value to the `--column' "
-  "(`-c') option in slashes (`\\', as in `-c\\^mag\\'). To print the selected "
-  "columns on the command-line, don't specify an output file.\n"
+  PROG_NAME" can be used to view the information, select columns, or "
+  "convert tables. The inputs and outputs can be plain text (with "
+  "whitespace or comma as delimiters), FITS ascii, or FITS binary tables. "
+  "The output columns can either be selected by number (counting from 1), "
+  "name or using regular expressions. For regular expressions, enclose the "
+  "value to the `--column' (`-c') option in slashes (`\\', as in "
+  "`-c\\^mag\\'). To print the selected columns on the command-line, don't "
+  "specify an output file.\n"
   GAL_STRINGS_MORE_HELP_INFO
   /* After the list of options: */
   "\v"
@@ -117,7 +107,7 @@ struct argp_option options[] =
       0,
       "Ignore case when matching column information.",
       1,
-      NULL, GAL_DATA_TYPE_INT
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
     },
 
 
@@ -151,9 +141,9 @@ struct argp_option options[] =
       'i',
       0,
       0,
-      "Only print table and columns information.",
+      "Only print table and column information.",
       -1,
-      NULL, GAL_DATA_TYPE_INT
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
     },
 
 
@@ -165,17 +155,11 @@ struct argp_option options[] =
 
 
 /* Parse a single option: */
-static error_t
+error_t
 parse_opt(int key, char *arg, struct argp_state *state)
 {
-  /* Save the arguments structure: */
-  char *tstring;
   struct tableparams *p = state->input;
 
-  /* Set the pointer to the common parameters for all programs
-     here: */
-  state->child_inputs[0]=&p->cp;
-
   /* In case the user incorrectly uses the equal sign (for example
      with a short format or with space in the long format, then `arg`
      start with (if the short version was called) or be (if the long
@@ -188,41 +172,10 @@ parse_opt(int key, char *arg, struct argp_state *state)
                "there should be no space between the option, equal sign "
                "and value");
 
+  /* Set the key to this option. */
   switch(key)
     {
 
-
-    /* Input: */
-    case 'c':
-      gal_checkset_allocate_copy(arg, &tstring);
-      gal_linkedlist_add_to_stll(&p->columns, tstring);
-      break;
-
-    case 's':
-      gal_checkset_allocate_copy(arg, &p->up.searchin);
-      p->up.searchinset=1;
-      break;
-
-    case 'I':
-      p->ignorecase=1;
-      p->up.ignorecaseset=1;
-      break;
-
-
-    /* Output: */
-    case 't':
-      gal_checkset_allocate_copy(arg, &p->up.tabletype);
-      p->up.tabletypeset=1;
-      break;
-
-
-    /* Operating modes: */
-    case 'i':
-      p->information=1;
-      p->up.informationset=1;
-      break;
-
-
     /* Read the non-option tokens (arguments): */
     case ARGP_KEY_ARG:
       if(p->up.filename)
@@ -241,32 +194,27 @@ parse_opt(int key, char *arg, struct argp_state *state)
       break;
 
 
-
-
-
+    /* This is an option, set its value. */
     default:
-      return ARGP_ERR_UNKNOWN;
+      return gal_options_set_from_key(key, arg, options);
     }
+
   return 0;
 }
 
 
 
+/* Define the child argp structure. */
+static struct argp gal_options_common_child = {gal_commonopts_options,
+                                               gal_options_common_argp_parse,
+                                               NULL, NULL, NULL, NULL, NULL};
 
-
-/* Specify the children parsers: */
-struct argp_child children[]=
+static struct argp_child children[]=
   {
-    {&commonargp, 0, NULL, 0},
+    {&gal_options_common_child, 0, NULL, 0},
     {0, 0, 0, 0}
   };
 
-
-
-
-
-/* Basic structure defining the whole argument reading process. */
 static struct argp thisargp = {options, parse_opt, args_doc,
                                doc, children, NULL, NULL};
-
 #endif
diff --git a/bin/table/main.h b/bin/table/main.h
index 4866551..bb4e25a 100644
--- a/bin/table/main.h
+++ b/bin/table/main.h
@@ -23,14 +23,14 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef MAIN_H
 #define MAIN_H
 
-#include <gnuastro/fits.h>
+#include <gnuastro/data.h>
 
-#include <commonparams.h>
+#include <options.h>
 
 /* Progarm name macros: */
-#define SPACK           "asttable" /* Subpackage executable name. */
-#define SPACK_NAME      "Table"    /* Subpackage full name.       */
-#define SPACK_STRING    SPACK_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
+#define PROG_EXEC       "asttable" /* Program executable name. */
+#define PROG_NAME       "Table"    /* Program full name.       */
+#define PROG_STRING     PROG_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
 
 
 
@@ -60,7 +60,7 @@ struct tableparams
 {
   /* Other structures: */
   struct uiparams          up;  /* User interface parameters.           */
-  struct gal_commonparams  cp;  /* Common parameters.                   */
+  struct gal_options_common_params cp; /* Common parameters.            */
 
   /* Input */
   struct gal_linkedlist_stll *columns; /* List of given columns.        */
diff --git a/bin/table/ui.c b/bin/table/ui.c
index 8168572..f9a5000 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -22,6 +22,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 **********************************************************************/
 #include <config.h>
 
+#include <argp.h>
 #include <math.h>
 #include <stdio.h>
 #include <errno.h>
@@ -33,13 +34,12 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <gnuastro/fits.h>
 #include <gnuastro/table.h>
-#include <gnuastro/txtarray.h>
+#include <gnuastro/linkedlist.h>
 
 #include <nproc.h>               /* From Gnulib.                   */
 #include <timing.h>              /* Includes time.h and sys/time.h */
 #include <checkset.h>
-#include <commonargs.h>
-#include <configfiles.h>
+#include <fixedstringmacros.h>
 
 #include "main.h"
 
@@ -49,7 +49,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 /* Set the file names of the places where the default parameters are
    put. */
-#define CONFIG_FILE SPACK CONF_POSTFIX
 #define SYSCONFIG_FILE SYSCONFIG_DIR "/" CONFIG_FILE
 #define USERCONFIG_FILEEND USERCONFIG_DIR CONFIG_FILE
 #define CURDIRCONFIG_FILE CURDIRCONFIG_DIR CONFIG_FILE
@@ -63,197 +62,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-/**************************************************************/
-/**************       Options and parameters    ***************/
-/**************************************************************/
-void
-readconfig(char *filename, struct tableparams *p)
-{
-  FILE *fp;
-  size_t lineno=0, len=200;
-  /*struct uiparams *up=&p->up;*/
-  struct gal_commonparams *cp=&p->cp;
-  char *line, *name, *value, *tstring;
-  char key='a';        /* Not used, just a place holder. */
-
-  /* When the file doesn't exist or can't be opened, it is ignored. It
-     might be intentional, so there is no error. If a parameter is
-     missing, it will be reported after all defaults are read. */
-  fp=fopen(filename, "r");
-  if (fp==NULL) return;
-
-
-  /* Allocate some space for `line` with `len` elements so it can
-     easily be freed later on. The value of `len` is arbitarary at
-     this point, during the run, getline will change it along with the
-     pointer to line. */
-  errno=0;
-  line=malloc(len*sizeof *line);
-  if(line==NULL)
-    error(EXIT_FAILURE, errno, "ui.c: %zu bytes in readdefaults",
-          len * sizeof *line);
-
-  /* Read the tokens in the file:  */
-  while(getline(&line, &len, fp) != -1)
-    {
-      /* Prepare the "name" and "value" strings, also set lineno. */
-      GAL_CONFIGFILES_START_READING_LINE;
-
-
-
-
-      /* Inputs: */
-      if(strcmp(name, "hdu")==0)
-        gal_checkset_allocate_copy_set(value, &cp->hdu, &cp->hduset);
-
-      else if(strcmp(name, "column")==0)
-        {
-          gal_checkset_allocate_copy(value, &tstring);
-          gal_linkedlist_add_to_stll(&p->columns, tstring);
-        }
-
-      else if(strcmp(name, "searchin")==0)
-        {
-          if(p->up.searchinset) continue;
-          gal_checkset_allocate_copy(value, &p->up.searchin);
-          p->up.searchinset=1;
-        }
-
-      else if(strcmp(name, "ignorecase")==0)
-        {
-          if(p->up.ignorecaseset) continue;
-          gal_checkset_int_zero_or_one(value, &p->ignorecase, "ignorecase",
-                                       key, SPACK, filename, lineno);
-          p->up.ignorecaseset=1;
-        }
-
-
-
-      /* Outputs */
-      else if(strcmp(name, "output")==0)
-        gal_checkset_allocate_copy_set(value, &cp->output, &cp->outputset);
-
-      else if (strcmp(name, "tabletype")==0)
-        {
-          if(p->up.tabletypeset) continue;
-          gal_checkset_allocate_copy_set(value, &p->up.tabletype,
-                                         &p->up.tabletypeset);
-        }
-
-
-
-      /* Operating modes: */
-      else if (strcmp(name, "information")==0)
-        {
-          if(p->up.informationset) continue;
-          gal_checkset_int_zero_or_one(value, &p->information, name,
-                                       key, SPACK, filename, lineno);
-          p->up.informationset=1;
-        }
-
-
-      /* Read options common to all programs */
-      GAL_CONFIGFILES_READ_COMMONOPTIONS_FROM_CONF
-
-
-      else
-        error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                      "`%s` not recognized.\n", name);
-    }
-
-  free(line);
-  fclose(fp);
-}
-
-
-
-
-
-void
-printvalues(FILE *fp, struct tableparams *p)
-{
-  struct uiparams *up=&p->up;
-  struct gal_linkedlist_stll *tmp;
-  struct gal_commonparams *cp=&p->cp;
-
-
-  /* Print all the options that are set. Separate each group with a
-     commented line explaining the options in that group. */
-  fprintf(fp, "\n# Input:\n");
-  if(cp->hduset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("hdu", cp->hdu);
-  if(p->columns)
-    for(tmp=p->columns;tmp!=NULL;tmp=tmp->next)
-      GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("column", tmp->v);
-  if(up->ignorecaseset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "ignorecase", p->ignorecase);
-  if(up->searchinset)
-    fprintf(fp, CONF_SHOWFMT"%s\n", "searchin", up->searchin);
-
-
-  fprintf(fp, "\n# Output:\n");
-  if(up->tabletypeset)
-    fprintf(fp, CONF_SHOWFMT"%s\n", "tabletype", p->up.tabletype);
-
-
-  /* For the operating mode, first put the macro to print the common
-     options, then the (possible options particular to this
-     program). */
-  fprintf(fp, "\n# Operating mode:\n");
-  if(up->informationset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "information", p->information);
-
-  GAL_CONFIGFILES_PRINT_COMMONOPTIONS;
-}
-
-
-
-
-
-
-/* Note that numthreads will be used automatically based on the
-   configure time. */
-void
-checkifset(struct tableparams *p)
-{
-  /*struct uiparams *up=&p->up;*/
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-
-  int intro=0;
-  if(cp->hduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("hdu");
-
-  if(up->searchinset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("searchin");
-
-  /* If the output is a FITS file, but tabletype is not set, then report
-     this option as missing. */
-  if( p->cp.output && gal_fits_name_is_fits(p->cp.output)
-      && up->tabletypeset==0 )
-    GAL_CONFIGFILES_REPORT_NOTSET("tabletype");
-
-  GAL_CONFIGFILES_END_OF_NOTSET_REPORT;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 
 /**************************************************************/
 /***************       Sanity Check         *******************/
@@ -405,33 +213,26 @@ void
 setparams(int argc, char *argv[], struct tableparams *p)
 {
   struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
+  struct gal_options_common_params *cp=&p->cp;
 
   /* Set the non-zero initial values, the structure was initialized to
      have a zero value for all elements. */
-  cp->spack         = SPACK;
-  cp->verb          = 1;
-  cp->numthreads    = num_processors(NPROC_CURRENT);
-  cp->removedirinfo = 1;
+  cp->numthreads = num_processors(NPROC_CURRENT);
 
   /* Initialize this utility's pointers to NULL. */
   p->columns=NULL;
   up->filename=NULL;
 
-  /* Read the arguments. */
+  /* Read the command-line arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
-  /* Add the user default values and save them if asked. */
-  GAL_CONFIGFILES_CHECK_SET_CONFIG;
-
-  /* Check if all the required parameters are set. */
-  checkifset(p);
+  /* Read the configuration files. */
+  gal_options_parse_configs(PROG_NAME, options, gal_commonopts_options);
 
-  /* Print the values for each parameter. */
-  if(cp->printparams)
-    GAL_CONFIGFILES_REPORT_PARAMETERS_SET;
+  printf("\n--- back in `ui.c' ---\n");
+  exit(0);
 
   /* Do a sanity check. */
   sanitycheck(p);
diff --git a/configure.ac b/configure.ac
index d61293e..171598a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -250,7 +250,7 @@ AM_CONDITIONAL([COND_GNULIBCHECK], [test 
$enable_gnulibcheck = yes])
 AC_DEFINE_UNQUOTED([CONF_POSTFIX], [".conf"], [Configuration file post fix.])
 AC_DEFINE_UNQUOTED([CURDIRCONFIG_DIR], [".AC_PACKAGE_TARNAME/"],
                    [Local data dir.])
-AC_DEFINE_UNQUOTED([USERCONFIG_DIR], ["/.local/etc/"],
+AC_DEFINE_UNQUOTED([USERCONFIG_DIR], [".local/etc/"],
                    [User data dir.])
 AC_DEFINE_UNQUOTED([CONF_SHOWFMT], [" %-20s"],
                    [Configuration file name format.])
diff --git a/doc/Makefile.am b/doc/Makefile.am
index b314c29..76ec7cc 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -147,7 +147,7 @@ endif
 # it. Unfortunately as far as I know, pattern rules are not portable in all
 # implementations of Make, so we have to list all the utilities manually.
 toputildir=$(top_builddir)/bin
-ALLMANSDEP = $(top_srcdir)/lib/commonargs.h
+ALLMANSDEP = $(top_srcdir)/lib/commonopts.h
 man/astarithmetic.1: $(top_srcdir)/bin/arithmetic/args.h  $(ALLMANSDEP)
        $(MAYBE_HELP2MAN) -n "arithmetic operations on images and numbers" \
                          --libtool $(toputildir)/arithmetic/astarithmetic
diff --git a/lib/Makefile.am b/lib/Makefile.am
index adac941..6bd9d54 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -41,14 +41,16 @@ libgnuastro_la_LDFLAGS = -version-info $(GAL_LT_VERSION)
 
 # Specify the library .c files
 libgnuastro_la_SOURCES = arithmetic.c arithmetic-binary.c               \
-  arithmetic-onlyint.c array.c box.c checkset.c configfiles.c data.c    \
-  fits.c git.c linkedlist.c mesh.c mode.c polygon.c qsort.c             \
+  arithmetic-onlyint.c array.c box.c checkset.c data.c fits.c git.c     \
+  linkedlist.c mesh.c mode.c options.c polygon.c qsort.c                \
   spatialconvolve.c statistics.c table.c threads.c timing.c txt.c wcs.c
 
 
 
 
 
+
+
 # Installed headers, note that we are not blindly including all `.h' files
 # in the $(headersdir) directory. Some of the header files don't need to be
 # installed.
@@ -70,10 +72,9 @@ pkginclude_HEADERS = gnuastro/config.h 
$(headersdir)/arithmetic.h       \
 # and if they are not explicitly mentioned somewhere in the Makefile, they
 # will not distributed, so we need to explicitly tell Automake to
 # distribute them here.
-EXTRA_DIST = gnuastro.pc.in arithmetic-binary.h        arithmetic-onlyint.h    
\
-  arithmetic-other.h config.h.in checkset.h commonargs.h commonparams.h \
-  configfiles.h fixedstringmacros.h mode.h neighbors.h timing.h         \
-  $(headersdir)/README
+EXTRA_DIST = $(headersdir)/README gnuastro.pc.in arithmetic-binary.h    \
+  arithmetic-onlyint.h arithmetic-other.h config.h.in checkset.h        \
+  fixedstringmacros.h mode.h neighbors.h options.h timing.h
 
 
 
diff --git a/lib/commonargs.h b/lib/commonargs.h
deleted file mode 100644
index 7ef8620..0000000
--- a/lib/commonargs.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*********************************************************************
-Argument parsing for options that are common to all programs.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-Gnuastro is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
-**********************************************************************/
-#ifndef __GAL_COMMONARGS_H__
-#define __GAL_COMMONARGS_H__
-
-#include <argp.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <fitsio.h>
-
-#include <checkset.h>
-#include <commonparams.h>
-#include <fixedstringmacros.h>
-
-/* These are separate in each package. */
-#include "main.h"
-#include "cite.h"
-
-
-
-
-
-
-
-
-/* Fixed options for all the programs:
-
-   Free letters (-V which is used by GNU is also removed):
-
-   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
-
-   Used numbers <= 1004
-
-   You can use this above list to set short options for the different
-   utilities.
- */
-static struct argp_option gal_commonargs_options[] =
-  {
-    /* -1 is the code for operating modes: */
-    {
-      "quiet",
-      'q',
-      0,
-      0,
-      "Only report errors, remain quiet about steps.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "printparams",
-      'P',
-      0,
-      0,
-      "Print parameter values to be used and abort.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "setdirconf",
-      'S',
-      0,
-      0,
-      "Set default values for this directory and abort.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "setusrconf",
-      'U',
-      0,
-      0,
-      "Set default values for this user and abort.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "numthreads",
-      'N',
-      "INT",
-      0,
-      "Number of CPU threads to use.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "cite",
-      1000,
-      0,
-      0,
-      "BibTeX citation for "SPACK_NAME".",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "onlydirconf",
-      1001,
-      0,
-      0,
-      "Only read current directory configuration file.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "onlyversion",
-      1002,
-      "STR",
-      0,
-      "Only run if the program version is this.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "log",
-      1003,
-      0,
-      0,
-      "No log file for programs which make one.",
-      -1,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "minmapsize",
-      1004,
-      "INT",
-      0,
-      "Minimum no. bytes to map arrays to hdd/ssd.",
-      -1,
-      NULL, GAL_DATA_TYPE_ULONG
-    },
-
-
-
-
-    /* 1 is the code for inputs. Some utilities might need their own
-       HDU option reader, if that is the case, then the NOTCOMMONHDU
-       is defined in their main.h.*/
-#ifndef NOTCOMMONHDU
-    {
-      "hdu",
-      'h',
-      "STR",
-      0,
-      "Extension name or number of input data.",
-      1,
-      NULL, GAL_DATA_TYPE_STRING
-    },
-#endif
-
-
-
-
-
-    /* 2 is the code for output in all programs: */
-    {
-      "output",
-      'o',
-      "STR",
-      0,
-      "Output file or directory name.",
-      2,
-      NULL, GAL_DATA_TYPE_STRING
-    },
-    {
-      "dontdelete",
-      'D',
-      0,
-      0,
-      "Don't delete output if it exists.",
-      2,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-    {
-      "keepinputdir",
-      'K',
-      0,
-      0,
-      "Do not remove input's dir info for output.",
-      2,
-      NULL, GAL_DATA_TYPE_UCHAR
-    },
-
-
-
-    {0}
-  };
-
-
-
-
-
-
-
-
-
-
-static error_t
-gal_checkset_commonargs_cparse_opt(int key, char *arg, struct argp_state 
*state)
-{
-  /* Save the arguments structure: */
-  struct gal_commonparams *cp=state->input;
-
-  /* In case the user incorrectly uses the equal sign (for example
-     with a short format or with space in the long format, then `arg`
-     start with (if the short version was called) or be (if the long
-     version was called with a space) the equal sign. So, here we
-     check if the first character of arg is the equal sign, then the
-     user is warned and the program is stopped: */
-  if(arg && arg[0]=='=')
-    argp_error(state, "incorrect use of the equal sign (`=`). For short "
-               "options, `=` should not be used and for long options, "
-               "there should be no space between the option, equal sign "
-               "and value");
-
-  switch(key)
-    {
-
-    /* Operating modes: */
-    case 'q':
-      cp->verb=0;
-      cp->quietset=1;
-      break;
-    case 'P':
-      cp->printparams=1;
-      break;
-    case 'S':
-      cp->setdirconf=1;
-      break;
-    case 'U':
-      cp->setusrconf=1;
-      break;
-    case 'N':
-      gal_checkset_sizet_l_zero(arg, &cp->numthreads, "numthreads", key,
-                                cp->spack, NULL, 0);
-      cp->numthreadsset=1;
-      break;
-    case 1000:
-      PRINTCITEABORT;
-      break;
-    case 1001:
-      cp->onlydirconf=1;
-      cp->onlydirconfset=1;
-      break;
-    case 1002:
-      cp->onlyversion=arg;
-      cp->onlyversionset=1;
-      break;
-    case 1003:
-      cp->nolog=1;
-      cp->nologset=1;
-      break;
-    case 1004:
-      gal_checkset_sizet_l_zero(arg, &cp->minmapsize, "minmapsize", key,
-                                cp->spack, NULL, 0);
-      cp->minmapsizeset=1;
-      break;
-
-    /* Input/output: */
-    case 'h':
-      gal_checkset_allocate_copy_set(arg, &cp->hdu, &cp->hduset);
-      break;
-    case 'o':
-      gal_checkset_allocate_copy_set(arg, &cp->output, &cp->outputset);
-      break;
-    case 'D':
-      cp->dontdelete=1;
-      cp->dontdeleteset=1;
-      break;
-    case 'K':
-      cp->removedirinfo=0;
-      cp->removedirinfoset=1;
-      break;
-
-
-    /* Once finished: */
-    case ARGP_KEY_END:
-      if(cp->setdirconf && cp->setusrconf)
-        error(EXIT_FAILURE, 0, "only one of `--setusrconf` or "
-              "`--setdirconf` may be set in each run. You have asked "
-              "for both");
-      break;
-
-    /* If the argument is not known. */
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-
-  return 0;
-}
-
-
-
-
-
-
-
-
-
-
-static struct argp commonargp = {gal_commonargs_options,
-                                 gal_checkset_commonargs_cparse_opt,
-                                 NULL, NULL, NULL, NULL, NULL};
-
-
-
-#endif  /* __GAL_COMMONARGS_H__ */
diff --git a/lib/commonopts.h b/lib/commonopts.h
new file mode 100644
index 0000000..a4e3b4c
--- /dev/null
+++ b/lib/commonopts.h
@@ -0,0 +1,193 @@
+/*********************************************************************
+Common parameters between all programs.
+
+IMPORTANT: This header must only be included the programs, not libraries.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+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
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#ifndef __GAL_COMMONOPTS_H__
+#define __GAL_COMMONOPTS_H__
+
+/* Common options for all programs.
+
+   IMPORTANT NOTE:
+
+     This header should only be included in the programs, not the
+     libraries, and in particular `options.c'. Because we want each program
+     to have its own allocation of the common options structure. If it is
+     included in options.c, then it will be shared between all the
+     programs.
+
+
+   Free letters (-V which is used by GNU is also removed):
+
+   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
+
+   Used numbers <= 1004
+
+   You can use this above list to set short options for the different
+   utilities.
+ */
+struct argp_option gal_commonopts_options[] =
+  {
+    /* Input/output. */
+#ifndef NOT_COMMON_HDU_PARSER
+    {                           /* Some utilities need to parse `hdu' them-*/
+      "hdu",                    /* selves. In this case, they will define  */
+      'h',                      /* `NOT_COMMON_HDU_PARSER' and set their   */
+      "STR",                    /* own `hdu' option structure. */
+      0,
+      "Extension name or number of input data.",
+      1,                        /* Input. */
+      NULL, GAL_DATA_TYPE_STRING
+    },
+#endif
+    {
+      "output",
+      'o',
+      "STR",
+      0,
+      "Output file or directory name.",
+      2,                        /* Output. */
+      NULL, GAL_DATA_TYPE_STRING
+    },
+    {
+      "dontdelete",
+      'D',
+      0,
+      0,
+      "Don't delete output if it exists.",
+      2,                        /* Output. */
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "keepinputdir",
+      'K',
+      0,
+      0,
+      "Keep input directory for automatic output.",
+      2,                        /* Output. */
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+
+
+
+    /* Operating mode. */
+    {
+      "quiet",
+      'q',
+      0,
+      0,
+      "Only report errors, remain quiet about steps.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "numthreads",
+      'N',
+      "INT",
+      0,
+      "Number of CPU threads to use.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_DATA_TYPE_ULONG
+    },
+    {
+      "minmapsize",
+      1004,
+      "INT",
+      0,
+      "Minimum no. bytes to map arrays to hdd/ssd.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_DATA_TYPE_ULONG
+    },
+    {
+      "log",
+      1003,
+      0,
+      0,
+      "No log file for programs which make one.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+
+
+
+    /* Internal (before control goes back to the program). */
+    {
+      "cite",
+      1000,
+      0,
+      0,
+      "BibTeX citation for this program.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "printparams",
+      'P',
+      0,
+      0,
+      "Print parameter values to be used and abort.",
+      -1,
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "setdirconf",
+      'S',
+      0,
+      0,
+      "Set default values for this directory and abort.",
+      -1,
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "setusrconf",
+      'U',
+      0,
+      0,
+      "Set default values for this user and abort.",
+      -1,
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "onlydirconf",
+      1001,
+      0,
+      0,
+      "Only read current directory configuration file.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_OPTIONS_NO_ARG_TYPE
+    },
+    {
+      "onlyversion",
+      1002,
+      "STR",
+      0,
+      "Only run if the program version is this.",
+      -1,                       /* Operating mode. */
+      NULL, GAL_DATA_TYPE_STRING
+    },
+
+
+
+    {0}
+  };
+
+#endif
diff --git a/lib/commonparams.h b/lib/commonparams.h
deleted file mode 100644
index 70de2f5..0000000
--- a/lib/commonparams.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*********************************************************************
-Common parameters for all the utilities.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-Gnuastro is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
-**********************************************************************/
-#ifndef __GAL_COMMONPARAMS_H__
-#define __GAL_COMMONPARAMS_H__
-
-
-
-/* The structure keeping all the common parameters in gnuastro. This
-   could be part of commonargs.h, but since main.h in all those
-   programs will need this structure, there will be problems about the
-   unused `commonargp` structure.*/
-struct gal_commonparams
-{
-  char        *spack;  /* Subpackage name.                          */
-
-  /* Input/Output: */
-  char       *output;  /* Directory containg output.                */
-  char          *hdu;  /* Image extension.                          */
-  int     dontdelete;  /* ==1: Don't delete existing.               */
-  int  removedirinfo;  /* ==1: Remove directory information.        */
-
-  /* Operating modes: */
-  int           verb;  /* ==1: report steps. ==0 don't.             */
-  int    printparams;  /* Only print the used values.               */
-  int     setdirconf;  /* ==1: Set the current directory config.    */
-  int     setusrconf;  /* ==1: Set the user default values.         */
-  size_t  numthreads;  /* Number of threads to use.                 */
-  int    onlydirconf;  /* Only check current directory conf. file.  */
-  char  *onlyversion;  /* The string of the requested version.      */
-  size_t  minmapsize;  /* The minimum bytes necessary to use mmap.  */
-  int          nolog;  /* ==1: do not make a log file.              */
-
-  /* Check: */
-  int       quietset;  /* If the verbose flag is called.            */
-  int  numthreadsset;  /* If the number of threads are set.         */
-  int onlyversionset;  /* If the only version option is set.        */
-  int onlydirconfset;  /* If --onlydirconf was set before this.     */
-  int         hduset;  /* If the input image extension is set.      */
-  int      outputset;  /* If the output is set.                     */
-  int       nologset;  /* If nolog is set.                          */
-  int  minmapsizeset;  /* If minmapsize is set.                     */
-  int  dontdeleteset;  /* If the --dontdelete option was called.    */
-  int removedirinfoset;  /* If --keepinputdir was called.           */
-};
-
-#endif
diff --git a/lib/configfiles.c b/lib/configfiles.c
deleted file mode 100644
index 9162ff0..0000000
--- a/lib/configfiles.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*********************************************************************
-configfiles -- Read configuration files for each program.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-Gnuastro is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
-**********************************************************************/
-#include <config.h>
-
-#include <time.h>
-#include <stdio.h>
-#include <errno.h>
-#include <error.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/stat.h>                /* For mkdir permission flags. */
-
-#include "checkset.h"
-#include "configfiles.h"
-
-
-
-
-/* Add the HOME environment variable to the given directory. */
-char *
-gal_configfiles_add_home_dir(char *dir)
-{
-  char *home;
-
-  /* Get the home environment variable. */
-  home=getenv("HOME");
-  if(home==NULL)
-    error(EXIT_FAILURE, 0, "the HOME environment variable "
-          "is not defined");
-
-  /* Concatenate the two strings together: */
-  return gal_checkset_malloc_cat(home, dir);
-}
-
-
-
-
-
-void
-gal_configfiles_read_name_value(char *line, char *filename, size_t lineno,
-                                char **name, char **value)
-{
-  int notyetfinished=1, inword=0, inquote=0;
-
-  /* Initialize name and value: */
-  *name=NULL;
-  *value=NULL;
-
-  /* Go through the characters and set the values: */
-  do
-    switch(*line)
-      {
-      case ' ': case '\t': case '\v': case '\n': case '\r':
-        if(inword) /* Only considered in a word, not in a quote*/
-          {
-            inword=0;
-            *line='\0';
-            if(*value && inquote==0)
-              notyetfinished=0;
-          }
-        break;
-      case '#':
-        notyetfinished=0;
-        break;
-      case '"':
-        if(inword)
-          error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                        "Quotes have to be surrounded by whitespace "
-                        "characters (space, tab, new line, etc).");
-        if(inquote)
-          {
-            *line='\0';
-            inquote=0;
-            notyetfinished=0;
-          }
-        else
-          {
-            if(*name==NULL)
-              error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                            "Parameter name should not start with "
-                            "double quotes (\").");
-            inquote=1;
-            *value=line+1;
-          }
-        break;
-      default:
-        if(inword==0 && inquote==0)
-          {
-            if(*name==NULL)
-              *name=line;
-            else  /* name is set, now assign *value. */
-              *value=line;
-            inword=1;
-          }
-        break;
-      }
-  while(*(++line)!='\0' && notyetfinished);
-
-  /* In the last line of the file, there is no new line to be
-     converted to a '\0' character! So if value has been assigned, we
-     are not in a quote and the line has finished, it means the given
-     value has also finished. */
-  if(*line=='\0' && *value && inquote==0)
-    notyetfinished=0;
-
-  /* This was a blank line: */
-  if(*name==NULL && *value==NULL)
-    return;
-
-  /* Name or value were set but not yet finished. */
-  if(notyetfinished)
-    error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                  "line finished before parameter name and "
-                  "value could be read.");
-}
-
-
-
-
-
-FILE *
-gal_configfiles_write_local_config_stop(char *indir, char *filename,
-                                        char *spack, char *spack_name,
-                                        char **outfilename)
-{
-  DIR *dp;
-  FILE *fp;
-  time_t rawtime;
-
-  errno=0;
-  time(&rawtime);
-
-  /* Make sure the directory exists, if it doesn't, try to make it.*/
-  dp=opendir(indir);
-  if(dp==NULL)               /* The directory could not be opened. */
-    {
-      if(errno==ENOENT)
-        {
-          errno=0;
-          if(mkdir(indir, S_IRWXU)==-1)
-            error(EXIT_FAILURE, errno, "%s: could not be created. Try "
-                  "running:\n\n    mkdir -p %s\n\nto built it and run "
-                  "your previous command again", indir, indir);
-        }
-      else
-        error(EXIT_FAILURE, errno, "%s", indir);
-    }
-  else
-    {
-      errno=0;
-      if (closedir(dp)==-1)
-        error(EXIT_FAILURE, errno, "%s", indir);
-    }
-
-
-  /* Make the local defaults file and put the top information in
-     it. */
-  *outfilename=gal_checkset_malloc_cat(indir, filename);
-
-  /* Check if the file opening was successful: */
-  errno=0;
-  fp=fopen(*outfilename, "w");
-  if (fp==NULL)
-    error(EXIT_FAILURE, errno, "%s", *outfilename);
-
-  /* write the comments: */
-  fprintf(fp, "# Default parameters for %s (%s).\n"
-          "# %s is part of GNU Astronomy Utitlies.\n"
-          "# This file was created on %s#\n"
-          "# Use the long option name of each parameter followed by\n"
-          "# a value. The name and value should be separated by\n"
-          "# at least one of the following characters:\n"
-          "# space, `,`, `=` or `:`.\n#\n"
-          "# Run `%s --help` or `info %s`\n"
-          "# for more information.\n#\n"
-          "# NOTE I:  All counting is from zero, not one.\n"
-          "# NOTE II: Lines starting with `#` are ignored.\n",
-          spack_name, spack, spack_name, ctime(&rawtime), spack, spack);
-
-  return fp;
-}
-
-
-
-
-
-void
-gal_configfiles_print_type(FILE *fp, int bitpix)
-{
-  switch(bitpix)
-    {
-    case BYTE_IMG:
-      fprintf(fp, CONF_SHOWFMT"%s\n", "type", "byte");
-      break;
-    case SHORT_IMG:
-      fprintf(fp, CONF_SHOWFMT"%s\n", "type", "short");
-      break;
-    case LONG_IMG:
-      fprintf(fp, CONF_SHOWFMT"%s\n", "type", "long");
-      break;
-    case LONGLONG_IMG:
-      fprintf(fp, CONF_SHOWFMT"%s\n", "type", "longlong");
-      break;
-    case FLOAT_IMG:
-      fprintf(fp, CONF_SHOWFMT"%s\n", "type", "float");
-      break;
-    case DOUBLE_IMG:
-      fprintf(fp, CONF_SHOWFMT"%s\n", "type", "double");
-      break;
-    default:
-      error(EXIT_FAILURE, 0, "a bug! the value of bitpix is not recognized "
-            "in `gal_configfiles_print_type'. Please contact us at %s so "
-            "we can address the problem.", PACKAGE_BUGREPORT);
-    }
-}
diff --git a/lib/configfiles.h b/lib/configfiles.h
deleted file mode 100644
index 7055d92..0000000
--- a/lib/configfiles.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/*********************************************************************
-configfiles -- Read configuration files for each program.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-Gnuastro is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
-**********************************************************************/
-#ifndef __GAL_CONFIGFILES_H__
-#define __GAL_CONFIGFILES_H__
-
-/* Include other headers if necessary here. Note that other header files
-   must be included before the C++ preparations below */
-
-
-
-/* C++ Preparations */
-#undef __BEGIN_C_DECLS
-#undef __END_C_DECLS
-#ifdef __cplusplus
-# define __BEGIN_C_DECLS extern "C" {
-# define __END_C_DECLS }
-#else
-# define __BEGIN_C_DECLS                /* empty */
-# define __END_C_DECLS                  /* empty */
-#endif
-/* End of C++ preparations */
-
-
-
-/* Actual header contants (the above were for the Pre-processor). */
-__BEGIN_C_DECLS  /* From C++ preparations */
-
-
-
-/**************************************************************/
-/************               Macros                *************/
-/**************************************************************/
-/* Simple macros: */
-#define GAL_CONFIGFILES_DELIMITERS " ,=:\t\n"
-
-
-
-#define GAL_CONFIGFILES_START_READING_LINE {                            \
-    ++lineno;                                                           \
-  if(*line=='#') continue;                                              \
-  else gal_configfiles_read_name_value(line, filename, lineno,          \
-                                       &name, &value);                  \
-  if(name==NULL && value==NULL) continue;                               \
-}
-
-
-
-/* Functional macros: These are not actual functions, because they
-   depend on functions that are different for different programs. So
-   they have to be written into the functions with a macro. */
-#define GAL_CONFIGFILES_SAVE_LOCAL_CONFIG(INDIR) {                      \
-    FILE *fp;                                                           \
-    char *outfilename, *command;                                        \
-    fp=gal_configfiles_write_local_config_stop(INDIR, CONFIG_FILE,      \
-                                               SPACK, SPACK_NAME,       \
-                                               &outfilename);           \
-    printvalues(fp, p);                                                 \
-    errno=0;                                                            \
-    if(fclose(fp)==-1)                                                  \
-      error(EXIT_FAILURE, errno, "%s", outfilename);                    \
-    command=gal_checkset_malloc_cat("cat ", outfilename);               \
-    printf("Values saved in %s:\n\n", outfilename);                     \
-    if(system(command))                                                 \
-      error(EXIT_FAILURE, 0, "the `%s` command could not be run or "    \
-            "failed", command);                                         \
-    free(outfilename);                                                  \
-    free(command);                                                      \
-    exit(EXIT_SUCCESS);                                                 \
-  }
-
-
-
-
-
-#define GAL_CONFIGFILES_CHECK_SET_CONFIG {                              \
-    char *userconfig_dir, *userconfig_file;                             \
-                                                                        \
-    readconfig(CURDIRCONFIG_FILE, p);                                   \
-    if(cp->setdirconf)                                                  \
-      GAL_CONFIGFILES_SAVE_LOCAL_CONFIG(CURDIRCONFIG_DIR);              \
-    if(cp->onlyversionset && strcmp(cp->onlyversion, PACKAGE_VERSION))  \
-      error(EXIT_FAILURE, 0, "you are currently running Gnuastro %s. "  \
-            "However, this run should be with version `%s'.\n\n"        \
-            "To resolve the situation, use the the '--onlyversion' "    \
-            "option, either on the command-line or in a configuration " \
-            "file. For example, set it to `%s' by repeating the "       \
-            "previous command with:\n\n"                                \
-            "    --onlyversion=%s\n\n"                                  \
-            "Alternatively, you can install Gnuastro %s.\n\n"           \
-            "NOTE: If you didn't set this option on the command-line, " \
-            "it was probably intended for reproducability. If so, it "  \
-            "is advised to install Gnuastro %s",                        \
-            PACKAGE_VERSION, cp->onlyversion, PACKAGE_VERSION,          \
-            PACKAGE_VERSION, cp->onlyversion, cp->onlyversion);         \
-                                                                        \
-    if(cp->onlydirconf==0)                                              \
-      {                                                                 \
-        userconfig_dir=gal_configfiles_add_home_dir(USERCONFIG_DIR);    \
-        userconfig_file=                                                \
-          gal_configfiles_add_home_dir(USERCONFIG_FILEEND);             \
-        readconfig(userconfig_file, p);                                 \
-        if(cp->setusrconf)                                              \
-          GAL_CONFIGFILES_SAVE_LOCAL_CONFIG(userconfig_dir);            \
-        readconfig(SYSCONFIG_FILE, p);                                  \
-        free(userconfig_file);                                          \
-        free(userconfig_dir);                                           \
-      }                                                                 \
-  }
-
-
-
-
-
-
-
-#define GAL_CONFIGFILES_REPORT_NOTSET(var_name) {                       \
-    if(intro==0)                                                        \
-      {                                                                 \
-        fprintf(stderr, SPACK": Parameter(s) not set: `%s'",            \
-                (var_name));                                            \
-        intro=1;                                                        \
-      }                                                                 \
-    else                                                                \
-      fprintf(stderr, ", `%s'", (var_name));                            \
-  }
-
-
-
-
-
-#define GAL_CONFIGFILES_END_OF_NOTSET_REPORT {                          \
-    if(intro)                                                           \
-      {                                                                 \
-        char *userconfig_file;                                          \
-        fprintf(stderr, ".\n\n");                                       \
-        fprintf(stderr, "You can assign values in the local, user or "  \
-                "system wide default files. Otherwise you have to "     \
-                "explicitly assign a value to them each time as a "     \
-                "command-line option. See `%s --help` or `info %s` for "\
-                "more information.\n\n", SPACK, SPACK);                 \
-        userconfig_file=                                                \
-          gal_configfiles_add_home_dir(USERCONFIG_FILEEND);             \
-        fprintf(stderr, "Default files checked (existing or not):\n");  \
-        fprintf(stderr, "   %s\n", CURDIRCONFIG_FILE);                  \
-        if(p->cp.onlydirconf==0)                                        \
-          fprintf(stderr, "   %s\n   %s\n", userconfig_file,            \
-                  SYSCONFIG_FILE);                                      \
-        free(userconfig_file);                                          \
-        exit(EXIT_FAILURE);                                             \
-      }                                                                 \
-  }
-
-
-
-
-
-#define GAL_CONFIGFILES_REPORT_PARAMETERS_SET {                         \
-    fprintf(stdout, "# "SPACK_STRING"\n");                              \
-    fprintf(stdout, "# Written on %s", ctime(&p->rawtime));             \
-    printvalues(stdout, p);                                             \
-    exit(EXIT_SUCCESS);                                                 \
-  }
-
-
-
-
-
-/* Read the options that are common to all programs from the
-   configuration file. Since these two checks are within an if-else
-   structure, they should not be placed within an `{' and `}'. */
-#define GAL_CONFIGFILES_READ_COMMONOPTIONS_FROM_CONF                    \
-    else if(strcmp(name, "quiet")==0)                                   \
-      {                                                                 \
-        int tint;                                                       \
-        if(cp->quietset) continue;                                      \
-        gal_checkset_int_zero_or_one(value, &tint, name, key, SPACK,    \
-                                     filename, lineno);                 \
-        cp->verb=!tint;                                                 \
-        cp->quietset=1;                                                 \
-      }                                                                 \
-    else if(strcmp(name, "numthreads")==0)                              \
-      {                                                                 \
-        if(cp->numthreadsset) continue;                                 \
-        gal_checkset_sizet_l_zero(value, &cp->numthreads, name, key,    \
-                                  SPACK, filename, lineno);             \
-        cp->numthreadsset=1;                                            \
-      }                                                                 \
-    else if(strcmp(name, "onlydirconf")==0)                             \
-      {                                                                 \
-        if(cp->onlydirconfset) continue;                                \
-        gal_checkset_int_zero_or_one(value, &cp->onlydirconf, name,     \
-                                     key, SPACK, filename, lineno);     \
-        cp->onlydirconfset=1;                                           \
-      }                                                                 \
-    else if(strcmp(name, "onlyversion")==0)                             \
-      {                                                                 \
-        if(cp->onlyversionset) continue;                                \
-        gal_checkset_allocate_copy_set(value, &cp->onlyversion,         \
-                                       &cp->onlyversionset);            \
-        cp->onlyversionset=1;                                           \
-      }                                                                 \
-    else if(strcmp(name, "nolog")==0)                                   \
-      {                                                                 \
-        if(cp->nologset) continue;                                      \
-        gal_checkset_int_zero_or_one(value, &cp->nolog, name, key,      \
-                                     SPACK, filename, lineno);          \
-        cp->nologset=1;                                                 \
-      }                                                                 \
-    else if(strcmp(name, "minmapsize")==0)                              \
-      {                                                                 \
-        if(cp->minmapsizeset) continue;                                 \
-        gal_checkset_sizet_l_zero(value, &cp->minmapsize, name, key,    \
-                                  SPACK, filename, lineno);             \
-        cp->minmapsizeset=1;                                            \
-      }                                                                 \
-                                                                        \
-                                                                        \
-    else if(strcmp(name, "dontdelete")==0)                              \
-      {                                                                 \
-        if(cp->dontdeleteset) continue;                                 \
-        gal_checkset_int_zero_or_one(value, &cp->dontdelete, name, key, \
-                                     SPACK, filename, lineno);          \
-        cp->dontdeleteset=1;                                            \
-      }                                                                 \
-    else if(strcmp(name, "keepinputdir")==0)                            \
-      {                                                                 \
-        int tint;                                                       \
-        if(cp->removedirinfoset) continue;                              \
-        gal_checkset_int_zero_or_one(value, &tint, name, key,           \
-                                     SPACK, filename, lineno);          \
-        cp->removedirinfo=!tint;                                        \
-        cp->removedirinfoset=1;                                         \
-      }                                                                 \
-
-
-
-
-
-
-
-/* Write common options: */
-#define GAL_CONFIGFILES_PRINT_COMMONOPTIONS {                           \
-    if(cp->quietset)                                                    \
-      fprintf(fp, CONF_SHOWFMT"%d\n", "quiet", !p->cp.verb);            \
-    if(cp->numthreadsset)                                               \
-      fprintf(fp, CONF_SHOWFMT"%zu\n", "numthreads", p->cp.numthreads); \
-    if(cp->onlydirconfset)                                              \
-      fprintf(fp, CONF_SHOWFMT"%d\n", "onlydirconf", p->cp.onlydirconf);\
-    if(cp->onlyversionset)                                              \
-      GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("onlyversion",         \
-                                                 cp->onlyversion);      \
-    if(cp->nologset)                                                    \
-      fprintf(fp, CONF_SHOWFMT"%d\n", "nolog", p->cp.nolog);            \
-    if(cp->dontdeleteset)                                               \
-      fprintf(fp, CONF_SHOWFMT"%d\n", "dontdelete", p->cp.dontdelete);  \
-    if(cp->removedirinfoset)                                            \
-      fprintf(fp, CONF_SHOWFMT"%d\n", "keepinputdir", !p->cp.removedirinfo); \
-  }
-
-
-
-
-
-
-
-
-/**************************************************************/
-/************       Function declarations         *************/
-/**************************************************************/
-char *
-gal_configfiles_add_home_dir(char *dir);
-
-void
-gal_configfiles_read_name_value(char *line, char *filename, size_t lineno,
-                                char **name, char **value);
-
-FILE *
-gal_configfiles_write_local_config_stop(char *indir, char *filename,
-                                        char *spack, char *spack_name,
-                                        char **outfilename);
-void
-gal_configfiles_print_type(FILE *fp, int bitpix);
-
-
-
-__END_C_DECLS    /* From C++ preparations */
-
-#endif           /* __GAL_CONFIGFILES_H__ */
diff --git a/lib/data.c b/lib/data.c
index c626842..37fff2a 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -35,6 +35,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <gnuastro/data.h>
 #include <gnuastro/table.h>
+#include <gnuastro/linkedlist.h>
 
 #include <checkset.h>
 
@@ -44,6 +45,234 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
+
+/*************************************************************
+ **************            Type info           ***************
+ *************************************************************/
+
+char *
+gal_data_type_as_string(int type, int long_name)
+{
+  switch(type)
+    {
+    case GAL_DATA_TYPE_BIT:
+      if(long_name) return "bit";             else return "b";
+
+    case GAL_DATA_TYPE_UCHAR:
+      if(long_name) return "unsigned char";   else return "uc";
+
+      /* 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:
+      if(long_name) return "char";            else return "c";
+
+    case GAL_DATA_TYPE_STRING:
+      if(long_name) return "string";          else return "str";
+
+    case GAL_DATA_TYPE_USHORT:
+      if(long_name) return "unsigned short";  else return "us";
+
+    case GAL_DATA_TYPE_SHORT:
+      if(long_name) return "short";           else return "s";
+
+    case GAL_DATA_TYPE_UINT:
+      if(long_name) return "unsigned int";    else return "ui";
+
+    case GAL_DATA_TYPE_INT:
+      if(long_name) return "int";             else return "i";
+
+    case GAL_DATA_TYPE_ULONG:
+      if(long_name) return "unsigned long";   else return "ul";
+
+    case GAL_DATA_TYPE_LONG:
+      if(long_name) return "long";            else return "l";
+
+    case GAL_DATA_TYPE_LONGLONG:
+      if(long_name) return "LONGLONG";        else return "L";
+
+    case GAL_DATA_TYPE_FLOAT:
+      if(long_name) return "float";           else return "f";
+
+    case GAL_DATA_TYPE_DOUBLE:
+      if(long_name) return "double";          else return "d";
+
+    case GAL_DATA_TYPE_COMPLEX:
+      if(long_name) return "complex float";   else return "cf";
+
+    case GAL_DATA_TYPE_DCOMPLEX:
+      if(long_name) return "complex double";  else return "cd";
+
+    case GAL_DATA_TYPE_STRLL:
+      if(long_name) return "string linked list";  else return "strll";
+
+    default:
+      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
+            "`gal_data_type_as_string'", type);
+    }
+
+  /* Any of the cases above should return this function, so if control
+     reaches here, there is a bug. */
+  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 "
+        "the `gal_data_type_as_string' function. This must not happen",
+        PACKAGE_BUGREPORT);
+  return NULL;
+}
+
+
+
+
+
+int
+gal_data_string_as_type(char *str)
+{
+  if(      !strcmp(str, "b")   || !strcmp(str, "bit") )
+    return GAL_DATA_TYPE_BIT;
+
+  else if( !strcmp(str, "uc")  || !strcmp(str, "unsigned char") )
+    return GAL_DATA_TYPE_UCHAR;
+
+  else if( !strcmp(str, "c")   || !strcmp(str, "char") )
+    return GAL_DATA_TYPE_CHAR;
+
+  else if( !strcmp(str, "str") || !strcmp(str, "string") )
+    return GAL_DATA_TYPE_STRING;
+
+  else if( !strcmp(str, "us")  || !strcmp(str, "unsigned short") )
+    return GAL_DATA_TYPE_USHORT;
+
+  else if( !strcmp(str, "s")   || !strcmp(str, "short") )
+    return GAL_DATA_TYPE_SHORT;
+
+  else if( !strcmp(str, "ui")  || !strcmp(str, "unsigned int") )
+    return GAL_DATA_TYPE_UINT;
+
+  else if( !strcmp(str, "i")   || !strcmp(str, "int") )
+    return GAL_DATA_TYPE_INT;
+
+  else if( !strcmp(str, "ul")  || !strcmp(str, "unsigned long") )
+    return GAL_DATA_TYPE_ULONG;
+
+  else if( !strcmp(str, "l")   || !strcmp(str, "long") )
+    return GAL_DATA_TYPE_LONG;
+
+  else if( !strcmp(str, "L")   || !strcmp(str, "LONGLONG") )
+    return GAL_DATA_TYPE_LONGLONG;
+
+  else if( !strcmp(str, "f")   || !strcmp(str, "float") )
+    return GAL_DATA_TYPE_FLOAT;
+
+  else if( !strcmp(str, "d")   || !strcmp(str, "double") )
+    return GAL_DATA_TYPE_DOUBLE;
+
+  else if( !strcmp(str, "cf")  || !strcmp(str, "complex float") )
+    return GAL_DATA_TYPE_COMPLEX;
+
+  else if( !strcmp(str, "cd")  || !strcmp(str, "complex double") )
+    return GAL_DATA_TYPE_DCOMPLEX;
+
+  else
+    return GAL_DATA_TYPE_INVALID;
+
+  /* Any of the cases above should return this function, so if control
+     reaches here, there is a bug. */
+  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 "
+        "the `gal_data_string_as_type' function. This must not happen",
+        PACKAGE_BUGREPORT);
+  return 0;
+}
+
+
+
+
+
+/* Put the minimum (or maximum for the `gal_data_type_max') value for the
+   type in the space (that must already be allocated before the call to
+   this function) pointed to by in.  */
+void
+gal_data_type_min(int type, void *in)
+{
+  switch(type)
+    {
+    case GAL_DATA_TYPE_UCHAR:    *(unsigned char *)in  = 0;            break;
+    case GAL_DATA_TYPE_CHAR:     *(char *)in           = CHAR_MIN;     break;
+    case GAL_DATA_TYPE_USHORT:   *(unsigned short *)in = 0;            break;
+    case GAL_DATA_TYPE_SHORT:    *(short *)in          = SHRT_MIN;     break;
+    case GAL_DATA_TYPE_UINT:     *(unsigned int *)in   = 0;            break;
+    case GAL_DATA_TYPE_INT:      *(int *)in            = INT_MIN;      break;
+    case GAL_DATA_TYPE_ULONG:    *(unsigned long *)in  = 0;            break;
+    case GAL_DATA_TYPE_LONG:     *(long *)in           = LONG_MIN;     break;
+    case GAL_DATA_TYPE_LONGLONG: *(LONGLONG *)in       = LONGLONG_MIN; break;
+    case GAL_DATA_TYPE_FLOAT:    *(float *)in          = -FLT_MAX;     break;
+    case GAL_DATA_TYPE_DOUBLE:   *(double *)in         = -DBL_MAX;     break;
+    default:
+      error(EXIT_FAILURE, 0, "type code %d not recognized in "
+            "`gal_data_type_min'", type);
+    }
+}
+
+
+
+
+
+void
+gal_data_type_max(int type, void *in)
+{
+  switch(type)
+    {
+    case GAL_DATA_TYPE_UCHAR:    *(unsigned char *)in  = UCHAR_MAX;    break;
+    case GAL_DATA_TYPE_CHAR:     *(char *)in           = CHAR_MAX;     break;
+    case GAL_DATA_TYPE_USHORT:   *(unsigned short *)in = USHRT_MAX;    break;
+    case GAL_DATA_TYPE_SHORT:    *(short *)in          = SHRT_MAX;     break;
+    case GAL_DATA_TYPE_UINT:     *(unsigned int *)in   = UINT_MAX;     break;
+    case GAL_DATA_TYPE_INT:      *(int *)in            = INT_MAX;      break;
+    case GAL_DATA_TYPE_ULONG:    *(unsigned long *)in  = ULONG_MAX;    break;
+    case GAL_DATA_TYPE_LONG:     *(long *)in           = LONG_MAX;     break;
+    case GAL_DATA_TYPE_LONGLONG: *(LONGLONG *)in       = LONGLONG_MAX; break;
+    case GAL_DATA_TYPE_FLOAT:    *(float *)in          = FLT_MAX;      break;
+    case GAL_DATA_TYPE_DOUBLE:   *(double *)in         = DBL_MAX;      break;
+    default:
+      error(EXIT_FAILURE, 0, "type code %d not recognized in "
+            "`gal_data_type_min'", type);
+    }
+}
+
+
+
+
+
+/* Since linked lists need a different process than arrays, for functions
+   that work on both, it is convenient to simiplify the check with this
+   function. */
+int
+gal_data_is_linked_list(int type)
+{
+  return type==GAL_DATA_TYPE_STRLL;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 /*********************************************************************/
 /*************          Size and allocation        *******************/
 /*********************************************************************/
@@ -1900,229 +2129,107 @@ gal_data_string_to_number(char *string)
 
 
 
-/* You have a string and you want to put it into an element of the array of
-   a data structure. The array doesn't necessarily have to be allocated
-   (!=NULL). If it wasn't allocated, it will be allocated here based on the
-   `size' element in the data structure. If size is 0, a one element array
-   will be allocated. If the data structure isn't already allocated or its
-   type is negative, this function will act like
-   `gal_data_string_to_number' where the type will be set based on the
-   value of the number. If the string is blank, this function won't do
-   anything.
-
-   Use `gal_table_read_blank' as a basis for this function, then remove
-   that function. */
-void
-gal_data_string_to_array_elem(gal_data_t **outdata, size_t index,
-                              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.
 
+   Note that when we are dealing with a string type, `*out' should be
+   interpretted as `char **' (one element in an array of pointers to
+   different strings).
 
-/*************************************************************
- **************            Type info           ***************
- *************************************************************/
-
-char *
-gal_data_type_as_string(int type, int long_name)
+   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])*/
+int
+gal_data_string_to_type(void **out, char *string, int type)
 {
-  switch(type)
+  double d;
+  LONGLONG L;
+  void *value;
+  char *tailptr;
+  int status=0, allocated=0;
+
+  /* If the output is NULL, then allocate the necessary space if we are not
+     dealing with a linked list. In a linked list, a NULL value is
+     meaningful (it is the end of the list). */
+  if(*out==NULL && gal_data_is_linked_list(type)==0)
     {
-    case GAL_DATA_TYPE_BIT:
-      if(long_name) return "bit";             else return "b";
+      allocated=1;
+      *out=gal_data_malloc_array(type, 1);
+    }
+  value=*out;
 
-    case GAL_DATA_TYPE_UCHAR:
-      if(long_name) return "unsigned char";   else return "uc";
+  /* Read the string depending on the type. */
+  switch(type)
+    {
 
-      /* 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:
-      if(long_name) return "char";            else return "c";
+    /* Linked lists, currently only string linked lists. */
+    case GAL_DATA_TYPE_STRLL:
+      gal_linkedlist_add_to_stll( (struct gal_linkedlist_stll **)out, string);
+      break;
 
+    /* String, just allocate and copy the string and keep its pointer in
+       the place `*out' points to (for strings, `*out' is `char **'). */
     case GAL_DATA_TYPE_STRING:
-      if(long_name) return "string";          else return "str";
-
-    case GAL_DATA_TYPE_USHORT:
-      if(long_name) return "unsigned short";  else return "us";
-
-    case GAL_DATA_TYPE_SHORT:
-      if(long_name) return "short";           else return "s";
-
-    case GAL_DATA_TYPE_UINT:
-      if(long_name) return "unsigned int";    else return "ui";
-
-    case GAL_DATA_TYPE_INT:
-      if(long_name) return "int";             else return "i";
-
-    case GAL_DATA_TYPE_ULONG:
-      if(long_name) return "unsigned long";   else return "ul";
-
-    case GAL_DATA_TYPE_LONG:
-      if(long_name) return "long";            else return "l";
-
-    case GAL_DATA_TYPE_LONGLONG:
-      if(long_name) return "LONGLONG";        else return "L";
+      gal_checkset_allocate_copy(string, value);
+      break;
 
+    /* Floating point: Read it as a double or long, then put it in the
+       array. When the conversion can't be done (the string isn't a number
+       for example), then just assume no blank value was given. */
     case GAL_DATA_TYPE_FLOAT:
-      if(long_name) return "float";           else return "f";
-
     case GAL_DATA_TYPE_DOUBLE:
-      if(long_name) return "double";          else return "d";
-
-    case GAL_DATA_TYPE_COMPLEX:
-      if(long_name) return "complex float";   else return "cf";
-
-    case GAL_DATA_TYPE_DCOMPLEX:
-      if(long_name) return "complex double";  else return "cd";
-
-    default:
-      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
-            "`gal_data_type_as_string'", type);
-    }
-
-  /* Any of the cases above should return this function, so if control
-     reaches here, there is a bug. */
-  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 "
-        "the `gal_data_type_as_string' function. This must not happen",
-        PACKAGE_BUGREPORT);
-  return NULL;
-}
-
-
-
-
-
-int
-gal_data_string_as_type(char *str)
-{
-  if(      !strcmp(str, "b")   || !strcmp(str, "bit") )
-    return GAL_DATA_TYPE_BIT;
-
-  else if( !strcmp(str, "uc")  || !strcmp(str, "unsigned char") )
-    return GAL_DATA_TYPE_UCHAR;
-
-  else if( !strcmp(str, "c")   || !strcmp(str, "char") )
-    return GAL_DATA_TYPE_CHAR;
-
-  else if( !strcmp(str, "str") || !strcmp(str, "string") )
-    return GAL_DATA_TYPE_STRING;
-
-  else if( !strcmp(str, "us")  || !strcmp(str, "unsigned short") )
-    return GAL_DATA_TYPE_USHORT;
-
-  else if( !strcmp(str, "s")   || !strcmp(str, "short") )
-    return GAL_DATA_TYPE_SHORT;
-
-  else if( !strcmp(str, "ui")  || !strcmp(str, "unsigned int") )
-    return GAL_DATA_TYPE_UINT;
-
-  else if( !strcmp(str, "i")   || !strcmp(str, "int") )
-    return GAL_DATA_TYPE_INT;
-
-  else if( !strcmp(str, "ul")  || !strcmp(str, "unsigned long") )
-    return GAL_DATA_TYPE_ULONG;
-
-  else if( !strcmp(str, "l")   || !strcmp(str, "long") )
-    return GAL_DATA_TYPE_LONG;
-
-  else if( !strcmp(str, "L")   || !strcmp(str, "LONGLONG") )
-    return GAL_DATA_TYPE_LONGLONG;
-
-  else if( !strcmp(str, "f")   || !strcmp(str, "float") )
-    return GAL_DATA_TYPE_FLOAT;
-
-  else if( !strcmp(str, "d")   || !strcmp(str, "double") )
-    return GAL_DATA_TYPE_DOUBLE;
-
-  else if( !strcmp(str, "cf")  || !strcmp(str, "complex float") )
-    return GAL_DATA_TYPE_COMPLEX;
-
-  else if( !strcmp(str, "cd")  || !strcmp(str, "complex double") )
-    return GAL_DATA_TYPE_DCOMPLEX;
-
-  else
-    return GAL_DATA_TYPE_INVALID;
-
-  /* Any of the cases above should return this function, so if control
-     reaches here, there is a bug. */
-  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 "
-        "the `gal_data_string_as_type' function. This must not happen",
-        PACKAGE_BUGREPORT);
-  return 0;
-}
-
-
-
-
+      d=strtod(string, &tailptr);
+      if(*tailptr!='\0')
+        status=1;
+      else
+        {
+          if(type==GAL_DATA_TYPE_FLOAT) *(float *) value=d;
+          else                          *(double *) value=d;
+        }
+      break;
 
-/* Put the minimum (or maximum for the `gal_data_type_max') value for the
-   type in the space (that must already be allocated before the call to
-   this function) pointed to by in.  */
-void
-gal_data_type_min(int type, void *in)
-{
-  switch(type)
-    {
-    case GAL_DATA_TYPE_UCHAR:    *(unsigned char *)in  = 0;            break;
-    case GAL_DATA_TYPE_CHAR:     *(char *)in           = CHAR_MIN;     break;
-    case GAL_DATA_TYPE_USHORT:   *(unsigned short *)in = 0;            break;
-    case GAL_DATA_TYPE_SHORT:    *(short *)in          = SHRT_MIN;     break;
-    case GAL_DATA_TYPE_UINT:     *(unsigned int *)in   = 0;            break;
-    case GAL_DATA_TYPE_INT:      *(int *)in            = INT_MIN;      break;
-    case GAL_DATA_TYPE_ULONG:    *(unsigned long *)in  = 0;            break;
-    case GAL_DATA_TYPE_LONG:     *(long *)in           = LONG_MIN;     break;
-    case GAL_DATA_TYPE_LONGLONG: *(LONGLONG *)in       = LONGLONG_MIN; break;
-    case GAL_DATA_TYPE_FLOAT:    *(float *)in          = -FLT_MAX;     break;
-    case GAL_DATA_TYPE_DOUBLE:   *(double *)in         = -DBL_MAX;     break;
+    /* Integers. */
     default:
-      error(EXIT_FAILURE, 0, "type code %d not recognized in "
-            "`gal_data_type_min'", type);
+      L=strtoll(string, &tailptr, 0);
+      if(*tailptr!='\0')
+        status=1;
+      else
+        switch(type)
+          {
+          /* The signed values can easily be put in. */
+          case GAL_DATA_TYPE_CHAR:             *(char *) value = L; break;
+          case GAL_DATA_TYPE_SHORT:           *(short *) value = L; break;
+          case GAL_DATA_TYPE_INT:               *(int *) value = L; break;
+          case GAL_DATA_TYPE_LONG:             *(long *) value = L; break;
+          case GAL_DATA_TYPE_LONGLONG:     *(LONGLONG *) value = L; break;
+
+          /* For the unsigned types, the value has to be positive, so if
+             the input was negative, then just return a status of one and
+             don't store the value. */
+          default:
+            if(L<0)
+              status=1;
+            else
+              switch(type)
+                {
+                case GAL_DATA_TYPE_UCHAR:  *(unsigned char *)  value=L; break;
+                case GAL_DATA_TYPE_USHORT: *(unsigned short *) value=L; break;
+                case GAL_DATA_TYPE_UINT:   *(unsigned int *)   value=L; break;
+                case GAL_DATA_TYPE_ULONG:  *(unsigned long *)  value=L; break;
+                default:
+                  error(EXIT_FAILURE, 0, "type code %d not recognized in "
+                        "`gal_data_string_to_type'", type);
+                }
+          }
     }
-}
-
-
 
-
-
-void
-gal_data_type_max(int type, void *in)
-{
-  switch(type)
-    {
-    case GAL_DATA_TYPE_UCHAR:    *(unsigned char *)in  = UCHAR_MAX;    break;
-    case GAL_DATA_TYPE_CHAR:     *(char *)in           = CHAR_MAX;     break;
-    case GAL_DATA_TYPE_USHORT:   *(unsigned short *)in = USHRT_MAX;    break;
-    case GAL_DATA_TYPE_SHORT:    *(short *)in          = SHRT_MAX;     break;
-    case GAL_DATA_TYPE_UINT:     *(unsigned int *)in   = UINT_MAX;     break;
-    case GAL_DATA_TYPE_INT:      *(int *)in            = INT_MAX;      break;
-    case GAL_DATA_TYPE_ULONG:    *(unsigned long *)in  = ULONG_MAX;    break;
-    case GAL_DATA_TYPE_LONG:     *(long *)in           = LONG_MAX;     break;
-    case GAL_DATA_TYPE_LONGLONG: *(LONGLONG *)in       = LONGLONG_MAX; break;
-    case GAL_DATA_TYPE_FLOAT:    *(float *)in          = FLT_MAX;      break;
-    case GAL_DATA_TYPE_DOUBLE:   *(double *)in         = DBL_MAX;      break;
-    default:
-      error(EXIT_FAILURE, 0, "type code %d not recognized in "
-            "`gal_data_type_min'", type);
-    }
+  /* If reading was unsuccessful, then free the space if it was allocated,
+     then return the status. */
+  if(status && allocated)
+    free(value);
+  return status;
 }
diff --git a/lib/fixedstringmacros.h b/lib/fixedstringmacros.h
index 1979cdf..70d01e1 100644
--- a/lib/fixedstringmacros.h
+++ b/lib/fixedstringmacros.h
@@ -40,7 +40,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #define GAL_STRINGS_TOP_HELP_INFO                                       \
-  "\n"SPACK_NAME" is part of "PACKAGE_STRING".\n"
+  "\n"PROG_NAME" is part of "PACKAGE_STRING".\n"
 
 
 
@@ -48,17 +48,18 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define GAL_STRINGS_MORE_HELP_INFO                                      \
   "\nFor more information, please run any of the "                      \
   "following commands. They will respectively show you the `Invoking "  \
-  SPACK_NAME"' subsection, the complete `"SPACK_NAME"' section, or "    \
-  "the full "PACKAGE_NAME" manual. In particular the first contains "   \
-  "a very complete explanation of each option.\n\n"                     \
-  "     info "SPACK"\n\n"                                               \
-  "     info "SPACK_NAME"\n\n"                                          \
+  PROG_NAME"' subsection, the complete `"PROG_NAME"' section, or the"   \
+  "full "PACKAGE_NAME" manual. In particular the first contains a very "\
+  "comprehensive explanation of "PROG_NAME"'s invocation and all the "  \
+  "options.\n\n"                                                        \
+  "     info "PROG_EXEC"\n\n"                                           \
+  "     info "PROG_NAME"\n\n"                                           \
   "     info "PACKAGE_TARNAME"\n\n"                                     \
   "If you couldn't find your answer in the manual, you can get "        \
   "direct help from experienced Gnuastro users and developers. "        \
   "For more information, please run:\n\n"                               \
   "     info help-gnuastro\n\n"                                         \
-  SPACK_NAME" options:"                                                 \
+  PROG_NAME" options:"                                                  \
 
 
 
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 2be4e26..17f14ec 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -177,7 +177,8 @@ gal_data_type_min(int type, void *in);
 void
 gal_data_type_max(int type, void *in);
 
-
+int
+gal_data_is_linked_list(int type);
 
 
 
@@ -301,7 +302,8 @@ gal_data_to_same_type(gal_data_t *f, gal_data_t *s,
 gal_data_t *
 gal_data_string_to_number(char *string);
 
-
+int
+gal_data_string_to_type(void **out, char *string, int type);
 
 
 
diff --git a/lib/options.c b/lib/options.c
new file mode 100644
index 0000000..f299677
--- /dev/null
+++ b/lib/options.c
@@ -0,0 +1,244 @@
+/*********************************************************************
+Function to parse options and configuration file values.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+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
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#include <config.h>
+
+#include <argp.h>
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gnuastro/data.h>
+
+#include <options.h>
+
+
+
+
+
+
+
+
+
+
+/**********************************************************************/
+/************             Option utilities              ***************/
+/**********************************************************************/
+int
+gal_options_is_last(struct argp_option *option)
+{
+  return ( option->key==0 && option->name==NULL
+           && option->doc==NULL && option->group==0 );
+}
+
+
+
+
+int
+gal_options_is_category_title(struct argp_option *option)
+{
+  return ( option->key==0 && option->name==NULL );
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**********************************************************************/
+/************            Command-line options           ***************/
+/**********************************************************************/
+/* Set the value given to the command-line, where we have the integer `key'
+   of the option, not its long name as a string. */
+error_t
+gal_options_set_from_key(int key, char *arg, struct argp_option *options)
+{
+  size_t i;
+
+  /* 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
+     options array finishs with an all zero element, so we don't need to
+     know the number before hand.*/
+  for(i=0;1;++i)
+    {
+      /* Check if the key corresponds to this option. */
+      if(options[i].key==key)
+        {
+          /* 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.
+
+             As a result, only when searching for options on the
+             command-line, a second value to the same option will replace
+             the first one. This will not happen in configuration files. */
+          if(options[i].value && gal_data_is_linked_list(options[i].type)==0)
+            {
+              free(options[i].value);
+              options[i].value=NULL;
+            }
+
+          /* 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]. */
+          if(arg)
+            gal_data_string_to_type(&options[i].value, arg,
+                                    options[i].type);
+          else
+            {
+              /* Make sure the option has the type set for options with no
+                 argument. So, give it a value of 1. */
+              if(options[i].type==GAL_OPTIONS_NO_ARG_TYPE)
+                gal_data_string_to_type(&(options[i].value), "1",
+                                        options[i].type);
+              else
+                error(EXIT_FAILURE, 0, "A bug! Please contact us at %s to "
+                      "correct it. Options with no arguments, must have "
+                      "type `%s' to be read in `gal_options_read_from_key'. "
+                      "However, the option with key `%d' has type %s",
+                      PACKAGE_BUGREPORT,
+                      gal_data_type_as_string(GAL_OPTIONS_NO_ARG_TYPE, 1),
+                      key, gal_data_type_as_string(options[i].type, 1));
+            }
+
+
+          /* We have found and set the value given to this option, so just
+             return success (an error_t of 0 means success). */
+          return 0;
+        }
+      else
+        {
+          /* The last option has all its values set to zero. */
+          if(gal_options_is_last(&options[i]))
+            return ARGP_ERR_UNKNOWN;
+        }
+    }
+}
+
+
+
+
+
+error_t
+gal_options_common_argp_parse(int key, char *arg, struct argp_state *state)
+{
+  /* In case the user incorrectly uses the equal sign (for example
+     with a short format or with space in the long format, then `arg`
+     start with (if the short version was called) or be (if the long
+     version was called with a space) the equal sign. So, here we
+     check if the first character of arg is the equal sign, then the
+     user is warned and the program is stopped: */
+  if(arg && arg[0]=='=')
+    argp_error(state, "incorrect use of the equal sign (`=`). For short "
+               "options, `=` should not be used and for long options, "
+               "there should be no space between the option, equal sign "
+               "and value");
+
+  /*********************************************************************/
+  /*********************************************************************/
+  /*********************************************************************
+
+
+   -----> Do this check before passing control to the program. <-----
+
+
+  if( key==ARGP_KEY_END )
+    {
+      if(cp->setdirconf && cp->setusrconf)
+        error(EXIT_FAILURE, 0, "only one of `--setusrconf` or "
+              "`--setdirconf` may be set in each run. You have asked "
+              "for both");
+    }
+   *********************************************************************/
+  /*********************************************************************/
+  /*********************************************************************/
+
+  return gal_options_set_from_key(key, arg, gal_commonopts_options);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**********************************************************************/
+/************            Configuration files            ***************/
+/**********************************************************************/
+/*
+error_t
+gal_options_set_from_name(char *name, char *arg, struct argp_option *options)
+{
+
+}
+*/
+
+
+
+
+/* Read the configuration files and put the values of the options not given
+   into it. The directories containing the configuration files are fixed
+   for all the programs.
+
+    - `SYSCONFIG_DIR' is passed onto each program at compile time from the
+      command-line. You can search for it in the outputs of `make'.
+
+    - `'
+*/
+void
+gal_options_parse_configs(char *progname, struct argp_option *progopts,
+                          struct argp_option *commopts)
+{
+  printf("\nhere\n");
+}
diff --git a/lib/options.h b/lib/options.h
new file mode 100644
index 0000000..9febc1b
--- /dev/null
+++ b/lib/options.h
@@ -0,0 +1,111 @@
+/*********************************************************************
+Function to parse options and configuration file values.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+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
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#ifndef __GAL_OPTIONS_H__
+#define __GAL_OPTIONS_H__
+
+#include <argp.h>
+
+#include <gnuastro/data.h>
+
+
+
+
+
+
+/**********************************************************************/
+/************                Common options             ***************/
+/**********************************************************************/
+
+/* Type for options that don't accept an argument/value. This macro is
+   defined to help make the definition and processing of these options
+   easier and less buggy. Please use this macro for such options. */
+#define GAL_OPTIONS_NO_ARG_TYPE GAL_DATA_TYPE_UCHAR
+
+
+extern struct argp_option gal_commonopts_options[];
+
+
+/* The structure keeping all the values of the common options in Gnuastro's
+   programs. */
+struct gal_options_common_params
+{
+  /* Input/Output: */
+  char          *hdu;     /* Image extension.                            */
+  char       *output;     /* Directory containg output.                  */
+  int     dontdelete;     /* ==1: Don't delete existing file.            */
+  int   keepinputdir;     /* Keep input directory for automatic output.  */
+
+  /* Operating modes: */
+  int          quiet;     /* ==1: don't print anything but errors.       */
+  size_t  numthreads;     /* Number of threads to use.                   */
+  size_t  minmapsize;     /* The minimum bytes necessary to use mmap.    */
+  int            log;     /* Make a log file.                            */
+
+  /* Internal (before control goes back to the program). */
+  int           cite;     /* BibTeX citation for program and abort.      */
+  int    printparams;     /* Print all option values and abort.          */
+  int     setdirconf;     /* Set default values for this dir and abort.  */
+  int     setusrconf;     /* Set default values for this user and abort. */
+  int    onlydirconf;     /* Only read current directory config file.    */
+  int    onlyversion;     /* Only run program with this version.         */
+};
+
+
+
+
+
+/**********************************************************************/
+/************         Main user functions/macros        ***************/
+/**********************************************************************/
+
+int
+gal_options_is_last(struct argp_option *option);
+
+int
+gal_options_is_category_title(struct argp_option *option);
+
+
+
+
+
+/**********************************************************************/
+/************            Command-line options           ***************/
+/**********************************************************************/
+error_t
+gal_options_set_from_key(int key, char *arg, struct argp_option *options);
+
+error_t
+gal_options_common_argp_parse(int key, char *arg, struct argp_state *state);
+
+
+
+
+
+/**********************************************************************/
+/************            Configuration files            ***************/
+/**********************************************************************/
+void
+gal_options_parse_configs(char *progname, struct argp_option *progopts,
+                          struct argp_option *commopts);
+
+
+#endif
diff --git a/lib/table.c b/lib/table.c
index 62be3c2..bda2f62 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -349,83 +349,29 @@ gal_table_col_print_info(gal_data_t *col, int tabletype, 
char *fmt, char *lng)
 void
 gal_table_read_blank(gal_data_t *col, char *blank)
 {
-  double d;
-  long long L;
-  char *tailptr;
-
   /* If there is nothing to use as blank, then don't continue, note that
      the column data structure was initialized to mean that there is no
      blank value. */
   if(blank==NULL) return;
 
-  /* Just for a sanity check, the ndim element should be zero. */
-  if(col->ndim)
-    error(EXIT_FAILURE, 0, "A bug! The number of dimensions in the data "
-          "structure passed `to gal_table_read_blank' must be zero, but it "
-          "is %zu", col->ndim);
-
-  /* Allocate space to keep the blank value and initialize the dimension
-     and size parameters appropriately. */
-  errno=0;
-  col->dsize=malloc(sizeof *col->dsize);
-  if(col->dsize==NULL)
-    error(EXIT_FAILURE, 0, "%zu bytes for `col->dsize' in `txt_read_blank' ",
-          sizeof *col->dsize);
-  col->dsize[0]=col->ndim=col->size=1;
-  col->array=gal_data_malloc_array(col->type, col->size);
-
-  /* Put the blank value in depending on the type.*/
-  switch(col->type)
-    {
-
-    /* String. */
-    case GAL_DATA_TYPE_STRING:
-      gal_checkset_allocate_copy(blank, col->array);
-      break;
-
-    /* Floating point: Read it as a double or long, then put it in the
-       array. When the conversion can't be done (the string isn't a number
-       for example), then just assume no blank value was given. */
-    case GAL_DATA_TYPE_FLOAT:
-    case GAL_DATA_TYPE_DOUBLE:
-      d=strtod(blank, &tailptr);
-      if(*tailptr!='\0') { free(col->array); col->array=NULL;}
-      else
-        {
-          if(col->type==GAL_DATA_TYPE_FLOAT) *(float *) col->array=d;
-          else                              *(double *) col->array=d;
-        }
-      break;
-
-    /* Integers. */
-    default:
-      L=strtoll(blank, &tailptr, 0);
-      if(*tailptr!='\0') { free(col->array); col->array=NULL; }
-      else
-        switch(col->type)
-          {
-          case GAL_DATA_TYPE_UCHAR:   *(unsigned char *) col->array=L; break;
-          case GAL_DATA_TYPE_CHAR:             *(char *) col->array=L; break;
-          case GAL_DATA_TYPE_USHORT: *(unsigned short *) col->array=L; break;
-          case GAL_DATA_TYPE_SHORT:           *(short *) col->array=L; break;
-          case GAL_DATA_TYPE_UINT:     *(unsigned int *) col->array=L; break;
-          case GAL_DATA_TYPE_INT:               *(int *) col->array=L; break;
-          case GAL_DATA_TYPE_ULONG:   *(unsigned long *) col->array=L; break;
-          case GAL_DATA_TYPE_LONG:             *(long *) col->array=L; break;
-          case GAL_DATA_TYPE_LONGLONG:     *(LONGLONG *) col->array=L; break;
-          default:
-            error(EXIT_FAILURE, 0, "type code %d not recognized in "
-                  "`txt_str_to_blank'", col->type);
-          }
-    }
-
-  /* If the blank value couldn't be read, then set the initialized lengths
-     to zero again, as if this function wasn't called at all. */
-  if(col->array==NULL)
+  /* Just for a sanity check, the ndim and array elements should be zero. */
+  if(col->ndim || col->array)
+    error(EXIT_FAILURE, 0, "A bug! The number of dimensions, and the pointer "
+          "to the array in the data structure passed "
+          "`to gal_table_read_blank' must be zero");
+
+  /* Read the blank value as the given type, If successful, then
+     `gal_data_string_to_type) will return 0. In that case, we need to
+     initialize the necessary paramters to read this data structure
+     correctly. */
+  if(gal_data_string_to_type(&(col->array), blank, col->type)==0)
     {
-      col->ndim=col->size=0;
-      free(col->dsize);
-      col->dsize=NULL;
+      errno=0;
+      col->dsize=malloc(sizeof *col->dsize);
+      if(col->dsize==NULL)
+        error(EXIT_FAILURE, 0, "%zu bytes for `col->dsize' in "
+              "`txt_read_blank' ", sizeof *col->dsize);
+      col->dsize[0]=col->ndim=col->size=1;
     }
 }
 



reply via email to

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