--- eggdrop/src/mod/module.h 2010-07-08 23:23:06.000000000 +0400 +++ eggdrop/src/mod/module.h 2010-07-24 16:10:56.000000000 +0400 @@ -485,6 +485,15 @@ #define check_conflags ((int (*) (struct flag_record *, int))global[296]) #define increase_socks_max ((int (*)(void))global[297]) #define LOG_TS ((char *)(global[298])) +#ifdef USE_TCL_BYTE_ARRAYS +#define Tcl_EggSetVar ((CONST char *(*) (Tcl_Interp *, CONST char *, CONST char *newValue, int))global[299]) +#define Tcl_EggSetVar2 ((CONST char *(*) (Tcl_Interp *, CONST char *, CONST char *, CONST char *, int))global[300]) +#define Tcl_EggAppendResult ((void (*) TCL_VARARGS_DEF(Tcl_Interp *,arg1))global[301]) +#define Tcl_EggAppendElement ((void (*) (Tcl_Interp *, CONST char *))global[302]) +#define Tcl_EggEval ((int (*) (Tcl_Interp *interp, CONST char *script))global[303]) +#define Tcl_EggGlobalEval ((int (*) (Tcl_Interp *interp, CONST char *script))global[304]) +#define Tcl_EggNewStringObj ((Tcl_Obj *(*) (CONST char *bytes, int length))global[305]) +#endif /* USE_TCL_BYTE_ARRAYS */ /* hostmasking */ #define maskhost(a,b) maskaddr((a),(b),3) --- eggdrop/src/mod/server.mod/server.c 2010-07-12 20:18:09.000000000 +0400 +++ eggdrop/src/mod/server.mod/server.c 2010-07-24 16:08:03.000000000 +0400 @@ -1164,7 +1164,16 @@ Tcl_TraceVar(irp, name1, TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, nick_change, cdata); } else { /* writes */ +#ifdef USE_TCL_ENCODING + Tcl_DString dstr; +#endif new = Tcl_GetVar2(interp, name1, name2, TCL_GLOBAL_ONLY); +#ifdef USE_TCL_ENCODING + /* properly convert string to system encoding. */ + Tcl_DStringInit(&dstr); + Tcl_UtfToExternalDString(NULL, new, -1, &dstr); + new = Tcl_DStringValue(&dstr); +#endif if (strcmp(origbotname, (char *) new)) { if (origbotname[0]) { putlog(LOG_MISC, "*", "* IRC NICK CHANGE: %s -> %s", origbotname, new); @@ -1174,6 +1183,9 @@ if (server_online) dprintf(DP_SERVER, "NICK %s\n", origbotname); } +#ifdef USE_TCL_ENCODING + Tcl_DStringFree(&dstr); +#endif } return NULL; } @@ -1861,6 +1873,9 @@ char *server_start(Function *global_funcs) { EGG_CONST char *s; +#ifdef USE_TCL_ENCODING + Tcl_DString dstr; +#endif global = global_funcs; @@ -1932,8 +1947,17 @@ tcl_eggserver(NULL, interp, "servers", NULL, 0); tcl_traceserver("servers", NULL); s = Tcl_GetVar(interp, "nick", TCL_GLOBAL_ONLY); +#ifdef USE_TCL_ENCODING + /* properly convert string to system encoding. */ + Tcl_DStringInit(&dstr); + Tcl_UtfToExternalDString(NULL, s, -1, &dstr); + s = Tcl_DStringValue(&dstr); +#endif if (s) strncpyz(origbotname, s, NICKLEN); +#ifdef USE_TCL_ENCODING + Tcl_DStringFree(&dstr); +#endif Tcl_TraceVar(interp, "nick", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS, nick_change, NULL); --- eggdrop/src/modules.c 2010-07-08 23:23:06.000000000 +0400 +++ eggdrop/src/modules.c 2010-07-24 16:02:59.000000000 +0400 @@ -576,7 +576,24 @@ /* 296 - 299 */ (Function) check_conflags, (Function) increase_socks_max, - (Function) log_ts + (Function) log_ts, +#ifdef USE_TCL_BYTE_ARRAYS + (Function) Tcl_EggSetVar, /* 299 */ + (Function) Tcl_EggSetVar2, /* 300 */ + (Function) Tcl_EggAppendResult, /* 301 */ + (Function) Tcl_EggAppendElement, /* 302 */ + (Function) Tcl_EggEval, /* 303 */ + (Function) Tcl_EggGlobalEval, /* 304 */ + (Function) Tcl_EggNewStringObj /* 305 */ +#else + (Function) 0, /* 299 */ + (Function) 0, /* 300 */ + (Function) 0, /* 301 */ + (Function) 0, /* 302 */ + (Function) 0, /* 303 */ + (Function) 0, /* 304 */ + (Function) 0 /* 305 */ +#endif /* USE_TCL_BYTE_ARRAYS */ }; void init_modules(void) --- eggdrop/src/tcl.c 2010-07-12 19:40:52.000000000 +0400 +++ eggdrop/src/tcl.c 2010-07-24 15:49:26.000000000 +0400 @@ -275,17 +275,31 @@ Tcl_Obj *obj; unsigned char *bytes; int len; + Tcl_DString ds; + int binary; obj = Tcl_GetVar2Ex(interp, name1, name2, 0); if (!obj) return NULL; len = 0; - bytes = Tcl_GetByteArrayFromObj(obj, &len); - if (!bytes) - return NULL; + binary = 0; + if (obj->typePtr != NULL) + if (strcmp(obj->typePtr->name, "bytearray") == 0) + binary = 1; + if (!binary) { + char *strptr = Tcl_GetStringFromObj(obj, &len); + bytes = (unsigned char *)Tcl_UtfToExternalDString(NULL, strptr, len, &ds); + } + else { + bytes = Tcl_GetByteArrayFromObj(obj, &len); + if (!bytes) + return NULL; + } s = malloc(len + 1); egg_memcpy(s, bytes, len); s[len] = 0; + if (!binary) + Tcl_DStringFree(&ds); } #else s = (char *) Tcl_GetVar2(interp, name1, name2, 0); @@ -329,6 +343,8 @@ void **callback_data; Function func; ClientData cd; + Tcl_DString ds; + int binary; objc += 5; strings = (char **) nmalloc(sizeof(char *) * objc); @@ -337,11 +353,23 @@ utftot += sizeof(char *) * objc; objc -= 5; for (i = 0; i < objc; i++) { - byteptr = (char *) Tcl_GetByteArrayFromObj(objv[i], &len); + binary = 0; + if (objv[i]->typePtr != NULL) + if (strcmp(objv[i]->typePtr->name, "bytearray") == 0) + binary = 1; + if (!binary) { + char *strptr = Tcl_GetStringFromObj(objv[i], &len); + byteptr = Tcl_UtfToExternalDString(NULL, strptr, len, &ds); + } + else { + byteptr = (char *)Tcl_GetByteArrayFromObj(objv[i], &len); + } strings[i] = (char *) nmalloc(len + 1); utftot += len + 1; strncpy(strings[i], byteptr, len); strings[i][len] = 0; + if (!binary) + Tcl_DStringFree(&ds); } callback_data = (void **) cdata; func = (Function) callback_data[0]; @@ -501,6 +529,7 @@ {"logfile-suffix", logfile_suffix, 20, 0}, {"timestamp-format",log_ts, 32, 0}, {"pidfile", pid_file, 120, STR_PROTECT}, + {"sp_version", "0010", 0, 0}, {NULL, NULL, 0, 0} }; --- eggdrop/src/tclhash.c 2010-06-29 19:52:24.000000000 +0400 +++ eggdrop/src/tclhash.c 2010-07-24 16:16:53.000000000 +0400 @@ -717,7 +717,22 @@ */ Tcl_SetVar(interp, "lastbind", (char *) mask, TCL_GLOBAL_ONLY); - x = Tcl_VarEval(interp, proc, param, NULL); + // x = Tcl_VarEval(interp, proc, param, NULL); + { + char *cstr; + int len0 = proc ? strlen(proc) : 0; + int len1 = param ? strlen(param) : 0; + cstr = (char *)nmalloc(len0 + len1 + 1); + *cstr = '\0'; + if (proc) + { + strcpy(cstr, proc); + if (len1) + strcat(cstr, param); + } + x = Tcl_Eval(interp, cstr); + nfree(cstr); + } Context; if (x == TCL_ERROR) { @@ -1019,8 +1034,19 @@ if (x == BIND_EXECUTED || x == BIND_EXEC_LOG) { if (tcl_resultempty()) return ""; - else + else { +#ifdef USE_TCL_ENCODING + static char result[512]; + int dstWroteBytes; + Tcl_UtfToExternal(interp, NULL, tcl_resultstring(), -1, 0, NULL, + result, sizeof(result), NULL, &dstWroteBytes, NULL); + if (dstWroteBytes == 0) + return ""; + return result; +#else return tcl_resultstring(); +#endif + } } else return text; } @@ -1289,3 +1315,104 @@ nfree(l); } } + +#ifdef USE_TCL_BYTE_ARRAYS +#undef Tcl_SetVar2 +#undef Tcl_AppendResult +#undef Tcl_AppendElement +#undef Tcl_Eval +#undef Tcl_GlobalEval +#undef Tcl_NewStringObj + +void Tcl_EggAppendResult TCL_VARARGS_DEF(Tcl_Interp *, arg1) +{ + Tcl_Interp *interp; + va_list argList; + Tcl_DString ds; + char *param; + char *string; + interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList); + while (1) { + string = va_arg(argList, char *); + + if (string == NULL) break; + param = (char *) Tcl_ExternalToUtfDString(NULL, string, -1, &ds); + Tcl_AppendResult(interp, param, NULL); + Tcl_DStringFree(&ds); + } + va_end(argList); +} + +void Tcl_EggAppendElement(Tcl_Interp *interp, CONST char *string) +{ + Tcl_DString ds; + char *param; + param = (char *) Tcl_ExternalToUtfDString(NULL, string, -1, &ds); + Tcl_AppendElement(interp, param); + Tcl_DStringFree(&ds); +} + +CONST char *Tcl_EggSetVar(Tcl_Interp *interp, CONST char *varName, + CONST char *newValue, int flags) +{ + Tcl_DString ds; + char *ret; + ret = (char *) Tcl_SetVar2(interp, varName, (char *) NULL, + (char *) Tcl_ExternalToUtfDString(NULL, newValue, -1, &ds), flags); + Tcl_DStringFree(&ds); + return ret; +} + +CONST char *Tcl_EggSetVar2(Tcl_Interp *interp, CONST char *part1, CONST char *part2, + CONST char *newValue, int flags) +{ + Tcl_DString ds; + char *ret; + ret = (char *) Tcl_SetVar2(interp, part1, part2, + (char *) Tcl_ExternalToUtfDString(NULL, newValue, -1, &ds), flags); + Tcl_DStringFree(&ds); + return ret; +} + +int Tcl_EggEval(Tcl_Interp *interp, CONST char *script) +{ + Tcl_DString ds; + int ret; + ret = Tcl_Eval(interp, (char *) Tcl_ExternalToUtfDString(NULL, script, -1, &ds)); + Tcl_DStringFree(&ds); + return ret; +} + +int Tcl_EggGlobalEval(Tcl_Interp *interp, CONST char *script) +{ + Tcl_DString ds; + int ret; + ret = Tcl_GlobalEval(interp, (char *) Tcl_ExternalToUtfDString(NULL, script, -1, &ds)); + Tcl_DStringFree(&ds); + return ret; +} + +Tcl_Obj *Tcl_EggNewStringObj(CONST char *bytes, int length) +{ + Tcl_DString ds; + Tcl_Obj *ret; + int len; + char *ptr; + + ptr = Tcl_ExternalToUtfDString(NULL, bytes, length, &ds); + len = Tcl_DStringLength(&ds); + + ret = Tcl_NewStringObj(ptr, len); + + Tcl_DStringFree(&ds); + return ret; +} + +#define Tcl_SetVar2 Tcl_EggSetVar2 +#define Tcl_AppendResult Tcl_EggAppendResult +#define Tcl_AppendElement Tcl_EggAppendElement +#define Tcl_Eval Tcl_EggEval +#define Tcl_GlobalEval Tcl_EggGlobalEval +#define Tcl_NewStringObj Tcl_EggNewStringObj + +#endif /* USE_TCL_BYTE_ARRAYS */ --- eggdrop/src/tclhash.h 2010-07-12 19:40:52.000000000 +0400 +++ eggdrop/src/tclhash.h 2010-07-24 15:59:35.000000000 +0400 @@ -25,6 +25,25 @@ #ifndef _EGG_TCLHASH_H #define _EGG_TCLHASH_H +#ifdef USE_TCL_BYTE_ARRAYS + +#define Tcl_SetVar Tcl_EggSetVar +#define Tcl_SetVar2 Tcl_EggSetVar2 +#define Tcl_AppendResult Tcl_EggAppendResult +#define Tcl_AppendElement Tcl_EggAppendElement +#define Tcl_Eval Tcl_EggEval +#define Tcl_GlobalEval Tcl_EggGlobalEval +#define Tcl_NewStringObj Tcl_EggNewStringObj + +CONST char *Tcl_EggSetVar(Tcl_Interp *, CONST char *, CONST char *newValue, int); +CONST char *Tcl_EggSetVar2(Tcl_Interp *, CONST char *, CONST char *, CONST char *, int); +void Tcl_EggAppendResult TCL_VARARGS_DEF(Tcl_Interp *,arg1); +void Tcl_EggAppendElement(Tcl_Interp *, CONST char *); +int Tcl_EggEval(Tcl_Interp *interp, CONST char *script); +int Tcl_EggGlobalEval(Tcl_Interp *interp, CONST char *script); +Tcl_Obj * Tcl_EggNewStringObj(CONST char *bytes, int length); + +#endif /* USE_TCL_BYTE_ARRAYS */ #define TC_DELETED 0x0001 /* This command/trigger was deleted. */