X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=base%2Fparse.c;h=aa1c1a7698efbccdae4c0e5818214b32dd52e285;hp=125dd61eb9e182a2fbfd36f46ac824f38a9f006e;hb=ca8b96bf81245f21fe3906c71dc2994bfc5e516f;hpb=310a482133795d0bee9621003c0a0b3813a47037 diff --git a/base/parse.c b/base/parse.c index 125dd61..aa1c1a7 100644 --- a/base/parse.c +++ b/base/parse.c @@ -1,16 +1,105 @@ - sc= enum_lookup_cached(ip,objv[1],subcommands,"hbytes subcommand"); +/* + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include "chiark-tcl-base.h" -static Tcl_Obj *hb_getvar(Tcl_Interp *ip, Tcl_Obj *varname) { - int ec; - Tcl_Obj *value; +int cht_pat_charfrom(Tcl_Interp *ip, Tcl_Obj *obj, int *val, + const char *opts, const char *what) { + *val= cht_enum1_lookup_cached_func(ip,obj,opts,what); + if (*val==-1) return TCL_ERROR; + return TCL_OK; +} + +int cht_pat_int(Tcl_Interp *ip, Tcl_Obj *obj, int *val) { + return Tcl_GetIntFromObj(ip, obj, val); +} + +int cht_pat_long(Tcl_Interp *ip, Tcl_Obj *obj, long *val) { + return Tcl_GetLongFromObj(ip, obj, val); +} + +int cht_pat_string(Tcl_Interp *ip, Tcl_Obj *obj, const char **val) { + *val= Tcl_GetString(obj); + return TCL_OK; +} + +int cht_pat_constv(Tcl_Interp *ip, Tcl_Obj *var, + Tcl_Obj **val_r, Tcl_ObjType *type) { + int rc; + Tcl_Obj *val; - value= Tcl_ObjGetVar2(ip,varname,0,TCL_LEAVE_ERR_MSG); - if (!value) return 0; + val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG); + if (!val) return TCL_ERROR; + + if (type) { + rc= Tcl_ConvertToType(ip,val,type); + if (rc) return rc; + } - ec= Tcl_ConvertToType(ip,value,&hbytes_type); - if (ec) return 0; + *val_r= val; + return TCL_OK; +} - return value; +void cht_init_somethingv(Something_Var *sth) { + sth->obj=0; sth->var=0; sth->copied=0; } +int cht_pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var, + Something_Var *sth, Tcl_ObjType *type) { + int rc; + Tcl_Obj *val; + + sth->var= var; + + val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG); + if (!val) return TCL_ERROR; + + rc= Tcl_ConvertToType(ip,val,type); + if (rc) return rc; + + if (Tcl_IsShared(val)) { + val= Tcl_DuplicateObj(val); + sth->copied= 1; + } + Tcl_InvalidateStringRep(val); + sth->obj= val; + + return TCL_OK; +} + +void cht_fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth) { + Tcl_Obj *ro; + + if (!rc) { + assert(sth->obj); + ro= Tcl_ObjSetVar2(ip,sth->var,0,sth->obj,TCL_LEAVE_ERR_MSG); + if (!ro) rc= TCL_ERROR; + } + if (rc && sth->copied) + Tcl_DecrRefCount(sth->obj); +} + +Tcl_Obj *cht_ret_long(Tcl_Interp *ip, long val) { + return Tcl_NewLongObj(val); +} + +Tcl_Obj *cht_ret_string(Tcl_Interp *ip, const char *val) { + return Tcl_NewStringObj(val,-1); +}