diff --git a/docs/src/faq.md b/docs/src/faq.md index dbe3928..0500e80 100644 --- a/docs/src/faq.md +++ b/docs/src/faq.md @@ -14,8 +14,8 @@ This is the focus of the [Visualization](@ref) tutorial. ## How can I silence warnings or remove exports? -- From the module: see [`CrystalNets.toggle_warning`](@ref) and [`CrystalNets.toggle_export`](@ref) -- From the executable: use the `--no-warn` and `--no-export` flags. +- From the module: see [`CrystalNets.toggle_warning`](@ref), [`CrystalNets.toggle_error`](@ref) and [`CrystalNets.toggle_export`](@ref) +- From the executable: use the `--no-warn`, `--no-error` and `--no-export` flags. For exports, each `export_...` keyword argument to [`Options`](@ref CrystalNets.Options) can be individually set to `false` or `""` to silence this particular export. See also the paragraph on [export options](@ref exports). diff --git a/src/CrystalNets.jl b/src/CrystalNets.jl index 02f24f3..cfbf633 100644 --- a/src/CrystalNets.jl +++ b/src/CrystalNets.jl @@ -49,6 +49,7 @@ import Logging using ProgressMeter const DOWARN = Base.RefValue{Bool}(false) +const DOERROR = Base.RefValue{Bool}(true) const DOEXPORT = Base.RefValue{Bool}(false) """ @@ -62,6 +63,17 @@ function toggle_warning(to=nothing) DOWARN[] = to isa Nothing ? !DOWARN[] : to end +""" + toggle_error(to=nothing) + +Toggle @error visibility on (if `to == true`) or off (if `to == false`). +Without an argument, toggle on and off repeatedly at each call. +""" +function toggle_error(to=nothing) + global DOERROR + DOERROR[] = to isa Nothing ? !DOERROR[] : to +end + """ toggle_export(to=nothing) @@ -75,6 +87,7 @@ end function __init__() toggle_warning("--no-warn" ∉ ARGS) + toggle_error("--no-error" ∉ ARGS) toggle_export("--no-export" ∉ ARGS) nothing end diff --git a/src/executable.jl b/src/executable.jl index c15dfa6..3fb0efc 100644 --- a/src/executable.jl +++ b/src/executable.jl @@ -85,6 +85,10 @@ function parse_commandline(args) help = "Discard all warnings and information messages." action = :store_true + "--no-error" + help = "Discard all @error messages." + action = :store_true + "--no-export" help = "Do not automatically export the parsed input." action = :store_true @@ -264,6 +268,9 @@ function main(args) if parsed_args[:no_warn]::Bool toggle_warning(false) end + if parsed_args[:no_error]::Bool + toggle_error(false) + end if parsed_args[:no_export]::Bool if !isnothing(parsed_args[:export_to]) return parse_error("""Cannot use both arguments "--export-to" and "--no-export".""") diff --git a/src/input.jl b/src/input.jl index 70833db..6508a83 100644 --- a/src/input.jl +++ b/src/input.jl @@ -44,7 +44,7 @@ function parse_cif(file) @toggleassert loopisspecified if startswith(l[i:j], "data") inloop = false - @ifwarn if haskey(all_data, "atom_site_fract_x") + @iferror if haskey(all_data, "atom_site_fract_x") @error lazy"The CIF file $name may contain multiple inputs: only keeping the last one." end i, j, x = nextword(l, x) @@ -82,7 +82,7 @@ function parse_cif(file) loopspec = String[] lastword = "" elseif j-i ≥ 4 && l[i:i+4] == "data_" - @ifwarn if haskey(all_data, "data") && haskey(all_data, "atom_site_fract_x") + @iferror if haskey(all_data, "data") && haskey(all_data, "atom_site_fract_x") @error lazy"The CIF file $name may contain multiple inputs: only keeping the last one." end all_data["data"] = l[i+5:j] @@ -259,12 +259,12 @@ function CIF(parsed::Dict{String, Union{Vector{String},String}}) if x == 0 || y == 0 empty!(bonds) missingatom = x == 0 ? bond_a[i] : bond_b[i] - @ifwarn @error lazy"""Atom $missingatom, used in a bond, has either zero or multiple placements in CIF file $(parsed["__name"]). This invalidates all bonds from the file, which will thus be discarded.""" + @iferror @error lazy"""Atom $missingatom, used in a bond, has either zero or multiple placements in CIF file $(parsed["__name"]). This invalidates all bonds from the file, which will thus be discarded.""" break end d = 1.004f0*dists[i] # to avoid rounding errors if isnan(d) || (d != -Inf32 && (d ≤ 0f0 || isinf(d))) - @ifwarn @error lazy"""Invalid bond distance of $d between atoms $(bond_a[i]) and $(bond_b[i]) in CIF file $(parsed["__name"]).""" + @iferror @error lazy"""Invalid bond distance of $d between atoms $(bond_a[i]) and $(bond_b[i]) in CIF file $(parsed["__name"]).""" continue end push!(bonds[x], (y, d)) @@ -680,7 +680,7 @@ function fix_valence!(graph::PeriodicGraph3D, pos, types, passH, passO, passCN, checked || @reduce_valence dofix 2 4 1 anychecked |= checked end - @ifwarn anychecked && @error lazy"Found what looks like a disordered carbon ring for $(options.name): use of disordered input is not advised, please double-check the detected topology or provide a clean input." + @iferror anychecked && @error lazy"Found what looks like a disordered carbon ring for $(options.name): use of disordered input is not advised, please double-check the detected topology or provide a clean input." if !isempty(invalidatoms) s = String.(collect(invalidatoms)) @ifwarn begin @@ -718,13 +718,13 @@ function sanitize_removeatoms!(graph::PeriodicGraph3D, pos, types, mat, options) if flag && any(>(2.6), lengths) # This warning could be out of a @ifwarn because it reliably indicates # cases where the input was not properly cleaned - @ifwarn @error lazy"Very suspicious connectivity found for $(options.name)." + @iferror @error lazy"Very suspicious connectivity found for $(options.name)." flag = false end else at = get(atomic_numbers, t, nothing) if at === nothing - @ifwarn @error lazy"Unrecognized atom type \"$t\" in $(options.name) will be considered a dummy atom." + @iferror @error lazy"Unrecognized atom type \"$t\" in $(options.name) will be considered a dummy atom." push!(toremove, i) elseif ismetal[at::Int] for u in neighbors(graph, i) diff --git a/src/types.jl b/src/types.jl index d8fc713..989abf2 100644 --- a/src/types.jl +++ b/src/types.jl @@ -940,7 +940,7 @@ function UnderlyingNets(g::SmallPseudoGraph, options::Options) groups = UnderlyingNets() graph = g isa PeriodicGraph ? g : PeriodicGraph(g) dimensions = PeriodicGraphs.dimensionality(graph) - @ifwarn if haskey(dimensions, 0) + @iferror if haskey(dimensions, 0) @error "Detected substructure of dimension 0 in the input graph. It will be ignored for topology computation." end cell = Cell() diff --git a/src/utils.jl b/src/utils.jl index f872f69..3f0f41c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -58,6 +58,20 @@ macro ifwarn(ex) end end +macro iferror(ex) + return quote + if (DOERROR[]::Bool) + @static if VERSION < v"1.7-" + $(esc(ex)) + else + Base.with_logger(minimal_logger) do + $(esc(ex)) + end + end + end + end +end + function recursive_readdir!(stored, prefix, path) for f in readdir(path; sort=false, join=false)