From 56e4848ebdfe554a36533ead4584b6043c8ad92c Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Tue, 19 Jul 2016 15:31:21 +0200 Subject: [PATCH] The predicates associated with a view are now described in its comments field --- src/obiview.c | 213 ++++++++++++++++++++++++++++++++++++++++---------- src/obiview.h | 2 +- 2 files changed, 172 insertions(+), 43 deletions(-) diff --git a/src/obiview.c b/src/obiview.c index 491661d..61cdca7 100644 --- a/src/obiview.c +++ b/src/obiview.c @@ -175,12 +175,13 @@ int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p); * * @param view The view. * - * @returns A boolean value indicating whether the view has a NUC_SEQUENCE_COLUMN column. + * @returns A character string describing the predicate. + * @retval NULL if the predicate is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -bool view_has_nuc_sequence_column(Obiview_p view); +char* view_has_nuc_sequence_column(Obiview_p view); /** @@ -191,12 +192,13 @@ bool view_has_nuc_sequence_column(Obiview_p view); * * @param view The view. * - * @returns A boolean value indicating whether the view has a QUALITY_COLUMN column. + * @returns A character string describing the predicate. + * @retval NULL if the predicate is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -bool view_has_quality_column(Obiview_p view); +char* view_has_quality_column(Obiview_p view); /** @@ -207,12 +209,13 @@ bool view_has_quality_column(Obiview_p view); * * @param view The view. * - * @returns A boolean value indicating whether the view has a ID_COLUMN column. + * @returns A character string describing the predicate. + * @retval NULL if the predicate is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -bool view_has_id_column(Obiview_p view); +char* view_has_id_column(Obiview_p view); /** @@ -223,12 +226,13 @@ bool view_has_id_column(Obiview_p view); * * @param view The view. * - * @returns A boolean value indicating whether the view has a DEFINITION_COLUMN column. + * @returns A character string describing the predicate. + * @retval NULL if the predicate is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -bool view_has_definition_column(Obiview_p view); +char* view_has_definition_column(Obiview_p view); /** @@ -239,12 +243,13 @@ bool view_has_definition_column(Obiview_p view); * * @param view The view. * - * @returns A boolean value indicating whether the sequence and quality columns correspond properly. + * @returns A character string describing the predicate. + * @retval NULL if the predicate is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -bool view_check_quality_matches_seq_column(Obiview_p view); +char* view_check_quality_matches_seq_column(Obiview_p view); /** @@ -253,12 +258,13 @@ bool view_check_quality_matches_seq_column(Obiview_p view); * @param view The view. * @param predicate_function The predicate function to use. * - * @returns The boolean value returned by the predicate function. + * @returns A character string describing the predicate. + * @retval NULL if the predicate is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -bool view_check_one_predicate(Obiview_p view, bool (*predicate_function)(Obiview_p view)); +char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view)); /** @@ -266,13 +272,13 @@ bool view_check_one_predicate(Obiview_p view, bool (*predicate_function)(Obiview * * @param view The view. * - * @retval 0 if all the predicates are OK. - * @retval -1 if at least one predicate was found to be false. + * @returns A character string describing all the predicates separated by line breaks. + * @retval NULL if at least one of the predicates is false or if there was an error. * * @since July 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -int view_check_all_predicates(Obiview_p view); +char* view_check_all_predicates(Obiview_p view); /************************************************************************ @@ -532,43 +538,91 @@ int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p) /****** PREDICATE FUNCTIONS *******/ -bool view_has_nuc_sequence_column(Obiview_p view) +char* view_has_nuc_sequence_column(Obiview_p view) { + char* predicate; + + predicate = (char*) malloc((strlen("The view has an associated nucleotide sequence column.") + 1) * sizeof(char)); + if (predicate == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate character string."); + return NULL; + } + + strcpy(predicate, "The view has an associated nucleotide sequence column."); + if (obi_view_get_column(view, NUC_SEQUENCE_COLUMN) != NULL) - return true; + return predicate; else - return false; + return NULL; } -bool view_has_quality_column(Obiview_p view) +char* view_has_quality_column(Obiview_p view) { + char* predicate; + + predicate = (char*) malloc((strlen("The view has an associated sequence quality column.") + 1) * sizeof(char)); + if (predicate == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate character string."); + return NULL; + } + + strcpy(predicate, "The view has an associated sequence quality column."); + if (obi_view_get_column(view, QUALITY_COLUMN) != NULL) - return true; + return predicate; else - return false; + return NULL; } -bool view_has_id_column(Obiview_p view) +char* view_has_id_column(Obiview_p view) { + char* predicate; + + predicate = (char*) malloc((strlen("The view has an associated identifier column.") + 1) * sizeof(char)); + if (predicate == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate character string."); + return NULL; + } + + strcpy(predicate, "The view has an associated identifier column."); + if (obi_view_get_column(view, ID_COLUMN) != NULL) - return true; + return predicate; else - return false; + return NULL; } -bool view_has_definition_column(Obiview_p view) +char* view_has_definition_column(Obiview_p view) { + char* predicate; + + predicate = (char*) malloc((strlen("The view has an associated definition column.") + 1) * sizeof(char)); + if (predicate == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate character string."); + return NULL; + } + + strcpy(predicate, "The view has an associated definition column."); + if (obi_view_get_column(view, DEFINITION_COLUMN) != NULL) - return true; + return predicate; else - return false; + return NULL; } -bool view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error if there is one? +char* view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error if there is one? { index_t i, j; index_t nb_elements_per_line; @@ -577,10 +631,21 @@ bool view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error i char* seq; OBIDMS_column_p qual_column; OBIDMS_column_p seq_column; + char* predicate; + + predicate = (char*) malloc((strlen("The sequences and sequence quality arrays match.") + 1) * sizeof(char)); + if (predicate == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate character string."); + return NULL; + } + + strcpy(predicate, "The sequences and sequence quality arrays match."); qual_column = obi_view_get_column(view, QUALITY_COLUMN); if (qual_column == NULL) - return false; + return NULL; seq_column = obi_view_get_column(view, ((qual_column->header)->associated_column).column_name); //seq_column = obi_open_column(view->dms, ((qual_column->header)->associated_column).column_name, ((qual_column->header)->associated_column).version); @@ -588,12 +653,12 @@ bool view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error i // TODO if outside of view, make function that opens a column from a column reference structure? if (seq_column == NULL) - return false; + return NULL; nb_elements_per_line = (qual_column->header)->nb_elements_per_line; // Check that the quality and the sequence columns have the same number of elements per line if (nb_elements_per_line != (seq_column->header)->nb_elements_per_line) - return false; + return NULL; for (i=0; i < (view->infos)->line_count; i++) { @@ -605,36 +670,91 @@ bool view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error i { // Test that the lengths of the quality and the sequence are equal if (qual_len != (int)strlen(seq)) - return false; + return NULL; } // Test if one value is NA and not the other else if (((qual == OBIQual_int_NA) && (seq != OBISeq_NA)) || ((qual != OBIQual_int_NA) && (seq == OBISeq_NA))) - return false; + return NULL; } } //obi_close_column(seq_column); - return true; + return predicate; } -bool view_check_one_predicate(Obiview_p view, bool (*predicate_function)(Obiview_p view)) +char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view)) { return predicate_function(view); } -int view_check_all_predicates(Obiview_p view) +char* view_check_all_predicates(Obiview_p view) { - int i; + int i, j; + size_t size_to_allocate; + char* predicate = NULL; + char* all_predicates_string = NULL; + char** all_predicates = NULL; + + size_to_allocate = 0; + + // Allocate memory for predicate array + all_predicates = (char**) malloc((view->nb_predicates) * sizeof(char*)); + if (all_predicates == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate array."); + return NULL; + } for (i=0; i < view->nb_predicates; i++) { - if (view_check_one_predicate(view, (view->predicate_functions)[i]) == false) - return -1; + // Initialize predicate in predicate array + all_predicates[i] = NULL; + + // Check the predicate + predicate = view_check_one_predicate(view, (view->predicate_functions)[i]); + if (predicate == NULL) + { + // TODO discuss + for (j=0; j<=i; j++) + free(all_predicates[j]); + free(all_predicates); + return NULL; + } + else + { + all_predicates[i] = predicate; + size_to_allocate = size_to_allocate + strlen(predicate) + 1; // +1 for '\n' + } } - return 0; + + size_to_allocate += 1; // +1 for '\0' + + all_predicates_string = (char*) malloc(size_to_allocate * sizeof(char)); + if (all_predicates_string == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for predicate character string."); + return NULL; + } + + // Build the character string with all the predicates + strcpy(all_predicates_string, all_predicates[0]); + for (i=1; i < view->nb_predicates; i++) + { + strcat(all_predicates_string, "\n"); + strcat(all_predicates_string, all_predicates[i]); + } + + // Free everything + for (i=0; i < view->nb_predicates; i++) + free(all_predicates[i]); + free(all_predicates); + + return all_predicates_string; } @@ -894,7 +1014,7 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v // Add predicate functions of the view type view->nb_predicates = 5; // TODO macro? - view->predicate_functions = malloc((view->nb_predicates) * sizeof(bool (*) (bool))); + view->predicate_functions = malloc((view->nb_predicates) * sizeof(char* (*) (bool))); (view->predicate_functions)[0] = view_has_nuc_sequence_column; (view->predicate_functions)[1] = view_has_quality_column; @@ -1398,10 +1518,19 @@ int obi_close_view(Obiview_p view) int obi_save_and_close_view(Obiview_p view) { + char* predicates; + if (!(view->read_only)) { - if (view_check_all_predicates(view) < 0) + predicates = view_check_all_predicates(view); + if (predicates == NULL) return -1; // TODO reverse view (delete files) + else + { + // TODO check size and grow file if needed + strcpy((view->infos)->comments, predicates); + free(predicates); + } if (obi_save_view(view) < 0) return -1; } diff --git a/src/obiview.h b/src/obiview.h index d086513..f2acffe 100644 --- a/src/obiview.h +++ b/src/obiview.h @@ -108,7 +108,7 @@ typedef struct Obiview { */ int nb_predicates; /**< Number of predicates to test when closing the view. */ - bool (**predicate_functions)(struct Obiview* view); /**< Array of pointers on all predicate functions to test when closing the view. + char* (**predicate_functions)(struct Obiview* view); /**< Array of pointers on all predicate functions to test when closing the view. */ } Obiview_t, *Obiview_p;