]> git.saurik.com Git - apple/security.git/blame - cdsa/cdsa_utilities/debugsupport.h
Security-54.1.9.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / debugsupport.h
CommitLineData
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
42namespace Security {
43namespace 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//
53class Name {
54public:
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
74private:
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//
83class Target {
84public:
85 Target();
86 virtual ~Target();
87
88 // get default (singleton) Target
89 static Target &get();
90
91 void setFromEnvironment();
92
93public:
94 class Sink {
95 public:
96 virtual ~Sink();
97 virtual void put(const char *buffer, unsigned int length) = 0;
29654253 98 virtual void dump(const char *buffer);
bac41a7b
A
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
110public:
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
116protected:
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
130protected:
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
29654253
A
145 static terminate_handler previousTerminator; // for chaining
146 static void terminator();
147
bac41a7b
A
148 // the default Target
149 static Target *singleton;
150};
151
152
153//
154// Standard Target::Sinks
155//
156class FileSink : public Target::Sink {
157public:
158 FileSink(FILE *f) : file(f), addDate(false), lockIO(true), lock(false) { }
159 void put(const char *, unsigned int);
29654253 160 void dump(const char *text);
bac41a7b
A
161 void configure(const char *);
162
163private:
164 FILE *file;
165 bool addDate;
166 bool lockIO;
167 Mutex lock;
168};
169
170class SyslogSink : public Target::Sink {
171public:
172 SyslogSink(int pri) : priority(pri), dumpBase(dumpBuffer), dumpPtr(dumpBuffer) { }
173 void put(const char *, unsigned int);
29654253 174 void dump(const char *text);
bac41a7b
A
175 void configure(const char *);
176
177private:
178 int priority;
179
29654253
A
180 // a sliding buffer to hold partial line output
181 static const size_t dumpBufferSize = 1024; // make this about 2 * maximum line length of dumps
bac41a7b
A
182 char dumpBuffer[dumpBufferSize];
183 char *dumpBase, *dumpPtr;
184};
185
186
187#else // NDEBUG
188
189//
190// Note that we don't scaffold up the entire Target hierarchy for NDEBUG.
191// If you directly manipulate debug Targets, Names, or Sinks, you need to
192// conditionalize the code based on NDEBUG.
193//
194
195#endif // NDEBUG
196
197
198} // end namespace Debug
199
200} // end namespace Security
201
bac41a7b
A
202
203#endif //_H_DEBUGSUPPORT