/* * @file miniMpr.cpp * @brief Mini Mbedthis Portable Runtime (MPR) * @copy default * * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved. * * This software is distributed under commercial and open source licenses. * You may use the GPL open source license described below or you may acquire * a commercial license from Mbedthis Software. You agree to be fully bound * by the terms of either license. Consult the LICENSE.TXT distributed with * this software for full details. * * This software is open source; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See the GNU General Public License for more * details at: http://www.mbedthis.com/downloads/gplLicense.html * * This program is distributed WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * This GPL license does NOT permit incorporating this software into * proprietary programs. If you are unable to comply with the GPL, you must * acquire a commercial license to use this software. Commercial licenses * for this software and support services are available from Mbedthis * Software at http://www.mbedthis.com * * @end */ #include "miniMpr.h" /************************************ Code ************************************/ #if !BLD_APPWEB #if !BLD_GOAHEAD_WEBSERVER static void *mpr_ctx; /* set the memory context to be used for all ejs variables */ void mprSetCtx(TALLOC_CTX *ctx) { mpr_ctx = ctx; } /* return the memory context being used for all ejs variables */ void *mprMemCtx(void) { return mpr_ctx; } void mprFree(void *ptr) { talloc_free(ptr); } void *mprMalloc(uint size) { return talloc_size(mpr_ctx, size); } /******************************************************************************/ void *mprRealloc(void *ptr, uint size) { return talloc_realloc_size(mpr_ctx, ptr, size); } /******************************************************************************/ char *mprStrdup(const char *str) { if (str == 0) { str = ""; } return talloc_strdup(mpr_ctx, str); } /*****************************************************************************/ int mprAllocSprintf(char **msgbuf, int maxSize, const char *fmt, ...) { va_list args; char *buf; int count; va_start(args, fmt); buf = mprMalloc(maxSize + 1); count = mtVsprintf(buf, maxSize, fmt, args); *msgbuf = buf; va_end(args); return count; } /*****************************************************************************/ int mprAllocVsprintf(char **msgbuf, int maxSize, const char *fmt, va_list args) { char *buf; int count; buf = mprMalloc(maxSize + 1); count = mtVsprintf(buf, maxSize, fmt, args); *msgbuf = buf; return count; } /*****************************************************************************/ /* * Format a number as a string. FUTURE -- reverse args to be standard. * ie. mprItoa(char *userBuf, int bufsize, int value); */ char *mprItoa(int value, char *buf, int width) { char numBuf[16]; char *cp, *dp, *endp; int negative; cp = &numBuf[sizeof(numBuf)]; *--cp = '\0'; if (value < 0) { negative = 1; value = -value; width--; } else { negative = 0; } do { *--cp = '0' + (value % 10); value /= 10; } while (value > 0); if (negative) { *--cp = '-'; } dp = buf; endp = &buf[width]; while (dp < endp && *cp) { *dp++ = *cp++; } *dp++ = '\0'; return buf; } /*****************************************************************************/ void mprLog(int level, const char *fmt, ...) { va_list args; char *buf; if (DEBUGLVL(level)) { va_start(args, fmt); mprAllocVsprintf(&buf, MPR_MAX_STRING, fmt, args); va_end(args); DEBUG(level, ("mprLog: %s", buf)); mprFree(buf); } } /*****************************************************************************/ void mprBreakpoint(const char *file, int line, const char *cond) { char *buf; mprAllocSprintf(&buf, MPR_MAX_STRING, "esp exception - ASSERT at %s:%d, %s\n", file, line, cond); ejs_exception(buf); } #endif /* !BLD_GOAHEAD_WEBSERVER */ /*****************************************************************************/ /* * Create a general growable array structure */ MprArray *mprCreateArray() { MprArray *array; int size; array = (MprArray*) mprMalloc(sizeof(MprArray)); if (array == 0) { return 0; } memset(array, 0, sizeof(MprArray)); size = MPR_ARRAY_INCR * sizeof(void*); array->handles = (void**) mprMalloc(size); if (array->handles == 0) { mprFree(array); return 0; } memset(array->handles, 0, size); array->max = MPR_ARRAY_INCR; array->used = 0; return array; } /*****************************************************************************/ /* * Dispose of the array. Callers responsibility to dispose of handle entries. */ void mprDestroyArray(MprArray *array) { mprAssert(array); mprAssert(array->max >= 0); mprAssert(array->used >= 0); mprFree(array->handles); mprFree(array); } /*****************************************************************************/ /* * Add an item to the array */ int mprAddToArray(MprArray *array, void *item) { int memsize, idx, len; mprAssert(array); mprAssert(array->max >= 0); mprAssert(array->used >= 0); if (array->used < array->max) { idx = array->used++; mprAssert(idx >= 0 && idx < array->max); mprAssert(array->handles[idx] == 0); array->handles[idx] = item; return idx; } for (idx = array->used; idx < array->max; idx++) { if (array->handles[idx] == 0) { array->used++; mprAssert(array->handles[idx] == 0); array->handles[idx] = item; return idx; } } len = array->max + MPR_ARRAY_INCR; memsize = len * sizeof(void*); array->handles = (void**) mprRealloc((void*) array->handles, memsize); if (array->handles == NULL) { return -1; } memset(&array->handles[array->max], 0, sizeof(void*) * MPR_ARRAY_INCR); array->max = len; array->used++; mprAssert(idx >= 0 && idx < array->max); mprAssert(array->handles[idx] == 0); array->handles[idx] = item; return idx; } /*****************************************************************************/ /* * Remove from the array */ int mprRemoveFromArray(MprArray *array, int idx) { mprAssert(array); mprAssert(array->max > 0); mprAssert(idx >= 0 && idx < array->max); mprAssert(array->handles[idx] != 0); mprAssert(array->used > 0); array->handles[idx] = 0; return --array->used; } /*****************************************************************************/ /* * Thread-safe wrapping of strtok. Note "str" is modifed as per strtok() */ char *mprStrTok(char *str, const char *delim, char **tok) { char *start, *end; int i; start = str ? str : *tok; if (start == 0) { return 0; } i = strspn(start, delim); start += i; if (*start == '\0') { *tok = 0; return 0; } end = strpbrk(start, delim); if (end) { *end++ = '\0'; i = strspn(end, delim); end += i; } *tok = end; return start; } /*****************************************************************************/ static int mprCoreStrcat(int alloc, char **destp, int destMax, int existingLen, const char *delim, const char *src, va_list args) { va_list ap; char *dest, *dp; const char *str; int sepLen, addBytes, required; mprAssert(destp); mprAssert(destMax > 0); mprAssert(src); dest = *destp; sepLen = (delim) ? strlen(delim) : 0; #ifdef HAVE_VA_COPY va_copy(ap, args); #elif HAVE___VA_COPY __va_copy(ap, args); #else ap = args; #endif addBytes = 0; str = src; while (str) { addBytes += strlen(str) + sepLen; str = va_arg(ap, const char*); } if (existingLen > 0) { addBytes += sepLen; } required = existingLen + addBytes + 1; if (required >= destMax) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (alloc) { if (dest == 0) { dest = (char*) mprMalloc(required); } else { dest = (char*) mprRealloc(dest, required); } } else { dest = (char*) *destp; } dp = &dest[existingLen]; if (delim) { strcpy(dp, delim); dp += sepLen; } if (addBytes > 0) { #ifdef HAVE_VA_COPY va_copy(ap, args); #elif HAVE___VA_COPY __va_copy(ap, args); #else ap = args; #endif str = src; while (str) { strcpy(dp, str); dp += strlen(str); str = va_arg(ap, char*); if (delim && str) { strcpy(dp, delim); dp += sepLen; } } } else if (dest == 0) { dest = (char*) mprMalloc(1); } *dp = '\0'; *destp = dest; mprAssert(dp < &dest[required]); return required - 1; } /*****************************************************************************/ int mprReallocStrcat(char **destp, int destMax, int existingLen, const char *delim, const char *src,...) { va_list ap; int rc; va_start(ap, src); rc = mprCoreStrcat(1, destp, destMax, existingLen, delim, src, ap); va_end(ap); return rc; } /*****************************************************************************/ /* * Return the directory portion of a pathname into the users buffer. */ int mprGetDirName(char *buf, int bufsize, char *path) { char *cp; int dlen; mprAssert(path); mprAssert(buf); mprAssert(bufsize > 0); cp = strrchr(path, '/'); if (cp == 0) { #if WIN cp = strrchr(path, '\\'); if (cp == 0) #endif { buf[0] = '\0'; return 0; } } if (cp == path && cp[1] == '\0') { strcpy(buf, "."); return 0; } dlen = cp - path; if (dlen < bufsize) { if (dlen == 0) { dlen++; } mprMemcpy(buf, bufsize, path, dlen); buf[dlen] = '\0'; return 0; } return MPR_ERR_WONT_FIT; } /*****************************************************************************/ int mprStrcpy(char *dest, int destMax, const char *src) { int len; mprAssert(dest); mprAssert(destMax > 0); mprAssert(src); len = strlen(src); if (len >= destMax && len > 0) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (len > 0) { memcpy(dest, src, len); dest[len] = '\0'; } else { *dest = '\0'; len = 0; } return len; } /*****************************************************************************/ int mprMemcpy(char *dest, int destMax, const char *src, int nbytes) { mprAssert(dest); mprAssert(destMax > nbytes); mprAssert(src); mprAssert(nbytes > 0); if (nbytes > destMax) { mprAssert(0); return MPR_ERR_WONT_FIT; } if (nbytes > 0) { memcpy(dest, src, nbytes); return nbytes; } else { return 0; } } /*****************************************************************************/ #else void miniMprDummy() {} #endif // !BLD_APPWEB && !BLD_GOAHEAD_WEBSERVER /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */