gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master e5373e0 034/125: Column info read from comment


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e5373e0 034/125: Column info read from comments in ASCII tables
Date: Sun, 23 Apr 2017 22:36:31 -0400 (EDT)

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

    Column info read from comments in ASCII tables
    
    The column information can now be read from a properly formatted comment in
    an ASCII txt table file as described in the previous commit. It is the same
    format that `lib/txt.c' will write a table to an ASCII table. This makes it
    easy to read and write tables to and from FITS formats while preseving
    information like column name, units, and etc.
    
    Some other things that were done in this commit:
    
     - To make the type reading and writing easier, a new
       `gal_data_string_as_type' was defined in `data.c' to read a string and
       specify the type it refers to. The old `gal_data_type_string' was also
       renamed to `gal_data_type_as_string' since it does the opposite.
    
     - The `gal_data_copy_to_new_type' is now in `data.c' and the old
       `data-copy.[ch]' files were removed.
---
 bin/table/ui.c      |   2 +-
 bootstrap.conf      |   1 +
 lib/Makefile.am     |   8 +-
 lib/arithmetic.c    |   6 +-
 lib/data-copy.c     | 149 ---------------------------
 lib/data-copy.h     |  29 ------
 lib/data.c          | 280 ++++++++++++++++++++++++++++++++++++++++++---------
 lib/gnuastro/data.h |  41 ++++----
 lib/gnuastro/txt.h  |   1 +
 lib/table.c         |   2 +-
 lib/txt.c           | 284 +++++++++++++++++++++++++++++++++++++++++++++++-----
 11 files changed, 527 insertions(+), 276 deletions(-)

diff --git a/bin/table/ui.c b/bin/table/ui.c
index 1ecc510..90593f7 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -381,7 +381,7 @@ print_information_exit(struct tableparams *p)
       printf("%-8zu%-25s%-20s%-18s%s\n", i+1,
              name ? name : "N/A" ,
              unit ? unit : "N/A" ,
-             gal_data_type_string(allcols[i].type, 1),
+             gal_data_type_as_string(allcols[i].type, 1),
              comment ? comment : "N/A");
       if(name)    free(name);
       if(unit)    free(unit);
diff --git a/bootstrap.conf b/bootstrap.conf
index a9c3d30..18f8e9d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -167,6 +167,7 @@ gnulib_modules="
     getline
     strcase
     gendocs
+    mbstok_r
     git-version-gen
 "
 
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e01c3a9..adac941 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -42,7 +42,7 @@ 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    \
-  data-copy.c fits.c git.c linkedlist.c mesh.c mode.c polygon.c qsort.c \
+  fits.c git.c linkedlist.c mesh.c mode.c polygon.c qsort.c             \
   spatialconvolve.c statistics.c table.c threads.c timing.c txt.c wcs.c
 
 
@@ -71,9 +71,9 @@ pkginclude_HEADERS = gnuastro/config.h 
$(headersdir)/arithmetic.h       \
 # 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 data-copy.h config.h.in checkset.h commonargs.h    \
-  commonparams.h configfiles.h fixedstringmacros.h mode.h neighbors.h   \
-  timing.h $(headersdir)/README
+  arithmetic-other.h config.h.in checkset.h commonargs.h commonparams.h \
+  configfiles.h fixedstringmacros.h mode.h neighbors.h timing.h         \
+  $(headersdir)/README
 
 
 
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index c45c743..162984e 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -277,7 +277,7 @@ arithmetic_check_float_input(gal_data_t *in, int operator, 
char *numstr)
             "after it so it is directly read into the proper precision "
             "floating point number (based on the number of non-zero "
             "decimals it has)", gal_arithmetic_operator_string(operator),
-            numstr, gal_data_type_string(in->type, 1));
+            numstr, gal_data_type_as_string(in->type, 1));
     }
 }
 
@@ -780,7 +780,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
   if(cond->type!=GAL_DATA_TYPE_UCHAR)
     error(EXIT_FAILURE, 0, "the condition operand to `arithmetic_where' "
           "must be an `unsigned char' type, but the given condition "
-          "operator has a `%s' type", gal_data_type_string(cond->type, 1));
+          "operator has a `%s' type", gal_data_type_as_string(cond->type, 1));
 
   /* The dimension and sizes of the out and condition data sets must be the
      same. */
