src/generic/webutl.c (191 lines of code) (raw):

/* * 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; }