/*********************************************************************** * Copyright (C) 1995 Joe English * Freely redistributable *********************************************************************** * * subst.c,v 1.6 1998/11/10 00:07:00 jenglish Exp * * Author: Joe English * Created: 11 Apr 1995 * Description: Fixed-string substitutions * */ #include #include #include "tcl.h" #include "project.h" #include "ctrie.h" #include "esis.h" #include "tclcost.h" /* SubstProc -- substitution command implementation procedure */ static int SubstProc(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { CTrie subst = (CTrie)(clientData); Tcl_DString result; char *startp, *endp, *matchp; CTrieNode curnode, matchnode, nextnode; CHECKNARGS(1, "string"); Tcl_DStringInit(&result); startp = endp = argv[1]; matchp = 0; curnode = ctrie_root(subst); matchnode = 0; /* %%% verify that this works */ while (*startp) { nextnode = *endp ? ctrie_findch(curnode, *endp) : 0; if (nextnode) { curnode = nextnode; if (ctrie_hasvalue(curnode)) { matchnode = curnode; matchp = endp; } ++endp; } else /* flush */ { if (matchnode) { ASSERT(matchp != 0, "Out of sync 1"); Tcl_DStringAppend(&result, ctrie_getvalue(matchnode), -1); startp = matchp + 1; } else { ASSERT(matchp == 0, "Out of sync 2"); Tcl_DStringAppend(&result, startp, 1); ++startp; } endp = startp; curnode = ctrie_root(subst); matchp = 0; matchnode = 0; } } Tcl_DStringResult(interp, &result); return TCL_OK; } /* * Destructor */ /*ARGSUSED*/ static void ctnfreeproc(CTrieNode ctn, void *closure) { if (ctrie_hasvalue(ctn)) free(ctrie_getvalue(ctn)); } static void SubstDtor(ClientData clientData) { CTrie subst = (CTrie)clientData; ctrie_foreach(subst, ctnfreeproc, 0); ctrie_destroy(subst); } /*ARGSUSED*/ int DefineSubstProc(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { char *cmdName; char **pairs; int npairs, i; CTrie subst; CHECKNARGS(2,"name subst-pairs"); cmdName = argv[1]; if (TCL_ERROR == Tcl_SplitList(interp, argv[2], &npairs, &pairs)) return TCL_ERROR; if (npairs % 2 != 0) { Tcl_AppendResult(interp, argv[0], ": odd number of pairs"); Tcl_FreeSplitList(pairs); return TCL_ERROR; } subst = ctrie_create(); for (i=0; i