gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 5c891c20 1/2: Table: --head and --tail correct


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 5c891c20 1/2: Table: --head and --tail corrections moved to where they are applied
Date: Wed, 15 Jun 2022 15:12:29 -0400 (EDT)

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

    Table: --head and --tail corrections moved to where they are applied
    
    Until now, the sanity checks of '--head' and '--tail' were done at the very
    start of Table, before any processing was done on it! As part of those
    sanity checks, Table would make sure that the values given to these two
    options were not larger than the input table's size. It would then adjust
    their values if they were larger.
    
    This caused a problem when later steps would limit the number of rows! For
    example through the '--range' option. Causing the user to see that the
    '--range' option has been ignored for example!
    
    With this commit, the necessary corrections to '--head' and '--tail' are
    now done in the same step that they are applied. This fixes the problem
    above.
    
    In the process, I also noticed that the formatting sanity checks for the
    '--rowlimit' option are done in the 'ui_preparations' function, while the
    tests don't depend on the values of the input table! So they are now placed
    in the 'ui_read_check_only_options' function which is the proper place for
    these tests.
    
    This bug was reported by Sepideh Eskandarlou.
    
    This fixes bug #62636.
---
 NEWS              |   2 +
 bin/table/table.c |  16 +++++++-
 bin/table/ui.c    | 112 +++++++++++++++++++++++-------------------------------
 3 files changed, 63 insertions(+), 67 deletions(-)

diff --git a/NEWS b/NEWS
index dbc3d1e4..0158b28f 100644
--- a/NEWS
+++ b/NEWS
@@ -114,6 +114,8 @@ See the end of the file for license conditions.
               ('./configure --enable-debug'). Found by Raul Infante-Sainz.
   bug #62597: Arithmetic not writing single-valued output into a file when
               called with '--output'. Reported by Raul Infante-Sainz.
+  bug #62636: Table ignoring '--range' when '--head' is also
+              called. Reported by Sepideh Eskandarlou.
 
 
 
diff --git a/bin/table/table.c b/bin/table/table.c
index 690a40c2..853c554e 100644
--- a/bin/table/table.c
+++ b/bin/table/table.c
@@ -658,6 +658,17 @@ table_select_by_position(struct tableparams *p)
   size_t i, start, end;
   double *darr = p->rowlimit ? p->rowlimit->array : NULL;
 
+  /* If the head or tail values are given and are larger than the number of
+     rows, just set them to the number of rows (print the all the final
+     rows). This is how the 'head' and 'tail' programs of GNU Coreutils
+     operate. */
+  p->head = ( ((p->head!=GAL_BLANK_SIZE_T) && (p->head > p->table->size))
+              ? p->table->size
+              : p->head );
+  p->tail = ( ((p->tail!=GAL_BLANK_SIZE_T) && (p->tail > p->table->size))
+              ? p->table->size
+              : p->tail );
+
   /* Random row selection (by position, not value). This step is
      independent of the other operations of this function, so as soon as
      its finished return. */
@@ -674,7 +685,8 @@ table_select_by_position(struct tableparams *p)
       return;
     }
 