@@ -1433,7 +1433,7 @@ gal_arithmetic_convert_to_compiled_type(gal_data_t *in, 
unsigned char flags)
         }
       else
         {
-          typestring=gal_data_type_string(in->type, 1);
+          typestring=gal_data_type_as_string(in->type, 1);
           error(EXIT_FAILURE, 0, "The given %s type data given to "
                 "binary operators is not compiled for native operation "
                 "and no larger types are compiled either.\n\nThe "
diff --git a/lib/data-copy.c b/lib/data-copy.c
deleted file mode 100644
index 82d0fbc..0000000
--- a/lib/data-copy.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*********************************************************************
-Arithmetic operations on data structures.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2016, 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 <errno.h>
-#include <error.h>
-
-#include <gnuastro/data.h>
-
-
-
-
-
-/* Generic function for all types. */
-#define COPY_OTYPE_ITYPE_SET(otype, itype) {                            \
-    itype *ia=in->array;                                                \
-    otype *oa=out->array, *of=oa+out->size;                             \
-    do *oa=*ia++; while(++oa<of);                                       \
-  }
-
-
-
-
-
-/* Output type is set, now choose the input type. */
-#define COPY_OTYPE_SET(otype)                                           \
-  switch(in->type)                                                      \
-    {                                                                   \
-    case GAL_DATA_TYPE_UCHAR:                                           \
-      COPY_OTYPE_ITYPE_SET(otype, unsigned char);                       \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_CHAR:                                            \
-      COPY_OTYPE_ITYPE_SET(otype, char);                                \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_USHORT:                                          \
-      COPY_OTYPE_ITYPE_SET(otype, unsigned short);                      \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_SHORT:                                           \
-      COPY_OTYPE_ITYPE_SET(otype, short);                               \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_ULONG:                                           \
-      COPY_OTYPE_ITYPE_SET(otype, unsigned long);                       \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_LONG:                                            \
-      COPY_OTYPE_ITYPE_SET(otype, long);                                \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_LONGLONG:                                        \
-      COPY_OTYPE_ITYPE_SET(otype, LONGLONG);                            \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_FLOAT:                                           \
-      COPY_OTYPE_ITYPE_SET(otype, float);                               \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
-      COPY_OTYPE_ITYPE_SET(otype, double);                              \
-      break;                                                            \
-                                                                        \
-    default:                                                            \
-      error(EXIT_FAILURE, 0, "type %d not recognized for "              \
-            "for newtype in COPY_OTYPE_SET", in->type);                 \
-    }
-
-
-
-
-
-gal_data_t *
-gal_data_copy_to_new_type(gal_data_t *in, int newtype)
-{
-  gal_data_t *out;
-
-  /* Allocate space for the output type */
-  out=gal_data_alloc(NULL, newtype, in->ndim, in->dsize, in->wcs,
-                     0, in->minmapsize, in->name, in->unit, in->comment);
-
-  /* Fill in the output array: */
-  switch(newtype)
-    {
-    case GAL_DATA_TYPE_UCHAR:
-      COPY_OTYPE_SET(unsigned char);
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
-      COPY_OTYPE_SET(char);
-      break;
-
-    case GAL_DATA_TYPE_USHORT:
-      COPY_OTYPE_SET(unsigned short);
-      break;
-
-    case GAL_DATA_TYPE_SHORT:
-      COPY_OTYPE_SET(short);
-      break;
-
-    case GAL_DATA_TYPE_ULONG:
-      COPY_OTYPE_SET(unsigned long);
-      break;
-
-    case GAL_DATA_TYPE_LONG:
-      COPY_OTYPE_SET(long);
-      break;
-
-    case GAL_DATA_TYPE_LONGLONG:
-      COPY_OTYPE_SET(LONGLONG);
-      break;
-
-    case GAL_DATA_TYPE_FLOAT:
-      COPY_OTYPE_SET(float);
-      break;
-
-    case GAL_DATA_TYPE_DOUBLE:
-      COPY_OTYPE_SET(double);
-      break;
-
-    default:
-      error(EXIT_FAILURE, 0, "type %d not recognized for "
-            "for newtype in gal_data_copy_to_new_type", newtype);
-    }
-
-  /* Return the created array */
-  return out;
-}
diff --git a/lib/data-copy.h b/lib/data-copy.h
deleted file mode 100644
index a1e4258..0000000
--- a/lib/data-copy.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*********************************************************************
-Arithmetic operations on data structures.
-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_DATA_COPY_H__
-#define __GAL_DATA_COPY_H__
-
-gal_data_t *
-gal_data_copy_to_new_type(gal_data_t *in, int newtype);
-
-#endif
diff --git a/lib/data.c b/lib/data.c
index f3189db..7412d07 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -37,7 +37,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/table.h>
 
 #include <checkset.h>
-#include <data-copy.h>
 
 
 
@@ -1392,73 +1391,126 @@ gal_data_flag_blank(gal_data_t *data)
 
 
 /*************************************************************
- **************       Types and copying       ***************
+ **************       Types and copying        ***************
  *************************************************************/
-char *
-gal_data_type_string(int type, int long_name)
+
+/* gal_data_copy_to_new_type: Macro for all tyeps. */
+#define COPY_OTYPE_ITYPE_SET(otype, itype) {                            \
+    itype *ia=in->array;                                                \
+    otype *oa=out->array, *of=oa+out->size;                             \
+    do *oa=*ia++; while(++oa<of);                                       \
+  }
+
+
+
+
+
+/* gal_data_copy_to_new_type: Output type is set, now choose the input
+   type. */
+#define COPY_OTYPE_SET(otype)                                           \
+  switch(in->type)                                                      \
+    {                                                                   \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, unsigned char);                       \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_CHAR:                                            \
+      COPY_OTYPE_ITYPE_SET(otype, char);                                \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_USHORT:                                          \
+      COPY_OTYPE_ITYPE_SET(otype, unsigned short);                      \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_SHORT:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, short);                               \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_ULONG:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, unsigned long);                       \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONG:                                            \
+      COPY_OTYPE_ITYPE_SET(otype, long);                                \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONGLONG:                                        \
+      COPY_OTYPE_ITYPE_SET(otype, LONGLONG);                            \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, float);                               \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      COPY_OTYPE_ITYPE_SET(otype, double);                              \
+      break;                                                            \
+                                                                        \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized for "              \
+            "for newtype in COPY_OTYPE_SET", in->type);                 \
+    }
+
+
+
+
+
+/* Copy a given data structure to a new one (possibly with a new type). */
+gal_data_t *
+gal_data_copy_to_new_type(gal_data_t *in, int newtype)
 {
-  switch(type)
-    {
-    case GAL_DATA_TYPE_BIT:
-      if(long_name) return "bit";             else return "b";
+  gal_data_t *out;
 
-    case GAL_DATA_TYPE_UCHAR:
-      if(long_name) return "unsigned char";   else return "uc";
+  /* Allocate space for the output type */
+  out=gal_data_alloc(NULL, newtype, in->ndim, in->dsize, in->wcs,
+                     0, in->minmapsize, in->name, in->unit, in->comment);
 
-      /* 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";
+  /* Fill in the output array: */
+  switch(newtype)
+    {
+    case GAL_DATA_TYPE_UCHAR:
+      COPY_OTYPE_SET(unsigned char);
+      break;
 
-    case GAL_DATA_TYPE_STRING:
-      if(long_name) return "string";          else return "str";
+    case GAL_DATA_TYPE_CHAR:
+      COPY_OTYPE_SET(char);
+      break;
 
     case GAL_DATA_TYPE_USHORT:
-      if(long_name) return "unsigned short";  else return "us";
+      COPY_OTYPE_SET(unsigned short);
+      break;
 
     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";
+      COPY_OTYPE_SET(short);
+      break;
 
     case GAL_DATA_TYPE_ULONG:
-      if(long_name) return "unsigned long";   else return "ul";
+      COPY_OTYPE_SET(unsigned long);
+      break;
 
     case GAL_DATA_TYPE_LONG:
-      if(long_name) return "long";            else return "l";
+      COPY_OTYPE_SET(long);
+      break;
 
     case GAL_DATA_TYPE_LONGLONG:
-      if(long_name) return "LONGLONG";        else return "L";
+      COPY_OTYPE_SET(LONGLONG);
+      break;
 
     case GAL_DATA_TYPE_FLOAT:
-      if(long_name) return "float";           else return "f";
+      COPY_OTYPE_SET(float);
+      break;
 
     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";
+      COPY_OTYPE_SET(double);
+      break;
 
     default:
-      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
-            "`gal_data_type_string'", type);
+      error(EXIT_FAILURE, 0, "type %d not recognized for "
+            "for newtype in gal_data_copy_to_new_type", newtype);
     }
 
-  /* 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_string' function. This must not happen",
-        PACKAGE_BUGREPORT);
-  return NULL;
+  /* Return the created array */
+  return out;
 }
 
 
