postgres_extension/utils/
elog.rs1#![macro_use]
2#![allow(non_snake_case)]
3
4use libc::*;
5use std::ffi::CString;
6use crate::setjmp::*;
7
8#[repr(C)]
9pub struct ErrorContextCallback {
10 previous: *mut ErrorContextCallback,
11 callback: extern fn(arg: *mut c_void),
12 arg: *mut c_void,
13}
14
15#[macro_export]
16macro_rules! elog {
17 ($elevel:expr, $fmt:expr, $($args:tt)*) => {
18 postgres_extension::utils::elog::elog_internal(
19 file!(), line!(), $elevel, &format!($fmt, $($args)*));
20 };
21}
22
23extern {
24 fn elog_start(filename : *const c_char, lineno : c_int, funcname : *const c_char ) -> ();
25 fn elog_finish(elevel : c_int, fmt : *const c_char, ...) -> ();
26 pub fn pg_re_throw() -> ();
27}
28
29pub static mut POSTGRES_THREW_EXCEPTION: bool = false;
30
31pub const DEBUG5 : i32 = 10;
32pub const DEBUG4 : i32 = 11;
33pub const DEBUG3 : i32 = 12;
34pub const DEBUG2 : i32 = 13;
35pub const DEBUG1 : i32 = 14;
36pub const LOG : i32 = 15;
37pub const INFO : i32 = 17;
38pub const NOTICE : i32 = 18;
39pub const WARNING : i32 = 19;
40pub const ERROR : i32 = 20;
41pub const FATAL : i32 = 21;
42pub const PANIC : i32 = 22;
43pub fn elog_internal(filename: &str, lineno: u32, elevel: i32, fmt: &str) -> () {
44 let cfilename = CString::new(filename).unwrap().as_ptr();
45 let clineno = lineno as c_int;
46 let cfuncname = std::ptr::null::<c_char>();
48 let celevel = elevel as c_int;
49 let cfmt = CString::new(fmt).unwrap();
50
51 unsafe {
52 elog_start(cfilename, clineno, cfuncname);
53 elog_finish(celevel, cfmt.as_ptr());
54 }
55}
56
57extern "C" {
58 #[allow(dead_code)]
59 pub static mut PG_exception_stack: *mut sigjmp_buf;
60 pub static mut error_context_stack: *mut ErrorContextCallback;
61}
62
63pub struct PgError;
64
65#[macro_export]
66macro_rules! longjmp_panic {
67 ($e:expr) => {
68 let retval;
69 unsafe {
70 use postgres_extension::utils::elog
71 ::{PG_exception_stack,
72 error_context_stack,
73 PgError};
74 use postgres_extension::setjmp::{sigsetjmp,sigjmp_buf};
75 let save_exception_stack: *mut sigjmp_buf = PG_exception_stack;
76 let save_context_stack: *mut ErrorContextCallback = error_context_stack;
77 let mut local_sigjmp_buf: sigjmp_buf = std::mem::uninitialized();
78 if sigsetjmp(&mut local_sigjmp_buf, 0) == 0 {
79 PG_exception_stack = &mut local_sigjmp_buf;
80 retval = $e;
81 } else {
82 PG_exception_stack = save_exception_stack;
83 error_context_stack = save_context_stack;
84 POSTGRES_THREW_EXCEPTION = true;
85 panic!(PgError);
86 }
87 PG_exception_stack = save_exception_stack;
88 error_context_stack = save_context_stack;
89 }
90 retval
91 }
92}