]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | ||
19 | // | |
20 | // debugsupport - support interface for making and managing debugger objects. | |
21 | // | |
22 | // This header is not needed for logging debug messages. | |
23 | // | |
24 | #ifndef _H_DEBUGSUPPORT | |
25 | #define _H_DEBUGSUPPORT | |
26 | ||
27 | // | |
28 | // Generate stub-code support if NDEBUG (but not CLEAN_NDEBUG) is set, to support | |
29 | // client code that may have been generated with debug enabled. You don't actually | |
30 | // get *real* debug logging, of course, just cheap dummy stubs to keep the linker happy. | |
31 | // | |
32 | #if defined(NDEBUG) && !defined(CLEAN_NDEBUG) | |
33 | # undef NDEBUG | |
34 | # define NDEBUG_STUBS | |
35 | #endif | |
36 | ||
37 | #include <Security/debugging.h> | |
38 | #include <Security/threading.h> | |
39 | #include <cstdarg> | |
40 | #include <set> | |
41 | ||
42 | namespace Security { | |
43 | namespace Debug { | |
44 | ||
45 | ||
46 | #if !defined(NDEBUG) | |
47 | ||
48 | ||
49 | // | |
50 | // Debug scope names - short strings with value semantics. | |
51 | // We don't use STL strings because of overhead. | |
52 | // | |
53 | class Name { | |
54 | public: | |
55 | static const int maxLength = 12; | |
56 | ||
57 | Name(const char *s) | |
58 | { strncpy(mName, s, maxLength-1); mName[maxLength-1] = '\0'; } | |
59 | ||
60 | Name(const char *start, const char *end) | |
61 | { | |
62 | int length = end - start; if (length >= maxLength) length = maxLength - 1; | |
63 | memcpy(mName, start, length); memset(mName + length, 0, maxLength - length); | |
64 | } | |
65 | ||
66 | operator const char *() const { return mName; } | |
67 | ||
68 | bool operator < (const Name &other) const | |
69 | { return memcmp(mName, other.mName, maxLength) < 0; } | |
70 | ||
71 | bool operator == (const Name &other) const | |
72 | { return memcmp(mName, other.mName, maxLength) == 0; } | |
73 | ||
74 | private: | |
75 | char mName[maxLength]; // null terminated for easy printing | |
76 | }; | |
77 | ||
78 | ||
79 | // | |
80 | // A debugging Target. This is an object that receives debugging requests. | |
81 | // You can have many, but one default one is always provided. | |
82 | // | |
83 | class Target { | |
84 | public: | |
85 | Target(); | |
86 | virtual ~Target(); | |
87 | ||
88 | // get default (singleton) Target | |
89 | static Target &get(); | |
90 | ||
91 | void setFromEnvironment(); | |
92 | ||
93 | public: | |
94 | class Sink { | |
95 | public: | |
96 | virtual ~Sink(); | |
97 | virtual void put(const char *buffer, unsigned int length) = 0; | |
98 | virtual void dump(const char *format, va_list args); | |
99 | virtual void configure(const char *argument); | |
100 | }; | |
101 | ||
102 | void to(Sink *sink); | |
103 | void to(const char *filename); | |
104 | void to(int syslogPriority); | |
105 | void to(FILE *openFile); | |
106 | ||
107 | void configure(); // from DEBUGOPTIONS | |
108 | void configure(const char *options); // from explicit string | |
109 | ||
110 | public: | |
111 | void message(const char *scope, const char *format, va_list args); | |
112 | bool debugging(const char *scope); | |
113 | void dump(const char *format, va_list args); | |
114 | bool dump(const char *scope); | |
115 | ||
116 | protected: | |
117 | class Selector { | |
118 | public: | |
119 | Selector(); | |
120 | void operator = (const char *config); | |
121 | ||
122 | bool operator () (const char *name) const; | |
123 | ||
124 | private: | |
125 | bool useSet; // use contents of enableSet | |
126 | bool negate; // negate meaning of enableSet | |
127 | set<Name> enableSet; // set of names | |
128 | }; | |
129 | ||
130 | protected: | |
131 | static const size_t messageConstructionSize = 512; // size of construction buffer | |
132 | ||
133 | Selector logSelector; // selector for logging | |
134 | Selector dumpSelector; // selector for dumping | |
135 | ||
136 | // output option state (from last configure call) | |
137 | bool showScope; // include scope in output lines | |
138 | bool showThread; // include #Threadid in output lines | |
139 | bool showPid; // include [Pid] in output lines | |
140 | size_t dumpLimit; // max. # of bytes dumped by dumpData & friends | |
141 | ||
142 | // current output support | |
143 | Sink *sink; | |
144 | ||
145 | // the default Target | |
146 | static Target *singleton; | |
147 | }; | |
148 | ||
149 | ||
150 | // | |
151 | // Standard Target::Sinks | |
152 | // | |
153 | class FileSink : public Target::Sink { | |
154 | public: | |
155 | FileSink(FILE *f) : file(f), addDate(false), lockIO(true), lock(false) { } | |
156 | void put(const char *, unsigned int); | |
157 | void dump(const char *format, va_list args); | |
158 | void configure(const char *); | |
159 | ||
160 | private: | |
161 | FILE *file; | |
162 | bool addDate; | |
163 | bool lockIO; | |
164 | Mutex lock; | |
165 | }; | |
166 | ||
167 | class SyslogSink : public Target::Sink { | |
168 | public: | |
169 | SyslogSink(int pri) : priority(pri), dumpBase(dumpBuffer), dumpPtr(dumpBuffer) { } | |
170 | void put(const char *, unsigned int); | |
171 | void dump(const char *format, va_list args); | |
172 | void configure(const char *); | |
173 | ||
174 | private: | |
175 | int priority; | |
176 | ||
177 | static const size_t dumpBufferSize = 1024; | |
178 | char dumpBuffer[dumpBufferSize]; | |
179 | char *dumpBase, *dumpPtr; | |
180 | }; | |
181 | ||
182 | ||
183 | #else // NDEBUG | |
184 | ||
185 | // | |
186 | // Note that we don't scaffold up the entire Target hierarchy for NDEBUG. | |
187 | // If you directly manipulate debug Targets, Names, or Sinks, you need to | |
188 | // conditionalize the code based on NDEBUG. | |
189 | // | |
190 | ||
191 | #endif // NDEBUG | |
192 | ||
193 | ||
194 | } // end namespace Debug | |
195 | ||
196 | } // end namespace Security | |
197 | ||
198 | #ifdef _CPP_DEBUGGING | |
199 | #pragma export off | |
200 | #endif | |
201 | ||
202 | #endif //_H_DEBUGSUPPORT |