X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=base%2Fhook.c;h=6e4b3a102e4abe26cf48cdb26faad2066dd2d439;hp=9243724ecc91b3deaf08976949f6a6fa86a3be11;hb=382dc154ad04e75c16d062af9e4ab49a82330ba0;hpb=82f88c53ddb84e42c770c23feb9bb0ee18341188 diff --git a/base/hook.c b/base/hook.c index 9243724..6e4b3a1 100644 --- a/base/hook.c +++ b/base/hook.c @@ -1,4 +1,19 @@ /* + * base code for various Tcl extensions + * Copyright 2006-2012 Ian Jackson + * + * This program is free software; 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, see . */ #include "chiark-tcl-base.h" @@ -36,11 +51,15 @@ void cht_obj_updatestr_vstringls(Tcl_Obj *o, ...) { va_list al; char *p; const char *part; - int l, pl; + int l; + size_t pl; va_start(al,o); - for (l=0; (part= va_arg(al, const char*)); ) - l+= va_arg(al, int); + for (l=0; (part= va_arg(al, const char*)); ) { + pl= va_arg(al, size_t); + assert(pl <= INT_MAX/2 - l); + l += pl; + } va_end(al); o->length= l; @@ -48,7 +67,7 @@ void cht_obj_updatestr_vstringls(Tcl_Obj *o, ...) { va_start(al,o); for (p= o->bytes; (part= va_arg(al, const char*)); p += pl) { - pl= va_arg(al, int); + pl= va_arg(al, size_t); memcpy(p, part, pl); } va_end(al); @@ -65,7 +84,7 @@ void cht_obj_updatestr_string(Tcl_Obj *o, const char *str) { int cht_get_urandom(Tcl_Interp *ip, Byte *buffer, int l) { static FILE *urandom; - int r, esave; + int r; if (!urandom) { urandom= fopen(URANDOM,"rb"); @@ -74,45 +93,31 @@ int cht_get_urandom(Tcl_Interp *ip, Byte *buffer, int l) { r= fread(buffer,1,l,urandom); if (r==l) return 0; - esave= errno; - fclose(urandom); urandom=0; - if (ferror(urandom)) { - return cht_posixerr(ip,errno,"read " URANDOM); + r = cht_posixerr(ip,errno,"read " URANDOM); } else { assert(feof(urandom)); - return cht_staticerr(ip, URANDOM " gave eof!", 0); + r = cht_staticerr(ip, URANDOM " gave eof!", 0); } + fclose(urandom); urandom=0; + return r; } -int cht_initextension(Tcl_Interp *ip, const TopLevel_Command *cmds, - int *donep /* or 0, meaning no types follow */, - ... /* types, terminated by 0 */) { - static int cht_initd; - - const TopLevel_Command *cmd; - Tcl_ObjType *ot; - - va_list al; +void cht_prepare__basic(Tcl_Interp *ip) { + static int prepared; - if (!cht_initd) { - cht_initd= 1; - Tcl_RegisterObjType(&cht_tabledataid_nearlytype); - Tcl_RegisterObjType(&cht_enum_nearlytype); - Tcl_RegisterObjType(&cht_enum1_nearlytype); - } - - if (donep && !*donep) { - *donep= 1; - va_start(al, donep); - while ((ot= va_arg(al, Tcl_ObjType*))) - Tcl_RegisterObjType(ot); - } + if (prepared) return; + Tcl_RegisterObjType(&cht_tabledataid_nearlytype); + Tcl_RegisterObjType(&cht_enum_nearlytype); + Tcl_RegisterObjType(&cht_enum1_nearlytype); + prepared= 1; +} +void cht_setup__commands(Tcl_Interp *ip, const TopLevel_Command *cmds) { + const TopLevel_Command *cmd; + for (cmd= cmds; cmd->name; cmd++) Tcl_CreateObjCommand(ip, (char*)cmd->name, cmd->func, 0,0); - - return TCL_OK; }