gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 79c3879: Library (fits.h): date to seconds set


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 79c3879: Library (fits.h): date to seconds sets NULL pointer when no sub-second
Date: Sun, 31 Jan 2021 10:49:54 -0500 (EST)

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

    Library (fits.h): date to seconds sets NULL pointer when no sub-second
    
    Until now, when there was no sub-second value in the input date string, the
    'gal_fits_key_date_to_seconds' function wouldn't touch the sub-second
    string or value. This would require the user to initialize these pointers
    before calling this function (which would not always happen!). This would
    cause a problem in their checks afterwards. This actually happened in the
    Fits program that called this function!
    
    With this commit, when there is no sub-second in the input date, the
    'gal_fits_key_date_to_seconds' function will put a NULL pointer in the
    expected string and a NaN value in the expected sub-second value.
    
    Also, just to avoid compiler warnings in the Fits program, I initialized
    the sub-second string in the Fits program to NULL before calling
    'gal_fits_key_date_to_seconds'.
---
 bin/fits/keywords.c |  5 ++---
 doc/gnuastro.texi   |  9 ++++++---
 lib/fits.c          | 30 ++++++++++++++++++------------
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/bin/fits/keywords.c b/bin/fits/keywords.c
index 9e207ef..41a3525 100644
--- a/bin/fits/keywords.c
+++ b/bin/fits/keywords.c
@@ -404,15 +404,14 @@ keywords_date_to_seconds(struct fitsparams *p, fitsfile 
*fptr)
   int status=0;
   double subsec;
   size_t seconds;
-  char *subsecstr;
+  char *subsecstr=NULL;
   char fitsdate[FLEN_KEYWORD];
 
   /* Read the requested FITS keyword. */
   if( fits_read_key(fptr, TSTRING, p->datetosec, &fitsdate, NULL, &status) )
     gal_fits_io_error(status, NULL);
 
-  /* Return the number of seconds (and subseconds) that it corresponds
-     to. */
+  /* Return the number of seconds (and subseconds).*/
   seconds=gal_fits_key_date_to_seconds(fitsdate, &subsecstr, &subsec);
   if(seconds==GAL_BLANK_SIZE_T)
     error(EXIT_FAILURE, 0, "the time string couldn't be interpretted");
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index ee2dd1b..b9837de 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -23871,9 +23871,12 @@ Return the Unix epoch time (number of seconds that 
have passed since 00:00:00 Th
 This function will return @code{GAL_BLANK_SIZE_T} if the broken-down time 
couldn't be converted to seconds.
 
 The Unix epoch time is in units of seconds, but the FITS date format allows 
sub-second accuracy.
-The last two arguments are for the (optional) sub-second portion.
-If @code{fitsdate} contains sub-second accuracy, then the starting of the 
sub-second part's string is stored in @code{subsecstr} (allocated separately), 
and @code{subsec} will be the corresponding numerical value (between 0 and 1, 
in double precision floating point).
-So to avoid leaking memory, when @code{subsecstr!=NULL}, it must be freed.
+The last two arguments are for the optional sub-second portion.
+If you don't want sub-second information, just set the second argument to 
@code{NULL}.
+
+If @code{fitsdate} contains sub-second accuracy and @code{subsecstr!=NULL}, 
then the starting of the sub-second part's string is stored in @code{subsecstr} 
(malloc'ed), and @code{subsec} will be the corresponding numerical value 
(between 0 and 1, in double precision floating point).
+So to avoid leaking memory, if a sub-second string is requested, it must be 
freed after calling this function.
+When a sub-second string doesn't exist (and it is requested), then a value of 
@code{NULL} and NaN will be written in @code{*subsecstr} and @code{*subsec} 
respectively.
 
 This is a very useful function for operations on the FITS date values, for 
example sorting FITS files by their dates, or finding the time difference 
between two FITS files.
 The advantage of working with the Unix epoch time is that you don't have to 
worry about calendar details (for example the number of days in different 
months, or leap years, etc).
diff --git a/lib/fits.c b/lib/fits.c
index 6dac672..b93dc17 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -1103,25 +1103,31 @@ gal_fits_key_date_to_seconds(char *fitsdate, char 
**subsecstr,
   char *tmp;
   struct tm tp;
   size_t seconds;
-  void *outptr=subsec;
+  void *subsecptr=subsec;
 
   /* Fill in the 'tp' elements with values read from the string. */
   tmp=gal_fits_key_date_to_struct_tm(fitsdate, &tp);
 
-  /* If the user cared about the remainder (sub-second string), then set it
-     and convert it to a double type. */
-  if(subsecstr && tmp)
+  /* If the user wanted a possible sub-second string/value, then
+     'subsecstr!=NULL'. */
+  if(subsecstr)
     {
-      /* Set the output pointer. */
+      /* Set the output pointer. Note that it may be NULL if there was no
+         sub-second string, but that is fine (and desired because the user
+         can use this to check if there was a sub-string or not). */
       *subsecstr=tmp;
 
-      /* Convert the remainder string to double-precision floating point
-         (if the given pointer isn't NULL). */
-      if(subsec)
-        if( gal_type_from_string(&outptr, tmp, GAL_TYPE_FLOAT64) )
-          error(EXIT_FAILURE, 0, "%s: the sub-second portion of '%s' (or "
-                "'%s') couldn't be read as a number", __func__, fitsdate,
-                tmp);
+      /* If there was a sub-second string, then also read it as a
+         double-precision floating point. */
+      if(tmp)
+        {
+          if(subsec)
+            if( gal_type_from_string(&subsecptr, tmp, GAL_TYPE_FLOAT64) )
+              error(EXIT_FAILURE, 0, "%s: the sub-second portion of '%s' (or "
+                    "'%s') couldn't be read as a number", __func__, fitsdate,
+                    tmp);
+        }
+      else { if(subsec) *subsec=NAN; }
     }
 
   /* Convert the contents of the 'tm' structure to 'time_t' (a positive



reply via email to

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