@@ -1649,8 +1701,144 @@ gal_data_string_to_number(char *string)
 
 
 /*************************************************************
- **************    Type minimum and maximums   ***************
+ **************            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";
+
+    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 -1;
+
+  /* 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.  */
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 4230e9b..6e3934c 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -181,6 +181,24 @@ typedef struct gal_data_t
 
 
 
+/*************************************************************
+ **************        Type information        ***************
+ *************************************************************/
+char *
+gal_data_type_as_string(int type, int long_name);
+
+int
+gal_data_string_as_type(char *str);
+
+void
+gal_data_type_min(int type, void *in);
+
+void
+gal_data_type_max(int type, void *in);
+
+
+
+
 
 /*********************************************************************/
 /*************         Size and allocation         *******************/
@@ -269,16 +287,13 @@ gal_data_flag_blank(gal_data_t *data);
 
 
 /*************************************************************
- **************       Types and copying        ***************
+ **************            Copying             ***************
  *************************************************************/
-char *
-gal_data_type_string(int type, int long_name);
-
 gal_data_t *
-gal_data_copy(gal_data_t *in);
+gal_data_copy_to_new_type(gal_data_t *in, int newtype);
 
 gal_data_t *
-gal_data_copy_to_new_type(gal_data_t *in, int newtype);
+gal_data_copy(gal_data_t *in);
 
 int
 gal_data_out_type(gal_data_t *first, gal_data_t *second);
