2 * Raster error handling for CUPS.
4 * Copyright 2007-2015 by Apple Inc.
5 * Copyright 2007 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
14 #include <cups/raster-private.h>
21 typedef struct _cups_raster_error_s
/**** Error buffer structure ****/
23 char *start
, /* Start of buffer */
24 *current
, /* Current position in buffer */
25 *end
; /* End of buffer */
26 } _cups_raster_error_t
;
33 static _cups_raster_error_t
*get_error_buffer(void);
37 * '_cupsRasterAddError()' - Add an error message to the error buffer.
41 _cupsRasterAddError(const char *f
, /* I - Printf-style error message */
42 ...) /* I - Additional arguments as needed */
44 _cups_raster_error_t
*buf
= get_error_buffer();
46 va_list ap
; /* Pointer to additional arguments */
47 char s
[2048]; /* Message string */
48 ssize_t bytes
; /* Bytes in message string */
51 DEBUG_printf(("_cupsRasterAddError(f=\"%s\", ...)", f
));
54 bytes
= vsnprintf(s
, sizeof(s
), f
, ap
);
60 DEBUG_printf(("1_cupsRasterAddError: %s", s
));
64 if ((size_t)bytes
>= sizeof(s
))
67 if (bytes
> (ssize_t
)(buf
->end
- buf
->current
))
70 * Allocate more memory...
73 char *temp
; /* New buffer */
74 size_t size
; /* Size of buffer */
77 size
= (size_t)(buf
->end
- buf
->start
+ 2 * bytes
+ 1024);
80 temp
= realloc(buf
->start
, size
);
91 buf
->end
= temp
+ size
;
92 buf
->current
= temp
+ (buf
->current
- buf
->start
);
97 * Append the message to the end of the current string...
100 memcpy(buf
->current
, s
, (size_t)bytes
);
101 buf
->current
+= bytes
- 1;
106 * '_cupsRasterClearError()' - Clear the error buffer.
110 _cupsRasterClearError(void)
112 _cups_raster_error_t
*buf
= get_error_buffer();
116 buf
->current
= buf
->start
;
119 *(buf
->start
) = '\0';
124 * 'cupsRasterErrorString()' - Return the last error from a raster function.
126 * If there are no recent errors, NULL is returned.
128 * @since CUPS 1.3/macOS 10.5@
131 const char * /* O - Last error */
132 cupsRasterErrorString(void)
134 _cups_raster_error_t
*buf
= get_error_buffer();
138 if (buf
->current
== buf
->start
)
145 #ifdef HAVE_PTHREAD_H
147 * Implement per-thread globals...
150 # include <pthread.h>
157 static pthread_key_t raster_key
= 0; /* Thread local storage key */
158 static pthread_once_t raster_key_once
= PTHREAD_ONCE_INIT
;
159 /* One-time initialization object */
166 static void raster_init(void);
167 static void raster_destructor(void *value
);
171 * 'get_error_buffer()' - Return a pointer to thread local storage.
174 _cups_raster_error_t
* /* O - Pointer to error buffer */
175 get_error_buffer(void)
177 _cups_raster_error_t
*buf
; /* Pointer to error buffer */
181 * Initialize the global data exactly once...
184 DEBUG_puts("3get_error_buffer()");
186 pthread_once(&raster_key_once
, raster_init
);
189 * See if we have allocated the data yet...
192 if ((buf
= (_cups_raster_error_t
*)pthread_getspecific(raster_key
))
195 DEBUG_puts("4get_error_buffer: allocating memory for thread.");
198 * No, allocate memory as set the pointer for the key...
201 buf
= calloc(1, sizeof(_cups_raster_error_t
));
202 pthread_setspecific(raster_key
, buf
);
204 DEBUG_printf(("4get_error_buffer: buf=%p", (void *)buf
));
208 * Return the pointer to the data...
216 * 'raster_init()' - Initialize error buffer once.
222 pthread_key_create(&raster_key
, raster_destructor
);
224 DEBUG_printf(("3raster_init(): raster_key=%x(%u)", (unsigned)raster_key
, (unsigned)raster_key
));
229 * 'raster_destructor()' - Free memory allocated by get_error_buffer().
233 raster_destructor(void *value
) /* I - Data to free */
235 _cups_raster_error_t
*buf
= (_cups_raster_error_t
*)value
;
239 DEBUG_printf(("3raster_destructor(value=%p)", value
));
250 * Implement static globals...
254 * 'get_error_buffer()' - Return a pointer to thread local storage.
257 _cups_raster_error_t
* /* O - Pointer to error buffer */
258 get_error_buffer(void)
260 static _cups_raster_error_t buf
= { 0, 0, 0 };
266 #endif /* HAVE_PTHREAD_H */