]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/error.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / error.c
1 /*
2 * "$Id: error.c 6274 2007-02-13 21:05:28Z mike $"
3 *
4 * Raster error handling for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 2007 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * _cupsRasterAddError() - Add an error message to the error buffer.
29 * _cupsRasterClearError() - Clear the error buffer.
30 * cupsRasterErrorString() - Return the last error from a raster function.
31 * get_error_buffer() - Return a pointer to thread local storage.
32 * raster_init() - Initialize error buffer once.
33 * raster_destructor() - Free memory allocated by get_error_buffer().
34 */
35
36 /*
37 * Include necessary headers...
38 */
39
40 #include "image-private.h"
41 #include <stdarg.h>
42
43
44 /*
45 * Local structures...
46 */
47
48 typedef struct _cups_raster_error_s /**** Error buffer structure ****/
49 {
50 char *start, /* Start of buffer */
51 *current, /* Current position in buffer */
52 *end; /* End of buffer */
53 } _cups_raster_error_t;
54
55
56 /*
57 * Local functions...
58 */
59
60 static _cups_raster_error_t *get_error_buffer(void);
61
62
63 /*
64 * '_cupsRasterAddError()' - Add an error message to the error buffer.
65 */
66
67 void
68 _cupsRasterAddError(const char *f, /* I - Printf-style error message */
69 ...) /* I - Additional arguments as needed */
70 {
71 _cups_raster_error_t *buf = get_error_buffer();
72 /* Error buffer */
73 va_list ap; /* Pointer to additional arguments */
74 char s[2048]; /* Message string */
75 size_t bytes; /* Bytes in message string */
76
77
78 va_start(ap, f);
79 bytes = vsnprintf(s, sizeof(s), f, ap);
80 va_end(ap);
81
82 if (bytes <= 0)
83 return;
84
85 bytes ++;
86
87 if (bytes >= sizeof(s))
88 return;
89
90 if (bytes > (buf->end - buf->current))
91 {
92 /*
93 * Allocate more memory...
94 */
95
96 char *temp; /* New buffer */
97 size_t size; /* Size of buffer */
98
99
100 size = buf->end - buf->start + 2 * bytes + 1024;
101
102 if (buf->start)
103 temp = realloc(buf->start, size);
104 else
105 temp = malloc(size);
106
107 if (!temp)
108 return;
109
110 /*
111 * Update pointers...
112 */
113
114 buf->end = temp + size;
115 buf->current = temp + (buf->current - buf->start);
116 buf->start = temp;
117 }
118
119 /*
120 * Append the message to the end of the current string...
121 */
122
123 memcpy(buf->current, s, bytes);
124 buf->current += bytes - 1;
125 }
126
127
128 /*
129 * '_cupsRasterClearError()' - Clear the error buffer.
130 */
131
132 void
133 _cupsRasterClearError(void)
134 {
135 _cups_raster_error_t *buf = get_error_buffer();
136 /* Error buffer */
137
138
139 buf->current = buf->start;
140
141 if (buf->start)
142 *(buf->start) = '\0';
143 }
144
145
146 /*
147 * 'cupsRasterErrorString()' - Return the last error from a raster function.
148 *
149 * If there are no recent errors, NULL is returned.
150 *
151 * @since CUPS 1.3@
152 */
153
154 const char * /* O - Last error */
155 cupsRasterErrorString(void)
156 {
157 _cups_raster_error_t *buf = get_error_buffer();
158 /* Error buffer */
159
160
161 if (buf->current == buf->start)
162 return (NULL);
163 else
164 return (buf->start);
165 }
166
167
168 #ifdef HAVE_PTHREAD_H
169 /*
170 * Implement per-thread globals...
171 */
172
173 # include <pthread.h>
174
175
176 /*
177 * Local globals...
178 */
179
180 static pthread_key_t raster_key = -1;
181 /* Thread local storage key */
182 static pthread_once_t raster_key_once = PTHREAD_ONCE_INIT;
183 /* One-time initialization object */
184
185
186 /*
187 * Local functions...
188 */
189
190 static void raster_init(void);
191 static void raster_destructor(void *value);
192
193
194 /*
195 * 'get_error_buffer()' - Return a pointer to thread local storage.
196 */
197
198 _cups_raster_error_t * /* O - Pointer to error buffer */
199 get_error_buffer(void)
200 {
201 _cups_raster_error_t *buf; /* Pointer to error buffer */
202
203
204 /*
205 * Initialize the global data exactly once...
206 */
207
208 DEBUG_printf(("get_error_buffer(): raster_key_once=%d\n",
209 raster_key_once));
210
211 pthread_once(&raster_key_once, raster_init);
212
213 /*
214 * See if we have allocated the data yet...
215 */
216
217 if ((buf = (_cups_raster_error_t *)pthread_getspecific(raster_key))
218 == NULL)
219 {
220 DEBUG_puts("get_error_buffer: allocating memory for thread...");
221
222 /*
223 * No, allocate memory as set the pointer for the key...
224 */
225
226 buf = calloc(1, sizeof(_cups_raster_error_t));
227 pthread_setspecific(raster_key, buf);
228
229 DEBUG_printf((" buf=%p\n", buf));
230 }
231
232 /*
233 * Return the pointer to the data...
234 */
235
236 return (buf);
237 }
238
239
240 /*
241 * 'raster_init()' - Initialize error buffer once.
242 */
243
244 static void
245 raster_init(void)
246 {
247 pthread_key_create(&raster_key, raster_destructor);
248
249 DEBUG_printf(("raster_init(): raster_key=%x(%u)\n", raster_key,
250 raster_key));
251 }
252
253
254 /*
255 * 'raster_destructor()' - Free memory allocated by get_error_buffer().
256 */
257
258 static void
259 raster_destructor(void *value) /* I - Data to free */
260 {
261 _cups_raster_error_t *buf = (_cups_raster_error_t *)value;
262 /* Error buffer */
263
264
265 DEBUG_printf(("raster_destructor(value=%p)\n", value));
266
267 if (buf->start)
268 free(buf->start);
269
270 free(value);
271 }
272
273
274 #else
275 /*
276 * Implement static globals...
277 */
278
279 /*
280 * 'get_error_buffer()' - Return a pointer to thread local storage.
281 */
282
283 _cups_raster_error_t * /* O - Pointer to error buffer */
284 get_error_buffer(void)
285 {
286 static _cups_raster_error_t buf = { 0, 0, 0 };
287 /* Error buffer */
288
289
290 return (&buf);
291 }
292 #endif /* HAVE_PTHREAD_H */
293
294
295 /*
296 * End of "$Id: error.c 6274 2007-02-13 21:05:28Z mike $".
297 */