]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/debugsupport.h
Security-177.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / debugsupport.h
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 #include <Security/debugging.h>
33 #include <Security/threading.h>
34 #include <cstdarg>
35 #include <set>
36
37 namespace Security {
38 namespace Debug {
39
40
41 //
42 // Debug scope names - short strings with value semantics.
43 // We don't use STL strings because of overhead.
44 //
45 class Name {
46 public:
47 static const int maxLength = 12;
48
49 Name(const char *s)
50 { strncpy(mName, s, maxLength-1); mName[maxLength-1] = '\0'; }
51
52 Name(const char *start, const char *end)
53 {
54 int length = end - start; if (length >= maxLength) length = maxLength - 1;
55 memcpy(mName, start, length); memset(mName + length, 0, maxLength - length);
56 }
57
58 operator const char *() const { return mName; }
59
60 bool operator < (const Name &other) const
61 { return memcmp(mName, other.mName, maxLength) < 0; }
62
63 bool operator == (const Name &other) const
64 { return memcmp(mName, other.mName, maxLength) == 0; }
65
66 private:
67 char mName[maxLength]; // null terminated for easy printing
68 };
69
70
71 //
72 // A debugging Target. This is an object that receives debugging requests.
73 // You can have many, but one default one is always provided.
74 //
75 class Target {
76 public:
77 Target();
78 virtual ~Target();
79
80 // get default (singleton) Target
81 static Target &get();
82
83 void setFromEnvironment();
84
85 public:
86 class Sink {
87 public:
88 virtual ~Sink();
89 virtual void put(const char *buffer, unsigned int length) = 0;
90 virtual void dump(const char *buffer);
91 virtual void configure(const char *argument);
92 };
93
94 void to(Sink *sink);
95 void to(const char *filename);
96 void to(int syslogPriority);
97 void to(FILE *openFile);
98
99 void configure(); // from DEBUGOPTIONS
100 void configure(const char *options); // from explicit string
101
102 public:
103 void message(const char *scope, const char *format, va_list args);
104 bool debugging(const char *scope);
105 void dump(const char *format, va_list args);
106 bool dump(const char *scope);
107
108 protected:
109 class Selector {
110 public:
111 Selector();
112 void operator = (const char *config);
113
114 bool operator () (const char *name) const;
115
116 private:
117 bool useSet; // use contents of enableSet
118 bool negate; // negate meaning of enableSet
119 set<Name> enableSet; // set of names
120 };
121
122 protected:
123 static const size_t messageConstructionSize = 512; // size of construction buffer
124
125 Selector logSelector; // selector for logging
126 Selector dumpSelector; // selector for dumping
127
128 // output option state (from last configure call)
129 bool showScope; // include scope in output lines
130 bool showThread; // include #Threadid in output lines
131 bool showPid; // include [Pid] in output lines
132 size_t dumpLimit; // max. # of bytes dumped by dumpData & friends
133
134 // current output support
135 Sink *sink;
136
137 static terminate_handler previousTerminator; // for chaining
138 static void terminator();
139
140 // the default Target
141 static Target *singleton;
142 };
143
144
145 //
146 // Standard Target::Sinks
147 //
148 class FileSink : public Target::Sink {
149 public:
150 FileSink(FILE *f) : file(f), addDate(false), lockIO(true), lock(false) { }
151 void put(const char *, unsigned int);
152 void dump(const char *text);
153 void configure(const char *);
154
155 private:
156 FILE *file;
157 bool addDate;
158 bool lockIO;
159 Mutex lock;
160 };
161
162 class SyslogSink : public Target::Sink {
163 public:
164 SyslogSink(int pri) : priority(pri), dumpBase(dumpBuffer), dumpPtr(dumpBuffer) { }
165 void put(const char *, unsigned int);
166 void dump(const char *text);
167 void configure(const char *);
168
169 private:
170 int priority;
171
172 // a sliding buffer to hold partial line output
173 static const size_t dumpBufferSize = 1024; // make this about 2 * maximum line length of dumps
174 char dumpBuffer[dumpBufferSize];
175 char *dumpBase, *dumpPtr;
176 };
177
178
179 } // end namespace Debug
180 } // end namespace Security
181
182
183 #endif //_H_DEBUGSUPPORT