/* * t4parse.cpp -- * * This file contains procedures to parse vertex and insert-order * specifications. * * Authors: Jacob Levy and Jean-Claude Wippler. * jyl@best.com jcw@equi4.com * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "t4graphrep.h" /* * This pattern is used to split appart vertex specifications into their * elements. */ static char *splitpattern = (char *) "split {%s} ()"; static int splitpatternlen = 9; /* * These are the names of the insert orders in Tcl: */ static CONST84 char *ionames[] = { (char *) "none", (char *) "at", (char *) "first", (char *) "last", (char *) "before", (char *) "after", NULL }; int T4Graph_ParseVertexName(Tcl_Interp *interp, char *specstr, char **fnpp, int *indexp, T4VertexNameKinds *vnkp) { int iv, len; char *cmdbuf; Tcl_Obj **objv; Tcl_DString ds; /* * If the spec is of the form "a(b)" or "(b)" then split it up. * Use the part before the open-paren as the name of a vertex and * the part inside the parens as an index. Thus, "foo(3)" means the * third vertex named "foo". */ if (Tcl_StringMatch(specstr, "*(*)") == 1) { Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "split {", -1); Tcl_DStringAppend(&ds, specstr, -1); cmdbuf = Tcl_DStringAppend(&ds, "} ()", -1); if (Tcl_Eval(interp, cmdbuf) == TCL_ERROR) { Tcl_DStringFree(&ds); return TCL_ERROR; } Tcl_DStringFree(&ds); if (Tcl_ListObjGetElements(interp, Tcl_GetObjResult(interp), &len, &objv) == TCL_ERROR) { return TCL_ERROR; } if (len != 3) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "\"", specstr, "\": badly formed vertex spec", NULL); return TCL_ERROR; } specstr = Tcl_GetString(objv[0]); if (Tcl_GetIntFromObj(interp, objv[1], &iv) == TCL_ERROR) { iv = 1; } /* * Interpreter result should not be reset because it would smash * specstr. Only reset it after use, in the caller of ParseVertexName. */ *fnpp = specstr; *indexp = iv; *vnkp = T4VNK_INDEX; return TCL_OK; } /* * See if it is an integer. If so, use that as a rank. */ Tcl_SetStringObj(Tcl_GetObjResult(interp), specstr, -1); if (Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &iv) == TCL_OK) { Tcl_ResetResult(interp); *fnpp = NULL; *indexp = iv; *vnkp = T4VNK_RANK; return TCL_OK; } /* * Simple form. Use it as the name of a field. */ Tcl_ResetResult(interp); *fnpp = specstr; *indexp = 1; *vnkp = T4VNK_INDEX; return TCL_OK; } /* * T4Graph_ParseInsertOrder -- * * This procedure parses a string that denotes an insert order as * defined by enum e4_InsertOrder in /main/include/e4common.h. * * Results: * A standard Tcl result. Upon success the output parameter iop is * set to one of the values defined by enum e4_InsertOrder. * * Side effects: * None. */ int T4Graph_ParseInsertOrder(Tcl_Interp *interp, Tcl_Obj *spec, e4_InsertOrder *iop) { return Tcl_GetIndexFromObj(interp, spec, (CONST84 char **) ionames, (char *) "insert order", 0, (int *) iop); }