2 Unix SMB/CIFS implementation.
4 Parameter loading functions
6 Copyright (C) David Mulder 2024
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #![allow(non_upper_case_globals)]
24 #![allow(non_camel_case_types)]
25 #![allow(non_snake_case)]
27 #![allow(clippy::upper_case_acronyms)]
28 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
31 pub const MAX_DEBUG_LEVEL: u32 = ffi::MAX_DEBUG_LEVEL;
32 pub const DBGLVL_ERR: u32 = ffi::DBGLVL_ERR;
33 pub const DBGLVL_WARNING: u32 = ffi::DBGLVL_WARNING;
34 pub const DBGLVL_NOTICE: u32 = ffi::DBGLVL_NOTICE;
35 pub const DBGLVL_INFO: u32 = ffi::DBGLVL_INFO;
36 pub const DBGLVL_DEBUG: u32 = ffi::DBGLVL_DEBUG;
38 pub const DEBUG_DEFAULT_STDERR: ffi::debug_logtype =
39 ffi::debug_logtype_DEBUG_DEFAULT_STDERR;
40 pub const DEBUG_DEFAULT_STDOUT: ffi::debug_logtype =
41 ffi::debug_logtype_DEBUG_DEFAULT_STDOUT;
42 pub const DEBUG_FILE: ffi::debug_logtype = ffi::debug_logtype_DEBUG_FILE;
43 pub const DEBUG_STDOUT: ffi::debug_logtype = ffi::debug_logtype_DEBUG_STDOUT;
44 pub const DEBUG_STDERR: ffi::debug_logtype = ffi::debug_logtype_DEBUG_STDERR;
45 pub const DEBUG_CALLBACK: ffi::debug_logtype =
46 ffi::debug_logtype_DEBUG_CALLBACK;
48 pub fn debug_set_logfile(name: &str) {
49 let name_cstr = chelps::wrap_string(name);
51 ffi::debug_set_logfile(name_cstr);
52 chelps::string_free(name_cstr);
56 pub fn setup_logging(prog_name: &str, new_logtype: ffi::debug_logtype) {
57 let prog_name_cstr = chelps::wrap_string(prog_name);
59 ffi::setup_logging(prog_name_cstr, new_logtype);
60 chelps::string_free(prog_name_cstr);
71 macro_rules! debuglevel_set {
74 $crate::ffi::debuglevel_set_class(
75 $crate::ffi::DBGC_ALL as usize,
83 macro_rules! DBG_PREFIX {
84 ($level:expr $(, $arg:expr)* $(,)?) => {{
85 if $level <= $crate::ffi::MAX_DEBUG_LEVEL {
86 let location = format!("{}:{}", file!(), line!());
87 let location_cstr = chelps::wrap_string(&location);
88 let function = chelps::function!();
89 let function_msg = format!("{}: ", function);
90 let function_cstr = chelps::wrap_string(&function);
91 let function_msg_cstr = chelps::wrap_string(&function_msg);
92 // Always append a newline to the debug, otherwise it won't flush
94 let msg = format!("{}\n", format!($($arg),*));
95 let msg_cstr = chelps::wrap_string(&msg);
97 let _ = $crate::ffi::debuglevel_get_class($crate::ffi::DBGC_CLASS as usize) >= ($level as i32)
98 && $crate::ffi::dbghdrclass($level as i32,
99 $crate::ffi::DBGC_CLASS as i32,
102 && $crate::ffi::dbgtext(function_msg_cstr)
103 && $crate::ffi::dbgtext(msg_cstr);
104 chelps::string_free(location_cstr);
105 chelps::string_free(function_cstr);
106 chelps::string_free(function_msg_cstr);
107 chelps::string_free(msg_cstr);
114 macro_rules! DBG_ERR {
115 ($msg:expr $(, $arg:expr)* $(,)?) => {{
116 $crate::DBG_PREFIX!($crate::ffi::DBGLVL_ERR, $msg, $($arg),*)
121 macro_rules! DBG_WARNING {
122 ($msg:expr $(, $arg:expr)* $(,)?) => {{
123 $crate::DBG_PREFIX!($crate::ffi::DBGLVL_WARNING, $msg, $($arg),*)
128 macro_rules! DBG_NOTICE {
129 ($msg:expr $(, $arg:expr)* $(,)?) => {{
130 $crate::DBG_PREFIX!($crate::ffi::DBGLVL_NOTICE, $msg, $($arg),*)
135 macro_rules! DBG_INFO {
136 ($msg:expr $(, $arg:expr)* $(,)?) => {{
137 $crate::DBG_PREFIX!($crate::ffi::DBGLVL_INFO, $msg, $($arg),*)
142 macro_rules! DBG_DEBUG {
143 ($msg:expr $(, $arg:expr)* $(,)?) => {{
144 $crate::DBG_PREFIX!($crate::ffi::DBGLVL_DEBUG, $msg, $($arg),*)
154 use tempfile::NamedTempFile;
157 fn test_debug_constants() {
158 assert_eq!(MAX_DEBUG_LEVEL, ffi::MAX_DEBUG_LEVEL);
159 assert_eq!(DBGLVL_ERR, ffi::DBGLVL_ERR);
160 assert_eq!(DBGLVL_WARNING, ffi::DBGLVL_WARNING);
161 assert_eq!(DBGLVL_NOTICE, ffi::DBGLVL_NOTICE);
162 assert_eq!(DBGLVL_INFO, ffi::DBGLVL_INFO);
163 assert_eq!(DBGLVL_DEBUG, ffi::DBGLVL_DEBUG);
166 DEBUG_DEFAULT_STDERR,
167 ffi::debug_logtype_DEBUG_DEFAULT_STDERR
170 DEBUG_DEFAULT_STDOUT,
171 ffi::debug_logtype_DEBUG_DEFAULT_STDOUT
173 assert_eq!(DEBUG_FILE, ffi::debug_logtype_DEBUG_FILE);
174 assert_eq!(DEBUG_STDOUT, ffi::debug_logtype_DEBUG_STDOUT);
175 assert_eq!(DEBUG_STDERR, ffi::debug_logtype_DEBUG_STDERR);
176 assert_eq!(DEBUG_CALLBACK, ffi::debug_logtype_DEBUG_CALLBACK);
179 macro_rules! test_dbg_macro {
183 fn [<test_dbg_ $level:lower _macro>]() {
184 let logfile = NamedTempFile::new().expect("Failed to create temporary file");
185 let logfile = logfile.path().to_str().unwrap();
186 setup_logging("test_program", DEBUG_FILE);
187 debug_set_logfile(logfile);
189 let logfile_output = concat!("This is a ", stringify!($level), " message");
191 debuglevel_set!([<DBGLVL_ $level:upper>]);
193 [<DBG_ $level:upper>]!("{}\n", logfile_output);
196 let mut file = File::open(logfile).expect("Failed to open logfile");
197 let mut logfile_contents = String::new();
198 file.read_to_string(&mut logfile_contents)
199 .expect("Failed to read logfile");
201 logfile_contents.contains(logfile_output),
202 "Test data missing from logfile: {}",
210 test_dbg_macro!(DEBUG);
211 // Multiple re-inits of the debug env cause it to fail, so we can't
212 // reliably test all of these in one go.
213 //test_dbg_macro!(INFO);
214 //test_dbg_macro!(NOTICE);
215 //test_dbg_macro!(WARNING);
216 //test_dbg_macro!(ERR);