[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 26cdc23: More clear names for functions in `ty
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 26cdc23: More clear names for functions in `type.h' |
Date: |
Sat, 29 Apr 2017 21:09:02 -0400 (EDT) |
branch: master
commit 26cdc23e3567ba3cdb6199ccf594d1a699d73d55
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
More clear names for functions in `type.h'
Some of the functions in `type.h' have been renamed to be more clear, for
example `gal_type_to_string' has been renamed to `gal_type_name', so it
doesn't get confused with converting a given number to a string. Generally,
the functions in this header have been managed better and as discussed
below, some `data.h' functions have been moved to `type.h'.
Until now, the there were several extra functions in `data.h' to do with a
single element on a dataset's array. But they were out of place there since
that header is for very basic operations on a whole dataset. While writing
the manual, I they were moved to the `type.h' header because they fit
better there (these functions were at a lower level). Also the
`gal_data_copy_element_same_type' was removed and in the few places that it
was used, we are now using `memcpy' along with `gal_data_ptr_increment'.
Also, the old `gal_data_copy_to_new_type_to_allocated' has been removed
since it was actually never used! Its functionality has been moved to
`gal_data_copy_to_allocated'.
---
bin/arithmetic/arithmetic.c | 2 +-
bin/convertt/ui.c | 6 +-
bin/crop/ui.c | 6 +-
bin/fits/fits.c | 2 +-
bin/mkcatalog/ui.c | 6 +-
bin/noisechisel/detection.c | 2 +-
bin/noisechisel/sky.c | 2 +-
bin/statistics/statistics.c | 12 +-
bin/statistics/ui.c | 2 +-
doc/gnuastro.texi | 156 ++++++++++++++---
lib/arithmetic-onlyint.c | 2 +-
lib/arithmetic.c | 6 +-
lib/binary.c | 6 +-
lib/blank.c | 2 +-
lib/convolve.c | 3 +-
lib/data.c | 408 ++++++--------------------------------------
lib/fits.c | 8 +-
lib/gnuastro/data.h | 34 +---
lib/gnuastro/type.h | 28 ++-
lib/options.c | 20 +--
lib/statistics.c | 37 ++--
lib/table.c | 8 +-
lib/txt.c | 10 +-
lib/type.c | 280 +++++++++++++++++++++++++++++-
24 files changed, 567 insertions(+), 481 deletions(-)
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index 95ddf58..ed00325 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -152,7 +152,7 @@ reversepolish(struct imgarithparams *p)
operation on them. */
if(gal_fits_name_is_fits(token->v))
add_operand(p, token->v, NULL);
- else if( (d1=gal_data_string_to_number(token->v)) )
+ else if( (d1=gal_data_copy_string_to_number(token->v)) )
add_operand(p, NULL, d1);
else
{
diff --git a/bin/convertt/ui.c b/bin/convertt/ui.c
index 01dbd40..053947f 100644
--- a/bin/convertt/ui.c
+++ b/bin/convertt/ui.c
@@ -244,7 +244,7 @@ ui_read_check_only_options(struct converttparams *p)
is indeed smaller than fluxhigh. */
if(p->fluxlowstr)
{
- p->fluxlow=gal_data_string_to_number(p->fluxlowstr);
+ p->fluxlow=gal_data_copy_string_to_number(p->fluxlowstr);
if(p->fluxlow==NULL)
error(EXIT_FAILURE, 0, "value to the `--fluxlow' (`-L', %s) "
"couldn't be read as a number", p->fluxlowstr);
@@ -252,7 +252,7 @@ ui_read_check_only_options(struct converttparams *p)
if(p->fluxhighstr)
{
- p->fluxhigh=gal_data_string_to_number(p->fluxhighstr);
+ p->fluxhigh=gal_data_copy_string_to_number(p->fluxhighstr);
if(p->fluxhigh==NULL)
error(EXIT_FAILURE, 0, "value to the `--fluxhigh' (`-H', %s) "
"couldn't be read as a number", p->fluxhighstr);
@@ -337,7 +337,7 @@ ui_make_change_struct(char *arg)
{
/* Read the number and increment the counter. */
++counter;
- data=gal_data_string_to_number(p);
+ data=gal_data_copy_string_to_number(p);
if(data==NULL)
error(EXIT_FAILURE, 0, "`%s' (input number %zu to the "
"`--change' option) couldn't be read as a number", p,
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 0142e9b..f5371fa 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -713,9 +713,9 @@ ui_preparations(struct cropparams *p)
"information (press `SPACE' for going down and `q' to "
"return to the command-line):\n\n"
" $ info Arithmetic\n",
- img->name, gal_type_to_string(p->type, 1),
- gal_type_to_string(firsttype, 1), img->name,
- gal_type_to_string(p->type, 1));
+ img->name, gal_type_name(p->type, 1),
+ gal_type_name(firsttype, 1), img->name,
+ gal_type_name(p->type, 1));
}
/* In WCS mode, Check resolution and get the first pixel
diff --git a/bin/fits/fits.c b/bin/fits/fits.c
index 7a3c5d4..1d3d649 100644
--- a/bin/fits/fits.c
+++ b/bin/fits/fits.c
@@ -139,7 +139,7 @@ fits_print_extension_info(struct fitsparams *p)
{
case IMAGE_HDU:
gal_fits_img_info(fptr, &type, &ndim, &dsize);
- tstr=gal_type_to_string(type , 1);
+ tstr=gal_type_name(type , 1);
break;
case ASCII_TBL:
diff --git a/bin/mkcatalog/ui.c b/bin/mkcatalog/ui.c
index 1541bd1..0fc988e 100644
--- a/bin/mkcatalog/ui.c
+++ b/bin/mkcatalog/ui.c
@@ -463,12 +463,12 @@ ui_preparations_read_inputs(struct mkcatalogparams *p)
asprintf(&namestypes, "However, `%s' (hdu: %s) and `%s' (hdu: %s) "
"have types of `%s' and `%s' respectively", objectsfile,
p->objectshdu, clumpsfile, p->clumpshdu,
- gal_type_to_string(p->objects->type, 1),
- gal_type_to_string(p->clumps->type, 1) );
+ gal_type_name(p->objects->type, 1),
+ gal_type_name(p->clumps->type, 1) );
else
asprintf(&namestypes, "However, %s (hdu: %s) has a type of %s",
objectsfile, p->objectshdu,
- gal_type_to_string(p->objects->type, 1));
+ gal_type_name(p->objects->type, 1));
error(EXIT_FAILURE, 0, "labeled images (for objects or clumps) must "
"have an integer datatype. %s.\n\n"
"If you are sure the images contain only integer values but "
diff --git a/bin/noisechisel/detection.c b/bin/noisechisel/detection.c
index fc7aaaf..f528927 100644
--- a/bin/noisechisel/detection.c
+++ b/bin/noisechisel/detection.c
@@ -449,7 +449,7 @@ detection_sn(struct noisechiselparams *p, gal_data_t
*worklab, size_t num,
/* Sanity check. */
if(p->input->type!=GAL_TYPE_FLOAT32)
error(EXIT_FAILURE, 0, "%s: the input dataset must be float32 type, "
- "it is %s", __func__, gal_type_to_string(p->input->type, 1));
+ "it is %s", __func__, gal_type_name(p->input->type, 1));
if(!isnan(GAL_BLANK_FLOAT32))
error(EXIT_FAILURE, 0, "%s: only a NaN value is recognized for blank "
"floating point data types, the blank value is defined to be %f",
diff --git a/bin/noisechisel/sky.c b/bin/noisechisel/sky.c
index 96e6f24..92ee414 100644
--- a/bin/noisechisel/sky.c
+++ b/bin/noisechisel/sky.c
@@ -242,7 +242,7 @@ sky_subtract(struct noisechiselparams *p)
if(p->sky->type!=GAL_TYPE_FLOAT32)
error(EXIT_FAILURE, 0, "%s: only `float32' type is acceptable "
"for sky values. but `p->sky' has type `%s'", __func__,
- gal_type_to_string(p->sky->type, 1));
+ gal_type_name(p->sky->type, 1));
/* Go over all the tiles. */
for(tid=0; tid<p->cp.tl.tottiles; ++tid)
diff --git a/bin/statistics/statistics.c b/bin/statistics/statistics.c
index 3502157..a873d32 100644
--- a/bin/statistics/statistics.c
+++ b/bin/statistics/statistics.c
@@ -60,7 +60,9 @@ statistics_pull_out_element(gal_data_t *input, size_t index)
size_t dsize=1;
gal_data_t *out=gal_data_alloc(NULL, input->type, 1, &dsize,
NULL, 1, -1, NULL, NULL, NULL);
- gal_data_copy_element_same_type(input, index, out->array);
+ memcpy( out->array,
+ gal_data_ptr_increment(input->array, index, input->type),
+ gal_type_sizeof(input->type) );
return out;
}
@@ -187,7 +189,7 @@ statistics_print_one_row(struct statisticsparams *p)
}
/* Print the number. */
- toprint=gal_data_write_to_string(out->array, out->type, 0);
+ toprint=gal_type_to_string(out->array, out->type, 0);
printf("%s ", toprint);
free(toprint);
@@ -767,14 +769,14 @@ print_basics(struct statisticsparams *p)
/* Minimum: */
tmp=gal_statistics_minimum(p->input);
- str=gal_data_write_to_string(tmp->array, tmp->type, 0);
+ str=gal_type_to_string(tmp->array, tmp->type, 0);
printf(" %-*s %s\n", namewidth, "Minimum:", str);
gal_data_free(tmp);
free(str);
/* Maximum: */
tmp=gal_statistics_maximum(p->input);
- str=gal_data_write_to_string(tmp->array, tmp->type, 0);
+ str=gal_type_to_string(tmp->array, tmp->type, 0);
printf(" %-*s %s\n", namewidth, "Maximum:", str);
gal_data_free(tmp);
free(str);
@@ -801,7 +803,7 @@ print_basics(struct statisticsparams *p)
/* Find and print the median: */
tmp=gal_statistics_median(p->input, 0);
- str=gal_data_write_to_string(tmp->array, tmp->type, 0);
+ str=gal_type_to_string(tmp->array, tmp->type, 0);
printf(" %-*s %s\n", namewidth, "Median:", str);
gal_data_free(tmp);
free(str);
diff --git a/bin/statistics/ui.c b/bin/statistics/ui.c
index b6b6607..662717a 100644
--- a/bin/statistics/ui.c
+++ b/bin/statistics/ui.c
@@ -750,7 +750,7 @@ ui_read_columns(struct statisticsparams *p)
case GAL_TYPE_COMPLEX64:
error(EXIT_FAILURE, 0, " read column number %zu has a %s type, "
"which is not currently supported by %s", counter,
- gal_type_to_string(tmp->type, 1), PROGRAM_NAME);
+ gal_type_name(tmp->type, 1), PROGRAM_NAME);
}
/* Put the column into the proper pointer. */
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 1e7a97f..a232cd9 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -547,10 +547,10 @@ Gnuastro library
Data container (@file{data.h})
-* Generic data container::
-* Dataset size and allocation::
-* Arrays of datasets::
-* Copying datasets::
+* Generic data container:: Definition of Gnuastro's generic container.
+* Dataset size and allocation:: Functions for size and allocation.
+* Arrays of datasets:: Functions to help with array of datasets.
+* Copying datasets:: Functions to copy a dataset to a new one.
Linked lists (@file{linkedlist.h})
@@ -16788,20 +16788,24 @@ Return the number of bytes occurpied by @code{type}.
Internally, this
function uses C's @code{sizeof} operator to measure the size of each type.
@end deftypefun
address@hidden {char *} gal_type_to_string (uint8_t @code{type}, int
@code{long_name})
-Return a string that contains the name of the type. This can be used in
address@hidden {char *} gal_type_name (uint8_t @code{type}, int
@code{long_name})
+Return a string that contains the name of @code{type}. This can be used in
messages to the users when your function/program accepts many types. It can
-return two types of string identifiers (short like @code{f32} or long like
address@hidden). The output string is statically allocated, so it should
-not be freed. The strings it will return for each type are the identifiers
-of the types in @ref{Numeric data types}.
+return both short and long formats of the type names (for example
address@hidden and @code{float32}). If @code{long_name} is non-zero, the long
+format will be returned, otherwise the short name will be returned. The
+output string is statically allocated, so it should not be freed. This
+function is the inverse of the @code{gal_type_from_name} function. For the
+full list of names/strings that this function will return, see @ref{Numeric
+data types}.
@end deftypefun
address@hidden uint8_t gal_type_from_string (char @code{*str})
address@hidden uint8_t gal_type_from_name (char @code{*str})
Return the Gnuastro integer constant that corresponds to the string
address@hidden This is effectively the inverse of the
address@hidden function and accepts both the short and long
-formats of each type.
address@hidden This function is the inverse of the @code{gal_type_name}
+function and accepts both the short and long formats of each type. For the
+full list of names/strings that this function will return, see @ref{Numeric
+data types}.
@end deftypefun
@deftypefun void gal_type_min (uint8_t @code{type}, void @code{*in})
@@ -16836,7 +16840,7 @@ Note: Do not use the maximum value for a blank value of
a general
@ref{Library blank values} for the definition and usage of blank values.
@end deftypefun
address@hidden int gal_type_is_linked_list (uint8_t @code{type})
address@hidden int gal_type_is_list (uint8_t @code{type})
Return 1 if the type is a linked list and zero otherwise.
@end deftypefun
@@ -16859,7 +16863,7 @@ free(bitstr);
@end example
@noindent
-It will produce:
+which will produce:
@example
2017: 11100001000001110000000000000000 (7E1)
@end example
@@ -16871,6 +16875,66 @@ use @code{printf}'s @code{%x} or @code{%X} to print
integers in hexadecimal
format.
@end deftypefun
address@hidden {char *} gal_type_to_string (void @code{*ptr}, uint8_t
@code{type}, int @code{quote_if_str_has_space});
+Read the contents of the memory that @code{ptr} points to (assuming it has
+type @code{type} and print it into an allocated string which is returned.
+
+If the memory is a string of characters and @code{quote_if_str_has_space}
+is non-zero, the output string will have double-quotes around it if it
+contains space characters. Also, note that in this case, @code{ptr} must be
+a pointer to an array of characters (or @code{char **}), as in the example
+below (which will put @code{"sample string"} into @code{out}):
+
address@hidden
+char *out, *string="sample string"
+out = gal_type_to_string(&string, GAL_TYPE_STRING, 1);
address@hidden example
address@hidden deftypefun
+
address@hidden 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 the pointer to it in
address@hidden When @code{*out!=NULL}, then it is assumed to be already
+allocated and the value will be simply put the memory. If
address@hidden, 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
+interpretted 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
address@hidden element where you want the value to be stored, for example
address@hidden&(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:
+
address@hidden
+if( gal_type_from_string(&out, string, GAL_TYPE_FLOAT32) )
+ @{
+ fprintf(stderr, "%s couldn't be read as float32.\n", string);
+ exit(EXIT_FAILURE);
+ @}
address@hidden example
address@hidden deftypefun
+
+
+
address@hidden {void *} gal_type_string_to_number (char @code{*string}, uint8_t
@code{*type})
+Read @code{string} into smallest type that can host the number, the
+allocated space for the number will be returned and the type of the number
+will be put into the memory that @code{type} points to. If @code{string}
+couldn't be read as a number, this function will return @code{NULL}.
+
+For the ranges acceptable by each type see @ref{Numeric data types}. For
+integers it is clear, for floating point types, this function will count
+the number of significant digits and determine if the given string is
+single or double precision as described in that section.
address@hidden deftypefun
@node Library blank values, Library data container, Library data types,
Gnuastro library
@subsection Library blank values (@file{blank.h})
@@ -17041,10 +17105,10 @@ dataset, the name of the dataset and some comments.
To deal with any
generic dataset, Gnuastro defines the @code{gal_data_t} as input or output.
@menu
-* Generic data container::
-* Dataset size and allocation::
-* Arrays of datasets::
-* Copying datasets::
+* Generic data container:: Definition of Gnuastro's generic container.
+* Dataset size and allocation:: Functions for size and allocation.
+* Arrays of datasets:: Functions to help with array of datasets.
+* Copying datasets:: Functions to copy a dataset to a new one.
@end menu
@node Generic data container, Dataset size and allocation, Library data
container, Library data container
@@ -17520,10 +17584,60 @@ given datset into another. The new dataset can have a
different type
values will be written into it). In all these cases, if the input dataset
is a tile, only the data within the tile are copied.
+In many of the functions here, it is possible to copy the dataset to a new
+numeric data type (see @ref{Numeric data types}. In such cases, Gnuastro's
+library is going to use the native conversion by C. So if you are
+converting to a smaller type, it is up to you to make sure that the values
+fit into the output type.
+
@deftypefun {gal_data_t *} gal_data_copy (gal_data_t @code{*in})
-Return a new dataset that is a copy of @code{in}.
+Return a new dataset that is a copy of @code{in}, the main meta-data of the
+input is also copied into the output.
address@hidden deftypefun
+
address@hidden {gal_data_t *} gal_data_copy_to_new_type (gal_data_t @code{*in},
uint8_t @code{newtype})
+Return a copy of the dataset @code{in}, converted to @code{newtype}, see
address@hidden data types} for Gnuastro library's type identifiers. The
+returned dataset will have all meta-data accept their type equal to the
+input's metadata.
address@hidden deftypefun
+
address@hidden {gal_data_t *} gal_data_copy_to_new_type_free (gal_data_t
@code{*in}, uint8_t @code{newtype})
+Return a copy of the dataset @code{in} that is converted to @code{newtype}
+and free the input dataset. See @ref{Library data types} for Gnuastro
+library's type identifiers. The returned dataset will have all meta-data,
+except their type, equal to the input's metadata. This function is similar
+to @code{gal_data_copy_to_new_type}, except that it will free the input
+dataset.
@end deftypefun
address@hidden {void} gal_data_copy_to_allocated (gal_data_t @code{*in},
gal_data_t @code{*out})
+Copy the contents of the array in @code{in} into the already allocated
+array in @code{out}. The types of the input and output may be different,
+type conversion will be done internally. When @code{in->size != out->size}
+this function will behave as follows:
+
address@hidden @code
address@hidden out->size < in->size
+This function won't re-allocate the necessary space, it will abort with an
+error, so please check before calling this function.
+
address@hidden out->size > in->size
+This function will write the values in @code{out->size} and
address@hidden>dsize} from the same values of @code{in}. So if you want to use
+a pre-allocated space/dataset multiple times with varying input sizes, be
+sure to reset @code{out->size} before every call to this function.
address@hidden table
address@hidden deftypefun
+
address@hidden {gal_data_t *} gal_data_copy_string_to_number (char
@code{*string})
+Read @code{string} into the smallest type that can store the value (see
address@hidden data types}). This function is just a wrapper for the
address@hidden, but will put the value into a
+single-element dataset.
address@hidden deftypefun
+
+
@node Linked lists, Table input output, Library data container, Gnuastro
library
@subsection Linked lists (@file{linkedlist.h})
diff --git a/lib/arithmetic-onlyint.c b/lib/arithmetic-onlyint.c
index b776496..53db601 100644
--- a/lib/arithmetic-onlyint.c
+++ b/lib/arithmetic-onlyint.c
@@ -315,7 +315,7 @@ arithmetic_onlyint_binary(int operator, unsigned char flags,
"and `q' to return to the command-line):\n\n"
" $ info gnuastro \"Gnuastro configure options\"\n",
gal_arithmetic_operator_string(operator),
- gal_type_to_string(lo->type, 1), gal_type_to_string(ro->type, 1));
+ gal_type_name(lo->type, 1), gal_type_name(ro->type, 1));
/* Set the output type. */
otype=gal_type_out(l->type, r->type);
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index 7055de8..969a9b0 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -238,7 +238,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_type_to_string(in->type, 1));
+ numstr, gal_type_name(in->type, 1));
}
}
@@ -615,7 +615,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out,
gal_data_t *cond,
if(cond->type!=GAL_TYPE_UINT8)
error(EXIT_FAILURE, 0, "%s: the condition operand must be an "
"`uint8' type, but the given condition operand has a "
- "`%s' type", __func__, gal_type_to_string(cond->type, 1));
+ "`%s' type", __func__, gal_type_name(cond->type, 1));
/* The dimension and sizes of the out and condition data sets must be the
same. */
@@ -1325,7 +1325,7 @@ gal_arithmetic_convert_to_compiled_type(gal_data_t *in,
unsigned char flags)
}
else
{
- typestring=gal_type_to_string(in->type, 1);
+ typestring=gal_type_name(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/binary.c b/lib/binary.c
index 67fd22c..8ac04af 100644
--- a/lib/binary.c
+++ b/lib/binary.c
@@ -383,7 +383,7 @@ gal_binary_connected_components(gal_data_t *binary,
gal_data_t **out,
if( lab->type!=GAL_TYPE_INT32 )
error(EXIT_FAILURE, 0, "%s: the `out' dataset must have `int32' type"
"but the array you have given is `%s' type", __func__,
- gal_type_to_string(lab->type, 1));
+ gal_type_name(lab->type, 1));
/* Reset all its values to zero. */
memset(lab->array, 0, lab->size * gal_type_sizeof(lab->type));
@@ -487,7 +487,7 @@ gal_binary_connected_adjacency_matrix(gal_data_t *adjacency,
if(adjacency->type != GAL_TYPE_UINT8)
error(EXIT_FAILURE, 0, "%s: input must have type `uint8'. However, the "
"input dataset has type of `%s'", __func__,
- gal_type_to_string(adjacency->type, 1));
+ gal_type_name(adjacency->type, 1));
if(adjacency->ndim != 2)
error(EXIT_FAILURE, 0, "%s: input must be 2-dimensional (a matrix)."
@@ -673,7 +673,7 @@ gal_binary_fill_holes(gal_data_t *input)
if( input->type != GAL_TYPE_UINT8 )
error(EXIT_FAILURE, 0, "%s: input must have `uint8' type, but its "
"input dataset has `%s' type", __func__,
- gal_type_to_string(input->type, 1));
+ gal_type_name(input->type, 1));
/* Make the inverse image. */
diff --git a/lib/blank.c b/lib/blank.c
index 8cc48e4..80ed2e2 100644
--- a/lib/blank.c
+++ b/lib/blank.c
@@ -288,7 +288,7 @@ gal_blank_flag(gal_data_t *input)
case GAL_TYPE_COMPLEX32:
case GAL_TYPE_COMPLEX64:
error(EXIT_FAILURE, 0, "%s: %s type not yet supported",
- __func__, gal_type_to_string(input->type, 1));
+ __func__, gal_type_name(input->type, 1));
/* Bad input. */
default:
diff --git a/lib/convolve.c b/lib/convolve.c
index 93ba823..608c005 100644
--- a/lib/convolve.c
+++ b/lib/convolve.c
@@ -618,8 +618,7 @@ gal_convolve_spatial_correct_ch_edge(gal_data_t *tiles,
gal_data_t *kernel,
error(EXIT_FAILURE, 0, "%s: the `tocorrect' dataset has to have the same "
"type as the block of the `tiles' input. The given types are `%s' "
"and `%s' respectively", __func__,
- gal_type_to_string(tocorrect->type, 1),
- gal_type_to_string(block->type, 1));
+ gal_type_name(tocorrect->type, 1), gal_type_name(block->type, 1));
/* Call the general function, which will do the correction. */
gal_convolve_spatial_general(tiles, kernel, numthreads,
diff --git a/lib/data.c b/lib/data.c
index de3163b..e06c243 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -548,7 +548,7 @@ data_copy_to_string_not_parsed(char *string, void *to,
uint8_t type)
gal_blank_write(to, type);
else
error(EXIT_FAILURE, 0, "%s: `%s' couldn't be parsed as `%s' type",
- __func__, string, gal_type_to_string(type, 1));
+ __func__, string, gal_type_name(type, 1));
}
@@ -594,7 +594,7 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
case GAL_TYPE_COMPLEX32:
case GAL_TYPE_COMPLEX64:
error(EXIT_FAILURE, 0, "%s: copying to %s type not currently "
- "supported", __func__, gal_type_to_string(to->type, 1));
+ "supported", __func__, gal_type_name(to->type, 1));
break;
default:
@@ -607,7 +607,7 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
gal_checkset_allocate_copy(strarr[i], &outstrarr[i]);
else
{
- if( gal_data_string_to_type(&ptr, strarr[i], to->type) )
+ if( gal_type_from_string(&ptr, strarr[i], to->type) )
data_copy_to_string_not_parsed(strarr[i], ptr, to->type);
}
}
@@ -699,7 +699,7 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
case GAL_TYPE_COMPLEX32:
case GAL_TYPE_COMPLEX64:
error(EXIT_FAILURE, 0, "%s: copying to %s type not currently supported",
- __func__, gal_type_to_string(from->type, 1));
+ __func__, gal_type_name(from->type, 1));
break;
default:
@@ -791,7 +791,7 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
case GAL_TYPE_COMPLEX64: \
error(EXIT_FAILURE, 0, "%s: copying from %s type to a numeric " \
"(real) type not supported", "COPY_OT_SET", \
- gal_type_to_string(in->type, 1)); \
+ gal_type_name(in->type, 1)); \
break; \
\
default: \
@@ -816,16 +816,6 @@ gal_data_copy(gal_data_t *in)
-/* Copy the input dataset into the already allocated space of out. */
-void
-gal_data_copy_to_allocated(gal_data_t *in, gal_data_t *out)
-{
- gal_data_copy_to_new_type_to_allocated(in, out, out->type);
-}
-
-
-
-
/* Copy a given data structure to a new one with any type (for the
output). The input can be a tile, in which case the output will be a
@@ -841,7 +831,7 @@ gal_data_copy_to_new_type(gal_data_t *in, uint8_t newtype)
0, in->minmapsize, in->name, in->unit, in->comment);
/* Fill in the output array: */
- gal_data_copy_to_new_type_to_allocated(in, out, newtype);
+ gal_data_copy_to_allocated(in, out);
/* Return the created array */
return out;
@@ -851,6 +841,40 @@ gal_data_copy_to_new_type(gal_data_t *in, uint8_t newtype)
+/* Copy the input data structure into a new type and free the allocated
+ space. */
+gal_data_t *
+gal_data_copy_to_new_type_free(gal_data_t *in, uint8_t newtype)
+{
+ gal_data_t *out, *iblock=gal_tile_block(in);
+
+ /* In a general application, it might happen that the type is equal with
+ the type of the input and the input isn't a tile. Since the job of
+ this function is to free the input dataset, and the user just wants
+ one dataset after this function finishes, we can safely just return
+ the input. */
+ if(newtype==iblock->type && in==iblock)
+ return in;
+ else
+ {
+ out=gal_data_copy_to_new_type(in, newtype);
+ if(iblock==in)
+ gal_data_free(in);
+ else
+ fprintf(stderr, "#####\nWarning from "
+ "`gal_data_copy_to_new_type_free'\n#####\n The input "
+ "dataset is a tile, not a contiguous (fully allocated) "
+ "patch of memory. So it has not been freed. Please use "
+ "`gal_data_copy_to_new_type' to avoid this warning.\n"
+ "#####");
+ return out;
+ }
+}
+
+
+
+
+
/* Copy a given dataset (`in') into an already allocated dataset `out' (the
actual dataset and its `array' element). The meta-data of `in' will be
fully copied into `out' also. `out->size' will be used to find the
@@ -867,8 +891,7 @@ gal_data_copy_to_new_type(gal_data_t *in, uint8_t newtype)
pre-allocated space with varying input sizes, be sure to reset
`out->size' before every call to this function. */
void
-gal_data_copy_to_new_type_to_allocated(gal_data_t *in, gal_data_t *out,
- uint8_t newtype)
+gal_data_copy_to_allocated(gal_data_t *in, gal_data_t *out)
{
gal_data_t *iblock=gal_tile_block(in);
@@ -911,7 +934,7 @@ gal_data_copy_to_new_type_to_allocated(gal_data_t *in,
gal_data_t *out,
case GAL_TYPE_COMPLEX32:
case GAL_TYPE_COMPLEX64:
error(EXIT_FAILURE, 0, "%s: copying to %s type not yet supported",
- __func__, gal_type_to_string(out->type, 1));
+ __func__, gal_type_name(out->type, 1));
break;
default:
@@ -931,344 +954,17 @@ gal_data_copy_to_new_type_to_allocated(gal_data_t *in,
gal_data_t *out,
-/* Copy the input data structure into a new type and free the allocated
- space. */
+/* Just a wrapper around `gal_type_from_string_auto', to return a
+ `gal_data_t' dataset hosting the allocated number. */
gal_data_t *
-gal_data_copy_to_new_type_free(gal_data_t *in, uint8_t type)
-{
- gal_data_t *out, *iblock=gal_tile_block(in);
-
- /* In a general application, it might happen that the type is equal with
- the type of the input and the input isn't a tile. Since the job of
- this function is to free the input dataset, and the user just wants
- one dataset after this function finishes, we can safely just return
- the input. */
- if(type==iblock->type && in==iblock)
- return in;
- else
- {
- out=gal_data_copy_to_new_type(in, type);
- if(iblock==in)
- gal_data_free(in);
- else
- fprintf(stderr, "#####\nWarning from "
- "`gal_data_copy_to_new_type_free'\n#####\n The input "
- "dataset is a tile, not a contiguous (fully allocated) "
- "patch of memory. So it has not been freed. Please use "
- "`gal_data_copy_to_new_type' to avoid this warning.\n"
- "#####");
- return out;
- }
-}
-
-
-
-
-
-/* Copy/read the element at `index' of the array in `data' into the space
- pointed to by `ptr'. */
-#define COPY_ELEM(IT) { \
- IT *restrict o=ptr, *restrict a=input->array; *o = a[index]; \
-}
-void
-gal_data_copy_element_same_type(gal_data_t *input, size_t index, void *ptr)
-{
- /* Set the value. */
- switch(input->type)
- {
- case GAL_TYPE_UINT8: COPY_ELEM( uint8_t ); break;
- case GAL_TYPE_INT8: COPY_ELEM( int8_t ); break;
- case GAL_TYPE_UINT16: COPY_ELEM( uint16_t ); break;
- case GAL_TYPE_INT16: COPY_ELEM( int16_t ); break;
- case GAL_TYPE_UINT32: COPY_ELEM( uint32_t ); break;
- case GAL_TYPE_INT32: COPY_ELEM( int32_t ); break;
- case GAL_TYPE_UINT64: COPY_ELEM( uint64_t ); break;
- case GAL_TYPE_INT64: COPY_ELEM( int64_t ); break;
- case GAL_TYPE_FLOAT32: COPY_ELEM( float ); break;
- case GAL_TYPE_FLOAT64: COPY_ELEM( double ); break;
- default:
- error(EXIT_FAILURE, 0, "%s: type code %d not recognized", __func__,
- input->type);
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*************************************************************
- ************** Write ***************
- *************************************************************/
-#define WRITE_TO_STRING(CTYPE, FMT) asprintf(&str, FMT, *(CTYPE *)ptr);
-
-char *
-gal_data_write_to_string(void *ptr, uint8_t type, int quote_if_str_has_space)
-{
- char *c, *str=NULL;
- switch(type)
- {
- /* For a string we might need to make sure it has no white space
- characters, if it does, it can be printed it within quotation
- signs. */
- case GAL_TYPE_STRING:
- if(quote_if_str_has_space)
- {
- c=*(char **)ptr; while(*c!='\0') if(isspace(*c++)) break;
- if(*c=='\0') asprintf(&str, "%s", *(char **)ptr);
- else asprintf(&str, "\"%s\" ", *(char **)ptr);
- }
- else
- asprintf(&str, "%s", *(char **)ptr);
- break;
-
- case GAL_TYPE_UINT8: WRITE_TO_STRING( uint8_t, "%"PRIu8 ); break;
- case GAL_TYPE_INT8: WRITE_TO_STRING( int8_t, "%"PRId8 ); break;
- case GAL_TYPE_UINT16: WRITE_TO_STRING( uint16_t, "%"PRIu16 ); break;
- case GAL_TYPE_INT16: WRITE_TO_STRING( int16_t, "%"PRId16 ); break;
- case GAL_TYPE_UINT32: WRITE_TO_STRING( uint32_t, "%"PRIu32 ); break;
- case GAL_TYPE_INT32: WRITE_TO_STRING( int32_t, "%"PRId32 ); break;
- case GAL_TYPE_UINT64: WRITE_TO_STRING( uint64_t, "%"PRIu64 ); break;
- case GAL_TYPE_INT64: WRITE_TO_STRING( int64_t, "%"PRId64 ); break;
- case GAL_TYPE_FLOAT32: WRITE_TO_STRING( float, "%.6g" ); break;
- case GAL_TYPE_FLOAT64: WRITE_TO_STRING( double, "%.10g" ); break;
-
- default:
- error(EXIT_FAILURE, 0, "%s: type code %d not recognized", __func__,
type);
- }
- return str;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*************************************************************
- ************** Read ***************
- *************************************************************/
-/* If the data structure was correctly created (the string was a number),
- then return its pointer. Otherwise, return NULL. */
-gal_data_t *
-gal_data_string_to_number(char *string)
+gal_data_copy_string_to_number(char *string)
{
void *ptr;
- gal_data_t *out;
- int fnz=-1, lnz=0; /* `F'irst (or `L'ast) `N'on-`Z'ero. */
- char *tailptr, *cp;
- size_t dsize[1]={1};
- uint8_t type, forcedfloat=0;
-
- /* Define initial spaces to keep the value. */
- uint8_t u8; int8_t i8; uint16_t u16; int16_t i16;
- uint32_t u32; int32_t i32; uint64_t u64; int64_t i64;
- float f; double d;
-
- /* First see if the number is a double (the most generic). */
- d=strtod(string, &tailptr);
- if(*tailptr=='f') { if(tailptr[1]=='\0') forcedfloat=1; else return NULL; }
- else if (*tailptr!='\0') return NULL;
-
- /* See if the number is actually an integer: */
- if( forcedfloat==0 && ceil(d) == d )
- {
- /* If the number is negative, put it in the signed types (based on
- its value). If its zero or positive, then put it in the unsigned
- types. */
- if( d < 0 )
- {
- if (d>INT8_MIN) {i8=d; ptr=&i8; type=GAL_TYPE_INT8;}
- else if(d>INT16_MIN) {i16=d; ptr=&i16; type=GAL_TYPE_INT16;}
- else if(d>INT32_MIN) {i32=d; ptr=&i32; type=GAL_TYPE_INT32;}
- else {i64=d; ptr=&i64; type=GAL_TYPE_INT64;}
- }
- else
- {
- if (d<=UINT8_MAX) {u8=d; ptr=&u8; type=GAL_TYPE_UINT8;}
- else if(d<=UINT16_MAX) {u16=d; ptr=&u16; type=GAL_TYPE_UINT16;}
- else if(d<=UINT32_MAX) {u32=d; ptr=&u32; type=GAL_TYPE_UINT32;}
- else {u64=d; ptr=&u64; type=GAL_TYPE_UINT64;}
- }
- }
- else
- {
- /* The maximum number of decimal digits to store in float or double
- precision floating point are:
-
- float: 23 mantissa bits + 1 hidden bit: log(224)÷log(10) = 7.22
- double: 52 mantissa bits + 1 hidden bit: log(253)÷log(10) = 15.95
-
- FLT_DIG (at least 6 in ISO C) keeps the number of digits (not zero
- before or after) that can be represented by a single precision
- floating point number. If there are more digits, then we should
- store the value as a double precision.
-
- Note that the number can have non-digit characters that we don't
- want, like: `.', `e', `E', `,'. */
- for(cp=string;*cp!='\0';++cp)
- if(isdigit(*cp) && *cp!='0' && fnz==-1)
- fnz=cp-string;
-
- /* In the previous loop, we went to the end of the string, so `cp'
- now points to its `\0'. We just have to iterate backwards! */
- for(;cp!=string;--cp)
- if(isdigit(*cp) && *cp!='0')
- {
- lnz=cp-string;
- break;
- }
-
- /* Calculate the number of decimal digits and decide if it the number
- should be a float or a double. */
- if( lnz-fnz < FLT_DIG || ( d<FLT_MAX && d>FLT_MIN ) )
- { f=d; ptr=&f; type=GAL_TYPE_FLOAT32; }
- else
- { ptr=&d; type=GAL_TYPE_FLOAT64; }
- }
-
- /* Allocate a one-element dataset, then copy the number into it. */
- out=gal_data_alloc(NULL, type, 1, dsize, NULL, 0, -1, NULL, NULL, NULL);
- memcpy(out->array, ptr, gal_type_sizeof(type));
- return out;
-}
-
-
-
-
-
-/* Read a string as a given data type and put a the pointer to it in
- *out. When the input `*out!=NULL', then it is assumed to be allocated
- and the value will be simply put there. If `*out==NULL', then space will
- be allocated for the given type and the string's value (in the given
- type) will be stored there.
-
- Note that when we are dealing with a string type, `*out' should be
- interpretted as `char **' (one element in an array of pointers to
- different strings). In other words, `out' should be `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. For
- an array, you have to pass the pointer to the `i'th element where you
- want the value to be stored, for example &(array[i]).
-
- If parsing was successful, it will return a 0. If there was a problem,
- it will return 1. */
-int
-gal_data_string_to_type(void **out, char *string, uint8_t type)
-{
- long l;
- double d;
- void *value;
- char *tailptr;
- int status=0, allocated=0;
-
- /* If the output is NULL, then allocate the necessary space if we are not
- dealing with a linked list. In a linked list, a NULL value is
- meaningful (it is the end of the list). */
- if( *out==NULL && !gal_type_is_linked_list(type) )
- {
- allocated=1;
- *out=gal_data_malloc_array(type, 1);
- }
- value=*out;
-
- /* Read the string depending on the type. */
- switch(type)
- {
-
- /* Linked lists, currently only string linked lists. */
- case GAL_TYPE_STRLL:
- gal_list_str_add( (struct gal_list_str_t **)out, string, 1);
- break;
-
- /* String, just allocate and copy the string and keep its pointer in
- the place `*out' points to (for strings, `*out' is `char **'). */
- case GAL_TYPE_STRING:
- gal_checkset_allocate_copy(string, value);
- break;
-
- /* 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. */
- case GAL_TYPE_FLOAT32:
- case GAL_TYPE_FLOAT64:
- d=strtod(string, &tailptr);
- if(*tailptr!='\0')
- status=1;
- else
- {
- if(type==GAL_TYPE_FLOAT32) *(float *) value=d;
- else *(double *) value=d;
- }
- break;
-
- /* Integers. */
- default:
- l=strtol(string, &tailptr, 0);
- if(*tailptr!='\0')
- status=1;
- else
- switch(type)
- {
- /* The signed values can easily be put in. */
- case GAL_TYPE_INT8: *(int8_t *) value = l; break;
- case GAL_TYPE_INT16: *(int16_t *) value = l; break;
- case GAL_TYPE_INT32: *(int32_t *) value = l; break;
- case GAL_TYPE_INT64: *(int64_t *) value = l; break;
-
- /* For the unsigned types, the value has to be positive, so if
- the input was negative, then just return a status of one and
- don't store the value. */
- default:
- if(l<0)
- status=1;
- else
- switch(type)
- {
- case GAL_TYPE_UINT8: *(uint8_t *) value=l; break;
- case GAL_TYPE_UINT16: *(uint16_t *) value=l; break;
- case GAL_TYPE_UINT32: *(uint32_t *) value=l; break;
- case GAL_TYPE_UINT64: *(uint64_t *) value=l; break;
- default:
- error(EXIT_FAILURE, 0, "%s: type code %d not recognized",
- __func__, type);
- }
- }
- }
-
- /* If reading was unsuccessful, then free the space if it was allocated,
- then return the status, don't touch the pointer. */
- if(status && allocated)
- {
- free(*out);
- *out=NULL;
- }
- return status;
+ uint8_t type;
+ size_t dsize=1;
+ ptr=gal_type_string_to_number(string, &type);
+ return ( ptr
+ ? gal_data_alloc(ptr, type, 1, &dsize, NULL, 0, -1,
+ NULL, NULL, NULL)
+ : NULL );
}
diff --git a/lib/fits.c b/lib/fits.c
index 31069d0..bdaac68 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -218,7 +218,7 @@ gal_fits_type_to_bitpix(uint8_t type)
case GAL_TYPE_COMPLEX32:
case GAL_TYPE_COMPLEX64:
error(EXIT_FAILURE, 0, "%s: type %s not recognized for FITS image "
- "BITPIX", __func__, gal_type_to_string(type, 1));
+ "BITPIX", __func__, gal_type_name(type, 1));
default:
error(EXIT_FAILURE, 0, "%s: type value of %d not recognized",
@@ -258,7 +258,7 @@ gal_fits_type_to_bin_tform(uint8_t type)
/* Not recognized by CFITSIO. */
case GAL_TYPE_UINT64:
error(EXIT_FAILURE, 0, "%s: type %s not recognized for FITS binary "
- "table TFORM", __func__, gal_type_to_string(type, 1));
+ "table TFORM", __func__, gal_type_name(type, 1));
break;
/* Wrong type code. */
@@ -342,12 +342,12 @@ gal_fits_type_to_datatype(uint8_t type)
if(w)
error(EXIT_FAILURE, 0, "%s: this system doesn't have a %d byte integer "
"type, so type `%s' cannot be written to FITS", __func__, w,
- gal_type_to_string(type, 1));
+ gal_type_name(type, 1));
else
error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s so we can "
"fix the problem. Control must not have reached the end for the "
"given type `%s'", __func__, PACKAGE_BUGREPORT,
- gal_type_to_string(type, 1));
+ gal_type_name(type, 1));
return -1;
}
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index dfe6c14..15761c9 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -287,45 +287,17 @@ gal_data_array_free(gal_data_t *dataarr, size_t num, int
free_array);
gal_data_t *
gal_data_copy(gal_data_t *in);
-void
-gal_data_copy_to_allocated(gal_data_t *in, gal_data_t *out);
-
gal_data_t *
gal_data_copy_to_new_type(gal_data_t *in, uint8_t newtype);
-void
-gal_data_copy_to_new_type_to_allocated(gal_data_t *in, gal_data_t *out,
- uint8_t newtype);
-
gal_data_t *
-gal_data_copy_to_new_type_free(gal_data_t *in, uint8_t type);
+gal_data_copy_to_new_type_free(gal_data_t *in, uint8_t newtype);
void
-gal_data_copy_element_same_type(gal_data_t *input, size_t index, void *ptr);
-
-
-
-
-
-/*************************************************************
- ************** Write ***************
- *************************************************************/
-char *
-gal_data_write_to_string(void *ptr, uint8_t type, int quote_if_str_has_space);
-
-
-
-
+gal_data_copy_to_allocated(gal_data_t *in, gal_data_t *out);
-/*************************************************************
- ************** Read ***************
- *************************************************************/
gal_data_t *
-gal_data_string_to_number(char *string);
-
-int
-gal_data_string_to_type(void **out, char *string, uint8_t type);
-
+gal_data_copy_string_to_number(char *string);
__END_C_DECLS /* From C++ preparations */
diff --git a/lib/gnuastro/type.h b/lib/gnuastro/type.h
index 3a1c605..e40aca5 100644
--- a/lib/gnuastro/type.h
+++ b/lib/gnuastro/type.h
@@ -103,16 +103,16 @@ enum gal_types
/*************************************************************
- ************** Functions ***************
+ ************** General info ***************
*************************************************************/
size_t
gal_type_sizeof(uint8_t type);
char *
-gal_type_to_string(uint8_t type, int long_name);
+gal_type_name(uint8_t type, int long_name);
uint8_t
-gal_type_from_string(char *str);
+gal_type_from_name(char *str);
void
gal_type_min(uint8_t type, void *in);
@@ -121,14 +121,34 @@ void
gal_type_max(uint8_t type, void *in);
int
-gal_type_is_linked_list(uint8_t type);
+gal_type_is_list(uint8_t type);
int
gal_type_out(int first_type, int second_type);
+
+
+
+
+/*************************************************************
+ ************** To/from string ***************
+ *************************************************************/
+
char *
gal_type_bit_string(void *in, size_t size);
+char *
+gal_type_to_string(void *ptr, uint8_t type, int quote_if_str_has_space);
+
+int
+gal_type_from_string(void **out, char *string, uint8_t type);
+
+void *
+gal_type_string_to_number(char *string, uint8_t *type);
+
+
+
+
__END_C_DECLS /* From C++ preparations */
diff --git a/lib/options.c b/lib/options.c
index 7172e83..611fd71 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -403,7 +403,7 @@ gal_options_read_type(struct argp_option *option, char *arg,
/* Note that `gal_data_type_as_string' returns a static string. But
the output must be an allocated string so we can free it. */
gal_checkset_allocate_copy(
- gal_type_to_string( *(uint8_t *)(option->value), 1), &str);
+ gal_type_name( *(uint8_t *)(option->value), 1), &str);
return str;
}
else
@@ -412,7 +412,7 @@ gal_options_read_type(struct argp_option *option, char *arg,
if(option->set) return NULL;
/* Read the value. */
- if ( (*(uint8_t *)(option->value) = gal_type_from_string(arg) )
+ if ( (*(uint8_t *)(option->value) = gal_type_from_name(arg) )
== GAL_TYPE_INVALID )
error_at_line(EXIT_FAILURE, 0, filename, lineno, "`%s' (value to "
"`%s' option) couldn't be recognized as a known "
@@ -916,7 +916,7 @@ gal_options_read_check(struct argp_option *option, char
*arg, char *filename,
if(option->set==GAL_OPTIONS_SET) return;
/* Read the string argument into the value. */
- if( gal_data_string_to_type(&option->value, arg, option->type) )
+ if( gal_type_from_string(&option->value, arg, option->type) )
/* Fortunately `error_at_line' will behave like `error' when the
filename is NULL (the option was read from a command-line). */
error_at_line(EXIT_FAILURE, 0, filename, lineno,
@@ -952,8 +952,8 @@ gal_options_read_check(struct argp_option *option, char
*arg, char *filename,
"correct it. Options with no arguments, must have "
"type `%s'. However, the `%s' option has type %s",
__func__, PACKAGE_BUGREPORT,
- gal_type_to_string(GAL_OPTIONS_NO_ARG_TYPE, 1),
- option->name, gal_type_to_string(option->type, 1));
+ gal_type_name(GAL_OPTIONS_NO_ARG_TYPE, 1),
+ option->name, gal_type_name(option->type, 1));
}
@@ -1010,7 +1010,7 @@ gal_options_set_from_key(int key, char *arg, struct
argp_option *options,
As a result, only when searching for options on the
command-line, a second value to the same option will replace
the first one. This will not happen in configuration files. */
- if(options[i].set && gal_type_is_linked_list(options[i].type)==0)
+ if(options[i].set && gal_type_is_list(options[i].type)==0)
options[i].set=GAL_OPTIONS_NOT_SET;
/* Parse the value. */
@@ -1188,7 +1188,7 @@ options_set_from_name(char *name, char *arg, struct
argp_option *options,
list. */
if( options[i].flags==OPTION_HIDDEN
|| ( options[i].set
- && !gal_type_is_linked_list(options[i].type ) ) )
+ && !gal_type_is_list(options[i].type ) ) )
return 0;
/* Read the value into the option and do a sanity check. */
@@ -1504,7 +1504,7 @@ options_print_any_type(struct argp_option *option, void
*ptr, int type,
/* Write the value into a string. */
str = ( option->func
? option->func(option, NULL, NULL, (size_t)(-1), cp->program_struct)
- : gal_data_write_to_string(ptr, type, 1) );
+ : gal_type_to_string(ptr, type, 1) );
/* If only the width was desired, don't actually print the string, just
return its length. Otherwise, print it. */
@@ -1538,7 +1538,7 @@ options_correct_max_lengths(struct argp_option *option,
int *max_nlen,
/* Get the length of the value and save its length length if its
larger than the widest value. */
- if(gal_type_is_linked_list(option->type))
+ if(gal_type_is_list(option->type))
{
/* A small sanity check. */
if(option->type!=GAL_TYPE_STRLL)
@@ -1668,7 +1668,7 @@ options_print_all_in_group(struct argp_option *options,
int groupint,
&& option_is_printable(&options[i]) ) /* Is relevant for printing.*/
{
/* Linked lists */
- if(gal_type_is_linked_list(options[i].type))
+ if(gal_type_is_list(options[i].type))
for(tmp=*(gal_list_str_t **)(options[i].value);
tmp!=NULL; tmp=tmp->next)
{
diff --git a/lib/statistics.c b/lib/statistics.c
index 0daa22e..419b9af 100644
--- a/lib/statistics.c
+++ b/lib/statistics.c
@@ -27,6 +27,7 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
#include <errno.h>
#include <error.h>
#include <float.h>
+#include <string.h>
#include <stdint.h>
#include <stdlib.h>
@@ -320,8 +321,9 @@ gal_statistics_quantile(gal_data_t *input, double quantile,
int inplace)
/* Find the index of the quantile. */
index=gal_statistics_quantile_index(nbs->size, quantile);
- /* Read the value at this index into the output. */
- gal_data_copy_element_same_type(nbs, index, out->array);
+ /* Write the value at this index into the output. */
+ memcpy(out->array, gal_data_ptr_increment(nbs->array, index, nbs->type),
+ gal_type_sizeof(nbs->type));
/* Clean up and return. */
if(nbs!=input) gal_data_free(nbs);
@@ -828,8 +830,8 @@ gal_statistics_mode(gal_data_t *input, float mirrordist,
int inplace)
size_t dsize=4, mdsize=1;
struct statistics_mode_params p;
int type=gal_tile_block(input)->type;
- gal_data_t *mode=gal_data_alloc(NULL, type, 1, &mdsize, NULL, 1, -1,
- NULL, NULL, NULL);
+ gal_data_t *tmptype=gal_data_alloc(NULL, type, 1, &mdsize, NULL, 1, -1,
+ NULL, NULL, NULL);
gal_data_t *b_val=gal_data_alloc(NULL, type, 1, &mdsize, NULL, 1, -1,
NULL, NULL, NULL);
gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
@@ -838,8 +840,9 @@ gal_statistics_mode(gal_data_t *input, float mirrordist,
int inplace)
/* A small sanity check. */
if(mirrordist<=0)
- error(EXIT_FAILURE, 0, "%s: %f not acceptable as a value to `mirrordist'. "
- "Only positive values can be given to it", __func__, mirrordist);
+ error(EXIT_FAILURE, 0, "%s: %f not acceptable as a value to "
+ "`mirrordist'. Only positive values can be given to it",
+ __func__, mirrordist);
/* Make sure the input doesn't have blank values and is sorted. */
@@ -879,15 +882,21 @@ gal_statistics_mode(gal_data_t *input, float mirrordist,
int inplace)
/* Do the golden-section search iteration, read the mode value from the
- input array and save it as the first element of the output dataset's
- array, then free the `mode' structure. */
+ input array and save it in the `tmptype' data structure that has the
+ same type as the input. */
modeindex = mode_golden_section(&p);
- gal_data_copy_element_same_type(p.data, modeindex, mode->array);
- mode=gal_data_copy_to_new_type_free(mode, GAL_TYPE_FLOAT64);
- gal_data_copy_element_same_type(mode, 0, &oa[0]);
+ memcpy( tmptype->array,
+ gal_data_ptr_increment(p.data->array, modeindex, p.data->type),
+ gal_type_sizeof(p.data->type) );
- /* Put in the rest of the values of the output structure. */
+ /* Convert the mode (which is in the same type as the input at this
+ stage) to float64. */
+ tmptype=gal_data_copy_to_new_type_free(tmptype, GAL_TYPE_FLOAT64);
+
+
+ /* Put the first three values into the output structure. */
+ oa[0] = *((double *)(tmptype->array));
oa[1] = ((double)modeindex) / ((double)(p.data->size-1));
oa[2] = mode_symmetricity(&p, modeindex, b_val->array);
@@ -897,7 +906,7 @@ gal_statistics_mode(gal_data_t *input, float mirrordist,
int inplace)
if(oa[2]>GAL_STATISTICS_MODE_GOOD_SYM)
{
b_val=gal_data_copy_to_new_type_free(b_val, GAL_TYPE_FLOAT64);
- gal_data_copy_element_same_type(b_val, 0, &oa[3]);
+ oa[3] = *((double *)(b_val->array));
}
else oa[0]=oa[1]=oa[2]=oa[3]=NAN;
@@ -909,8 +918,8 @@ gal_statistics_mode(gal_data_t *input, float mirrordist,
int inplace)
/* Clean up (if necessary), then return the output */
if(p.data!=input) gal_data_free(p.data);
+ gal_data_free(tmptype);
gal_data_free(b_val);
- gal_data_free(mode);
return out;
}
diff --git a/lib/table.c b/lib/table.c
index 1814dc3..17f1f23 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -237,8 +237,8 @@ gal_table_print_info(gal_data_t *allcols, size_t numcols,
size_t numrows)
if(allcols[i].unit && strlen(allcols[i].unit)>uw)
uw=strlen(allcols[i].unit);
if(allcols[i].type
- && strlen(gal_type_to_string(allcols[i].type, 1))>tw)
- tw=strlen(gal_type_to_string(allcols[i].type, 1));
+ && strlen(gal_type_name(allcols[i].type, 1))>tw)
+ tw=strlen(gal_type_name(allcols[i].type, 1));
}
/* We want one column space between the columns for readability, not the
@@ -262,7 +262,7 @@ gal_table_print_info(gal_data_t *allcols, size_t numcols,
size_t numrows)
printf("%-*zu%-*s%-*s%-*s%s\n", Nw, i+1,
nw, name ? name : GAL_BLANK_STRING ,
uw, unit ? unit : GAL_BLANK_STRING ,
- tw, gal_type_to_string(allcols[i].type, 1),
+ tw, gal_type_name(allcols[i].type, 1),
comment ? comment : GAL_BLANK_STRING);
}
@@ -460,7 +460,7 @@ gal_table_read_blank(gal_data_t *col, char *blank)
`gal_data_string_to_type' will return 0. In that case, we need to
initialize the necessary paramters to read this data structure
correctly. */
- if( !gal_data_string_to_type(&colarr, blank, col->type) )
+ if( !gal_type_from_string(&colarr, blank, col->type) )
{
errno=0;
col->dsize=malloc(sizeof *col->dsize);
diff --git a/lib/txt.c b/lib/txt.c
index f67e6dd..bfe4e0c 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -245,7 +245,7 @@ txt_info_from_comment(char *line, gal_data_t **datall, char
*comm_start)
}
else
{
- type=gal_type_from_string(typestr);
+ type=gal_type_from_name(typestr);
if(type==GAL_TYPE_INVALID) return;
}
}
@@ -746,7 +746,7 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char
*token,
if(data->type!=GAL_TYPE_STRING && *tailptr!='\0')
error_at_line(EXIT_FAILURE, 0, filename, lineno, "column %zu "
"(`%s') couldn't be read as a `%s' number",
- colnum, token, gal_type_to_string(data->type, 1) );
+ colnum, token, gal_type_name(data->type, 1) );
}
@@ -1081,10 +1081,10 @@ make_fmts_for_printf(gal_data_t *datall, int
leftadjust, size_t *len)
/* Set the string for the Gnuastro type. For strings, we also need to
write the maximum number of characters.*/
if(data->type==GAL_TYPE_STRING)
- sprintf(fmts[i*FMTS_COLS+1], "%s%d",
- gal_type_to_string(data->type, 0), data->disp_width);
+ sprintf(fmts[i*FMTS_COLS+1], "%s%d", gal_type_name(data->type, 0),
+ data->disp_width);
else
- strcpy(fmts[i*FMTS_COLS+1], gal_type_to_string(data->type, 0));
+ strcpy(fmts[i*FMTS_COLS+1], gal_type_name(data->type, 0));
/* Increment the column counter. */
diff --git a/lib/type.c b/lib/type.c
index 12a644b..3dca101 100644
--- a/lib/type.c
+++ b/lib/type.c
@@ -26,14 +26,24 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
#include <errno.h>
#include <error.h>
#include <float.h>
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <inttypes.h>
#include <gnuastro/type.h>
#include <gnuastro/data.h>
+#include <gnuastro/list.h>
+#include <gnuastro-internal/checkset.h>
+
+
+
+/*************************************************************
+ ************** General info ***************
+ *************************************************************/
size_t
gal_type_sizeof(uint8_t type)
{
@@ -100,7 +110,7 @@ gal_type_sizeof(uint8_t type)
char *
-gal_type_to_string(uint8_t type, int long_name)
+gal_type_name(uint8_t type, int long_name)
{
switch(type)
{
@@ -167,7 +177,7 @@ gal_type_to_string(uint8_t type, int long_name)
uint8_t
-gal_type_from_string(char *str)
+gal_type_from_name(char *str)
{
if( !strcmp(str, "b") || !strcmp(str, "bit") )
return GAL_TYPE_BIT;
@@ -281,7 +291,7 @@ gal_type_max(uint8_t type, void *in)
that work on both, it is convenient to simiplify the check with this
function. */
int
-gal_type_is_linked_list(uint8_t type)
+gal_type_is_list(uint8_t type)
{
return type==GAL_TYPE_STRLL;
}
@@ -300,6 +310,24 @@ gal_type_out(int first_type, int second_type)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*************************************************************
+ ************** To/from string ***************
+ *************************************************************/
/* Write the bit (0 or 1) contents of `in' into a string ready for
printing. `size' is used to determine the number of bytes to print. The
output string will be dynamically allocated within this function. This
@@ -327,3 +355,249 @@ gal_type_bit_string(void *in, size_t size)
/* Return the allocated and filled string. */
return str;
}
+
+
+
+
+
+/* Write the contents of memory that `ptr' points to as a string of type
+ `type'.*/
+#define TO_STRING(CTYPE, FMT) asprintf(&str, FMT, *(CTYPE *)ptr);
+char *
+gal_type_to_string(void *ptr, uint8_t type, int quote_if_str_has_space)
+{
+ char *c, *str=NULL;
+ switch(type)
+ {
+ /* For a string we might need to make sure it has no white space
+ characters, if it does, it can be printed it within quotation
+ signs. */
+ case GAL_TYPE_STRING:
+ if(quote_if_str_has_space)
+ {
+ c=*(char **)ptr; while(*c!='\0') if(isspace(*c++)) break;
+ if(*c=='\0') asprintf(&str, "%s", *(char **)ptr);
+ else asprintf(&str, "\"%s\" ", *(char **)ptr);
+ }
+ else
+ asprintf(&str, "%s", *(char **)ptr);
+ break;
+
+ case GAL_TYPE_UINT8: TO_STRING( uint8_t, "%"PRIu8 ); break;
+ case GAL_TYPE_INT8: TO_STRING( int8_t, "%"PRId8 ); break;
+ case GAL_TYPE_UINT16: TO_STRING( uint16_t, "%"PRIu16 ); break;
+ case GAL_TYPE_INT16: TO_STRING( int16_t, "%"PRId16 ); break;
+ case GAL_TYPE_UINT32: TO_STRING( uint32_t, "%"PRIu32 ); break;
+ case GAL_TYPE_INT32: TO_STRING( int32_t, "%"PRId32 ); break;
+ case GAL_TYPE_UINT64: TO_STRING( uint64_t, "%"PRIu64 ); break;
+ case GAL_TYPE_INT64: TO_STRING( int64_t, "%"PRId64 ); break;
+ case GAL_TYPE_FLOAT32: TO_STRING( float, "%.6g" ); break;
+ case GAL_TYPE_FLOAT64: TO_STRING( double, "%.10g" ); break;
+
+ default:
+ error(EXIT_FAILURE, 0, "%s: type code %d not recognized",
+ __func__, type);
+ }
+ return str;
+}
+
+
+
+
+
+/* Read a string as a given data type and put a the pointer to it in
+ *out. When the input `*out!=NULL', then it is assumed to be allocated
+ and the value will be simply put there. If `*out==NULL', then space will
+ be allocated for the given type and the string's value (in the given
+ type) will be stored there.
+
+ Note that when we are dealing with a string type, `*out' should be
+ interpretted as `char **' (one element in an array of pointers to
+ different strings). In other words, `out' should be `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. For
+ an array, you have to pass the pointer to the `i'th element where you
+ want the value to be stored, for example &(array[i]).
+
+ If parsing was successful, it will return a 0. If there was a problem,
+ it will return 1. */
+int
+gal_type_from_string(void **out, char *string, uint8_t type)
+{
+ long l;
+ double d;
+ void *value;
+ char *tailptr;
+ int status=0, allocated=0;
+
+ /* If the output is NULL, then allocate the necessary space if we are not
+ dealing with a linked list. In a linked list, a NULL value is
+ meaningful (it is the end of the list). */
+ if( *out==NULL && !gal_type_is_list(type) )
+ {
+ allocated=1;
+ *out=gal_data_malloc_array(type, 1);
+ }
+ value=*out;
+
+ /* Read the string depending on the type. */
+ switch(type)
+ {
+
+ /* Linked lists, currently only string linked lists. */
+ case GAL_TYPE_STRLL:
+ gal_list_str_add( (struct gal_list_str_t **)out, string, 1);
+ break;
+
+ /* String, just allocate and copy the string and keep its pointer in
+ the place `*out' points to (for strings, `*out' is `char **'). */
+ case GAL_TYPE_STRING:
+ gal_checkset_allocate_copy(string, value);
+ break;
+
+ /* 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. */
+ case GAL_TYPE_FLOAT32:
+ case GAL_TYPE_FLOAT64:
+ d=strtod(string, &tailptr);
+ if(*tailptr!='\0')
+ status=1;
+ else
+ {
+ if(type==GAL_TYPE_FLOAT32) *(float *) value=d;
+ else *(double *) value=d;
+ }
+ break;
+
+ /* Integers. */
+ default:
+ l=strtol(string, &tailptr, 0);
+ if(*tailptr!='\0')
+ status=1;
+ else
+ switch(type)
+ {
+ /* The signed values can easily be put in. */
+ case GAL_TYPE_INT8: *(int8_t *) value = l; break;
+ case GAL_TYPE_INT16: *(int16_t *) value = l; break;
+ case GAL_TYPE_INT32: *(int32_t *) value = l; break;
+ case GAL_TYPE_INT64: *(int64_t *) value = l; break;
+
+ /* For the unsigned types, the value has to be positive, so if
+ the input was negative, then just return a status of one and
+ don't store the value. */
+ default:
+ if(l<0)
+ status=1;
+ else
+ switch(type)
+ {
+ case GAL_TYPE_UINT8: *(uint8_t *) value=l; break;
+ case GAL_TYPE_UINT16: *(uint16_t *) value=l; break;
+ case GAL_TYPE_UINT32: *(uint32_t *) value=l; break;
+ case GAL_TYPE_UINT64: *(uint64_t *) value=l; break;
+ default:
+ error(EXIT_FAILURE, 0, "%s: type code %d not recognized",
+ __func__, type);
+ }
+ }
+ }
+
+ /* If reading was unsuccessful, then free the space if it was allocated,
+ then return the status, don't touch the pointer. */
+ if(status && allocated)
+ {
+ free(*out);
+ *out=NULL;
+ }
+ return status;
+}
+
+
+
+
+
+/* If the data structure was correctly created (the string was a number),
+ then return its pointer. Otherwise, return NULL. */
+void *
+gal_type_string_to_number(char *string, uint8_t *type)
+{
+ void *ptr, *out;
+ int fnz=-1, lnz=0; /* `F'irst (or `L'ast) `N'on-`Z'ero. */
+ char *tailptr, *cp;
+ uint8_t forcedfloat=0;
+
+ /* Define initial spaces to keep the value. */
+ uint8_t u8; int8_t i8; uint16_t u16; int16_t i16;
+ uint32_t u32; int32_t i32; uint64_t u64; int64_t i64;
+ float f; double d;
+
+ /* First see if the number is a double (the most generic). */
+ d=strtod(string, &tailptr);
+ if(*tailptr=='f') { if(tailptr[1]=='\0') forcedfloat=1; else return NULL; }
+ else if (*tailptr!='\0') return NULL;
+
+ /* See if the number is actually an integer: */
+ if( forcedfloat==0 && ceil(d) == d )
+ {
+ /* If the number is negative, put it in the signed types (based on
+ its value). If its zero or positive, then put it in the unsigned
+ types. */
+ if( d < 0 )
+ {
+ if (d>INT8_MIN) { i8=d; ptr=&i8; *type=GAL_TYPE_INT8; }
+ else if(d>INT16_MIN) { i16=d; ptr=&i16; *type=GAL_TYPE_INT16; }
+ else if(d>INT32_MIN) { i32=d; ptr=&i32; *type=GAL_TYPE_INT32; }
+ else { i64=d; ptr=&i64; *type=GAL_TYPE_INT64; }
+ }
+ else
+ {
+ if (d<=UINT8_MAX) { u8=d; ptr=&u8; *type=GAL_TYPE_UINT8; }
+ else if(d<=UINT16_MAX) { u16=d; ptr=&u16; *type=GAL_TYPE_UINT16; }
+ else if(d<=UINT32_MAX) { u32=d; ptr=&u32; *type=GAL_TYPE_UINT32; }
+ else { u64=d; ptr=&u64; *type=GAL_TYPE_UINT64; }
+ }
+ }
+ else
+ {
+ /* The maximum number of decimal digits to store in float or double
+ precision floating point are:
+
+ float: 23 mantissa bits + 1 hidden bit: log(224)÷log(10) = 7.22
+ double: 52 mantissa bits + 1 hidden bit: log(253)÷log(10) = 15.95
+
+ FLT_DIG (at least 6 in ISO C) keeps the number of digits (not zero
+ before or after) that can be represented by a single precision
+ floating point number. If there are more digits, then we should
+ store the value as a double precision.
+
+ Note that the number can have non-digit characters that we don't
+ want, like: `.', `e', `E', `,'. */
+ for(cp=string;*cp!='\0';++cp)
+ if(isdigit(*cp) && *cp!='0' && fnz==-1)
+ fnz=cp-string;
+
+ /* In the previous loop, we went to the end of the string, so `cp'
+ now points to its `\0'. We just have to iterate backwards! */
+ for(;cp!=string;--cp)
+ if(isdigit(*cp) && *cp!='0')
+ {
+ lnz=cp-string;
+ break;
+ }
+
+ /* Calculate the number of decimal digits and decide if it the number
+ should be a float or a double. */
+ if( lnz-fnz < FLT_DIG || ( d<FLT_MAX && d>FLT_MIN ) )
+ { f=d; ptr=&f; *type=GAL_TYPE_FLOAT32; }
+ else
+ { ptr=&d; *type=GAL_TYPE_FLOAT64; }
+ }
+
+ /* Allocate a one-element dataset, then copy the number into it. */
+ out=gal_data_malloc_array(*type, 1);
+ memcpy(out, ptr, gal_type_sizeof(*type));
+ return out;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master 26cdc23: More clear names for functions in `type.h',
Mohammad Akhlaghi <=