[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)