1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * String functions for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #define _CUPS_STRING_C_
16*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
17*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
18*5e7646d2SAndroid Build Coastguard Worker #include <stddef.h>
19*5e7646d2SAndroid Build Coastguard Worker #include <limits.h>
20*5e7646d2SAndroid Build Coastguard Worker
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker /*
23*5e7646d2SAndroid Build Coastguard Worker * Local globals...
24*5e7646d2SAndroid Build Coastguard Worker */
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker static _cups_mutex_t sp_mutex = _CUPS_MUTEX_INITIALIZER;
27*5e7646d2SAndroid Build Coastguard Worker /* Mutex to control access to pool */
28*5e7646d2SAndroid Build Coastguard Worker static cups_array_t *stringpool = NULL;
29*5e7646d2SAndroid Build Coastguard Worker /* Global string pool */
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker
32*5e7646d2SAndroid Build Coastguard Worker /*
33*5e7646d2SAndroid Build Coastguard Worker * Local functions...
34*5e7646d2SAndroid Build Coastguard Worker */
35*5e7646d2SAndroid Build Coastguard Worker
36*5e7646d2SAndroid Build Coastguard Worker static int compare_sp_items(_cups_sp_item_t *a, _cups_sp_item_t *b);
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker /*
40*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrAlloc()' - Allocate/reference a string.
41*5e7646d2SAndroid Build Coastguard Worker */
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker char * /* O - String pointer */
_cupsStrAlloc(const char * s)44*5e7646d2SAndroid Build Coastguard Worker _cupsStrAlloc(const char *s) /* I - String */
45*5e7646d2SAndroid Build Coastguard Worker {
46*5e7646d2SAndroid Build Coastguard Worker size_t slen; /* Length of string */
47*5e7646d2SAndroid Build Coastguard Worker _cups_sp_item_t *item, /* String pool item */
48*5e7646d2SAndroid Build Coastguard Worker *key; /* Search key */
49*5e7646d2SAndroid Build Coastguard Worker
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker /*
52*5e7646d2SAndroid Build Coastguard Worker * Range check input...
53*5e7646d2SAndroid Build Coastguard Worker */
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker if (!s)
56*5e7646d2SAndroid Build Coastguard Worker return (NULL);
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker /*
59*5e7646d2SAndroid Build Coastguard Worker * Get the string pool...
60*5e7646d2SAndroid Build Coastguard Worker */
61*5e7646d2SAndroid Build Coastguard Worker
62*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&sp_mutex);
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker if (!stringpool)
65*5e7646d2SAndroid Build Coastguard Worker stringpool = cupsArrayNew((cups_array_func_t)compare_sp_items, NULL);
66*5e7646d2SAndroid Build Coastguard Worker
67*5e7646d2SAndroid Build Coastguard Worker if (!stringpool)
68*5e7646d2SAndroid Build Coastguard Worker {
69*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
70*5e7646d2SAndroid Build Coastguard Worker
71*5e7646d2SAndroid Build Coastguard Worker return (NULL);
72*5e7646d2SAndroid Build Coastguard Worker }
73*5e7646d2SAndroid Build Coastguard Worker
74*5e7646d2SAndroid Build Coastguard Worker /*
75*5e7646d2SAndroid Build Coastguard Worker * See if the string is already in the pool...
76*5e7646d2SAndroid Build Coastguard Worker */
77*5e7646d2SAndroid Build Coastguard Worker
78*5e7646d2SAndroid Build Coastguard Worker key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str));
79*5e7646d2SAndroid Build Coastguard Worker
80*5e7646d2SAndroid Build Coastguard Worker if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL)
81*5e7646d2SAndroid Build Coastguard Worker {
82*5e7646d2SAndroid Build Coastguard Worker /*
83*5e7646d2SAndroid Build Coastguard Worker * Found it, return the cached string...
84*5e7646d2SAndroid Build Coastguard Worker */
85*5e7646d2SAndroid Build Coastguard Worker
86*5e7646d2SAndroid Build Coastguard Worker item->ref_count ++;
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG_GUARDS
89*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5_cupsStrAlloc: Using string %p(%s) for \"%s\", guard=%08x, "
90*5e7646d2SAndroid Build Coastguard Worker "ref_count=%d", item, item->str, s, item->guard,
91*5e7646d2SAndroid Build Coastguard Worker item->ref_count));
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker if (item->guard != _CUPS_STR_GUARD)
94*5e7646d2SAndroid Build Coastguard Worker abort();
95*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG_GUARDS */
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker return (item->str);
100*5e7646d2SAndroid Build Coastguard Worker }
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker /*
103*5e7646d2SAndroid Build Coastguard Worker * Not found, so allocate a new one...
104*5e7646d2SAndroid Build Coastguard Worker */
105*5e7646d2SAndroid Build Coastguard Worker
106*5e7646d2SAndroid Build Coastguard Worker slen = strlen(s);
107*5e7646d2SAndroid Build Coastguard Worker item = (_cups_sp_item_t *)calloc(1, sizeof(_cups_sp_item_t) + slen);
108*5e7646d2SAndroid Build Coastguard Worker if (!item)
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
111*5e7646d2SAndroid Build Coastguard Worker
112*5e7646d2SAndroid Build Coastguard Worker return (NULL);
113*5e7646d2SAndroid Build Coastguard Worker }
114*5e7646d2SAndroid Build Coastguard Worker
115*5e7646d2SAndroid Build Coastguard Worker item->ref_count = 1;
116*5e7646d2SAndroid Build Coastguard Worker memcpy(item->str, s, slen + 1);
117*5e7646d2SAndroid Build Coastguard Worker
118*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG_GUARDS
119*5e7646d2SAndroid Build Coastguard Worker item->guard = _CUPS_STR_GUARD;
120*5e7646d2SAndroid Build Coastguard Worker
121*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5_cupsStrAlloc: Created string %p(%s) for \"%s\", guard=%08x, "
122*5e7646d2SAndroid Build Coastguard Worker "ref_count=%d", item, item->str, s, item->guard,
123*5e7646d2SAndroid Build Coastguard Worker item->ref_count));
124*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG_GUARDS */
125*5e7646d2SAndroid Build Coastguard Worker
126*5e7646d2SAndroid Build Coastguard Worker /*
127*5e7646d2SAndroid Build Coastguard Worker * Add the string to the pool and return it...
128*5e7646d2SAndroid Build Coastguard Worker */
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(stringpool, item);
131*5e7646d2SAndroid Build Coastguard Worker
132*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker return (item->str);
135*5e7646d2SAndroid Build Coastguard Worker }
136*5e7646d2SAndroid Build Coastguard Worker
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker /*
139*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrDate()' - Return a localized date for a given time value.
140*5e7646d2SAndroid Build Coastguard Worker *
141*5e7646d2SAndroid Build Coastguard Worker * This function works around the locale encoding issues of strftime...
142*5e7646d2SAndroid Build Coastguard Worker */
143*5e7646d2SAndroid Build Coastguard Worker
144*5e7646d2SAndroid Build Coastguard Worker char * /* O - Buffer */
_cupsStrDate(char * buf,size_t bufsize,time_t timeval)145*5e7646d2SAndroid Build Coastguard Worker _cupsStrDate(char *buf, /* I - Buffer */
146*5e7646d2SAndroid Build Coastguard Worker size_t bufsize, /* I - Size of buffer */
147*5e7646d2SAndroid Build Coastguard Worker time_t timeval) /* I - Time value */
148*5e7646d2SAndroid Build Coastguard Worker {
149*5e7646d2SAndroid Build Coastguard Worker struct tm date; /* Local date/time */
150*5e7646d2SAndroid Build Coastguard Worker char temp[1024]; /* Temporary buffer */
151*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals(); /* Per-thread globals */
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker
154*5e7646d2SAndroid Build Coastguard Worker if (!cg->lang_default)
155*5e7646d2SAndroid Build Coastguard Worker cg->lang_default = cupsLangDefault();
156*5e7646d2SAndroid Build Coastguard Worker
157*5e7646d2SAndroid Build Coastguard Worker localtime_r(&timeval, &date);
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker if (cg->lang_default->encoding != CUPS_UTF8)
160*5e7646d2SAndroid Build Coastguard Worker {
161*5e7646d2SAndroid Build Coastguard Worker strftime(temp, sizeof(temp), "%c", &date);
162*5e7646d2SAndroid Build Coastguard Worker cupsCharsetToUTF8((cups_utf8_t *)buf, temp, (int)bufsize, cg->lang_default->encoding);
163*5e7646d2SAndroid Build Coastguard Worker }
164*5e7646d2SAndroid Build Coastguard Worker else
165*5e7646d2SAndroid Build Coastguard Worker strftime(buf, bufsize, "%c", &date);
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker return (buf);
168*5e7646d2SAndroid Build Coastguard Worker }
169*5e7646d2SAndroid Build Coastguard Worker
170*5e7646d2SAndroid Build Coastguard Worker
171*5e7646d2SAndroid Build Coastguard Worker /*
172*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrFlush()' - Flush the string pool.
173*5e7646d2SAndroid Build Coastguard Worker */
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker void
_cupsStrFlush(void)176*5e7646d2SAndroid Build Coastguard Worker _cupsStrFlush(void)
177*5e7646d2SAndroid Build Coastguard Worker {
178*5e7646d2SAndroid Build Coastguard Worker _cups_sp_item_t *item; /* Current item */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsStrFlush: %d strings in array",
182*5e7646d2SAndroid Build Coastguard Worker cupsArrayCount(stringpool)));
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&sp_mutex);
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker for (item = (_cups_sp_item_t *)cupsArrayFirst(stringpool);
187*5e7646d2SAndroid Build Coastguard Worker item;
188*5e7646d2SAndroid Build Coastguard Worker item = (_cups_sp_item_t *)cupsArrayNext(stringpool))
189*5e7646d2SAndroid Build Coastguard Worker free(item);
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(stringpool);
192*5e7646d2SAndroid Build Coastguard Worker stringpool = NULL;
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
195*5e7646d2SAndroid Build Coastguard Worker }
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker /*
199*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrFormatd()' - Format a floating-point number.
200*5e7646d2SAndroid Build Coastguard Worker */
201*5e7646d2SAndroid Build Coastguard Worker
202*5e7646d2SAndroid Build Coastguard Worker char * /* O - Pointer to end of string */
_cupsStrFormatd(char * buf,char * bufend,double number,struct lconv * loc)203*5e7646d2SAndroid Build Coastguard Worker _cupsStrFormatd(char *buf, /* I - String */
204*5e7646d2SAndroid Build Coastguard Worker char *bufend, /* I - End of string buffer */
205*5e7646d2SAndroid Build Coastguard Worker double number, /* I - Number to format */
206*5e7646d2SAndroid Build Coastguard Worker struct lconv *loc) /* I - Locale data */
207*5e7646d2SAndroid Build Coastguard Worker {
208*5e7646d2SAndroid Build Coastguard Worker char *bufptr, /* Pointer into buffer */
209*5e7646d2SAndroid Build Coastguard Worker temp[1024], /* Temporary string */
210*5e7646d2SAndroid Build Coastguard Worker *tempdec, /* Pointer to decimal point */
211*5e7646d2SAndroid Build Coastguard Worker *tempptr; /* Pointer into temporary string */
212*5e7646d2SAndroid Build Coastguard Worker const char *dec; /* Decimal point */
213*5e7646d2SAndroid Build Coastguard Worker int declen; /* Length of decimal point */
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker /*
217*5e7646d2SAndroid Build Coastguard Worker * Format the number using the "%.12f" format and then eliminate
218*5e7646d2SAndroid Build Coastguard Worker * unnecessary trailing 0's.
219*5e7646d2SAndroid Build Coastguard Worker */
220*5e7646d2SAndroid Build Coastguard Worker
221*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), "%.12f", number);
222*5e7646d2SAndroid Build Coastguard Worker for (tempptr = temp + strlen(temp) - 1;
223*5e7646d2SAndroid Build Coastguard Worker tempptr > temp && *tempptr == '0';
224*5e7646d2SAndroid Build Coastguard Worker *tempptr-- = '\0');
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker /*
227*5e7646d2SAndroid Build Coastguard Worker * Next, find the decimal point...
228*5e7646d2SAndroid Build Coastguard Worker */
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker if (loc && loc->decimal_point)
231*5e7646d2SAndroid Build Coastguard Worker {
232*5e7646d2SAndroid Build Coastguard Worker dec = loc->decimal_point;
233*5e7646d2SAndroid Build Coastguard Worker declen = (int)strlen(dec);
234*5e7646d2SAndroid Build Coastguard Worker }
235*5e7646d2SAndroid Build Coastguard Worker else
236*5e7646d2SAndroid Build Coastguard Worker {
237*5e7646d2SAndroid Build Coastguard Worker dec = ".";
238*5e7646d2SAndroid Build Coastguard Worker declen = 1;
239*5e7646d2SAndroid Build Coastguard Worker }
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker if (declen == 1)
242*5e7646d2SAndroid Build Coastguard Worker tempdec = strchr(temp, *dec);
243*5e7646d2SAndroid Build Coastguard Worker else
244*5e7646d2SAndroid Build Coastguard Worker tempdec = strstr(temp, dec);
245*5e7646d2SAndroid Build Coastguard Worker
246*5e7646d2SAndroid Build Coastguard Worker /*
247*5e7646d2SAndroid Build Coastguard Worker * Copy everything up to the decimal point...
248*5e7646d2SAndroid Build Coastguard Worker */
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker if (tempdec)
251*5e7646d2SAndroid Build Coastguard Worker {
252*5e7646d2SAndroid Build Coastguard Worker for (tempptr = temp, bufptr = buf;
253*5e7646d2SAndroid Build Coastguard Worker tempptr < tempdec && bufptr < bufend;
254*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *tempptr++);
255*5e7646d2SAndroid Build Coastguard Worker
256*5e7646d2SAndroid Build Coastguard Worker tempptr += declen;
257*5e7646d2SAndroid Build Coastguard Worker
258*5e7646d2SAndroid Build Coastguard Worker if (*tempptr && bufptr < bufend)
259*5e7646d2SAndroid Build Coastguard Worker {
260*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '.';
261*5e7646d2SAndroid Build Coastguard Worker
262*5e7646d2SAndroid Build Coastguard Worker while (*tempptr && bufptr < bufend)
263*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *tempptr++;
264*5e7646d2SAndroid Build Coastguard Worker }
265*5e7646d2SAndroid Build Coastguard Worker
266*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
267*5e7646d2SAndroid Build Coastguard Worker }
268*5e7646d2SAndroid Build Coastguard Worker else
269*5e7646d2SAndroid Build Coastguard Worker {
270*5e7646d2SAndroid Build Coastguard Worker strlcpy(buf, temp, (size_t)(bufend - buf + 1));
271*5e7646d2SAndroid Build Coastguard Worker bufptr = buf + strlen(buf);
272*5e7646d2SAndroid Build Coastguard Worker }
273*5e7646d2SAndroid Build Coastguard Worker
274*5e7646d2SAndroid Build Coastguard Worker return (bufptr);
275*5e7646d2SAndroid Build Coastguard Worker }
276*5e7646d2SAndroid Build Coastguard Worker
277*5e7646d2SAndroid Build Coastguard Worker
278*5e7646d2SAndroid Build Coastguard Worker /*
279*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrFree()' - Free/dereference a string.
280*5e7646d2SAndroid Build Coastguard Worker */
281*5e7646d2SAndroid Build Coastguard Worker
282*5e7646d2SAndroid Build Coastguard Worker void
_cupsStrFree(const char * s)283*5e7646d2SAndroid Build Coastguard Worker _cupsStrFree(const char *s) /* I - String to free */
284*5e7646d2SAndroid Build Coastguard Worker {
285*5e7646d2SAndroid Build Coastguard Worker _cups_sp_item_t *item, /* String pool item */
286*5e7646d2SAndroid Build Coastguard Worker *key; /* Search key */
287*5e7646d2SAndroid Build Coastguard Worker
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker /*
290*5e7646d2SAndroid Build Coastguard Worker * Range check input...
291*5e7646d2SAndroid Build Coastguard Worker */
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker if (!s)
294*5e7646d2SAndroid Build Coastguard Worker return;
295*5e7646d2SAndroid Build Coastguard Worker
296*5e7646d2SAndroid Build Coastguard Worker /*
297*5e7646d2SAndroid Build Coastguard Worker * Check the string pool...
298*5e7646d2SAndroid Build Coastguard Worker *
299*5e7646d2SAndroid Build Coastguard Worker * We don't need to lock the mutex yet, as we only want to know if
300*5e7646d2SAndroid Build Coastguard Worker * the stringpool is initialized. The rest of the code will still
301*5e7646d2SAndroid Build Coastguard Worker * work if it is initialized before we lock...
302*5e7646d2SAndroid Build Coastguard Worker */
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker if (!stringpool)
305*5e7646d2SAndroid Build Coastguard Worker return;
306*5e7646d2SAndroid Build Coastguard Worker
307*5e7646d2SAndroid Build Coastguard Worker /*
308*5e7646d2SAndroid Build Coastguard Worker * See if the string is already in the pool...
309*5e7646d2SAndroid Build Coastguard Worker */
310*5e7646d2SAndroid Build Coastguard Worker
311*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&sp_mutex);
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str));
314*5e7646d2SAndroid Build Coastguard Worker
315*5e7646d2SAndroid Build Coastguard Worker if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL &&
316*5e7646d2SAndroid Build Coastguard Worker item == key)
317*5e7646d2SAndroid Build Coastguard Worker {
318*5e7646d2SAndroid Build Coastguard Worker /*
319*5e7646d2SAndroid Build Coastguard Worker * Found it, dereference...
320*5e7646d2SAndroid Build Coastguard Worker */
321*5e7646d2SAndroid Build Coastguard Worker
322*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG_GUARDS
323*5e7646d2SAndroid Build Coastguard Worker if (key->guard != _CUPS_STR_GUARD)
324*5e7646d2SAndroid Build Coastguard Worker {
325*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5_cupsStrFree: Freeing string %p(%s), guard=%08x, ref_count=%d", key, key->str, key->guard, key->ref_count));
326*5e7646d2SAndroid Build Coastguard Worker abort();
327*5e7646d2SAndroid Build Coastguard Worker }
328*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG_GUARDS */
329*5e7646d2SAndroid Build Coastguard Worker
330*5e7646d2SAndroid Build Coastguard Worker item->ref_count --;
331*5e7646d2SAndroid Build Coastguard Worker
332*5e7646d2SAndroid Build Coastguard Worker if (!item->ref_count)
333*5e7646d2SAndroid Build Coastguard Worker {
334*5e7646d2SAndroid Build Coastguard Worker /*
335*5e7646d2SAndroid Build Coastguard Worker * Remove and free...
336*5e7646d2SAndroid Build Coastguard Worker */
337*5e7646d2SAndroid Build Coastguard Worker
338*5e7646d2SAndroid Build Coastguard Worker cupsArrayRemove(stringpool, item);
339*5e7646d2SAndroid Build Coastguard Worker
340*5e7646d2SAndroid Build Coastguard Worker free(item);
341*5e7646d2SAndroid Build Coastguard Worker }
342*5e7646d2SAndroid Build Coastguard Worker }
343*5e7646d2SAndroid Build Coastguard Worker
344*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
345*5e7646d2SAndroid Build Coastguard Worker }
346*5e7646d2SAndroid Build Coastguard Worker
347*5e7646d2SAndroid Build Coastguard Worker
348*5e7646d2SAndroid Build Coastguard Worker /*
349*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrRetain()' - Increment the reference count of a string.
350*5e7646d2SAndroid Build Coastguard Worker *
351*5e7646d2SAndroid Build Coastguard Worker * Note: This function does not verify that the passed pointer is in the
352*5e7646d2SAndroid Build Coastguard Worker * string pool, so any calls to it MUST know they are passing in a
353*5e7646d2SAndroid Build Coastguard Worker * good pointer.
354*5e7646d2SAndroid Build Coastguard Worker */
355*5e7646d2SAndroid Build Coastguard Worker
356*5e7646d2SAndroid Build Coastguard Worker char * /* O - Pointer to string */
_cupsStrRetain(const char * s)357*5e7646d2SAndroid Build Coastguard Worker _cupsStrRetain(const char *s) /* I - String to retain */
358*5e7646d2SAndroid Build Coastguard Worker {
359*5e7646d2SAndroid Build Coastguard Worker _cups_sp_item_t *item; /* Pointer to string pool item */
360*5e7646d2SAndroid Build Coastguard Worker
361*5e7646d2SAndroid Build Coastguard Worker
362*5e7646d2SAndroid Build Coastguard Worker if (s)
363*5e7646d2SAndroid Build Coastguard Worker {
364*5e7646d2SAndroid Build Coastguard Worker item = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str));
365*5e7646d2SAndroid Build Coastguard Worker
366*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG_GUARDS
367*5e7646d2SAndroid Build Coastguard Worker if (item->guard != _CUPS_STR_GUARD)
368*5e7646d2SAndroid Build Coastguard Worker {
369*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5_cupsStrRetain: Retaining string %p(%s), guard=%08x, "
370*5e7646d2SAndroid Build Coastguard Worker "ref_count=%d", item, s, item->guard, item->ref_count));
371*5e7646d2SAndroid Build Coastguard Worker abort();
372*5e7646d2SAndroid Build Coastguard Worker }
373*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG_GUARDS */
374*5e7646d2SAndroid Build Coastguard Worker
375*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&sp_mutex);
376*5e7646d2SAndroid Build Coastguard Worker
377*5e7646d2SAndroid Build Coastguard Worker item->ref_count ++;
378*5e7646d2SAndroid Build Coastguard Worker
379*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
380*5e7646d2SAndroid Build Coastguard Worker }
381*5e7646d2SAndroid Build Coastguard Worker
382*5e7646d2SAndroid Build Coastguard Worker return ((char *)s);
383*5e7646d2SAndroid Build Coastguard Worker }
384*5e7646d2SAndroid Build Coastguard Worker
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker /*
387*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrScand()' - Scan a string for a floating-point number.
388*5e7646d2SAndroid Build Coastguard Worker *
389*5e7646d2SAndroid Build Coastguard Worker * This function handles the locale-specific BS so that a decimal
390*5e7646d2SAndroid Build Coastguard Worker * point is always the period (".")...
391*5e7646d2SAndroid Build Coastguard Worker */
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker double /* O - Number */
_cupsStrScand(const char * buf,char ** bufptr,struct lconv * loc)394*5e7646d2SAndroid Build Coastguard Worker _cupsStrScand(const char *buf, /* I - Pointer to number */
395*5e7646d2SAndroid Build Coastguard Worker char **bufptr, /* O - New pointer or NULL on error */
396*5e7646d2SAndroid Build Coastguard Worker struct lconv *loc) /* I - Locale data */
397*5e7646d2SAndroid Build Coastguard Worker {
398*5e7646d2SAndroid Build Coastguard Worker char temp[1024], /* Temporary buffer */
399*5e7646d2SAndroid Build Coastguard Worker *tempptr; /* Pointer into temporary buffer */
400*5e7646d2SAndroid Build Coastguard Worker
401*5e7646d2SAndroid Build Coastguard Worker
402*5e7646d2SAndroid Build Coastguard Worker /*
403*5e7646d2SAndroid Build Coastguard Worker * Range check input...
404*5e7646d2SAndroid Build Coastguard Worker */
405*5e7646d2SAndroid Build Coastguard Worker
406*5e7646d2SAndroid Build Coastguard Worker if (!buf)
407*5e7646d2SAndroid Build Coastguard Worker return (0.0);
408*5e7646d2SAndroid Build Coastguard Worker
409*5e7646d2SAndroid Build Coastguard Worker /*
410*5e7646d2SAndroid Build Coastguard Worker * Skip leading whitespace...
411*5e7646d2SAndroid Build Coastguard Worker */
412*5e7646d2SAndroid Build Coastguard Worker
413*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*buf))
414*5e7646d2SAndroid Build Coastguard Worker buf ++;
415*5e7646d2SAndroid Build Coastguard Worker
416*5e7646d2SAndroid Build Coastguard Worker /*
417*5e7646d2SAndroid Build Coastguard Worker * Copy leading sign, numbers, period, and then numbers...
418*5e7646d2SAndroid Build Coastguard Worker */
419*5e7646d2SAndroid Build Coastguard Worker
420*5e7646d2SAndroid Build Coastguard Worker tempptr = temp;
421*5e7646d2SAndroid Build Coastguard Worker if (*buf == '-' || *buf == '+')
422*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = *buf++;
423*5e7646d2SAndroid Build Coastguard Worker
424*5e7646d2SAndroid Build Coastguard Worker while (isdigit(*buf & 255))
425*5e7646d2SAndroid Build Coastguard Worker if (tempptr < (temp + sizeof(temp) - 1))
426*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = *buf++;
427*5e7646d2SAndroid Build Coastguard Worker else
428*5e7646d2SAndroid Build Coastguard Worker {
429*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
430*5e7646d2SAndroid Build Coastguard Worker *bufptr = NULL;
431*5e7646d2SAndroid Build Coastguard Worker
432*5e7646d2SAndroid Build Coastguard Worker return (0.0);
433*5e7646d2SAndroid Build Coastguard Worker }
434*5e7646d2SAndroid Build Coastguard Worker
435*5e7646d2SAndroid Build Coastguard Worker if (*buf == '.')
436*5e7646d2SAndroid Build Coastguard Worker {
437*5e7646d2SAndroid Build Coastguard Worker /*
438*5e7646d2SAndroid Build Coastguard Worker * Read fractional portion of number...
439*5e7646d2SAndroid Build Coastguard Worker */
440*5e7646d2SAndroid Build Coastguard Worker
441*5e7646d2SAndroid Build Coastguard Worker buf ++;
442*5e7646d2SAndroid Build Coastguard Worker
443*5e7646d2SAndroid Build Coastguard Worker if (loc && loc->decimal_point)
444*5e7646d2SAndroid Build Coastguard Worker {
445*5e7646d2SAndroid Build Coastguard Worker strlcpy(tempptr, loc->decimal_point, sizeof(temp) - (size_t)(tempptr - temp));
446*5e7646d2SAndroid Build Coastguard Worker tempptr += strlen(tempptr);
447*5e7646d2SAndroid Build Coastguard Worker }
448*5e7646d2SAndroid Build Coastguard Worker else if (tempptr < (temp + sizeof(temp) - 1))
449*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = '.';
450*5e7646d2SAndroid Build Coastguard Worker else
451*5e7646d2SAndroid Build Coastguard Worker {
452*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
453*5e7646d2SAndroid Build Coastguard Worker *bufptr = NULL;
454*5e7646d2SAndroid Build Coastguard Worker
455*5e7646d2SAndroid Build Coastguard Worker return (0.0);
456*5e7646d2SAndroid Build Coastguard Worker }
457*5e7646d2SAndroid Build Coastguard Worker
458*5e7646d2SAndroid Build Coastguard Worker while (isdigit(*buf & 255))
459*5e7646d2SAndroid Build Coastguard Worker if (tempptr < (temp + sizeof(temp) - 1))
460*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = *buf++;
461*5e7646d2SAndroid Build Coastguard Worker else
462*5e7646d2SAndroid Build Coastguard Worker {
463*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
464*5e7646d2SAndroid Build Coastguard Worker *bufptr = NULL;
465*5e7646d2SAndroid Build Coastguard Worker
466*5e7646d2SAndroid Build Coastguard Worker return (0.0);
467*5e7646d2SAndroid Build Coastguard Worker }
468*5e7646d2SAndroid Build Coastguard Worker }
469*5e7646d2SAndroid Build Coastguard Worker
470*5e7646d2SAndroid Build Coastguard Worker if (*buf == 'e' || *buf == 'E')
471*5e7646d2SAndroid Build Coastguard Worker {
472*5e7646d2SAndroid Build Coastguard Worker /*
473*5e7646d2SAndroid Build Coastguard Worker * Read exponent...
474*5e7646d2SAndroid Build Coastguard Worker */
475*5e7646d2SAndroid Build Coastguard Worker
476*5e7646d2SAndroid Build Coastguard Worker if (tempptr < (temp + sizeof(temp) - 1))
477*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = *buf++;
478*5e7646d2SAndroid Build Coastguard Worker else
479*5e7646d2SAndroid Build Coastguard Worker {
480*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
481*5e7646d2SAndroid Build Coastguard Worker *bufptr = NULL;
482*5e7646d2SAndroid Build Coastguard Worker
483*5e7646d2SAndroid Build Coastguard Worker return (0.0);
484*5e7646d2SAndroid Build Coastguard Worker }
485*5e7646d2SAndroid Build Coastguard Worker
486*5e7646d2SAndroid Build Coastguard Worker if (*buf == '+' || *buf == '-')
487*5e7646d2SAndroid Build Coastguard Worker {
488*5e7646d2SAndroid Build Coastguard Worker if (tempptr < (temp + sizeof(temp) - 1))
489*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = *buf++;
490*5e7646d2SAndroid Build Coastguard Worker else
491*5e7646d2SAndroid Build Coastguard Worker {
492*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
493*5e7646d2SAndroid Build Coastguard Worker *bufptr = NULL;
494*5e7646d2SAndroid Build Coastguard Worker
495*5e7646d2SAndroid Build Coastguard Worker return (0.0);
496*5e7646d2SAndroid Build Coastguard Worker }
497*5e7646d2SAndroid Build Coastguard Worker }
498*5e7646d2SAndroid Build Coastguard Worker
499*5e7646d2SAndroid Build Coastguard Worker while (isdigit(*buf & 255))
500*5e7646d2SAndroid Build Coastguard Worker if (tempptr < (temp + sizeof(temp) - 1))
501*5e7646d2SAndroid Build Coastguard Worker *tempptr++ = *buf++;
502*5e7646d2SAndroid Build Coastguard Worker else
503*5e7646d2SAndroid Build Coastguard Worker {
504*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
505*5e7646d2SAndroid Build Coastguard Worker *bufptr = NULL;
506*5e7646d2SAndroid Build Coastguard Worker
507*5e7646d2SAndroid Build Coastguard Worker return (0.0);
508*5e7646d2SAndroid Build Coastguard Worker }
509*5e7646d2SAndroid Build Coastguard Worker }
510*5e7646d2SAndroid Build Coastguard Worker
511*5e7646d2SAndroid Build Coastguard Worker /*
512*5e7646d2SAndroid Build Coastguard Worker * Nul-terminate the temporary string and return the value...
513*5e7646d2SAndroid Build Coastguard Worker */
514*5e7646d2SAndroid Build Coastguard Worker
515*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
516*5e7646d2SAndroid Build Coastguard Worker *bufptr = (char *)buf;
517*5e7646d2SAndroid Build Coastguard Worker
518*5e7646d2SAndroid Build Coastguard Worker *tempptr = '\0';
519*5e7646d2SAndroid Build Coastguard Worker
520*5e7646d2SAndroid Build Coastguard Worker return (strtod(temp, NULL));
521*5e7646d2SAndroid Build Coastguard Worker }
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker /*
525*5e7646d2SAndroid Build Coastguard Worker * '_cupsStrStatistics()' - Return allocation statistics for string pool.
526*5e7646d2SAndroid Build Coastguard Worker */
527*5e7646d2SAndroid Build Coastguard Worker
528*5e7646d2SAndroid Build Coastguard Worker size_t /* O - Number of strings */
_cupsStrStatistics(size_t * alloc_bytes,size_t * total_bytes)529*5e7646d2SAndroid Build Coastguard Worker _cupsStrStatistics(size_t *alloc_bytes, /* O - Allocated bytes */
530*5e7646d2SAndroid Build Coastguard Worker size_t *total_bytes) /* O - Total string bytes */
531*5e7646d2SAndroid Build Coastguard Worker {
532*5e7646d2SAndroid Build Coastguard Worker size_t count, /* Number of strings */
533*5e7646d2SAndroid Build Coastguard Worker abytes, /* Allocated string bytes */
534*5e7646d2SAndroid Build Coastguard Worker tbytes, /* Total string bytes */
535*5e7646d2SAndroid Build Coastguard Worker len; /* Length of string */
536*5e7646d2SAndroid Build Coastguard Worker _cups_sp_item_t *item; /* Current item */
537*5e7646d2SAndroid Build Coastguard Worker
538*5e7646d2SAndroid Build Coastguard Worker
539*5e7646d2SAndroid Build Coastguard Worker /*
540*5e7646d2SAndroid Build Coastguard Worker * Loop through strings in pool, counting everything up...
541*5e7646d2SAndroid Build Coastguard Worker */
542*5e7646d2SAndroid Build Coastguard Worker
543*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&sp_mutex);
544*5e7646d2SAndroid Build Coastguard Worker
545*5e7646d2SAndroid Build Coastguard Worker for (count = 0, abytes = 0, tbytes = 0,
546*5e7646d2SAndroid Build Coastguard Worker item = (_cups_sp_item_t *)cupsArrayFirst(stringpool);
547*5e7646d2SAndroid Build Coastguard Worker item;
548*5e7646d2SAndroid Build Coastguard Worker item = (_cups_sp_item_t *)cupsArrayNext(stringpool))
549*5e7646d2SAndroid Build Coastguard Worker {
550*5e7646d2SAndroid Build Coastguard Worker /*
551*5e7646d2SAndroid Build Coastguard Worker * Count allocated memory, using a 64-bit aligned buffer as a basis.
552*5e7646d2SAndroid Build Coastguard Worker */
553*5e7646d2SAndroid Build Coastguard Worker
554*5e7646d2SAndroid Build Coastguard Worker count += item->ref_count;
555*5e7646d2SAndroid Build Coastguard Worker len = (strlen(item->str) + 8) & (size_t)~7;
556*5e7646d2SAndroid Build Coastguard Worker abytes += sizeof(_cups_sp_item_t) + len;
557*5e7646d2SAndroid Build Coastguard Worker tbytes += item->ref_count * len;
558*5e7646d2SAndroid Build Coastguard Worker }
559*5e7646d2SAndroid Build Coastguard Worker
560*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&sp_mutex);
561*5e7646d2SAndroid Build Coastguard Worker
562*5e7646d2SAndroid Build Coastguard Worker /*
563*5e7646d2SAndroid Build Coastguard Worker * Return values...
564*5e7646d2SAndroid Build Coastguard Worker */
565*5e7646d2SAndroid Build Coastguard Worker
566*5e7646d2SAndroid Build Coastguard Worker if (alloc_bytes)
567*5e7646d2SAndroid Build Coastguard Worker *alloc_bytes = abytes;
568*5e7646d2SAndroid Build Coastguard Worker
569*5e7646d2SAndroid Build Coastguard Worker if (total_bytes)
570*5e7646d2SAndroid Build Coastguard Worker *total_bytes = tbytes;
571*5e7646d2SAndroid Build Coastguard Worker
572*5e7646d2SAndroid Build Coastguard Worker return (count);
573*5e7646d2SAndroid Build Coastguard Worker }
574*5e7646d2SAndroid Build Coastguard Worker
575*5e7646d2SAndroid Build Coastguard Worker
576*5e7646d2SAndroid Build Coastguard Worker /*
577*5e7646d2SAndroid Build Coastguard Worker * '_cups_strcpy()' - Copy a string allowing for overlapping strings.
578*5e7646d2SAndroid Build Coastguard Worker */
579*5e7646d2SAndroid Build Coastguard Worker
580*5e7646d2SAndroid Build Coastguard Worker void
_cups_strcpy(char * dst,const char * src)581*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(char *dst, /* I - Destination string */
582*5e7646d2SAndroid Build Coastguard Worker const char *src) /* I - Source string */
583*5e7646d2SAndroid Build Coastguard Worker {
584*5e7646d2SAndroid Build Coastguard Worker while (*src)
585*5e7646d2SAndroid Build Coastguard Worker *dst++ = *src++;
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker *dst = '\0';
588*5e7646d2SAndroid Build Coastguard Worker }
589*5e7646d2SAndroid Build Coastguard Worker
590*5e7646d2SAndroid Build Coastguard Worker
591*5e7646d2SAndroid Build Coastguard Worker /*
592*5e7646d2SAndroid Build Coastguard Worker * '_cups_strdup()' - Duplicate a string.
593*5e7646d2SAndroid Build Coastguard Worker */
594*5e7646d2SAndroid Build Coastguard Worker
595*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_STRDUP
596*5e7646d2SAndroid Build Coastguard Worker char * /* O - New string pointer */
_cups_strdup(const char * s)597*5e7646d2SAndroid Build Coastguard Worker _cups_strdup(const char *s) /* I - String to duplicate */
598*5e7646d2SAndroid Build Coastguard Worker {
599*5e7646d2SAndroid Build Coastguard Worker char *t; /* New string pointer */
600*5e7646d2SAndroid Build Coastguard Worker size_t slen; /* Length of string */
601*5e7646d2SAndroid Build Coastguard Worker
602*5e7646d2SAndroid Build Coastguard Worker
603*5e7646d2SAndroid Build Coastguard Worker if (!s)
604*5e7646d2SAndroid Build Coastguard Worker return (NULL);
605*5e7646d2SAndroid Build Coastguard Worker
606*5e7646d2SAndroid Build Coastguard Worker slen = strlen(s);
607*5e7646d2SAndroid Build Coastguard Worker if ((t = malloc(slen + 1)) == NULL)
608*5e7646d2SAndroid Build Coastguard Worker return (NULL);
609*5e7646d2SAndroid Build Coastguard Worker
610*5e7646d2SAndroid Build Coastguard Worker return (memcpy(t, s, slen + 1));
611*5e7646d2SAndroid Build Coastguard Worker }
612*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_STRDUP */
613*5e7646d2SAndroid Build Coastguard Worker
614*5e7646d2SAndroid Build Coastguard Worker
615*5e7646d2SAndroid Build Coastguard Worker /*
616*5e7646d2SAndroid Build Coastguard Worker * '_cups_strcasecmp()' - Do a case-insensitive comparison.
617*5e7646d2SAndroid Build Coastguard Worker */
618*5e7646d2SAndroid Build Coastguard Worker
619*5e7646d2SAndroid Build Coastguard Worker int /* O - Result of comparison (-1, 0, or 1) */
_cups_strcasecmp(const char * s,const char * t)620*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(const char *s, /* I - First string */
621*5e7646d2SAndroid Build Coastguard Worker const char *t) /* I - Second string */
622*5e7646d2SAndroid Build Coastguard Worker {
623*5e7646d2SAndroid Build Coastguard Worker while (*s != '\0' && *t != '\0')
624*5e7646d2SAndroid Build Coastguard Worker {
625*5e7646d2SAndroid Build Coastguard Worker if (_cups_tolower(*s) < _cups_tolower(*t))
626*5e7646d2SAndroid Build Coastguard Worker return (-1);
627*5e7646d2SAndroid Build Coastguard Worker else if (_cups_tolower(*s) > _cups_tolower(*t))
628*5e7646d2SAndroid Build Coastguard Worker return (1);
629*5e7646d2SAndroid Build Coastguard Worker
630*5e7646d2SAndroid Build Coastguard Worker s ++;
631*5e7646d2SAndroid Build Coastguard Worker t ++;
632*5e7646d2SAndroid Build Coastguard Worker }
633*5e7646d2SAndroid Build Coastguard Worker
634*5e7646d2SAndroid Build Coastguard Worker if (*s == '\0' && *t == '\0')
635*5e7646d2SAndroid Build Coastguard Worker return (0);
636*5e7646d2SAndroid Build Coastguard Worker else if (*s != '\0')
637*5e7646d2SAndroid Build Coastguard Worker return (1);
638*5e7646d2SAndroid Build Coastguard Worker else
639*5e7646d2SAndroid Build Coastguard Worker return (-1);
640*5e7646d2SAndroid Build Coastguard Worker }
641*5e7646d2SAndroid Build Coastguard Worker
642*5e7646d2SAndroid Build Coastguard Worker /*
643*5e7646d2SAndroid Build Coastguard Worker * '_cups_strncasecmp()' - Do a case-insensitive comparison on up to N chars.
644*5e7646d2SAndroid Build Coastguard Worker */
645*5e7646d2SAndroid Build Coastguard Worker
646*5e7646d2SAndroid Build Coastguard Worker int /* O - Result of comparison (-1, 0, or 1) */
_cups_strncasecmp(const char * s,const char * t,size_t n)647*5e7646d2SAndroid Build Coastguard Worker _cups_strncasecmp(const char *s, /* I - First string */
648*5e7646d2SAndroid Build Coastguard Worker const char *t, /* I - Second string */
649*5e7646d2SAndroid Build Coastguard Worker size_t n) /* I - Maximum number of characters to compare */
650*5e7646d2SAndroid Build Coastguard Worker {
651*5e7646d2SAndroid Build Coastguard Worker while (*s != '\0' && *t != '\0' && n > 0)
652*5e7646d2SAndroid Build Coastguard Worker {
653*5e7646d2SAndroid Build Coastguard Worker if (_cups_tolower(*s) < _cups_tolower(*t))
654*5e7646d2SAndroid Build Coastguard Worker return (-1);
655*5e7646d2SAndroid Build Coastguard Worker else if (_cups_tolower(*s) > _cups_tolower(*t))
656*5e7646d2SAndroid Build Coastguard Worker return (1);
657*5e7646d2SAndroid Build Coastguard Worker
658*5e7646d2SAndroid Build Coastguard Worker s ++;
659*5e7646d2SAndroid Build Coastguard Worker t ++;
660*5e7646d2SAndroid Build Coastguard Worker n --;
661*5e7646d2SAndroid Build Coastguard Worker }
662*5e7646d2SAndroid Build Coastguard Worker
663*5e7646d2SAndroid Build Coastguard Worker if (n == 0)
664*5e7646d2SAndroid Build Coastguard Worker return (0);
665*5e7646d2SAndroid Build Coastguard Worker else if (*s == '\0' && *t == '\0')
666*5e7646d2SAndroid Build Coastguard Worker return (0);
667*5e7646d2SAndroid Build Coastguard Worker else if (*s != '\0')
668*5e7646d2SAndroid Build Coastguard Worker return (1);
669*5e7646d2SAndroid Build Coastguard Worker else
670*5e7646d2SAndroid Build Coastguard Worker return (-1);
671*5e7646d2SAndroid Build Coastguard Worker }
672*5e7646d2SAndroid Build Coastguard Worker
673*5e7646d2SAndroid Build Coastguard Worker
674*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_STRLCAT
675*5e7646d2SAndroid Build Coastguard Worker /*
676*5e7646d2SAndroid Build Coastguard Worker * '_cups_strlcat()' - Safely concatenate two strings.
677*5e7646d2SAndroid Build Coastguard Worker */
678*5e7646d2SAndroid Build Coastguard Worker
679*5e7646d2SAndroid Build Coastguard Worker size_t /* O - Length of string */
_cups_strlcat(char * dst,const char * src,size_t size)680*5e7646d2SAndroid Build Coastguard Worker _cups_strlcat(char *dst, /* O - Destination string */
681*5e7646d2SAndroid Build Coastguard Worker const char *src, /* I - Source string */
682*5e7646d2SAndroid Build Coastguard Worker size_t size) /* I - Size of destination string buffer */
683*5e7646d2SAndroid Build Coastguard Worker {
684*5e7646d2SAndroid Build Coastguard Worker size_t srclen; /* Length of source string */
685*5e7646d2SAndroid Build Coastguard Worker size_t dstlen; /* Length of destination string */
686*5e7646d2SAndroid Build Coastguard Worker
687*5e7646d2SAndroid Build Coastguard Worker
688*5e7646d2SAndroid Build Coastguard Worker /*
689*5e7646d2SAndroid Build Coastguard Worker * Figure out how much room is left...
690*5e7646d2SAndroid Build Coastguard Worker */
691*5e7646d2SAndroid Build Coastguard Worker
692*5e7646d2SAndroid Build Coastguard Worker dstlen = strlen(dst);
693*5e7646d2SAndroid Build Coastguard Worker
694*5e7646d2SAndroid Build Coastguard Worker if (size < (dstlen + 1))
695*5e7646d2SAndroid Build Coastguard Worker return (dstlen); /* No room, return immediately... */
696*5e7646d2SAndroid Build Coastguard Worker
697*5e7646d2SAndroid Build Coastguard Worker size -= dstlen + 1;
698*5e7646d2SAndroid Build Coastguard Worker
699*5e7646d2SAndroid Build Coastguard Worker /*
700*5e7646d2SAndroid Build Coastguard Worker * Figure out how much room is needed...
701*5e7646d2SAndroid Build Coastguard Worker */
702*5e7646d2SAndroid Build Coastguard Worker
703*5e7646d2SAndroid Build Coastguard Worker srclen = strlen(src);
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker /*
706*5e7646d2SAndroid Build Coastguard Worker * Copy the appropriate amount...
707*5e7646d2SAndroid Build Coastguard Worker */
708*5e7646d2SAndroid Build Coastguard Worker
709*5e7646d2SAndroid Build Coastguard Worker if (srclen > size)
710*5e7646d2SAndroid Build Coastguard Worker srclen = size;
711*5e7646d2SAndroid Build Coastguard Worker
712*5e7646d2SAndroid Build Coastguard Worker memmove(dst + dstlen, src, srclen);
713*5e7646d2SAndroid Build Coastguard Worker dst[dstlen + srclen] = '\0';
714*5e7646d2SAndroid Build Coastguard Worker
715*5e7646d2SAndroid Build Coastguard Worker return (dstlen + srclen);
716*5e7646d2SAndroid Build Coastguard Worker }
717*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_STRLCAT */
718*5e7646d2SAndroid Build Coastguard Worker
719*5e7646d2SAndroid Build Coastguard Worker
720*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_STRLCPY
721*5e7646d2SAndroid Build Coastguard Worker /*
722*5e7646d2SAndroid Build Coastguard Worker * '_cups_strlcpy()' - Safely copy two strings.
723*5e7646d2SAndroid Build Coastguard Worker */
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker size_t /* O - Length of string */
_cups_strlcpy(char * dst,const char * src,size_t size)726*5e7646d2SAndroid Build Coastguard Worker _cups_strlcpy(char *dst, /* O - Destination string */
727*5e7646d2SAndroid Build Coastguard Worker const char *src, /* I - Source string */
728*5e7646d2SAndroid Build Coastguard Worker size_t size) /* I - Size of destination string buffer */
729*5e7646d2SAndroid Build Coastguard Worker {
730*5e7646d2SAndroid Build Coastguard Worker size_t srclen; /* Length of source string */
731*5e7646d2SAndroid Build Coastguard Worker
732*5e7646d2SAndroid Build Coastguard Worker
733*5e7646d2SAndroid Build Coastguard Worker /*
734*5e7646d2SAndroid Build Coastguard Worker * Figure out how much room is needed...
735*5e7646d2SAndroid Build Coastguard Worker */
736*5e7646d2SAndroid Build Coastguard Worker
737*5e7646d2SAndroid Build Coastguard Worker size --;
738*5e7646d2SAndroid Build Coastguard Worker
739*5e7646d2SAndroid Build Coastguard Worker srclen = strlen(src);
740*5e7646d2SAndroid Build Coastguard Worker
741*5e7646d2SAndroid Build Coastguard Worker /*
742*5e7646d2SAndroid Build Coastguard Worker * Copy the appropriate amount...
743*5e7646d2SAndroid Build Coastguard Worker */
744*5e7646d2SAndroid Build Coastguard Worker
745*5e7646d2SAndroid Build Coastguard Worker if (srclen > size)
746*5e7646d2SAndroid Build Coastguard Worker srclen = size;
747*5e7646d2SAndroid Build Coastguard Worker
748*5e7646d2SAndroid Build Coastguard Worker memmove(dst, src, srclen);
749*5e7646d2SAndroid Build Coastguard Worker dst[srclen] = '\0';
750*5e7646d2SAndroid Build Coastguard Worker
751*5e7646d2SAndroid Build Coastguard Worker return (srclen);
752*5e7646d2SAndroid Build Coastguard Worker }
753*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_STRLCPY */
754*5e7646d2SAndroid Build Coastguard Worker
755*5e7646d2SAndroid Build Coastguard Worker
756*5e7646d2SAndroid Build Coastguard Worker /*
757*5e7646d2SAndroid Build Coastguard Worker * 'compare_sp_items()' - Compare two string pool items...
758*5e7646d2SAndroid Build Coastguard Worker */
759*5e7646d2SAndroid Build Coastguard Worker
760*5e7646d2SAndroid Build Coastguard Worker static int /* O - Result of comparison */
compare_sp_items(_cups_sp_item_t * a,_cups_sp_item_t * b)761*5e7646d2SAndroid Build Coastguard Worker compare_sp_items(_cups_sp_item_t *a, /* I - First item */
762*5e7646d2SAndroid Build Coastguard Worker _cups_sp_item_t *b) /* I - Second item */
763*5e7646d2SAndroid Build Coastguard Worker {
764*5e7646d2SAndroid Build Coastguard Worker return (strcmp(a->str, b->str));
765*5e7646d2SAndroid Build Coastguard Worker }
766