1 | /**
|
---|
2 | * @file exception.cpp
|
---|
3 | * @author myusgun@gmail.com
|
---|
4 | * @brief exception
|
---|
5 | */
|
---|
6 | #include "cf/exception.h"
|
---|
7 |
|
---|
8 | #include <string.h>
|
---|
9 |
|
---|
10 | #ifdef _ON_WINDOWS
|
---|
11 | # include <windows.h>
|
---|
12 | #else
|
---|
13 | # include <errno.h>
|
---|
14 | #endif
|
---|
15 |
|
---|
16 | cf::exception::exception(const cf::char_t * message,
|
---|
17 | const cf::char_t * file,
|
---|
18 | const cf::int32_t line,
|
---|
19 | const cf::char_t * func)
|
---|
20 | : mMessage(message),
|
---|
21 | mFile(file),
|
---|
22 | mLine(line),
|
---|
23 | mFunction(func)
|
---|
24 | {
|
---|
25 | #ifndef _HPUX
|
---|
26 | mStack.push_back(*this);
|
---|
27 | #endif
|
---|
28 | }
|
---|
29 |
|
---|
30 | cf::exception::exception(const cf::exception & ex,
|
---|
31 | const cf::char_t * file,
|
---|
32 | const cf::int32_t line,
|
---|
33 | const cf::char_t * func)
|
---|
34 | : mMessage(ex.what()),
|
---|
35 | mFile(file),
|
---|
36 | mLine(line),
|
---|
37 | mFunction(func)
|
---|
38 | {
|
---|
39 | #ifndef _HPUX
|
---|
40 | mStack = ex.mStack;
|
---|
41 | mStack.push_back(*this);
|
---|
42 | #endif
|
---|
43 | }
|
---|
44 |
|
---|
45 | cf::exception::~exception()
|
---|
46 | throw ()
|
---|
47 | {
|
---|
48 | }
|
---|
49 |
|
---|
50 | const cf::char_t * cf::exception::what() const
|
---|
51 | throw ()
|
---|
52 | {
|
---|
53 | return mMessage.c_str();
|
---|
54 | }
|
---|
55 |
|
---|
56 | const cf::char_t * cf::exception::file() const
|
---|
57 | {
|
---|
58 | return mFile.c_str();
|
---|
59 | }
|
---|
60 |
|
---|
61 | cf::int32_t cf::exception::line() const
|
---|
62 | {
|
---|
63 | return mLine;
|
---|
64 | }
|
---|
65 |
|
---|
66 | const cf::char_t * cf::exception::function() const
|
---|
67 | {
|
---|
68 | return mFunction.c_str();
|
---|
69 | }
|
---|
70 |
|
---|
71 | std::string cf::exception::stackTrace() const
|
---|
72 | {
|
---|
73 | #ifdef _HPUX
|
---|
74 | return mMessage;
|
---|
75 | #else
|
---|
76 | cf::uint32_t iter = 0;
|
---|
77 | cf::formatter fmt;
|
---|
78 |
|
---|
79 | fmt << mStack[0].what();
|
---|
80 | for ( ; iter < mStack.size() ; iter++)
|
---|
81 | {
|
---|
82 | const cf::exception & ex = mStack[iter];
|
---|
83 |
|
---|
84 | fmt << "\n "
|
---|
85 | << "#" << iter << " "
|
---|
86 | << "[" << ex.file() << ":" << ex.line() << "]"
|
---|
87 | << "[" << ex.function() << "()]";
|
---|
88 | }
|
---|
89 | fmt << "\n";
|
---|
90 |
|
---|
91 | return fmt.str();
|
---|
92 | #endif
|
---|
93 | }
|
---|
94 |
|
---|
95 | cf::int32_t cf::exception::systemCode()
|
---|
96 | {
|
---|
97 | #ifdef _ON_WINDOWS
|
---|
98 | # define SYSERR() GetLastError()
|
---|
99 | #else
|
---|
100 | # define SYSERR() errno
|
---|
101 | #endif
|
---|
102 | return static_cast<cf::int32_t>(SYSERR());
|
---|
103 | }
|
---|
104 |
|
---|
105 | std::string cf::exception::systemMessage()
|
---|
106 | {
|
---|
107 | std::string msg;
|
---|
108 |
|
---|
109 | #ifdef _ON_WINDOWS
|
---|
110 | cf::char_t * ptr = NULL;
|
---|
111 | cf::size_t size = 0;
|
---|
112 | const cf::uint32_t flag = FORMAT_MESSAGE_ALLOCATE_BUFFER
|
---|
113 | | FORMAT_MESSAGE_FROM_SYSTEM
|
---|
114 | | FORMAT_MESSAGE_IGNORE_INSERTS;
|
---|
115 | const cf::uint32_t langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
|
---|
116 |
|
---|
117 | size = FormatMessageA(flag, NULL, systemCode(), langID, (LPSTR)&ptr, 0, NULL);
|
---|
118 |
|
---|
119 | if (ptr && size > 0)
|
---|
120 | {
|
---|
121 | msg.assign(ptr, size);
|
---|
122 | LocalFree(ptr);
|
---|
123 | }
|
---|
124 | #else
|
---|
125 | msg = strerror(systemCode());
|
---|
126 | #endif
|
---|
127 |
|
---|
128 | return msg;
|
---|
129 | }
|
---|