Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ cran
/.vscode/launch.json
/Rplots.pdf
/_codeql_detected_source_root
tests/testthat/_problems/
20 changes: 20 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,23 @@ modify_list <- function(x, y) {

utils::modifyList(x, y)
}

#' Test function to verify error formatting with file and line information
#'
#' @description
#' This is a test function that throws an error from C code with file and line
#' information.
#' The error message should include the source file and line number where the
#' error occurred.
#'
#' @return This function never returns; it always throws an error.
#' @keywords internal
#' @noRd
#' @examples
#' \dontrun{
#' # This will throw an error with source location information
#' test_error_with_source()
#' }
test_error_with_source <- function() {
.Call(Rx_igraph_test_error_with_source)
}
2 changes: 2 additions & 0 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ extern SEXP Rx_igraph_st_vertex_connectivity(SEXP, SEXP, SEXP);
extern SEXP Rx_igraph_star(SEXP, SEXP, SEXP);
extern SEXP Rx_igraph_subcomponent(SEXP, SEXP, SEXP);
extern SEXP Rx_igraph_subisomorphic_lad(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
extern SEXP Rx_igraph_test_error_with_source(void);
extern SEXP Rx_igraph_transitivity_local_undirected_all(SEXP, SEXP);
extern SEXP Rx_igraph_union(SEXP, SEXP);
extern SEXP Rx_igraph_vcount(SEXP);
Expand Down Expand Up @@ -1192,6 +1193,7 @@ static const R_CallMethodDef CallEntries[] = {
{"Rx_igraph_star", (DL_FUNC) &Rx_igraph_star, 3},
{"Rx_igraph_subcomponent", (DL_FUNC) &Rx_igraph_subcomponent, 3},
{"Rx_igraph_subisomorphic_lad", (DL_FUNC) &Rx_igraph_subisomorphic_lad, 7},
{"Rx_igraph_test_error_with_source", (DL_FUNC) &Rx_igraph_test_error_with_source, 0},
{"Rx_igraph_transitivity_local_undirected_all", (DL_FUNC) &Rx_igraph_transitivity_local_undirected_all, 2},
{"Rx_igraph_union", (DL_FUNC) &Rx_igraph_union, 2},
{"Rx_igraph_vcount", (DL_FUNC) &Rx_igraph_vcount, 1},
Expand Down
24 changes: 20 additions & 4 deletions src/rinterface_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,18 @@ static inline const char* maybe_add_punctuation(const char* msg, const char* pun
return is_punctuated(msg) ? "" : punctuation;
}

/* Strip vendor/cigraph/src/ prefix from file path. This prefix depends on the
* build procedure, namely on the directory that the compiler is invoked from. */
static inline const char* simplify_file_path(const char *file) {
const char prefix[] = "vendor/cigraph/src/";
const size_t prefix_len = sizeof(prefix) - 1;

if (strncmp(file, prefix, prefix_len) == 0) {
return file + prefix_len;
}
return file;
}

void Rx_igraph_fatal_handler(const char *reason, const char *file, int line) {
#ifdef IGRAPH_SANITIZER_AVAILABLE
__sanitizer_print_stack_trace();
Expand All @@ -2336,10 +2348,12 @@ void Rx_igraph_error_handler(const char *reason, const char *file,
* IGRAPH_FINALLY_FREE() can then clean it up. */

if (Rx_igraph_errors_count == 0 || !Rx_igraph_in_r_check) {
const char* simplified_path = simplify_file_path(file);
snprintf(Rx_igraph_error_reason, sizeof(Rx_igraph_error_reason),
"At %s:%i : %s%s %s", file, line, reason,
maybe_add_punctuation(reason, ","),
igraph_strerror(igraph_errno));
"%s%s %s\nSource: %s:%i", reason,
maybe_add_punctuation(reason, "."),
igraph_strerror(igraph_errno),
simplified_path, line);
Rx_igraph_error_reason[sizeof(Rx_igraph_error_reason) - 1] = 0;

// FIXME: This is a hack, we should replace all memory allocations in the
Expand All @@ -2356,8 +2370,10 @@ void Rx_igraph_error_handler(const char *reason, const char *file,

void Rx_igraph_warning_handler(const char *reason, const char *file, int line) {
if (Rx_igraph_warnings_count == 0) {
const char* simplified_path = simplify_file_path(file);
snprintf(Rx_igraph_warning_reason, sizeof(Rx_igraph_warning_reason),
"At %s:%i : %s%s", file, line, reason, maybe_add_punctuation(reason, "."));
"%s%s\nSource: %s:%i", reason, maybe_add_punctuation(reason, "."),
simplified_path, line);
Rx_igraph_warning_reason[sizeof(Rx_igraph_warning_reason) - 1] = 0;
}
Rx_igraph_warnings_count++;
Expand Down
2 changes: 1 addition & 1 deletion src/sources-glue-c.mk
Original file line number Diff line number Diff line change
@@ -1 +1 @@
GLUE_C_SOURCES=rcallback.o rinterface.o rinterface_extra.o rrandom.o uuid.o
GLUE_C_SOURCES=rcallback.o rinterface.o rinterface_extra.o rrandom.o test_error_with_source.o uuid.o
33 changes: 33 additions & 0 deletions src/test_error_with_source.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* -*- mode: C -*- */
/*
IGraph library R interface.
Copyright (C) 2013 Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include "rinterface.h"

#include <R_ext/Visibility.h>

/* Test function to verify error formatting with file and line information */
attribute_visible SEXP Rx_igraph_test_error_with_source(void) {
igraph_errorf("Test error message for verifying source location formatting",
__FILE__, __LINE__, IGRAPH_EINVAL);
return R_NilValue;
}
4 changes: 4 additions & 0 deletions src/test_error_with_source.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated by deps.mk, do not edit by hand and do not add dependencies to system headers
test_error_with_source.o: \
rinterface.h \
test_error_with_source.c \
Loading