1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
crate::ix!();

pub fn format_exception(
        pex:        Option<&StdException>,
        psz_thread: &str) -> String {

    
    #[cfg(WIN32)]
    let psz_module: [i8; MAX_PATH] = "";

    #[cfg(WIN32)]
    get_module_file_namea(None, psz_module, size_of_val(&psz_module));

    #[cfg(not(WIN32))]
    let psz_module: &str = "bitcoin";

    if pex.is_some() {

        format!{
            "EXCEPTION: {:?}       \n{} in {}       \n",
                pex.unwrap(),
                psz_module,
                psz_thread
        }

    } else {

        format!{
            "UNKNOWN EXCEPTION       \n{} in {}       \n",
            psz_module,
            psz_thread
        }
    }
}

pub fn print_exception_continue(
        pex:        Option<&StdException>,
        psz_thread: &str)  {
    
    let message: String = format_exception(pex,psz_thread);

    println!("\n\n************************\n{}\n", message);

    eprintln!("\n\n************************\n{}\n", message);
}

/*
#ifdef WIN32
// Export main() and ensure working ASLR on Windows.
// Exporting a symbol will prevent the linker from stripping
// the .reloc section from the binary, which is a requirement
// for ASLR. This is a temporary workaround until a fixed
// version of binutils is used for releases.
__declspec(dllexport) int main(int argc, char* argv[])
{
    util::WinCmdLineArgs winArgs;
    std::tie(argc, argv) = winArgs.get();
#else
int main(int argc, char* argv[])
{
#endif
*/
pub fn cli_main(argv: &Vec<String>) -> Result<i32,StdException> {
    

    setup_environment();

    if !setup_networking() {
        eprintln!("Error: Initializing networking failed\n");
        return Ok(EXIT_FAILURE);
    }

    unsafe {
        event_set_log_callback(Some(libevent_log_cb));
    }

    let try_block = || -> TryBlockResult::<_,StdException> {
        let ret: i32 = app_init_rpc(argv);
        if ret != CONTINUE_EXECUTION {
            return TryBlockResult::Return(ret);
        }
        TryBlockResult::Success
    };

    match try_block() {
        TryBlockResult::Return(v)  => return Ok(v),
        TryBlockResult::Err(e)  => {
            print_exception_continue(Some(&e), "AppInitRPC()");
            return Ok(EXIT_FAILURE);
        },

        TryBlockResult::Break   => { }
        TryBlockResult::Success => { }
    }

    let mut ret: Result<i32,StdException> = Ok(EXIT_FAILURE);

    let try_block = |ret: &mut Result<i32,StdException>| -> TryBlockResult::<_,StdException> {
        *ret = command_linerpc(argv);

        match ret {
            Ok(_)  => {},
            Err(ref mut e) => return TryBlockResult::Err(e.clone()),
        }

        TryBlockResult::Success
    };

    match try_block(&mut ret) {
        TryBlockResult::Return(v)  => return v,
        TryBlockResult::Err(e)  => {
            match e {
                StdException::Default { .. }  => {
                    print_exception_continue(Some(&e), "CommandLineRPC()");
                }
                _  => {
                    print_exception_continue(None, "CommandLineRPC()");
                }
            }
        },

        TryBlockResult::Break   => { }
        TryBlockResult::Success => { }
    }

    ret
}