@@ -290,8 +305,6 @@ gal_data_to_same_type(gal_data_t *f, gal_data_t *s,
 
 
 
-
-
 /*************************************************************
  **************              Read              ***************
  *************************************************************/
@@ -302,18 +315,6 @@ gal_data_string_to_number(char *string);
 
 
 
-/*************************************************************
- **************    Type minimum and maximums   ***************
- *************************************************************/
-void
-gal_data_type_min(int type, void *in);
-
-void
-gal_data_type_max(int type, void *in);
-
-
-
-
 __END_C_DECLS    /* From C++ preparations */
 
 #endif           /* __GAL_DATA_H__ */
diff --git a/lib/gnuastro/txt.h b/lib/gnuastro/txt.h
index 277d8c4..71555ce 100644
--- a/lib/gnuastro/txt.h
+++ b/lib/gnuastro/txt.h
@@ -54,6 +54,7 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 /* Macros */
+#define GAL_TXT_DELIMITERS     " ,\t\f\v"
 #define GAL_TXT_MAX_FMT_LENGTH 20
 
 
diff --git a/lib/table.c b/lib/table.c
index 80f0efb..6ffd771 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -1,5 +1,5 @@
 /*********************************************************************
-txt -- Functions for I/O on text files.
+table -- Functions for I/O on tables.
 This is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
diff --git a/lib/txt.c b/lib/txt.c
index 478d8ed..a6f3eba 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -23,6 +23,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <config.h>
 
 #include <math.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <errno.h>
 #include <error.h>
@@ -43,7 +44,7 @@ enum txt_line_stat
 {
   TXT_LINESTAT_BLANK,
   TXT_LINESTAT_ISCOMMENT,
-  TXT_LINESTAT_NOTCOMMENT,
+  TXT_LINESTAT_DATAROW,
 };
 
 
@@ -51,7 +52,7 @@ enum txt_line_stat
 
 
 /* Return one of the `txt_line_stat' constant values. */
-int
+static int
 get_line_stat(char *line)
 {
   while(*line!='\n')
@@ -64,7 +65,7 @@ get_line_stat(char *line)
         case '#':
           return TXT_LINESTAT_ISCOMMENT;
         default:
-          return TXT_LINESTAT_NOTCOMMENT;
+          return TXT_LINESTAT_DATAROW;
         }
       ++line;
     }
@@ -75,13 +76,256 @@ get_line_stat(char *line)
 
 
 
