gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master cd5b5cf 13/16: Table prints contents of a FITS


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master cd5b5cf 13/16: Table prints contents of a FITS table
Date: Wed, 24 Aug 2016 22:27:44 +0000 (UTC)

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

    Table prints contents of a FITS table
    
    Table can now print the contents of a FITS table to the standard
    output. There are several options to determine the formatting of the output
    when it is printed. Currently for each column on each row a separate printf
    statement is issued, the speed is not bad, but there might be more
    efficient ways that we will have to work on.
---
 src/table/args.h        |  118 +++++++++++++++++++-
 src/table/asttable.conf |   12 +-
 src/table/main.h        |   50 +++++++--
 src/table/table.c       |  278 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/table/table.h       |    2 +
 src/table/ui.c          |  241 ++++++++++++++++++++++++++++++++--------
 src/table/ui.h          |    3 +
 7 files changed, 640 insertions(+), 64 deletions(-)

diff --git a/src/table/args.h b/src/table/args.h
index 9adb9ce..8708878 100644
--- a/src/table/args.h
+++ b/src/table/args.h
@@ -58,7 +58,10 @@ static char args_doc[] = "ASTRdata";
 const char doc[] =
   /* Before the list of options: */
   GAL_STRINGS_TOP_HELP_INFO
-  SPACK_NAME" print a FITS table or its information. \n"
+  SPACK_NAME" prints (in a human readable format) a FITS table or its "
+  "information. The output columns can either be selected by number, name "
+  "or using regular expressions. The format of their printing can also "
+  "be set (based on the type of data in the column).\n"
   GAL_STRINGS_MORE_HELP_INFO
   /* After the list of options: */
   "\v"
@@ -73,7 +76,7 @@ const char doc[] =
    a b d e f g j k l m n p r s t u v w x y z
    A B C E F G H J L M O Q R T U W X Y Z
 
-   Number keys used: Nothing!
+   Number keys used: 1008
 
    Options with keys (second structure element) larger than 500 do not
    have a short version.
@@ -110,6 +113,71 @@ static struct argp_option options[] =
       "Output:",
       2
     },
+    {
+      "feg",
+      1001,
+      "STR",
+      0,
+      "`f': only decimals, `e': scientific, `g': either.",
+      2
+    },
+    {
+      "sintwidth",
+      1002,
+      "INT",
+      0,
+      "Shorter integer column(s) width (num charachers).",
+      2
+    },
+    {
+      "lintwidth",
+      1003,
+      "INT",
+      0,
+      "Longer integer column(s) width (num charachers).",
+      2
+    },
+    {
+      "floatwidth",
+      1004,
+      "INT",
+      0,
+      "`float' column(s) width (num charachers).",
+      2
+    },
+    {
+      "doublewidth",
+      1005,
+      "INT",
+      0,
+      "`double' column(s) width (num charachers).",
+      2
+    },
+    {
+      "strwidth",
+      1006,
+      "INT",
+      0,
+      "String column(s) width (num charachers).",
+      2
+    },
+    {
+      "floatprecision",
+      1007,
+      "INT",
+      0,
+      "`float' column(s) precision.",
+      2
+    },
+    {
+      "doubleprecision",
+      1008,
+      "INT",
+      0,
+      "`double' column(s) precision.",
+      2
+    },
+
 
 
 
@@ -176,6 +244,52 @@ parse_opt(int key, char *arg, struct argp_state *state)
 
 
     /* Output: */
