r7008: - split out the loadparm type definitions so loadparm internals can be accesse...
[samba.git] / source / web_server / ejs / miniMpr.c
1 /*
2  *      @file   miniMpr.cpp
3  *      @brief  Mini Mbedthis Portable Runtime (MPR)
4  *      @copy   default
5  *      
6  *      Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
7  *      
8  *      This software is distributed under commercial and open source licenses.
9  *      You may use the GPL open source license described below or you may acquire 
10  *      a commercial license from Mbedthis Software. You agree to be fully bound 
11  *      by the terms of either license. Consult the LICENSE.TXT distributed with 
12  *      this software for full details.
13  *      
14  *      This software is open source; you can redistribute it and/or modify it 
15  *      under the terms of the GNU General Public License as published by the 
16  *      Free Software Foundation; either version 2 of the License, or (at your 
17  *      option) any later version. See the GNU General Public License for more 
18  *      details at: http://www.mbedthis.com/downloads/gplLicense.html
19  *      
20  *      This program is distributed WITHOUT ANY WARRANTY; without even the 
21  *      implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
22  *      
23  *      This GPL license does NOT permit incorporating this software into 
24  *      proprietary programs. If you are unable to comply with the GPL, you must
25  *      acquire a commercial license to use this software. Commercial licenses 
26  *      for this software and support services are available from Mbedthis 
27  *      Software at http://www.mbedthis.com 
28  *      
29  *      @end
30  */
31
32 #include        "web_server/ejs/miniMpr.h"
33
34 /************************************ Code ************************************/
35 #if !BLD_APPWEB
36 #if !BLD_GOAHEAD_WEBSERVER
37
38 static void *mpr_ctx;
39
40 void mprSetCtx(TALLOC_CTX *ctx)
41 {
42         mpr_ctx = ctx;
43 }
44
45 void mprFree(void *ptr)
46 {
47         talloc_free(ptr);
48 }
49
50 void *mprMalloc(uint size)
51 {
52         return talloc_size(mpr_ctx, size);
53 }
54
55 /******************************************************************************/
56
57 void *mprRealloc(void *ptr, uint size)
58 {
59         return talloc_realloc_size(mpr_ctx, ptr, size);
60 }
61
62 /******************************************************************************/
63
64 char *mprStrdup(const char *str)
65 {
66         if (str == 0) {
67                 str = "";
68         }
69         return talloc_strdup(mpr_ctx, str);
70 }
71
72 /*****************************************************************************/
73
74 int mprAllocSprintf(char **msgbuf, int maxSize, const char *fmt, ...)
75 {
76         va_list args;
77         char    *buf;
78         int             count;
79
80         va_start(args, fmt);
81         buf = mprMalloc(maxSize + 1);
82         count = mtVsprintf(buf, maxSize, fmt, args);
83         *msgbuf = buf;
84         va_end(args);
85         return count;
86 }
87
88 /*****************************************************************************/
89
90 int mprAllocVsprintf(char **msgbuf, int maxSize, const char *fmt, va_list args)
91 {
92         char    *buf;
93         int             count;
94
95         buf = mprMalloc(maxSize + 1);
96         count = mtVsprintf(buf, maxSize, fmt, args);
97         *msgbuf = buf;
98         return count;
99 }
100
101
102 /*****************************************************************************/
103 /*
104  *      Format a number as a string. FUTURE -- reverse args to be standard.
105  *              ie. mprItoa(char *userBuf, int bufsize, int value);
106  */
107
108 char *mprItoa(int value, char *buf, int width)
109 {
110         char    numBuf[16];
111         char    *cp, *dp, *endp;
112         int             negative;
113
114         cp = &numBuf[sizeof(numBuf)];
115         *--cp = '\0';
116
117         if (value < 0) {
118                 negative = 1;
119                 value = -value;
120                 width--;
121         } else {
122                 negative = 0;
123         }
124
125         do {
126                 *--cp = '0' + (value % 10);
127                 value /= 10;
128         } while (value > 0);
129
130         if (negative) {
131                 *--cp = '-';
132         }
133
134         dp = buf;
135         endp = &buf[width];
136         while (dp < endp && *cp) {
137                 *dp++ = *cp++;
138         }
139         *dp++ = '\0';
140         return buf;
141 }
142
143 /*****************************************************************************/
144
145 void mprLog(int level, const char *fmt, ...)
146 {
147         va_list args;
148         char    *buf;
149
150         if (DEBUGLVL(level)) {
151                 va_start(args, fmt);
152                 mprAllocVsprintf(&buf, MPR_MAX_STRING, fmt, args);
153                 va_end(args);
154                 DEBUG(level, ("mprLog: %s", buf));
155                 mprFree(buf);
156         }
157 }
158
159 /*****************************************************************************/
160
161 void mprBreakpoint(const char *file, int line, const char *cond)
162 {
163         char *buf;
164         mprAllocSprintf(&buf, MPR_MAX_STRING, "esp exception - ASSERT at %s:%d, %s\n", 
165                                         file, line, cond);
166         http_exception(buf);
167 }
168
169 #endif /* !BLD_GOAHEAD_WEBSERVER */
170 /*****************************************************************************/
171 /*
172  *      Create a general growable array structure
173  */
174
175 MprArray *mprCreateArray()
176 {
177         MprArray        *array;
178         int                     size;
179
180         array = (MprArray*) mprMalloc(sizeof(MprArray));
181         if (array == 0) {
182                 return 0;
183         }
184         memset(array, 0, sizeof(MprArray));
185
186         size = MPR_ARRAY_INCR * sizeof(void*);
187         array->handles = (void**) mprMalloc(size);
188         if (array->handles == 0) {
189                 mprFree(array);
190                 return 0;
191         }
192         memset(array->handles, 0, size);
193         array->max = MPR_ARRAY_INCR;
194         array->used = 0;
195         return array;
196 }
197
198 /*****************************************************************************/
199 /*
200  *      Dispose of the array. Callers responsibility to dispose of handle entries.
201  */
202
203 void mprDestroyArray(MprArray *array)
204 {
205         mprAssert(array);
206         mprAssert(array->max >= 0);
207         mprAssert(array->used >= 0);
208
209         mprFree(array->handles);
210         mprFree(array);
211 }
212
213 /*****************************************************************************/
214 /*
215  *      Add an item to the array
216  */
217
218 int mprAddToArray(MprArray *array, void *item)
219 {
220         int             memsize, idx, len;
221
222         mprAssert(array);
223         mprAssert(array->max >= 0);
224         mprAssert(array->used >= 0);
225
226         if (array->used < array->max) {
227                 idx = array->used++;
228                 mprAssert(idx >= 0 && idx < array->max);
229                 mprAssert(array->handles[idx] == 0);
230                 array->handles[idx] = item;
231                 return idx;
232         }
233
234         for (idx = array->used; idx < array->max; idx++) {
235                 if (array->handles[idx] == 0) {
236                         array->used++;
237                         mprAssert(array->handles[idx] == 0);
238                         array->handles[idx] = item;
239                         return idx;
240                 }
241         }
242
243         len = array->max + MPR_ARRAY_INCR;
244         memsize = len * sizeof(void*);
245         array->handles = (void**) mprRealloc((void*) array->handles, memsize);
246         if (array->handles == NULL) {
247                 return -1;
248         }
249         memset(&array->handles[array->max], 0, sizeof(void*) * MPR_ARRAY_INCR);
250         array->max = len;
251         array->used++;
252
253         mprAssert(idx >= 0 && idx < array->max);
254         mprAssert(array->handles[idx] == 0);
255
256         array->handles[idx] = item;
257         return idx;
258 }
259
260 /*****************************************************************************/
261 /*
262  *      Remove from the array
263  */
264
265 int mprRemoveFromArray(MprArray *array, int idx)
266 {
267         mprAssert(array);
268         mprAssert(array->max > 0);
269         mprAssert(idx >= 0 && idx < array->max);
270         mprAssert(array->handles[idx] != 0);
271         mprAssert(array->used > 0);
272
273         array->handles[idx] = 0;
274         return --array->used;
275 }
276
277 /*****************************************************************************/
278 /*
279  *      Thread-safe wrapping of strtok. Note "str" is modifed as per strtok()
280  */
281
282 char *mprStrTok(char *str, const char *delim, char **tok)
283 {
284         char    *start, *end;
285         int             i;
286
287         start = str ? str : *tok;
288
289         if (start == 0) {
290                 return 0;
291         }
292         
293         i = strspn(start, delim);
294         start += i;
295         if (*start == '\0') {
296                 *tok = 0;
297                 return 0;
298         }
299         end = strpbrk(start, delim);
300         if (end) {
301                 *end++ = '\0';
302                 i = strspn(end, delim);
303                 end += i;
304         }
305         *tok = end;
306         return start;
307 }
308
309 /*****************************************************************************/
310
311 static int mprCoreStrcat(int alloc, char **destp, int destMax, int existingLen, 
312         const char *delim, const char *src, va_list args)
313 {
314         va_list         ap;
315         char            *dest, *dp;
316         const char *str;
317         int                     sepLen, addBytes, required;
318
319         mprAssert(destp);
320         mprAssert(destMax > 0);
321         mprAssert(src);
322
323         dest = *destp;
324         sepLen = (delim) ? strlen(delim) : 0;
325
326 #ifdef __va_copy
327         __va_copy(ap, args);
328 #else
329         ap = args;
330 #endif
331         addBytes = 0;
332         str = src;
333         while (str) {
334                 addBytes += strlen(str) + sepLen;
335                 str = va_arg(ap, const char*);
336         }
337
338         if (existingLen > 0) {
339                 addBytes += sepLen;
340         }
341         required = existingLen + addBytes + 1;
342         if (required >= destMax) {
343                 mprAssert(0);
344                 return MPR_ERR_WONT_FIT;
345         }
346
347         if (alloc) {
348                 if (dest == 0) {
349                         dest = (char*) mprMalloc(required);
350                 } else {
351                         dest = (char*) mprRealloc(dest, required);
352                 }
353         } else {
354                 dest = (char*) *destp;
355         }
356
357         dp = &dest[existingLen];
358         if (delim) {
359                 strcpy(dp, delim);
360                 dp += sepLen;
361         }
362
363         if (addBytes > 0) {
364 #ifdef __va_copy
365                 __va_copy(ap, args);
366 #else
367                 ap = args;
368 #endif
369                 str = src;
370                 while (str) {
371                         strcpy(dp, str);
372                         dp += strlen(str);
373                         str = va_arg(ap, char*);
374                         if (delim && str) {
375                                 strcpy(dp, delim);
376                                 dp += sepLen;
377                         }
378                 }
379         } else if (dest == 0) {
380                 dest = (char*) mprMalloc(1);
381         } 
382         *dp = '\0';
383
384         *destp = dest;
385         mprAssert(dp < &dest[required]);
386         return required - 1;
387 }
388
389 /*****************************************************************************/
390
391 int mprReallocStrcat(char **destp, int destMax, int existingLen, 
392         const char *delim, const char *src,...)
393 {
394         va_list         ap;
395         int                     rc;
396
397         va_start(ap, src);
398         rc = mprCoreStrcat(1, destp, destMax, existingLen, delim, src, ap);
399         va_end(ap);
400         return rc;
401 }
402
403 /*****************************************************************************/
404 /*
405  *      Return the directory portion of a pathname into the users buffer.
406  */
407
408 int mprGetDirName(char *buf, int bufsize, char *path)
409 {
410         char    *cp;
411         int             dlen;
412
413         mprAssert(path);
414         mprAssert(buf);
415         mprAssert(bufsize > 0);
416
417         cp = strrchr(path, '/');
418         if (cp == 0) {
419 #if WIN
420                 cp = strrchr(path, '\\');
421                 if (cp == 0)
422 #endif
423                 {
424                         buf[0] = '\0';
425                         return 0;
426                 }
427         }
428
429         if (cp == path && cp[1] == '\0') {
430                 strcpy(buf, ".");
431                 return 0;
432         }
433
434         dlen = cp - path;
435         if (dlen < bufsize) {
436                 if (dlen == 0) {
437                         dlen++;
438                 }
439                 mprMemcpy(buf, bufsize, path, dlen);
440                 buf[dlen] = '\0';
441                 return 0;
442         }
443         return MPR_ERR_WONT_FIT;
444 }
445
446 /*****************************************************************************/
447
448 int mprStrcpy(char *dest, int destMax, const char *src)
449 {
450         int             len;
451
452         mprAssert(dest);
453         mprAssert(destMax > 0);
454         mprAssert(src);
455
456         len = strlen(src);
457         if (len >= destMax && len > 0) {
458                 mprAssert(0);
459                 return MPR_ERR_WONT_FIT;
460         }
461         if (len > 0) {
462                 memcpy(dest, src, len);
463                 dest[len] = '\0';
464         } else {
465                 *dest = '\0';
466                 len = 0;
467         } 
468         return len;
469 }
470
471 /*****************************************************************************/
472
473 int mprMemcpy(char *dest, int destMax, const char *src, int nbytes)
474 {
475         mprAssert(dest);
476         mprAssert(destMax > nbytes);
477         mprAssert(src);
478         mprAssert(nbytes > 0);
479
480         if (nbytes > destMax) {
481                 mprAssert(0);
482                 return MPR_ERR_WONT_FIT;
483         }
484         if (nbytes > 0) {
485                 memcpy(dest, src, nbytes);
486                 return nbytes;
487         } else {
488                 return 0;
489         }
490 }
491
492 /*****************************************************************************/
493 #else
494 void miniMprDummy() {}
495 #endif // !BLD_APPWEB && !BLD_GOAHEAD_WEBSERVER
496
497 /*
498  * Local variables:
499  * tab-width: 4
500  * c-basic-offset: 4
501  * End:
502  * vim:tw=78
503  * vim600: sw=4 ts=4 fdm=marker
504  * vim<600: sw=4 ts=4
505  */