version bump
[asdcplib.git] / src / KM_error.h
1 /*
2 Copyright (c) 2004-2014, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27   /*! \file    KM_error.h
28     \version $Id$
29     \brief   error reporting support
30   */
31
32
33
34 #ifndef _KM_ERROR_H_
35 #define _KM_ERROR_H_
36
37 #define KM_DECLARE_RESULT(sym, i, l) const Result_t RESULT_##sym = Result_t(i, #sym, l);
38
39 namespace Kumu
40 {
41   // Result code container. Both a signed integer and a text string are stored in the object.
42   // When defining your own codes your choice of integer values is mostly unconstrained, but pay
43   // attention to the numbering in the other libraries that use Kumu. Values between -99 and 99
44   // are reserved for Kumu.
45
46   class Result_t
47     {
48       int value;
49       const char* label;
50       const char* symbol;
51       Result_t();
52
53     public:
54       // Return registered Result_t for the given "value" code.
55       static const Result_t& Find(int value);
56
57       // Unregister the Result_t matching the given "value" code. Returns
58       // RESULT_FALSE if "value" does not match a registered Result_t.
59       // Returns RESULT_FAIL if ( value < -99 || value > 99 ) (Kumu core
60       // codes may not be deleted).
61       static Result_t Delete(int value);
62
63       // Iteration through registered result codes, not thread safe.
64       // Get accepts contiguous values from 0 to End() - 1.
65       static unsigned int End();
66       static const Result_t& Get(unsigned int);
67
68       Result_t(int v, const char* s, const char* l);
69       ~Result_t();
70
71       inline bool        operator==(const Result_t& rhs) const { return value == rhs.value; }
72       inline bool        operator!=(const Result_t& rhs) const { return value != rhs.value; }
73       inline bool        Success() const { return ( value >= 0 ); }
74       inline bool        Failure() const { return ( value < 0 ); }
75
76       inline int         Value() const { return value; }
77       inline operator    int() const { return value; }
78
79       inline const char* Label() const { return label; }
80       inline operator    const char*() const { return label; }
81
82       inline const char* Symbol() const { return symbol; }
83     };
84
85   KM_DECLARE_RESULT(FALSE,       1,   "Successful but not true.");
86   KM_DECLARE_RESULT(OK,          0,   "Success.");
87   KM_DECLARE_RESULT(FAIL,       -1,   "An undefined error was detected.");
88   KM_DECLARE_RESULT(PTR,        -2,   "An unexpected NULL pointer was given.");
89   KM_DECLARE_RESULT(NULL_STR,   -3,   "An unexpected empty string was given.");
90   KM_DECLARE_RESULT(ALLOC,      -4,   "Error allocating memory.");
91   KM_DECLARE_RESULT(PARAM,      -5,   "Invalid parameter.");
92   KM_DECLARE_RESULT(NOTIMPL,    -6,   "Unimplemented Feature.");
93   KM_DECLARE_RESULT(SMALLBUF,   -7,   "The given buffer is too small.");
94   KM_DECLARE_RESULT(INIT,       -8,   "The object is not yet initialized.");
95   KM_DECLARE_RESULT(NOT_FOUND,  -9,   "The requested file does not exist on the system.");
96   KM_DECLARE_RESULT(NO_PERM,    -10,  "Insufficient privilege exists to perform the operation.");
97   KM_DECLARE_RESULT(STATE,      -11,  "Object state error.");
98   KM_DECLARE_RESULT(CONFIG,     -12,  "Invalid configuration option detected.");
99   KM_DECLARE_RESULT(FILEOPEN,   -13,  "File open failure.");
100   KM_DECLARE_RESULT(BADSEEK,    -14,  "An invalid file location was requested.");
101   KM_DECLARE_RESULT(READFAIL,   -15,  "File read error.");
102   KM_DECLARE_RESULT(WRITEFAIL,  -16,  "File write error.");
103   KM_DECLARE_RESULT(ENDOFFILE,  -17,  "Attempt to read past end of file.");
104   KM_DECLARE_RESULT(FILEEXISTS, -18,  "Filename already exists.");
105   KM_DECLARE_RESULT(NOTAFILE,   -19,  "Filename not found.");
106   KM_DECLARE_RESULT(UNKNOWN,    -20,  "Unknown result code.");
107   KM_DECLARE_RESULT(DIR_CREATE, -21,  "Unable to create directory.");
108   KM_DECLARE_RESULT(NOT_EMPTY,  -22,  "Unable to delete non-empty directory.");
109   // 23-100 are reserved
110  
111 } // namespace Kumu
112
113 //--------------------------------------------------------------------------------
114 // convenience macros
115
116 // Convenience macros for managing return values in predicates
117 # define KM_SUCCESS(v) (((v) < 0) ? 0 : 1)
118 # define KM_FAILURE(v) (((v) < 0) ? 1 : 0)
119
120
121 // Returns RESULT_PTR if the given argument is NULL.
122 // See Result_t above for an explanation of RESULT_* symbols.
123 # define KM_TEST_NULL(p) \
124   if ( (p) == 0  ) { \
125     return Kumu::RESULT_PTR; \
126   }
127
128 // Returns RESULT_PTR if the given argument is NULL. See Result_t
129 // in WaimeaCore for an explanation of RESULT_* symbols. It then assumes
130 // that the argument is a pointer to a string and returns
131 // RESULT_NULL_STR if the first character is '\0'.
132 //
133 # define KM_TEST_NULL_STR(p) \
134   KM_TEST_NULL(p); \
135   if ( (p)[0] == '\0' ) { \
136     return Kumu::RESULT_NULL_STR; \
137   }
138
139 // RESULT_STATE is ambiguous.  Use these everywhere it is assigned to provide some context
140 #define KM_RESULT_STATE_TEST_IMPLICIT()                                 \
141   if ( result == Kumu::RESULT_STATE ) {                                 \
142     Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); \
143   }
144
145 #define KM_RESULT_STATE_TEST_THIS(_this__r_)                            \
146   if ( _this__r_ == Kumu::RESULT_STATE ) {                              \
147     Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__); \
148   }
149
150 #define KM_RESULT_STATE_HERE()                                          \
151   Kumu::DefaultLogSink().Error("RESULT_STATE RETURNED at %s (%d)\n", __FILE__, __LINE__);
152
153
154
155 namespace Kumu
156 {
157   // simple tracing mechanism
158   class DTrace_t
159   {
160     DTrace_t();
161     
162   protected:
163     const char* m_Label;
164     Result_t*   m_Watch;
165     int         m_Line;
166     const char* m_File;
167     int         m_Sequence;
168
169   public:
170     DTrace_t(const char* Label, Result_t* Watch, int Line, const char* File);
171     ~DTrace_t();
172   };
173 }
174
175 #ifdef KM_TRACE
176 #define WDTRACE(l) DTrace_t __wl__Trace__((l), 0, __LINE__, __FILE__)
177 #define WDTRACER(l,r) DTrace_t __wl__Trace__((l), &(r), __LINE__, __FILE__)
178 #else
179 #define WDTRACE(l)
180 #define WDTRACER(l,r)
181 #endif
182
183
184 #endif // _KM_ERROR_H_
185
186 //
187 // end KM_error.h
188 //