+    case 1001:
+      checkfge(arg, &p->up.feg);
+      p->up.fegset=1;
+      break;
+
+    case 1002:
+      gal_checkset_sizet_el_zero(arg, &p->up.sintwidth, "sintwidth", key,
+                                 SPACK, NULL, 0);
+      p->up.sintwidthset=1;
+      break;
+
+    case 1003:
+      gal_checkset_sizet_el_zero(arg, &p->up.lintwidth, "lintwidth", key,
+                                 SPACK, NULL, 0);
+      p->up.lintwidthset=1;
+      break;
+
+    case 1004:
+      gal_checkset_sizet_el_zero(arg, &p->up.floatwidth, "floatwidth", key,
+                                 SPACK, NULL, 0);
+      p->up.floatwidthset=1;
+      break;
+
+    case 1005:
+      gal_checkset_sizet_el_zero(arg, &p->up.doublewidth, "doublewidth", key,
+                                 SPACK, NULL, 0);
+      p->up.doublewidthset=1;
+      break;
+
+    case 1006:
+      gal_checkset_sizet_el_zero(arg, &p->up.strwidth, "strwidth", key,
+                                 SPACK, NULL, 0);
+      p->up.strwidthset=1;
+      break;
+
+    case 1007:
+      gal_checkset_sizet_el_zero(arg, &p->up.floatprecision,
+                                 "floatprecision", key, SPACK, NULL, 0);
+      p->up.floatprecisionset=1;
+      break;
+
+    case 1008:
+      gal_checkset_sizet_el_zero(arg, &p->up.doubleprecision,
+                                 "doubleprecision", key, SPACK, NULL, 0);
+      p->up.doubleprecisionset=1;
+      break;
 
 
     /* Operating modes: */
diff --git a/src/table/asttable.conf b/src/table/asttable.conf
index f5d6183..77973eb 100644
--- a/src/table/asttable.conf
+++ b/src/table/asttable.conf
@@ -18,6 +18,14 @@
 # without any warranty.
 
 # Input:
- hdu            0
+ hdu              0
 
-# Output:
\ No newline at end of file
+# Output:
+ feg              f
+ sintwidth        5
+ lintwidth       15
+ floatwidth      10
+ doublewidth     15
+ strwidth        20
+ floatprecision   3
+ doubleprecision  8
diff --git a/src/table/main.h b/src/table/main.h
index eea7b56..2e7bfd1 100644
--- a/src/table/main.h
+++ b/src/table/main.h
@@ -31,9 +31,19 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define SPACK_NAME      "Table"    /* Subpackage full name.       */
 #define SPACK_STRING    SPACK_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
 
+#define MAX_COL_FORMAT_LENGTH 20
 
 
 
+/* Structure to keep the information for each output column */
+struct outcolumn
+{
+  size_t inindex;               /* Row index (from 0) in input array.   */
+  int   datatype;               /* Type of data (from CFITSIO macros).  */
+  int     anynul;               /* If there is any blank characters.    */
+  void     *data;               /* Array keeping the column data.       */
+  char fmt[MAX_COL_FORMAT_LENGTH];  /* format to use in printf.         */
+};
 
 
 
@@ -47,9 +57,36 @@ struct uiparams
   char               *txtname;  /* Name of input text file.             */
   int              ignorecase;  /* Ignore case matching column names.   */
 
+  /* Input table parameters. */
+  size_t                ncols;  /* Number of columns in table.          */
+  int               *datatype;  /* Type of data in column.              */
+  char                **tform;  /* TFORM (another format for type).     */
+  char                **ttype;  /* Column name (one word).              */
+  char                **tunit;  /* Unit of values in column.            */
+
+  /* Print parameters: */
+  int                     feg;  /* format of floating points.           */
+  size_t            sintwidth;  /* Full width for short integers.       */
+  size_t            lintwidth;  /* Full width for short integers.       */
+  size_t           floatwidth;  /* Full width for all floats.           */
+  size_t          doublewidth;  /* Full width for all doubles.          */
+  size_t             strwidth;  /* Full width for all floats.           */
+  size_t       floatprecision;  /* Number of decimals for floats.       */
+  size_t      doubleprecision;  /* Number of decimals for doubles.      */
+
+  /* If values are set: */
   int                inputset;
   int          informationset;
   int           ignorecaseset;
+  int                  fegset;
+  int            sintwidthset;
+  int            lintwidthset;
+  int           floatwidthset;
+  int          doublewidthset;
+  int             strwidthset;
+  int       floatprecisionset;
+  int      doubleprecisionset;
+
 
   struct gal_linkedlist_stll *columns;
 };
@@ -69,20 +106,13 @@ struct tableparams
   fitsfile           *fitsptr;  /* FITS pointer (input or output).      */
 
   /* Output: */