-  /* Sanity check  */
+  /* Make sure the given values to '--rowlimit' are within the number of
+     rows until this point. */
   if(p->rowlimit)
     {
       if(darr[0]>=p->table->size)
@@ -713,7 +725,7 @@ table_select_by_position(struct tableparams *p)
             {
               /* Set the starting and ending indexs to free the allocated
                  space of each string. */
-              start = p->head!=GAL_BLANK_SIZE_T ? p->head        : 0;
+              start = p->head!=GAL_BLANK_SIZE_T ? p->head : 0;
               end   = ( p->head!=GAL_BLANK_SIZE_T
                         ? p->table->size
                         : p->table->size - p->tail );
diff --git a/bin/table/ui.c b/bin/table/ui.c
index c60f3aeb..8c8dc3c0 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -227,6 +227,7 @@ parse_opt(int key, char *arg, struct argp_state *state)
 static void
 ui_read_check_only_options(struct tableparams *p)
 {
+  size_t i;
   double *darr;
   gal_data_t *tmp;
 
@@ -274,15 +275,55 @@ ui_read_check_only_options(struct tableparams *p)
     }
 
   /* Make sure only one of the positional row selection operations is
-     called in this run.*/
-  if(p->rowlimit
-     && p->rowrandom
-     && p->head!=GAL_BLANK_SIZE_T
-     && p->tail!=GAL_BLANK_SIZE_T)
+     called in one run. */
+  if( (p->rowlimit!=NULL)
+      + (p->rowrandom!=0)
+      + (p->head!=GAL_BLANK_SIZE_T)
+      + (p->tail!=GAL_BLANK_SIZE_T) > 1 )
     error(EXIT_FAILURE, 0, "only one of the following options can be "
           "called in one run: '--head', '--tail', '--rowlimit' and "
           "'--rowrandom'");
 
+  /* Make sure the value to '--rowlimit' is in the correct format. */
+  if(p->rowlimit)
+    {
+      /* There should only be two values. */
+      if(p->rowlimit->size!=2)
+        error(EXIT_FAILURE, 0, "only two should be given to "
+              "'--rowlimit' (the top and bottom row numbers specifying "
+              "your desired range)");
+
+      /* Do individual checks. */
+      darr=p->rowlimit->array;
+      for(i=0;i<p->rowlimit->size;++i)
+        {
+          /* Make sure it isn't 0 or negative. */
+          if( darr[i]<=0 )
+            error(EXIT_FAILURE, 0, "%g (value given to '--rowlimit') "
+                  "is smaller than, or equal to, zero! This option's "
+                  "values are row-counters (starting from 1), so they "
+                  "must be positive integers", darr[i]);
+
+          /* Make sure its an integer. */
+          if( darr[i] != (size_t)(darr[i]) )
+            error(EXIT_FAILURE, 0, "%g (value given to '--rowlimit') is "
+                  "not an integer! This option's values are row-counters "
+                  "so they must be integers.", darr[i]);
+
+          /* Subtract 1 from the value, so it counts from 0. */
+          --darr[i];
+        }
+
+      /* Make sure that the first value is smaller than the second. */
+      if( darr[0] > darr[1] )
+        error(EXIT_FAILURE, 0, "the first value to '--rowlimit' (%g) is "
+              "larger than the second (%g). This option's values defines "
+              "a row-counter interval, assuming the first value is the top "
+              "of the desired interval (smaller row counter) and the second "
+              "value is the bottom of the desired interval (larger row "
+              "counter)", darr[0], darr[1]);
+    }
+
   /* If '--colmetadata' is given, make sure none of the given options have
      more than three values. */
   if(p->colmetadata)
@@ -291,11 +332,6 @@ ui_read_check_only_options(struct tableparams *p)
         error(EXIT_FAILURE, 0, "at most three values can be given to each "
               "call of '--colmetadata' ('-m') after the original columns "
               "name or number. But %zu strings have been given", tmp->size);
-
-  /* '--head' and '--tail' shouldn't be called together! */
-  if(p->head!=GAL_BLANK_SIZE_T && p->tail!=GAL_BLANK_SIZE_T)
-    error(EXIT_FAILURE, 0, "'--head' and '--tail' can't be called at "
-          "the same time");
 }
 
 
@@ -1131,8 +1167,7 @@ ui_check_select_sort_after(struct tableparams *p, size_t 
nselect,
 static void
 ui_preparations(struct tableparams *p)
 {
-  double *darr;
-  size_t i, *colmatch;
+  size_t *colmatch;
   gal_list_str_t *lines;
   size_t nselect=0, origoutncols=0;
   size_t sortindout=GAL_BLANK_SIZE_T;
@@ -1204,59 +1239,6 @@ ui_preparations(struct tableparams *p)
   /* Make sure the (possible) output name is writable. */
   gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
 
-
-  /* If the head or tail values are given and are larger than the number of
-     rows, just set them to the number of rows (print the all the final
-     rows). This is how the 'head' and 'tail' programs of GNU Coreutils
-     operate. */
-  p->head = ( ((p->head!=GAL_BLANK_SIZE_T) && (p->head > p->table->size))
-              ? p->table->size
-              : p->head );
-  p->tail = ( ((p->tail!=GAL_BLANK_SIZE_T) && (p->tail > p->table->size))
-              ? p->table->size
-              : p->tail );
-
-  /* If rows are given, do some sanity checks and make sure that they are
-     within the table's limits. */
-  if(p->rowlimit)
-    {
-      /* There should only be two values. */
-      if(p->rowlimit->size!=2)
-        error(EXIT_FAILURE, 0, "only two should be given to "
-              "'--rowlimit' (the top and bottom row numbers specifying "
-              "your desired range)");
-
-      /* Do individual checks. */
-      darr=p->rowlimit->array;
-      for(i=0;i<p->rowlimit->size;++i)
-        {
-          /* Make sure it isn't 0 or negative. */
-          if( darr[i]<=0 )
-            error(EXIT_FAILURE, 0, "%g (value given to '--rowlimit') "
-                  "is smaller than, or equal to, zero! This option's "
-                  "values are row-counters (starting from 1), so they "
-                  "must be positive integers", darr[i]);
-
-          /* Make sure its an integer. */
-          if( darr[i] != (size_t)(darr[i]) )
-            error(EXIT_FAILURE, 0, "%g (value given to '--rowlimit') is "
-                  "not an integer! This option's values are row-counters "
-                  "so they must be integers.", darr[i]);
-
-          /* Subtract 1 from the value, so it counts from 0. */
-          --darr[i];
-        }
-
-      /* Make sure that the first value is smaller than the second. */
-      if( darr[0] > darr[1] )
-        error(EXIT_FAILURE, 0, "the first value to '--rowlimit' (%g) is "
-              "larger than the second (%g). This option's values defines "
-              "a row-counter interval, assuming the first value is the top "
-              "of the desired interval (smaller row counter) and the second "
-              "value is the bottom of the desired interval (larger row "
-              "counter)", darr[0], darr[1]);
-    }
-
   /* If random rows are desired, we need to define a GSL random number
      generator structure. */
   if(p->rowrandom)



reply via email to

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