52b23608aa7e403846355e4be88c67c2b747f35b
[bbaumbach/samba-autobuild/.git] / source4 / lib / appweb / mpr / 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        "miniMpr.h"
33 #include "param/param.h"
34
35 /************************************ Code ************************************/
36 #if !BLD_APPWEB
37 #if !BLD_GOAHEAD_WEBSERVER
38
39 static void *mpr_ctx;
40
41 /* set the memory context to be used for all ejs variables */
42 void mprSetCtx(TALLOC_CTX *ctx)
43 {
44         mpr_ctx = ctx;
45 }
46
47 /* return the memory context being used for all ejs variables */
48 void *mprMemCtx(void)
49 {
50         return mpr_ctx;
51 }
52
53 /* return the loadparm context being used for all ejs variables */
54 struct loadparm_context *mprLpCtx(void)
55 {
56         return global_loadparm;
57 }
58
59 void mprFree(void *ptr)
60 {
61         talloc_free(ptr);
62 }
63
64 void *mprMalloc(uint size)
65 {
66         return talloc_size(mpr_ctx, size);
67 }
68
69 /******************************************************************************/
70
71 void *mprRealloc(void *ptr, uint size)
72 {
73         return talloc_realloc_size(mpr_ctx, ptr, size);
74 }
75
76 /******************************************************************************/
77
78 char *mprStrdup(const char *str)
79 {
80         if (str == 0) {
81                 str = "";
82         }
83         return talloc_strdup(mpr_ctx, str);
84 }
85
86 /*****************************************************************************/
87
88 int mprAllocSprintf(char **msgbuf, int maxSize, const char *fmt, ...)
89 {
90         va_list args;
91         char    *buf;
92         int             count;
93
94         va_start(args, fmt);
95         buf = mprMalloc(maxSize + 1);
96         count = mtVsprintf(buf, maxSize, fmt, args);
97         *msgbuf = buf;
98         va_end(args);
99         return count;
100 }
101
102 /*****************************************************************************/
103
104 int mprAllocVsprintf(char **msgbuf, int maxSize, const char *fmt, va_list args)
105 {
106         char    *buf;
107         int             count;
108
109         buf = mprMalloc(maxSize + 1);
110         count = mtVsprintf(buf, maxSize, fmt, args);
111         *msgbuf = buf;
112         return count;
113 }
114
115
116 /*****************************************************************************/
117 /*
118  *      Format a number as a string. FUTURE -- reverse args to be standard.
119  *              ie. mprItoa(char *userBuf, int bufsize, int value);
120  */
121
122 char *mprItoa(int value, char *buf, int width)
123 {
124         char    numBuf[16];
125         char    *cp, *dp, *endp;
126         int             negative;
127
128         cp = &numBuf[sizeof(numBuf)];
129         *--cp = '\0';
130
131         if (value < 0) {
132                 negative = 1;
133                 value = -value;
134                 width--;
135         } else {
136                 negative = 0;
137         }
138
139         do {
140                 *--cp = '0' + (value % 10);
141                 value /= 10;
142         } while (value > 0);
143
144         if (negative) {
145                 *--cp = '-';
146         }
147
148         dp = buf;
149         endp = &buf[width];
150         while (dp < endp && *cp) {
151                 *dp++ = *cp++;
152         }
153         *dp++ = '\0';
154         return buf;
155 }
156
157 /*****************************************************************************/
158
159 void mprLog(int level, const char *fmt, ...)
160 {
161         va_list args;
162         char    *buf;
163
164         if (DEBUGLVL(level)) {
165                 va_start(args, fmt);
166                 mprAllocVsprintf(&buf, MPR_MAX_STRING, fmt, args);
167                 va_end(args);
168                 DEBUG(level, ("mprLog: %s", buf));
169                 mprFree(buf);
170         }
171 }
172
173 /*****************************************************************************/
174
175 void mprBreakpoint(const char *file, int line, const char *cond)
176 {
177         char *buf;
178         mprAllocSprintf(&buf, MPR_MAX_STRING, "esp exception - ASSERT at %s:%d, %s\n", 
179                                         file, line, cond);
180         ejs_exception(buf);
181 }
182
183 #endif /* !BLD_GOAHEAD_WEBSERVER */
184 /*****************************************************************************/
185 /*
186  *      Create a general growable array structure
187  */
188
189 MprArray *mprCreateArray()
190 {
191         MprArray        *array;
192         int                     size;
193
194         array = (MprArray*) mprMalloc(sizeof(MprArray));
195         if (array == 0) {
196                 return 0;
197         }
198         memset(array, 0, sizeof(MprArray));
199
200         size = MPR_ARRAY_INCR * sizeof(void*);
201         array->handles = (void**) mprMalloc(size);
202         if (array->handles == 0) {
203                 mprFree(array);
204                 return 0;
205         }
206         memset(array->handles, 0, size);
207         array->max = MPR_ARRAY_INCR;
208         array->used = 0;
209         return array;
210 }
211
212 /*****************************************************************************/
213 /*
214  *      Dispose of the array. Callers responsibility to dispose of handle entries.
215  */
216
217 void mprDestroyArray(MprArray *array)
218 {
219         mprAssert(array);
220         mprAssert(array->max >= 0);
221         mprAssert(array->used >= 0);
222
223         mprFree(array->handles);
224         mprFree(array);
225 }
226
227 /*****************************************************************************/
228 /*
229  *      Add an item to the array
230  */
231
232 int mprAddToArray(MprArray *array, void *item)
233 {
234         int             memsize, idx, len;
235
236         mprAssert(array);
237         mprAssert(array->max >= 0);
238         mprAssert(array->used >= 0);
239
240         if (array->used < array->max) {
241                 idx = array->used++;
242                 mprAssert(idx >= 0 && idx < array->max);
243                 mprAssert(array->handles[idx] == 0);
244                 array->handles[idx] = item;
245                 return idx;
246         }
247
248         for (idx = array->used; idx < array->max; idx++) {
249                 if (array->handles[idx] == 0) {
250                         array->used++;
251                         mprAssert(array->handles[idx] == 0);
252                         array->handles[idx] = item;
253                         return idx;
254                 }
255         }
256
257         len = array->max + MPR_ARRAY_INCR;
258         memsize = len * sizeof(void*);
259         array->handles = (void**) mprRealloc((void*) array->handles, memsize);
260         if (array->handles == NULL) {
261                 return -1;
262         }
263         memset(&array->handles[array->max], 0, sizeof(void*) * MPR_ARRAY_INCR);
264         array->max = len;
265         array->used++;
266
267         mprAssert(idx >= 0 && idx < array->max);
268         mprAssert(array->handles[idx] == 0);
269
270         array->handles[idx] = item;
271         return idx;
272 }
273
274 /*****************************************************************************/
275 /*
276  *      Remove from the array
277  */
278
279 int mprRemoveFromArray(MprArray *array, int idx)
280 {
281         mprAssert(array);
282         mprAssert(array->max > 0);
283         mprAssert(idx >= 0 && idx < array->max);
284         mprAssert(array->handles[idx] != 0);
285         mprAssert(array->used > 0);
286
287         array->handles[idx] = 0;
288         return --array->used;
289 }
290
291 /*****************************************************************************/
292 /*
293  *      Thread-safe wrapping of strtok. Note "str" is modifed as per strtok()
294  */
295
296 char *mprStrTok(char *str, const char *delim, char **tok)
297 {
298         char    *start, *end;
299         int             i;
300
301         start = str ? str : *tok;
302
303         if (start == 0) {
304                 return 0;
305         }
306         
307         i = strspn(start, delim);
308         start += i;
309         if (*start == '\0') {
310                 *tok = 0;
311                 return 0;
312         }
313         end = strpbrk(start, delim);
314         if (end) {
315                 *end++ = '\0';
316                 i = strspn(end, delim);
317                 end += i;
318         }
319         *tok = end;
320         return start;
321 }
322
323 /*****************************************************************************/
324
325 static int mprCoreStrcat(int alloc, char **destp, int destMax, int existingLen, 
326         const char *delim, const char *src, va_list args)
327 {
328         va_list         ap;
329         char            *dest, *dp;
330         const char *str;
331         int                     sepLen, addBytes, required;
332
333         mprAssert(destp);
334         mprAssert(destMax > 0);
335         mprAssert(src);
336
337         dest = *destp;
338         sepLen = (delim) ? strlen(delim) : 0;
339
340         va_copy(ap, args);
341         addBytes = 0;
342         str = src;
343         while (str) {
344                 addBytes += strlen(str) + sepLen;
345                 str = va_arg(ap, const char*);
346         }
347         va_end(ap);
348
349         if (existingLen > 0) {
350                 addBytes += sepLen;
351         }
352         required = existingLen + addBytes + 1;
353         if (required >= destMax) {
354                 mprAssert(0);
355                 return MPR_ERR_WONT_FIT;
356         }
357
358         if (alloc) {
359                 if (dest == 0) {
360                         dest = (char*) mprMalloc(required);
361                 } else {
362                         dest = (char*) mprRealloc(dest, required);
363                 }
364         } else {
365                 dest = (char*) *destp;
366         }
367
368         dp = &dest[existingLen];
369         if (delim) {
370                 strcpy(dp, delim);
371                 dp += sepLen;
372         }
373
374         if (addBytes > 0) {
375                 va_copy(ap, args);
376                 str = src;
377                 while (str) {
378                         strcpy(dp, str);
379                         dp += strlen(str);
380                         str = va_arg(ap, char*);
381                         if (delim && str) {
382                                 strcpy(dp, delim);
383                                 dp += sepLen;
384                         }
385                 }
386                 va_end(ap);
387         } else if (dest == 0) {
388                 dest = (char*) mprMalloc(1);
389         } 
390         *dp = '\0';
391
392         *destp = dest;
393         mprAssert(dp < &dest[required]);
394         return required - 1;
395 }
396
397 /*****************************************************************************
398   Note that this VARARGS function must be NULL (not 0, this must be a
399   pointer) terminated
400 */
401
402 int mprReallocStrcat(char **destp, int destMax, int existingLen, 
403         const char *delim, const char *src,...)
404 {
405         va_list         ap;
406         int                     rc;
407
408         va_start(ap, src);
409         rc = mprCoreStrcat(1, destp, destMax, existingLen, delim, src, ap);
410         va_end(ap);
411         return rc;
412 }
413
414 /*****************************************************************************/
415 /*
416  *      Return the directory portion of a pathname into the users buffer.
417  */
418
419 int mprGetDirName(char *buf, int bufsize, char *path)
420 {
421         char    *cp;
422         int             dlen;
423
424         mprAssert(path);
425         mprAssert(buf);
426         mprAssert(bufsize > 0);
427
428         cp = strrchr(path, '/');
429         if (cp == 0) {
430 #if WIN
431                 cp = strrchr(path, '\\');
432                 if (cp == 0)
433 #endif
434                 {
435                         buf[0] = '\0';
436                         return 0;
437                 }
438         }
439
440         if (cp == path && cp[1] == '\0') {
441                 strcpy(buf, ".");
442                 return 0;
443         }
444
445         dlen = cp - path;
446         if (dlen < bufsize) {
447                 if (dlen == 0) {
448                         dlen++;
449                 }
450                 mprMemcpy(buf, bufsize, path, dlen);
451                 buf[dlen] = '\0';
452                 return 0;
453         }
454         return MPR_ERR_WONT_FIT;
455 }
456
457 /*****************************************************************************/
458
459 int mprStrcpy(char *dest, int destMax, const char *src)
460 {
461         int             len;
462
463         mprAssert(dest);
464         mprAssert(destMax > 0);
465         mprAssert(src);
466
467         len = strlen(src);
468         if (len >= destMax && len > 0) {
469                 mprAssert(0);
470                 return MPR_ERR_WONT_FIT;
471         }
472         if (len > 0) {
473                 memcpy(dest, src, len);
474                 dest[len] = '\0';
475         } else {
476                 *dest = '\0';
477                 len = 0;
478         } 
479         return len;
480 }
481
482 /*****************************************************************************/
483
484 int mprMemcpy(char *dest, int destMax, const char *src, int nbytes)
485 {
486         mprAssert(dest);
487         mprAssert(destMax > nbytes);
488         mprAssert(src);
489         mprAssert(nbytes > 0);
490
491         if (nbytes > destMax) {
492                 mprAssert(0);
493                 return MPR_ERR_WONT_FIT;
494         }
495         if (nbytes > 0) {
496                 memcpy(dest, src, nbytes);
497                 return nbytes;
498         } else {
499                 return 0;
500         }
501 }
502
503 /*****************************************************************************/
504 #else
505 void miniMprDummy() {}
506 #endif // !BLD_APPWEB && !BLD_GOAHEAD_WEBSERVER
507
508 /*
509  * Local variables:
510  * tab-width: 4
511  * c-basic-offset: 4
512  * End:
513  * vim:tw=78
514  * vim600: sw=4 ts=4 fdm=marker
515  * vim<600: sw=4 ts=4
516  */