-  size_t               nocols;  /* Number of output columns.            */
-  size_t               *ocols;  /* Output column indexs in input table. */
-
-  /* FITS table */
   size_t                nrows;  /* Number of rows in table.             */
-  size_t                ncols;  /* Number of columns in table.          */
-  int               *typecode;  /* Type of data in column.              */
-  char                **tform;  /* TFORM (another format for type).     */
-  char                **ttype;  /* Column name (one word).              */
-  char                **tunit;  /* Unit of values in column.            */
+  size_t               nocols;  /* Number of output columns.            */
+  struct outcolumn     *ocols;  /* Array of output column informatio.   */
 
   /* Internal: */
   int                onlyview;
-  time_t              rawtime;  /* Starting time of the program.      */
+  time_t              rawtime;  /* Starting time of the program.        */
 };
 
 #endif
diff --git a/src/table/table.c b/src/table/table.c
index 079800a..588aa42 100644
--- a/src/table/table.c
+++ b/src/table/table.c
@@ -34,16 +34,290 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+/**************************************************************/
+/***************        Input table         *******************/
+/**************************************************************/
+/* Set the format string for each column: */
+void
+setformatstring(struct tableparams *p, size_t outcolid)
+{
+  struct uiparams *up=&p->up;
+  char width[10], accu[10], *type=NULL;
+  struct outcolumn *ocol=&p->ocols[outcolid];
+
+
+  switch(ocol->datatype)
+    {
+    case TBIT:
+      error(EXIT_FAILURE, 0, "Table doesn't print TBIT data type "
+            "currently, please contact us at %s so we can implement "
+            "it.", PACKAGE_BUGREPORT);
+
+    case TBYTE:
+      type="u";
+      sprintf(width, "%lu", up->sintwidth);
+      accu[0]='\0';
+      break;
+
+    case TLOGICAL: case TSBYTE:
+      type="d";
+      sprintf(width, "%lu", up->sintwidth);
+      accu[0]='\0';
+      break;
+
+    case TSTRING:
+      type="s";
+      if(up->sintwidth) sprintf(width, "%lu", up->sintwidth);
+      else width[0]='\0';
+      accu[0]='\0';
+      break;
+
+    case TSHORT:
+      type="d";
+      sprintf(width, "%lu", up->sintwidth);
+      accu[0]='\0';
+      break;
+
+    case TLONG:
+      type="ld";
+      sprintf(width, "%lu", up->lintwidth);
+      accu[0]='\0';
+      break;
+
+    case TLONGLONG:
+      type="ld";
+      sprintf(width, "%lu", up->lintwidth);
+      accu[0]='\0';
+      break;
+
+    case TFLOAT:
+      type = up->feg=='f' ? "f" : ( up->feg=='e' ? "e" : "g");
+      sprintf(width, "%lu", up->floatwidth);
+      sprintf(accu, ".%lu", up->floatprecision);
+      break;
+
+    case TDOUBLE:
+      type = up->feg=='f' ? "f" : ( up->feg=='e' ? "e" : "g");
+      sprintf(width, "%lu", up->doublewidth);
+      sprintf(accu, ".%lu", up->doubleprecision);
+      break;
+
+    case TCOMPLEX:
+      error(EXIT_FAILURE, 0, "Table doesn't print TCOMPLEX data type "
+            "currently, please contact us at %s so we can implement "
+            "it.", PACKAGE_BUGREPORT);
+      break;
+
+    case TDBLCOMPLEX:
+      error(EXIT_FAILURE, 0, "Table doesn't print TDBLCOMPLEX data type "
+            "currently, please contact us at %s so we can implement "
+            "it.", PACKAGE_BUGREPORT);
+      break;
+
+    case TINT:
+      type="d";
+      sprintf(width, "%lu", up->sintwidth);
+      accu[0]='\0';
+      break;
+
+    case TUINT:
+      type="u";
+      sprintf(width, "%lu", up->sintwidth);
+      accu[0]='\0';
+      break;
+
+    case TUSHORT:
+      type="u";
+      sprintf(width, "%lu", up->sintwidth);
+      accu[0]='\0';
+      break;
+
+    case TULONG:
+      type="lu";
+      sprintf(width, "%lu", up->lintwidth);
+      accu[0]='\0';
+      break;
+
+    default:
+      error(EXIT_FAILURE, 0, "datatype value of %d not recognized in "
+            "gal_fits_datatype_alloc", ocol->datatype);
+    }
+
+  /* Put the type, width and accu into the format string for this
+     column: */
+  sprintf(ocol->fmt, "%%-%s%s%s", width, accu, type);
+}
+
+
+
+
+
+/* Read all the input columns */
+void
+readinputcols(struct tableparams *p)
+{
+  size_t i;
+  void *nulval;
+  struct outcolumn *col;
+  int datatype, status=0;
+
+  /* Get the contents of each table column: */
+  for(i=0;i<p->nocols;++i)
+    {
+      /* Variables for simple reading */
+      col=&p->ocols[i];
+      datatype=col->datatype;
+
+      /* Allocate the blank value and array to keep the actual of this
+         column. */
+      nulval=gal_fits_datatype_blank(datatype);
+      col->data=gal_fits_datatype_alloc(p->nrows, datatype);
+
+      /* Call CFITSIO to read the column information. */
+      fits_read_col(p->fitsptr, datatype, col->inindex+1, 1, 1,
+                    p->nrows, nulval, col->data, &col->anynul,
+                    &status);
+
+      /* Free the space allocated for the blank value, we don't need it any
+         more: it is an internal macro to Gnuastro (see `fits.h'), */
+      free(nulval);
+
+      /* Set the format string to print the column values. */
+      setformatstring(p, i);
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/***************       Output table         *******************/
+/**************************************************************/
+void
+printoutput(struct tableparams *p)
+{
+  size_t i, row;
+  struct outcolumn *ocols=p->ocols;
+
+  for(row=0;row<p->nrows;++row)
+    {
+      for(i=0;i<p->nocols;++i)
+        switch(ocols[i].datatype)
+          {
+          case TBIT:
+            error(EXIT_FAILURE, 0, "Table doesn't print TBIT data type "
+                  "currently, please contact us at %s so we can implement "
+                  "it.", PACKAGE_BUGREPORT);
+
+          case TBYTE:
+            printf(ocols[i].fmt, ((unsigned char *)ocols[i].data)[row]);
+            break;
+
+          case TLOGICAL: case TSBYTE:
+            printf(ocols[i].fmt, ((char *)ocols[i].data)[row]);
+            break;
+
+          case TSTRING:
+            printf(ocols[i].fmt, ((char **)ocols[i].data)[row]);
+            break;
+
+          case TSHORT:
+            printf(ocols[i].fmt, ((short *)ocols[i].data)[row]);
+            break;
+
+          case TLONG:
+            printf(ocols[i].fmt, ((long *)ocols[i].data)[row]);
+            break;
+
+          case TLONGLONG:
+            printf(ocols[i].fmt, ((LONGLONG *)ocols[i].data)[row]);
+            break;
+
+          case TFLOAT:
+            printf(ocols[i].fmt, ((float *)ocols[i].data)[row]);
+            break;
+
+          case TDOUBLE:
+            printf(ocols[i].fmt, ((double *)ocols[i].data)[row]);
+            break;
+
+          case TCOMPLEX:
+            error(EXIT_FAILURE, 0, "Table doesn't print TCOMPLEX data type "
+                  "currently, please contact us at %s so we can implement "
+                  "it.", PACKAGE_BUGREPORT);
+            break;
+
+          case TDBLCOMPLEX:
+            error(EXIT_FAILURE, 0, "Table doesn't print TDBLCOMPLEX data "
+                  "type currently, please contact us at %s so we can "
+                  "implement it.", PACKAGE_BUGREPORT);
+            break;
+
+          case TINT:
+            printf(ocols[i].fmt, ((char *)ocols[i].data)[row]);
+            break;
+
+          case TUINT:
+            printf(ocols[i].fmt, ((unsigned int *)ocols[i].data)[row]);
+            break;
+
+          case TUSHORT:
+            printf(ocols[i].fmt, ((unsigned short *)ocols[i].data)[row]);
+            break;
+
+          case TULONG:
+            printf(ocols[i].fmt, ((unsigned long *)ocols[i].data)[row]);
+            break;
+
+          default:
+            error(EXIT_FAILURE, 0, "datatype value of %d not recognized in "
+                  "printoutput", ocols[i].datatype);
+          }
+      printf("\n");
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
 
-/* Print all the column information: */
 
 
 
 
 
-/* Top level function */
+/**************************************************************/
+/***************       Top function         *******************/
+/**************************************************************/
 void
 table(struct tableparams *p)
 {
+  readinputcols(p);
 
+  printoutput(p);
 }
diff --git a/src/table/table.h b/src/table/table.h
index e28f32e..8c164ec 100644
--- a/src/table/table.h
+++ b/src/table/table.h
@@ -23,6 +23,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef TABLE_H
 #define TABLE_H
 
+
+
 void
 table(struct tableparams *p);
 
diff --git a/src/table/ui.c b/src/table/ui.c
index c9fd8e5..f65a344 100644
--- a/src/table/ui.c
+++ b/src/table/ui.c
@@ -65,6 +65,21 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /**************************************************************/
 /**************       Options and parameters    ***************/
 /**************************************************************/
+/* Check the value given for the fge option. */
+void
+checkfge(char *optarg, int *fge)
+{
+  *fge=optarg[0];
+  if( *fge!='f' && *fge!='g' && *fge!='g' )
+    error(EXIT_FAILURE, 0, "the value of `--fge' (`-f') must only be "
+          "one of the three `f', `g', or `e' characters. You have "
+          "given `%s'.", optarg);
+}
+
+
+
+
+
 void
 readconfig(char *filename, struct tableparams *p)
 {
@@ -125,6 +140,69 @@ readconfig(char *filename, struct tableparams *p)
       else if(strcmp(name, "output")==0)
         gal_checkset_allocate_copy_set(value, &cp->output, &cp->outputset);
 
+      else if (strcmp(name, "feg")==0)
+        {
+          if(p->up.fegset) continue;
+          checkfge(value, &p->up.feg);
+          p->up.fegset=1;
+        }
+
+      else if (strcmp(name, "sintwidth")==0)
+        {
+          if(p->up.sintwidthset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.sintwidth, name,
+                                       key, SPACK, filename, lineno);
+          p->up.sintwidthset=1;
+        }
+
+      else if (strcmp(name, "lintwidth")==0)
+        {
+          if(p->up.lintwidthset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.lintwidth, name,
+                                       key, SPACK, filename, lineno);
+          p->up.lintwidthset=1;
+        }
+
+      else if (strcmp(name, "floatwidth")==0)
+        {
+          if(p->up.floatwidthset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.floatwidth, name,
+                                       key, SPACK, filename, lineno);
+          p->up.floatwidthset=1;
+        }
+
+      else if (strcmp(name, "doublewidth")==0)
+        {
+          if(p->up.doublewidthset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.doublewidth, name,
+                                       key, SPACK, filename, lineno);
+          p->up.doublewidthset=1;
+        }
+
+      else if (strcmp(name, "strwidth")==0)
+        {
+          if(p->up.strwidthset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.strwidth, name,
+                                       key, SPACK, filename, lineno);
+          p->up.strwidthset=1;
+        }
+
+      else if (strcmp(name, "floatprecision")==0)
+        {
+          if(p->up.floatprecisionset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.floatprecision,
+                                       name, key, SPACK, filename, lineno);
+          p->up.floatprecisionset=1;
+        }
+
+      else if (strcmp(name, "doubleprecision")==0)
+        {
+          if(p->up.doubleprecisionset) continue;
+          gal_checkset_sizet_el_zero(value, &p->up.doubleprecision,
+                                       name, key, SPACK, filename, lineno);
+          p->up.doubleprecisionset=1;
+        }
+
 
 
       /* Operating modes: */
@@ -164,7 +242,7 @@ printvalues(FILE *fp, struct tableparams *p)
 
   /* Print all the options that are set. Separate each group with a
      commented line explaining the options in that group. */
-  fprintf(fp, "\n# Input image:\n");
+  fprintf(fp, "\n# Input:\n");
   if(cp->hduset)
     GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("hdu", cp->hdu);
   if(up->columns)
@@ -174,6 +252,25 @@ printvalues(FILE *fp, struct tableparams *p)
     fprintf(fp, CONF_SHOWFMT"%d\n", "ignorecase", up->ignorecase);
 
 
+  fprintf(fp, "\n# Output:\n");
+  if(up->fegset)
+    fprintf(fp, CONF_SHOWFMT"%c\n", "feg", up->feg);
+  if(up->sintwidthset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "sintwidth", up->sintwidth);
+  if(up->lintwidthset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "lintwidth", up->lintwidth);
+  if(up->floatwidthset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "floatwidth", up->floatwidth);
+  if(up->doublewidthset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "doublewidth", up->doublewidth);
+  if(up->strwidthset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "strwidth", up->strwidth);
+  if(up->floatprecisionset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "floatprecision", up->floatprecision);
+  if(up->doubleprecisionset)
+    fprintf(fp, CONF_SHOWFMT"%lu\n", "doubleprecision", up->doubleprecision);
+
+
   /* For the operating mode, first put the macro to print the common
      options, then the (possible options particular to this
      program). */
@@ -195,12 +292,29 @@ 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->fegset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("feg");
+  if(up->sintwidthset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("sintwidth");
+  if(up->lintwidthset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("lintwidth");
+  if(up->floatwidthset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("floatwidth");
+  if(up->doublewidthset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("doublewidth");
+  if(up->strwidthset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("strwidth");
+  if(up->floatprecisionset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("floatprecision");
+  if(up->doubleprecisionset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("doubleprecision");
 
   GAL_CONFIGFILES_END_OF_NOTSET_REPORT;
 }
@@ -344,16 +458,16 @@ printinfo(struct tableparams *p)
 {
   size_t i;
   char *typestring=NULL;
+  struct uiparams *up=&p->up;
 
   printf("%s (hdu: %s)\n", p->up.fitsname, p->cp.hdu);
-  printf("Column information\n");
   printf("---------------------------------------------------------\n");
-  printf("%-5s%-25s%-20s%s\n", "No.", "Column name", "Data type",
-         "Units");
+  printf("%-5s%-25s%-15s%s\n", "No.", "Column name", "Units",
+         "Data type");
   printf("---------------------------------------------------------\n");
-  for(i=0;i<p->ncols;++i)
+  for(i=0;i<up->ncols;++i)
     {
-      switch(p->typecode[i])
+      switch(up->datatype[i])
         {
         case TBIT:
           typestring="bit";
@@ -399,11 +513,11 @@ printinfo(struct tableparams *p)
           break;
         default:
           error(EXIT_FAILURE, 0, "%d (from TFORM%lu='%c') is not a "
-                "recognized CFITSIO datatype.",
-                p->typecode[i], i, p->tform[i][0]);
+                "recognized CFITSIO datatype.", up->datatype[i],
+                i, up->tform[i][0]);
         }
-      printf("%-5lu%-25s%-20s%s\n", i+1, p->ttype[i] ? p->ttype[i] : "---",
-             typestring, p->tunit[i] ? p->tunit[i] : "---");
+      printf("%-5lu%-25s%-15s%s\n", i+1, up->ttype[i] ? up->ttype[i] : "---",
+             up->tunit[i] ? up->tunit[i] : "---", typestring);
     }
 
 
@@ -437,12 +551,15 @@ printinfo(struct tableparams *p)
 void
 sanitycheck(struct tableparams *p)
 {
+  struct uiparams *up=&p->up;
 
   /* Set the FITS pointer and check the type of the fits file. */
   if(p->up.fitsname)
     {
       gal_fits_read_hdu(p->up.fitsname, p->cp.hdu, 1, &p->fitsptr);
-      gal_fits_table_size(p->fitsptr, &p->nrows, &p->ncols);
+      gal_fits_table_size(p->fitsptr, &p->nrows, &up->ncols);
+      readallcolinfo(p->fitsptr, up->ncols, &up->datatype,
+                     &up->tform, &up->ttype, &up->tunit);
     }
   else
     error(EXIT_FAILURE, 0, "Table is a new addition to Gnuastro and "
@@ -456,8 +573,6 @@ sanitycheck(struct tableparams *p)
     {
       if(p->up.fitsname)
         {
-          readallcolinfo(p->fitsptr, p->ncols, &p->typecode,
-                         &p->tform, &p->ttype, &p->tunit);
           printinfo(p);
           freeandreport(p);
           exit(EXIT_SUCCESS);
@@ -493,6 +608,7 @@ sanitycheck(struct tableparams *p)
 /**************************************************************/
 /***************       Preparations         *******************/
 /**************************************************************/
+
 /* FUnction to print regular expression error. This is taken from the GNU C
    library manual, with small modifications to fit out style, */
 void
@@ -523,11 +639,12 @@ regexerrorexit(int errcode, regex_t *compiled, char 
*input)
 void
 outputcolumns(struct tableparams *p)
 {
-  size_t i;
   long tlong;
   regex_t *regex;
   int regreturn=0;
+  size_t i, inindex;
   char *tailptr, *colstring;
+  struct uiparams *up=&p->up;
   struct gal_linkedlist_sll *colsll=NULL;
 
   /* Go through each given column string and take the appropriate step. */
@@ -553,10 +670,10 @@ outputcolumns(struct tableparams *p)
 
           /* Check if the given value is not larger than the number of
              columns in the input catalog. */
-          if(tlong>p->ncols)
+          if(tlong>up->ncols)
             error(EXIT_FAILURE, 0, "%s (hdu: %s) has %lu columns, but "
                   "you have asked for column number %lu", p->up.fitsname,
-                  p->cp.hdu, p->ncols, tlong);
+                  p->cp.hdu, up->ncols, tlong);
 
           /* Everything seems to be fine, put this column number in the
              output column numbers linked list. Note that internally, the
@@ -565,15 +682,6 @@ outputcolumns(struct tableparams *p)
         }
       else
         {
-          /* First we need to make sure that the full column information is
-             ready (so we can parse the values of the column names in
-             p->ttype). Note that the parsing function to read all column
-             information is not set by default. Note that this is only done
-             once (for the first string value to the `--column' option).*/
-          if(p->ttype==NULL)
-            readallcolinfo(p->fitsptr, p->ncols, &p->typecode,
-                           &p->tform, &p->ttype, &p->tunit);
-
           /* Allocate the regex_t structure: */
           errno=0; regex=malloc(sizeof *regex);
           if(regex==NULL)
@@ -604,9 +712,9 @@ outputcolumns(struct tableparams *p)
              column names. Just note that column names are not mandatory in
              the FITS standard, so some (or all) columns might not have
              names, if so `p->ttype[i]' will be NULL. */
-          for(i=0;i<p->ncols;++i)
-            if(p->ttype[i] && regexec(regex, p->ttype[i], 0, 0, 0)==0)
-                gal_linkedlist_add_to_sll(&colsll, i);
+          for(i=0;i<up->ncols;++i)
+            if(up->ttype[i] && regexec(regex, up->ttype[i], 0, 0, 0)==0)
+              gal_linkedlist_add_to_sll(&colsll, i);
 
           /* Free the regex_t structure: */
           regfree(regex);
@@ -616,12 +724,28 @@ outputcolumns(struct tableparams *p)
       free(colstring);
     }
 
-  /* Put the desired columns (in reverse order due to the nature of a
-     linked list) into an array to read from later, then pop everything to
-     the un-used `i' variable from the list (which will automatically free
-     any allocate space). */
-  gal_linkedlist_sll_to_array(colsll, &p->ocols, &p->nocols, 1);
-  while(colsll) gal_linkedlist_pop_from_sll(&colsll, &i);
+  /* Based on the number of columns found above, allocate an array of
+     `outcolumn' structures to keep the information for each column. */
+  p->nocols=gal_linkedlist_num_in_sll(colsll);
+  errno=0;
+  p->ocols=malloc(p->nocols*sizeof *p->ocols);
+  if(p->ocols==NULL)
+    error(EXIT_FAILURE, errno, "%lu bytes for p->ocols",
+          p->nocols*sizeof *p->ocols);
+
+  /* Fill in the output column with the needed input table
+     information. Note that a simple linked list is first-in-last-out, so
+     we have to fill in the output columns in reverse order. Also, note
+     that we are popping from the linked list keeping the indexs of the
+     output columns and thus also freeing their allocated space. */
+  i=p->nocols-1;
+  while(colsll)
+    {
+      gal_linkedlist_pop_from_sll(&colsll, &inindex);
+      p->ocols[i].datatype=up->datatype[inindex];
+      p->ocols[i].inindex=inindex;
+      --i;
+    }
 }
 
 
@@ -632,6 +756,7 @@ void
 preparearrays(struct tableparams *p)
 {
   size_t i;
+  struct uiparams *up=&p->up;
 
   /* Set the columns that should be included in the output. If up->columns
      is set, then use it, otherwise, set all the columns for printing. */
@@ -639,13 +764,17 @@ preparearrays(struct tableparams *p)
     outputcolumns(p);
   else
     {
-      p->nocols=p->ncols;
+      p->nocols=up->ncols;
       errno=0;
       p->ocols=malloc(p->nocols * sizeof *p->ocols);
       if(p->ocols==NULL)
         error(EXIT_FAILURE, errno, "%lu bytes for p->ocols",
               p->nocols * sizeof *p->ocols);
-      for(i=0;i<p->nocols;++i) p->ocols[i]=i;
+      for(i=0;i<p->nocols;++i)
+        {
+          p->ocols[i].datatype=up->datatype[i];
+          p->ocols[i].inindex=i;
+        }
     }
 }
 
@@ -684,9 +813,10 @@ setparams(int argc, char *argv[], struct tableparams *p)
   cp->removedirinfo = 1;
 
   /* Initialize this utility's pointers to NULL. */
+  p->ocols=NULL;
   up->columns=NULL;
   up->txtname=up->fitsname=NULL;
-  p->tform=p->ttype=p->tunit=NULL;
+  up->tform=up->ttype=up->tunit=NULL;
 
   /* Read the arguments. */
   errno=0;
@@ -739,25 +869,40 @@ setparams(int argc, char *argv[], struct tableparams *p)
 void
 freeandreport(struct tableparams *p)
 {
-  size_t i;
+  size_t i, j;
   int status=0;
+  char **rowofstrings;
+  struct uiparams *up=&p->up;
 
   /* Free the allocated arrays: */
-  free(p->ocols);
   free(p->cp.hdu);
-  free(p->typecode);
+  free(up->datatype);
   free(p->cp.output);
 
-  /* Free the internal pointers first, then the actual arrays: */
-  for(i=0;i<p->ncols;++i)
+  /* Free the input column information: */
+  for(i=0;i<up->ncols;++i)
     {
-      if(p->tform) free(p->tform[i]);
-      if(p->ttype) free(p->ttype[i]);
-      if(p->tunit) free(p->tunit[i]);
+      if(up->tform) free(up->tform[i]);
+      if(up->ttype) free(up->ttype[i]);
+      if(up->tunit) free(up->tunit[i]);
     }
-  free(p->tform);
-  free(p->ttype);
-  free(p->tunit);
+  free(up->tform);
+  free(up->ttype);
+  free(up->tunit);
+
+  /* Free the output column information: */
+  for(i=0;i<p->nocols;++i)
+    {
+      if(p->ocols[i].datatype==TSTRING)
+        {
+          rowofstrings=(char **)(p->ocols[i].data);
+          for(j=0;j<p->nrows;++j)
+            free(rowofstrings[j]);
+        }
+      else
+        free(p->ocols[i].data);
+    }
+  free(p->ocols);
 
   /* Close the FITS file: */
   if(p->up.fitsname && fits_close_file(p->fitsptr, &status))
diff --git a/src/table/ui.h b/src/table/ui.h
index c200304..76c304e 100644
--- a/src/table/ui.h
+++ b/src/table/ui.h
@@ -24,6 +24,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define UI_H
 
 void
+checkfge(char *optarg, int *fge);
+
+void
 setparams(int argc, char *argv[], struct tableparams *p);
 
 void



reply via email to

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