| top | | - proc int Wyrmassoc_Init—Initialise the wyrm-assoc package; returns TCL_OK or TCL_ERROR.
| - io Intr intr—Package initialised in the interpretter.
|
|
|
int Wyrmassoc_Init(Intr intr) {
ASSOCDECLARES;
if (Tcl_PkgProvide(intr,"wyrmassoc",VERSION)!=TCL_OK) return TCL_ERROR;
if (!Tcl_PkgRequire(intr,"wyrmwif","1",false)) return TCL_ERROR;
Tcl_CreateObjCommand(intr,"::wyrm::assoc",assoc,0,0);
Tcl_CreateObjCommand(intr,"::wyrm::vassoc",assoc,"vassoc",0);
ASSOCCALLS;
if (Tcl_VarEval(intr,
"namespace eval ::wyrm {namespace export assoc vassoc}\n",
0)!=TCL_OK) return TCL_ERROR;
if (wyrm_oavCommandInit(intr)!=TCL_OK) return TCL_ERROR;
return TCL_OK;
}
int Wyrmassoc_SafeInit(Intr intr) {
return Wyrmassoc_Init(intr);
}
| ^ | | | | | | section top | |
int Wyrmassoc_Init(Intr intr);
int Wyrmassoc_SafeInit(Intr intr);
| ^ | | | | | | section top | |
static int assoc(ClientData clientData,Intr intr,int N,Tcl_Obj *const P[]);
| ^ | | | | | | section top | | - proc int assoc—assoc command evaluator; returns TCL_OK or TCL_ERROR.
| - io Intr intr—Command result; sometimes variables can be defined in the current scope.
| - input int N—Number of command parameters.
| - input Obj* P—Command parameters.
|
|
|
static int assoc(ClientData clientData,Intr intr,int N,Tcl_Obj *const P[]) {
int N0 = N; Obj *P0 = P; int rc,index;
bool vassoc = streq(clientData,"vassoc"),changed = false,shared; Obj var = 0,mapping = 0;
static chars subcommand[] = {
"new","dump",
"empty","first","last","next","previous",
"filter","names",
"get","key","data","flags","put","delete","update",
"allow",
0
};
enum {
o_new,o_dump,
o_empty,o_first,o_last,o_next,o_previous,
o_filter,o_names,
o_get,o_key,o_data,o_flags,o_put,o_delete,o_update,
o_allow
};
if (N<=1) {
Tcl_WrongNumArgs(intr,1,P0,"subcommand ..."); return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(intr,P[1],(CONST char**)subcommand,"subcommand",0,&index)!=TCL_OK) {
return TCL_ERROR;
}
N -= 2; P += 2;
if (index==o_allow) {
if (N==2 || N==3) {
Obj intrpath = P[0]; int M; Obj *Q; Intr master,slave = intr;
Obj path = P[1];
chars pem = N==2 ? "w" : Tcl_GetString(P[2]);
bool writable = false;
while (*pem && !writable) if (*pem++=='w') writable = true;
if (Tcl_ListObjGetElements(intr,intrpath,&M,&Q)!=TCL_OK) return TCL_ERROR;
if (M==0) return rprintf(intr,"%!no interpretter path",TCL_ERROR);
while (M-->0) {
master = slave;
slave = Tcl_GetSlave(intr,Tcl_GetString(*P));
if (!slave) return rprintf(intr,"%!unknown slave: %{y}s",TCL_ERROR,*P);
P++;
}
<External mapping paths in safe interpretters>
}else {
Tcl_WrongNumArgs(intr,2,P0,"variable-name ...");
return TCL_ERROR;
}
Tcl_ResetResult(intr);
return TCL_OK;
}
if (index==o_new) {
if (vassoc) {
if (N>0) {
var = *P++; N--;
}else {
Tcl_WrongNumArgs(intr,N0,P0,"variable-name ...");
return TCL_ERROR;
}
}
}else {
if (vassoc) {
if (N>0) {
var = *P++; N--;
}else {
Tcl_WrongNumArgs(intr,N0,P0,"variable-name ...");
return TCL_ERROR;
}
mapping = Tcl_ObjGetVar2(intr,var,0,TCL_LEAVE_ERR_MSG);
if (!mapping && index!=o_new) return TCL_ERROR;
changed = !mapping;
}else {
if (N>0) {
mapping = *P++; N--;
}else {
Tcl_WrongNumArgs(intr,N0,P0,"mapping ...");
return TCL_ERROR;
}
}
}
switch (index) {
case o_put: case o_delete: case o_update: {
if (mapping && Tcl_IsShared(mapping)) {
mapping = Tcl_DuplicateObj(mapping);
incr (mapping);
changed = true;
}else {
incr (mapping);
}
} break;
}
switch (index) {
case o_new: <assoc new typename [base [p1 p2 ...]]> break;
case o_dump: <assoc dump mapping [p1 p2 ...]> break;
case o_empty: <assoc empty mapping> break;
case o_first: <assoc first mapping> break;
case o_last: <assoc last mapping> break;
case o_next: <assoc next mapping key> break;
case o_previous: <assoc previous mapping key> break;
case o_filter: case o_names: <assoc filter|names mapping [[glob|re] pattern]> break;
case o_get: <assoc get mapping> break;
case o_key: <assoc key mapping key> break;
case o_data: <assoc data mapping key> break;
case o_flags: <assoc flags mapping key> break;
case o_put: <assoc put mapping> break;
case o_delete: <assoc delete mapping key> break;
case o_update: <assoc update mapping key var [initial] {script}> break;
}
switch (index) {
case o_new: case o_put: case o_delete: case o_update:
if (vassoc && rc==TCL_OK && changed && mapping) {
if (!Tcl_ObjSetVar2(intr,var,0,mapping,TCL_LEAVE_ERR_MSG)) rc = TCL_ERROR;
}
decr(mapping);
break;
}
return rc;
}
| ^ | | | | | | section top | |
if (N==0) {
Tcl_WrongNumArgs(intr,N0,P0,"typename"); rc = TCL_ERROR;
}else if (N==1) {
Obj empty = incr(Tcl_NewObj());
changed = true;
mapping = wyrm_assocNew(intr,Tcl_GetString(P[0]),empty,0,0);
decr(empty);
if (mapping) {Tcl_SetObjResult(intr,mapping); rc = TCL_OK;}
else {rc = TCL_ERROR;}
}else {
changed = true;
mapping = wyrm_assocNew(intr,Tcl_GetString(P[0]),P[1],N-2,P+2);
if (mapping) {Tcl_SetObjResult(intr,mapping); rc = TCL_OK;}
else {rc = TCL_ERROR;}
}
| ^ | | | | | | section top | |
{
Obj result = wyrm_assocDump(intr,mapping,N,P);
if (result) {Tcl_SetObjResult(intr,result); decr(result); rc = TCL_OK;}
else {rc = TCL_ERROR;}
}
| ^ | | | | | | section top | |
if (N==0) {
int pos = wyrm_assocEmpty(intr,mapping);
if (pos==TCL_ERROR) rc = pos;
else {Tcl_SetObjResult(intr,Tcl_NewBooleanObj(pos==TCL_OK)); rc = TCL_OK;}
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping");
rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N==0) {
Obj key = wyrm_assocFirst(intr,mapping);
if (key) {Tcl_SetObjResult(intr,key); rc = TCL_OK;}
else rc = TCL_ERROR;
decr(key);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N==0) {
Obj key = wyrm_assocLast(intr,mapping);
if (key) {Tcl_SetObjResult(intr,key); rc = TCL_OK;}
else rc = TCL_ERROR;
decr(key);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N==1) {
Obj oldkey = *P;
Obj newkey = wyrm_assocNext(intr,mapping,oldkey);
if (newkey) {Tcl_SetObjResult(intr, newkey); rc = TCL_OK;}
else rc = TCL_ERROR;
decr(newkey);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping key"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N==1) {
Obj oldkey = *P;
Obj newkey = wyrm_assocPrevious(intr,mapping,oldkey);
if (newkey) {Tcl_SetObjResult(intr, newkey); rc = TCL_OK;}
else rc = TCL_ERROR;
decr(newkey);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping key"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (!(mapping=coerceToMapping(intr,mapping))) {
rc = TCL_ERROR;
} else if (N>2) {
Tcl_WrongNumArgs(intr,2,P0,"mapping [[-glob|-re] pattern]"); rc = TCL_ERROR;
}else {
Obj glob = 0;
Obj regexp = 0;
Obj result = 0;
Obj prefix = 0;
ptr cookie = 0;
bool sorted;
if (N==1) {
glob = *P;
}else if (N==2) {
static chars matcher[] = {
"-glob","glob","-regexp","regexp",0
};
enum {glob1,glob2,re1,re2};
int kind;
if (Tcl_GetIndexFromObj(intr,*P,(CONST char**)matcher,"kind of pattern",0,&kind)!=TCL_OK) {
rc = TCL_ERROR;
break;
}
switch (kind) {
case glob1: case glob2: glob = P[1]; break;
case re1: case re2: regexp = P[1]; break;
}
}
rc = glob ? wyrm_assocFilterGlob(intr,mapping,index==o_names,glob,&result,0,0)
: regexp ? wyrm_assocFilterRE(intr,mapping,index==o_names,regexp,&result,0,0)
: wyrm_assocFilter(intr,mapping,index==o_names,0,&result,0,0);
if (rc==TCL_OK) Tcl_SetObjResult(intr,result);
decr(result);
}
| ^ | | | | | | section top | |
{
Obj keyvar=0,datavar=0,flagsvar=0,exactvar=0,key=0,actualkey=0,data=0; int flags = -1,exact;
rc = TCL_OK;
while (N>=2) {
if (strbegins("-k",Tcl_GetString(P[0]))) {
keyvar = P[1]; N -= 2; P += 2;
}else if (strbegins("-d",Tcl_GetString(P[0]))) {
datavar = P[1]; N -= 2; P += 2;
}else if (strbegins("-f",Tcl_GetString(P[0]))) {
flagsvar = P[1]; N -= 2; P += 2;
}else if (strbegins("-e",Tcl_GetString(P[0]))) {
exactvar = P[1]; N -= 2; P += 2;
}else if (streq("--",Tcl_GetString(P[0]))) {
N -= 1; P += 1; break;
}else if (strbegins("-",Tcl_GetString(P[0]))) {
rprintf(intr,"unknown option: assoc get ... %{y}s",*P);
rc = TCL_ERROR; break;
}else {
break;
}
}
if (rc==TCL_OK) switch (N) {
case 2: datavar = P[1];
case 1: key = P[0];
break;
default:
Tcl_WrongNumArgs(intr,2,P0,"mapping [vars] key [datavar]"); rc = TCL_ERROR;
break;
}
if (rc!=TCL_OK) break;
rc = wyrm_assocGet(intr,mapping,key,&actualkey,&data,&flags);
if (rc==TCL_OK) {
exact = actualkey && streq(Tcl_GetString(key),Tcl_GetString(actualkey));
}else if (exactvar
&& (strbegins("missing: ",Tcl_GetStringResult(intr))
|| streq("empty mapping",Tcl_GetStringResult(intr)))
) {
rc = TCL_OK; exact = false;
}else {
break;
}
if (!exact && !keyvar && !exactvar) {
rprintf(intr,"missing: %{y}s",key); rc = TCL_ERROR;
}
if (keyvar && rc==TCL_OK && actualkey) {
if (!Tcl_ObjSetVar2(intr,keyvar,0,actualkey,TCL_LEAVE_ERR_MSG)) rc = TCL_ERROR;
}
if (datavar && rc==TCL_OK && data) {
if (!Tcl_ObjSetVar2(intr,datavar,0,data,TCL_LEAVE_ERR_MSG)) rc = TCL_ERROR;
}
if (flagsvar && rc==TCL_OK && flags>=0) {
Obj FLAGS = incr(Tcl_NewIntObj(flags));
if (!Tcl_ObjSetVar2(intr,flagsvar,0,FLAGS,TCL_LEAVE_ERR_MSG)) rc = TCL_ERROR;
decr(FLAGS);
}
if (exactvar && rc==TCL_OK) {
Obj EXACT = incr(Tcl_NewBooleanObj(exact));
if (!Tcl_ObjSetVar2(intr,exactvar,0,EXACT,TCL_LEAVE_ERR_MSG)) rc = TCL_ERROR;
decr(EXACT);
}
if (rc==TCL_OK) {
if (data) Tcl_SetObjResult(intr,data);
else Tcl_ResetResult(intr);
}
decr(actualkey); decr(data);
}
| ^ | | | | | | section top | |
if (N==1) {
Obj oldkey = *P;
Obj newkey = wyrm_assocKey(intr,mapping,oldkey);
if (newkey) {Tcl_SetObjResult(intr,newkey); rc = TCL_OK;}
else rc = TCL_ERROR;
decr(newkey);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping key"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N==1) {
Obj key = *P;
Obj data = wyrm_assocData(intr,mapping,key);
if (data) {Tcl_SetObjResult(intr,data); rc = TCL_OK;}
else rc = TCL_ERROR;
decr(data);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping key"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N==1) {
Obj key = *P;
int flags = wyrm_assocFlags(intr,mapping,key);
if (flags>=0) {Tcl_SetObjResult(intr,Tcl_NewIntObj(flags)); rc = TCL_OK;}
else rc = TCL_ERROR;
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping key"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
{
Obj key=0,data=0; int flags = -1;
rc = TCL_OK;
while (N>=2) {
if (strbegins("-k",Tcl_GetString(P[0]))) {
key = P[1]; N -= 2; P += 2;
}else if (strbegins("-d",Tcl_GetString(P[0]))) {
data = P[1]; N -= 2; P += 2;
}else if (strbegins("-f",Tcl_GetString(P[0]))) {
if (Tcl_GetIntFromObj(intr,P[1],&flags)==TCL_OK) {
N -= 2; P += 2;
}else {
rc = TCL_ERROR; break;
}
}else if (streq("--",Tcl_GetString(P[0]))) {
N -= 1; P += 1; break;
}else if (strbegins("-",Tcl_GetString(P[0]))) {
rprintf(intr,"unknown option: assoc put ... %{y}s",*P);
rc = TCL_ERROR; break;
}else {
break;
}
}
if (rc==TCL_OK) switch (N) {
case 2: key = P[0]; data = P[1]; break;
case 1: key = P[0];
break;
case 0:
if (key) break;
default:
Tcl_WrongNumArgs(intr,2,P0,"mapping [vars] key [data]"); rc = TCL_ERROR;
}
if (rc==TCL_OK) {
rc = wyrm_assocPut(intr,mapping,key,data,flags);
if (rc==TCL_OK) Tcl_SetObjResult(intr,mapping);
}
}
| ^ | | | | | | section top | |
if (N==1) {
rc = wyrm_assocDelete(intr,mapping,*P);
if (rc==TCL_OK) Tcl_SetObjResult(intr,mapping);
}else {
Tcl_WrongNumArgs(intr,2,P0,"mapping key"); rc = TCL_ERROR;
}
| ^ | | | | | | section top | |
if (N<3) {
Tcl_WrongNumArgs(intr,3,P0,"key var [default] {script}"); rc = TCL_ERROR;
}else if (N>4) {
Tcl_WrongNumArgs(intr,7,P0,"...: too many"); rc = TCL_ERROR;
}else {
Obj key = P[0];
Obj actualkey;
Obj data;
Obj var = P[1];
Obj val = 0;
Obj initial = N==3 ? 0 : P[2];
Obj script = N==3 ? P[2] : P[3];
bool atrisk = false;
rc = wyrm_assocGet(intr,mapping,key,&actualkey,&data,0);
if (rc==TCL_ERROR || !streq(Tcl_GetString(key),Tcl_GetString(actualkey))) {
if (initial) {
val = Tcl_ObjSetVar2(intr,var,0,initial,TCL_LEAVE_ERR_MSG);
}else {
initial = incr(Tcl_NewObj());
val = Tcl_ObjSetVar2(intr,var,0,initial,TCL_LEAVE_ERR_MSG);
decr(initial); initial = 0;
}
}else {
if (Tcl_IsShared(data)) {
atrisk = true;
rc = wyrm_assocPut(intr,mapping,key,(val=incr(Tcl_NewObj())),-1);
decr(val);
}
if (rc==TCL_OK && Tcl_IsShared(data)) {
val = incr(Tcl_DuplicateObj(data)); decr(data); data = val;
}
val = rc==TCL_OK ? Tcl_ObjSetVar2(intr,var,0,data,TCL_LEAVE_ERR_MSG) : 0;
}
rc = val ? TCL_OK : TCL_ERROR;
decr(actualkey);
decr(data);
if (rc==TCL_OK) rc = Tcl_EvalObjEx(intr,script,0);
val = Tcl_ObjGetVar2(intr,var,0,0);
if (val && wyrm_assocPut(intr,mapping,key,val,-1)==TCL_OK) atrisk = false;
if (!val) rc = TCL_ERROR;
if (rc==TCL_OK) {
Tcl_SetObjResult(intr,mapping);
}else if (atrisk) {
Tcl_AppendResult(intr," (The original value of '",Tcl_GetString(key),"' has been lost.)",0);
}
}
| ^ | | |
| |