gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master b4628d7: Library (txt.h): content check when t


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master b4628d7: Library (txt.h): content check when there is no metadata
Date: Sun, 1 Aug 2021 15:03:07 -0400 (EDT)

branch: master
commit b4628d726587605b56b553db25b09cc15af93809
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (txt.h): content check when there is no metadata
    
    Until now, when the user gave a plain-text file with no metadata, the
    'txt.h' library would just counts the tokens in the top line (to find
    number of columns in whole table) and assumed the contents are double
    precision floating point.
    
    It did ignore lines that are commented (starting with a '#'), however, when
    the first non-commented line contains words (or generally anything that is
    not a floating point number), this would cause very confusing error
    messages later in the programs (since the number of columns was not counted
    from the actual data, but the un-commented English text of the first line
    for example).
    
    With this commit, the plain-text table reading library checks if the tokens
    in the first non-commented line that doesn't have any metadata, is actually
    a number or not. It will abort with a warning if a non-number is found. In
    the error, it will print the problematic token, so the users notices the
    cause of the problem and corrects their input.
    
    In the process, the example in the documentation of 'gal_type_to_string'
    was corrected to be more clear on how to feed the pointer.
    
    This fixes bug #60999.
---
 NEWS              |  1 +
 doc/gnuastro.texi | 35 ++++++++++++++++-------------------
 lib/txt.c         | 14 ++++++++++++--
 3 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/NEWS b/NEWS
index f2c7873..e9584c7 100644
--- a/NEWS
+++ b/NEWS
@@ -126,6 +126,7 @@ See the end of the file for license conditions.
               even when '--quiet' is called, found by Raúl Infante-Sainz.
   bug #60989: MakeProfiles deletes input fits catalog when no output name
               specified.
+  bug #60999: No content check when plain-text table doesn't have metadata.
 
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 0c30746..20f40f5 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -23699,34 +23699,31 @@ out = gal_type_to_string(&string, GAL_TYPE_STRING, 1);
 @end deftypefun
 
 @deftypefun int gal_type_from_string (void @code{**out}, char @code{*string}, 
uint8_t @code{type})
-Read a string as a given data type and put a pointer to it in
-@code{*out}. When @code{*out!=NULL}, then it is assumed to be already
-allocated and the value will be simply put there. If @code{*out==NULL},
-then space will be allocated for the given type and the string will be read
-into that type.
+Read a string as a given data type and put a pointer to it in @code{*out}.
+When @code{*out!=NULL}, then it is assumed to be already allocated and the 
value will be simply put there.
+If @code{*out==NULL}, then space will be allocated for the given type and the 
string will be read into that type.
 
-Note that when we are dealing with a string type, @code{*out} should be
-interpreted as @code{char **} (one element in an array of pointers to
-different strings). In other words, @code{out} should be @code{char ***}.
+Note that when we are dealing with a string type, @code{*out} should be 
interpreted as @code{char **} (one element in an array of pointers to different 
strings).
+In other words, @code{out} should be @code{char ***}.
 
-This function can be used to fill in arrays of numbers from strings (in an
-already allocated data structure), or add nodes to a linked list (if the
-type is a list type). For an array, you have to pass the pointer to the
-@code{i}th element where you want the value to be stored, for example
-@code{&(array[i])}.
+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 (if the type 
is a list type).
+For an array, you have to pass the pointer to the @code{i}th element where you 
want the value to be stored, for example @code{&(array[i])}.
 
-If the string was successfully parsed to the requested type, this function
-will return a @code{0} (zero), otherwise it will return @code{1}
-(one). This output format will help you check the status of the conversion
-in a code like the example below:
+If the string was successfully parsed to the requested type, this function 
will return a @code{0} (zero), otherwise it will return @code{1} (one).
+This output format will help you check the status of the conversion in a code 
like the example below where we will try reading a string as a single precision 
floating point number.
 
 @example
-if( gal_type_from_string(&out, string, GAL_TYPE_FLOAT32) )
+float out;
+void *outptr=&out;
+if( gal_type_from_string(&outptr, string, GAL_TYPE_FLOAT32) )
   @{
-    fprintf(stderr, "%s couldn't be read as float32.\n", string);
+    fprintf(stderr, "%s couldn't be read as float32\n", string);
     exit(EXIT_FAILURE);
   @}
 @end example
+
+@noindent
+When you need to read many numbers into an array, @code{out} would be an 
array, and you can simply increment @code{outptr=out+i} (where you increment 
@code{i}).
 @end deftypefun
 
 @deftypefun {void *} gal_type_string_to_number (char @code{*string}, uint8_t 
@code{*type})
diff --git a/lib/txt.c b/lib/txt.c
index d7cbaff..171ca37 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -315,6 +315,8 @@ static size_t
 txt_info_from_first_row(char *in_line, gal_data_t **datall, int format,
                         int inplace)
 {
+  double tmpd;
+  void *tmpdptr=&tmpd;
   gal_data_t *col, *prev, *tmp;
   size_t n=0, maxcnum=0, numtokens;
   char *line, *token, *end, *aline=NULL;
@@ -392,7 +394,6 @@ txt_info_from_first_row(char *in_line, gal_data_t **datall, 
int format,
             {
               token=strtok_r(n==1?line:NULL, GAL_TXT_DELIMITERS, &line);
               if(token==NULL) break;
-              /* printf(" col %zu: =%s=\n", i, token); */
             }
         }
       else
@@ -410,6 +411,15 @@ txt_info_from_first_row(char *in_line, gal_data_t 
**datall, int format,
              information). */
           if( *datall==NULL || format==TXT_FORMAT_TABLE )
             {
+              /* Make sure the token is actually a number and print a good
+                 error message when the input isn't actually a number but a
+                 string (like uncommented metadata).*/
+              if( gal_type_from_string( &tmpdptr, token, GAL_TYPE_FLOAT64) )
+                error(EXIT_FAILURE, 0, "'%s' couldn't be read as a number "
+                      "(element %zu of first uncommented line)", token, n);
+
+              /* Allocate this column's dataset and set it's 'status' to
+                 the column number that it corresponds to. */
               gal_list_data_add_alloc(datall, NULL, GAL_TYPE_FLOAT64, 0,
                                       NULL, NULL, 0, -1, 1, NULL, NULL, NULL);
               (*datall)->status=n;
@@ -461,7 +471,7 @@ txt_info_from_first_row(char *in_line, gal_data_t **datall, 
int format,
               gal_data_free(col);
               col=tmp;
             }
-          else                /* Column has data.                          */
+          else /* Column has data. */
             {
               prev=col;
               col=col->next;



reply via email to

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