+/* Remove the spaces around the values, and if the final/trimmed string has
+   no length, return NULL. */
+static char *
+txt_no_space_before_after(char *str)
+{
+  char *end;
+
+  /* If str doesn't point to anything, just return the NULL pointer. */
+  if(str==NULL) return NULL;
+
+  /* Remove the spaces before the start of the string. */
+  while(isspace(*str)) ++str;
+
+  /* If there was nothing in the string, then just return the ending `\0'
+     character. */
+  if(*str=='\0') return NULL;
+
+  /* Remove the spaces at the end, and write a possibly new `\0'. */
+  end = str + strlen(str) - 1;
+  while(end>str && isspace(*end)) --end;
+  *(end+1)='\0';
+
+  /* Return the string. */
+  return *str=='\0' ? NULL : str;
+}
+
+
+
+
+
+/* Use the input `blank' string and the input column to put the blank value
+   in the column's array. If no blank string is given, then free the
+   column's array. */
+static void
+txt_read_blank(gal_data_t *col, char *blank)
+{
+  double d;
+  long long L;
+  char **strarr, *tailptr;
+
+  /* If there is nothing to use as blank, then free the array. */
+  if(blank==NULL)
+    {
+      free(col->array);
+      return;
+    }
+
+  /* String type. Copy the string.*/
+  if(col->type==GAL_DATA_TYPE_STRING)
+    {
+      strarr=col->array;
+      gal_checkset_allocate_copy(blank, &strarr[0]);
+    }
+
+  /* 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. */
+  else if(col->type==GAL_DATA_TYPE_FLOAT || col->type==GAL_DATA_TYPE_DOUBLE)
+    {
+      d=strtod(blank, &tailptr);
+      if(*tailptr!='\0') free(col->array);
+      else
+        {
+          if(col->type==GAL_DATA_TYPE_FLOAT) *(float *) col->array=d;
+          else                              *(double *) col->array=d;
+        }
+    }
+
+  /* Integers. */
+  else
+    {
+      L=strtoll(blank, &tailptr, 0);
+      if(*tailptr!='\0') free(col->array);
+      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);
+          }
+    }
+}
+
+
+
+
+
+
+/* Each column information comment should have a format like this:
+
+      # Column N: NAME [UNITS, TYPE, BLANK] COMMENT
+
+  TYPE has pre-defined values, and N must be an integer, but the rest can
+  contain any characters (including whitespace characters). The UNITS,
+  TYPE, BLANK tokens are optional, if not given, default values will be
+  set. But if there are comments, then the brackets themselves are required
+  to separate the name from the comments.
+
+  Any white space characters before or after the delimiters (`:', `[', `]',
+  `,') is ignored, but spaces within the values are kept. For example, in
+  the two following lines, NAME will be set to `col name' (even though
+  there are extra spaces in the second line, The column unit will be
+  set to `col unit'.
+
+      # Column 2: col name
+      # Column 2 :  col name     [ col unit, type ] Column comments.
+
+  When the column type is a string, the number of characters in the string
+  is also necessary, for example `str10'. Without an integer attached, the
+  line will be ignored.
+
+  In the case of an error or mis-match, the line will be ignored.
+
+  This function will make a linked list of information about each column
+  that has information in the comments. The information on each column
+  doesn't have to be in order, for example the information of column 10 can
+  be before column 7.
+*/
+static void
+txt_info_from_comment(char *line, gal_data_t **colsll)
+{
+  long dsize=1;
+  char *tailptr;
+  int index, type, strw=0;
+  char *number=NULL, *name=NULL, *comment=NULL;
+  char *inbrackets=NULL, *unit=NULL, *typestr=NULL, *blank=NULL;
+
+  /* Only read this comment if it follows the convention: */
+  if( !strncmp(line, "# Column ", 9) )
+    {
+      /* Set the name, inbrackets, and comments string in the first pass
+         through the line. */
+      number=line+9;
+      while(*line!='\0')
+        {
+          switch(*line)
+            {
+            case ':':
+              if(name==NULL) { *line='\0'; name=line+1; }
+              break;
+
+            case '[':
+              if(name && inbrackets==NULL) { *line='\0'; inbrackets=line+1; }
+              break;
+
+            case ']':
+              if(inbrackets && comment==NULL) { *line='\0'; comment=line+1; }
+              break;
+
+            case '\n':
+              *line='\0';
+              break;
+            }
+          ++line;
+        }
+
+      /* If there were brackets, then break it up. */
+      if(inbrackets)
+        {
+          unit=inbrackets;
+          while(*inbrackets!='\0')
+            {
+              if(*inbrackets==',')
+                {
+                  *inbrackets='\0';
+                  if     (typestr==NULL)  typestr = inbrackets+1;
+                  else if(blank==NULL)    blank   = inbrackets+1;
+                }
+              ++inbrackets;
+            }
+        }
+
+      /* Read the column number as an integer. If it can't be read as an
+         integer, or is zero or negative then just return without adding
+         anything to this line. */
+      index=strtol(number, &tailptr, 0);
+      if(*tailptr!='\0' || index<=0) return;
+
+      /* See if the type is a standard type, if so, then set the type,
+         otherwise, return and ignore this line. Just note that if we are
+         dealing with the string type, we have to pull out the number part
+         first. If there is no number, there will be an error.*/
+      typestr=txt_no_space_before_after(typestr);
+      if( !strncmp(typestr, "str", 3) )
+        {
+          type=GAL_DATA_TYPE_STRING;
+          strw=strtol(typestr+3, &tailptr, 0);
+          if(*tailptr!='\0' || strw<0) return;
+        }
+      else
+        {
+          type=gal_data_string_as_type(typestr);
+          if(type==-1) return;
+        }
+
+      /* Add this column's information into the columns linked list. We
+         will define the array to have one element to keep the blank
+         value. To keep the name, unit, and comment strings, trim the white
+         space before and after each before using them here.  */
+      gal_data_add_to_ll(colsll, NULL, type, 1, &dsize, NULL, 0, -1,
+                         txt_no_space_before_after(name),
+                         txt_no_space_before_after(unit),
+                         txt_no_space_before_after(comment) );
+
+      /* Put the number of this column into the status variable of the data
+         structure. If the type is string, then also copy the width into
+         the structure. */
+      (*colsll)->status=index;
+      if(type==GAL_DATA_TYPE_STRING) (*colsll)->disp_width=strw;
+
+      /* Write the blank value into the array. Note that this is not the
+         final column, we are just collecting information now. */
+      txt_read_blank(*colsll, txt_no_space_before_after(blank));
+    }
+}
+
+
+
+
+
+/* The input ASCII table might not have had information in its comments, or
+   the information might not have been complete. So we need to go through
+   the first row of data.*/
+void
+txt_info_from_row(char *line, gal_data_t **colsll)
+{
+  printf("%s\n", line);
+}
+
+
+
+
+
 /* Return the information about a text file table. */
 gal_data_t *
 gal_txt_table_info(char *filename, size_t *numcols)
 {
   FILE *fp;
   char *line;
-  size_t linelen=10;  /* This will be increased later by `getline'. */
+  gal_data_t *colsll=NULL;
+  size_t linelen=10; /* `linelen' will be increased by `getline'. */
 
   /* Open the file. */
   errno=0;
@@ -103,24 +347,18 @@ gal_txt_table_info(char *filename, size_t *numcols)
      lines, but also confirm the info by trying to read the first
      uncommented line. */
   while( getline(&line, &linelen, fp) != -1 )
-    switch(get_line_stat(line))
-      {
-      case TXT_LINESTAT_BLANK:
-        printf("blank\n");
-        break;
-
-      case TXT_LINESTAT_ISCOMMENT:
-        printf("comment\n");
-        break;
-
-      case TXT_LINESTAT_NOTCOMMENT:
-        printf("not comment\n");
-        break;
+    {
+      /* Line is a comment, see if it has formatted information. */
+      if( get_line_stat(line) == TXT_LINESTAT_ISCOMMENT )
+        txt_info_from_comment(line, &colsll);
 
-      default:
-        error(EXIT_FAILURE, 0, "linestatus code %d not recognized in "
-              "`gal_txt_table_info'", get_line_stat(line));
-      }
+      /* Line is actual data, use it to fill in the gaps.  */
+      if( get_line_stat(line) == TXT_LINESTAT_DATAROW )
+        {
+          txt_info_from_row(line, &colsll);
+          break;
+        }
+    }
 
   /* Clean up, close the file and return. */
   free(line);
@@ -305,10 +543,10 @@ make_fmts_for_printf(gal_data_t *cols, size_t numcols, 
int leftadjust,
       /* Set the string for the Gnuastro type. For strings, we also need to
          write the maximum number of characters.*/
       if(tmp->type==GAL_DATA_TYPE_STRING)
-        sprintf(fmts[i*2+1], "%s%zu", gal_data_type_string(tmp->type, 0),
+        sprintf(fmts[i*2+1], "%s%zu", gal_data_type_as_string(tmp->type, 0),
                 maxstrlen);
       else
-        strcpy(fmts[i*2+1], gal_data_type_string(tmp->type, 0));
+        strcpy(fmts[i*2+1], gal_data_type_as_string(tmp->type, 0));
 
 
       /* Increment the column counter. */



reply via email to

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