| /* |
| * webutl.c --- common utils used in more than one module |
| * nca-073-9 |
| * |
| * Copyright (c) 1996-2000 by Netcetera AG. |
| * Copyright (c) 2001 by Apache Software Foundation. |
| * All rights reserved. |
| * |
| * See the file "license.terms" for information on usage and |
| * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
| * |
| * @(#) $Id$ |
| * |
| */ |
| |
| #include <tcl.h> |
| #include <string.h> /* strlen */ |
| #include "webutl.h" |
| |
| /* ---------------------------------------------------------------------------- |
| * allocAndSet -- |
| * wrapper to Tcl_Alloc for zero-terminated char * (or 8-bit) strings |
| * ------------------------------------------------------------------------- */ |
| char __declspec(dllexport) *allocAndSet(const char *aString) |
| { |
| |
| char *cPtr = NULL; |
| |
| if (aString != NULL) { |
| |
| cPtr = Tcl_Alloc(strlen(aString) + 1); |
| if (cPtr != NULL) { |
| strcpy(cPtr, aString); |
| } |
| } |
| |
| return cPtr; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * allocAndSetN -- |
| * as allocAndSet, but only N bytes. Result is NULL-terminated. |
| * ------------------------------------------------------------------------- */ |
| char *allocAndSetN(const char *aString, int N) |
| { |
| |
| char *cPtr = NULL; |
| |
| if ((aString != NULL) && (N > 0)) { |
| |
| cPtr = Tcl_Alloc(N + 1); |
| if (cPtr != NULL) { |
| strncpy(cPtr, aString, N); |
| cPtr[N] = 0; |
| } |
| } |
| |
| return cPtr; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * strchrchr -- strchr for c0 first, or c1 if c0 fails. tag reports which trig. |
| * returns earlier match! |
| * ------------------------------------------------------------------------- */ |
| char *strchrchr(const char *cs, const char c0, const char c1, char *tag) |
| { |
| |
| char *res = NULL; |
| |
| *tag = -1; |
| |
| if (cs != NULL) { |
| |
| char *res0 = NULL; |
| char *res1 = NULL; |
| |
| res0 = strchr(cs, c0); |
| res1 = strchr(cs, c1); |
| |
| if (res0 != NULL) { |
| if (res1 != NULL) { |
| if (res1 > res0) { |
| res = res0; |
| *tag = 0; |
| } else { |
| res = res1; |
| *tag = 1; |
| } |
| } else { |
| res = res0; |
| *tag = 0; |
| } |
| } else { |
| if (res1 != NULL) { |
| res = res1; |
| *tag = 1; |
| } |
| } |
| } |
| return res; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * myUtfStrStr -- first try strstr, then try to lowercase and try again |
| * ------------------------------------------------------------------------- */ |
| char *myUtfStrStr(const char *s1, const char *s2) |
| { |
| |
| char *test = NULL; |
| char *internalS1 = NULL; |
| char *internalS2 = NULL; |
| |
| test = strstr(s1, s2); |
| |
| if (test == NULL) { |
| |
| internalS1 = allocAndSet(s1); |
| internalS2 = allocAndSet(s2); |
| |
| Tcl_UtfToLower(internalS1); |
| Tcl_UtfToLower(internalS2); |
| |
| test = strstr(internalS1, internalS2); |
| |
| if (test != NULL) |
| test = (char *) s1 + (test - internalS1); |
| |
| WebFreeIfNotNull(internalS1); |
| WebFreeIfNotNull(internalS2); |
| } |
| return test; |
| } |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * strWithoutLinebreak -- string without "\n" in there |
| * ------------------------------------------------------------------------- */ |
| char *strWithoutLinebreak(char *cs) |
| { |
| |
| int i = 0; |
| int delta = 0; |
| int len = 0; |
| |
| if (cs == NULL) |
| return NULL; |
| |
| len = strlen(cs); |
| |
| for (i = 0; (i + delta) < len; i++) { |
| if ((cs[i + delta] == '\r') || (cs[i + delta] == '\n')) { |
| delta++; |
| } |
| cs[i] = cs[i + delta]; |
| } |
| |
| for (; i < len; i++) |
| cs[i] = 0; |
| |
| return cs; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * webEat -- remove specified character from beginning |
| * ------------------------------------------------------------------------- */ |
| char *webEat(char eat, char *cs) |
| { |
| |
| int i = 0; |
| int len = 0; |
| |
| if (cs == NULL) |
| return NULL; |
| |
| len = strlen(cs); |
| |
| for (i = 0; i < len; i++) { |
| if (cs[i] != eat) |
| break; |
| } |
| |
| return &(cs[i]); |
| } |
| |
| |
| /* ---------------------------------------------------------------------------- |
| * handleConfig |
| * ------------------------------------------------------------------------- */ |
| int handleConfig(Tcl_Interp * interp, Tcl_Obj ** tclo, Tcl_Obj * newValue, |
| int deleteIfEmpty) |
| { |
| |
| if (*tclo == NULL) { |
| *tclo = Tcl_NewObj(); |
| Tcl_IncrRefCount(*tclo); |
| } |
| Tcl_SetObjResult(interp, Tcl_DuplicateObj(*tclo)); |
| |
| /* -------------------------------------------------------------------------- |
| * get |
| * ----------------------------------------------------------------------- */ |
| if (newValue == NULL) |
| return TCL_OK; |
| |
| /* -------------------------------------------------------------------------- |
| * set |
| * ----------------------------------------------------------------------- */ |
| Tcl_DecrRefCount(*tclo); |
| if (deleteIfEmpty && !strcmp(Tcl_GetString(newValue), "")) |
| *tclo = NULL; |
| else { |
| *tclo = Tcl_DuplicateObj(newValue); |
| Tcl_IncrRefCount(*tclo); |
| } |
| |
| return TCL_OK; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * tclGetListLength -- return list length of list, or -1 in case of error |
| * ------------------------------------------------------------------------- */ |
| int tclGetListLength(Tcl_Interp * interp, Tcl_Obj * list) |
| { |
| |
| int tmp = -1; |
| |
| if (Tcl_ListObjLength(interp, list, &tmp) == TCL_ERROR) { |
| LOG_MSG(interp, WRITE_LOG | SET_RESULT, __FILE__, __LINE__, |
| WEBSH, WEBLOG_INFO, |
| "error accessing length of \"", Tcl_GetString(list), |
| "\"", NULL); |
| return -1; |
| } |
| return tmp; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * tclSetEnv -- set/get environment variables via Tcl |
| * ------------------------------------------------------------------------- */ |
| Tcl_Obj *tclSetEnv(Tcl_Interp * interp, char *key, Tcl_Obj * val) |
| { |
| |
| Tcl_Obj *arrayName = NULL; |
| Tcl_Obj *res = NULL; |
| Tcl_Obj *tmp = NULL; |
| Tcl_Obj *keyObj = NULL; |
| |
| if ((interp == NULL) || (key == NULL)) |
| return NULL; |
| |
| arrayName = Tcl_NewStringObj("::env", 5); |
| Tcl_IncrRefCount(arrayName); |
| |
| keyObj = Tcl_NewStringObj(key, -1); |
| Tcl_IncrRefCount(keyObj); |
| |
| if (val == NULL) { |
| |
| /* get */ |
| tmp = Tcl_ObjGetVar2(interp, arrayName, keyObj, TCL_LEAVE_ERR_MSG); |
| if (tmp != NULL) |
| res = Tcl_DuplicateObj(tmp); |
| |
| } |
| else { |
| |
| /* set */ |
| res = |
| Tcl_ObjSetVar2(interp, arrayName, keyObj, val, TCL_LEAVE_ERR_MSG); |
| } |
| |
| Tcl_DecrRefCount(arrayName); |
| Tcl_DecrRefCount(keyObj); |
| |
| if (res) { |
| Tcl_IncrRefCount(res); |
| } |
| return res; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * deleteTclObj_fnc -- helper for hashutl (wrapper for Tcl_DecrRefCount) |
| * ------------------------------------------------------------------------- */ |
| int deleteTclObj_fnc(void *tclo, void *dum) |
| { |
| |
| if (tclo == NULL) |
| return TCL_ERROR; |
| |
| Tcl_DecrRefCount((Tcl_Obj *) tclo); |
| return TCL_OK; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| * Web_GetOrCreateGlobalVar - get global var from tcl |
| * ------------------------------------------------------------------------- */ |
| Tcl_Obj *Web_GetOrCreateGlobalVar(Tcl_Interp * interp, Tcl_Obj * name, |
| int *isNew) |
| { |
| |
| Tcl_Obj *var = NULL; |
| |
| if (interp == NULL) |
| return NULL; |
| |
| if (Tcl_InterpDeleted(interp)) |
| return NULL; |
| |
| /* fprintf(stdout,"DBG Web_GetOrCreateGlobalVar - trying to get global '%s'\n",Tcl_GetString(name)); fflush(stdout); */ |
| |
| /* -------------------------------------------------------------------------- |
| * exists ? |
| * ----------------------------------------------------------------------- */ |
| var = Tcl_ObjGetVar2(interp, name, NULL, TCL_GLOBAL_ONLY); |
| |
| /* -------------------------------------------------------------------------- |
| * ... no, make |
| * ----------------------------------------------------------------------- */ |
| if (var == NULL) { |
| |
| /* fprintf(stderr,"DBG Web_GetVarChannel - gonna create global '%s'\n",Tcl_GetString(name)); fflush(stderr); */ |
| var = Tcl_ObjSetVar2(interp, name, NULL, |
| Tcl_NewObj(), |
| TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG); |
| *isNew = 1; |
| Tcl_IncrRefCount(var); |
| } |
| |
| return var; |
| } |