/* * t4open.cpp -- * * Implementation of the the T4Graph command to open a storage. * * 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 procedure is called when the interpreter is deleted, to close * all storages that were registered with this interpreter. */ static void interpDelete(ClientData *ignored, Tcl_Interp *interp) { Tcl_HashSearch search; T4Storage *sp; for (sp = T4Graph_FirstStorage(&search); sp != NULL; sp = T4Graph_NextStorage(&search)) { sp->UnregisterStoragePerInterp(interp); } } /* * T4Graph_OpenStorageProc -- * * This procedure is called when "tgraph::open" is invoked. * Syntax: * tgraph::open name ?opt val ..? * * Results: * A standard Tcl result. The interpreter result will contain the * name of the opened storage if successful. * * Side effects: * May open a new storage. */ int T4Graph_OpenStorageProc(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { T4StorageOptions storageOptions; char *fnm = NULL; T4Storage *sp; /* * An even number of arguments is expected, and at least two * arguments are expected. */ if ((objc < 2) || ((objc % 2) != 0)) { Tcl_WrongNumArgs(interp, 1, objv, (char *) "name ?opt val ..?"); return TCL_ERROR; } /* * The second argument is the storage name. The rest of the arguments * are opt-val pairs. */ fnm = Tcl_GetString(objv[1]); /* * Initialize the storage options to the default values: */ storageOptions.driver = E4_METAKIT; storageOptions.rwmode = "rw"; storageOptions.modes = E4_DEFAULTSTATE; /* * Parse the rest of the arguments: */ if (!T4Graph_ParseStorageOptions(interp, objc-2, objv+2, &storageOptions)) { return TCL_ERROR; } /* * Attempt to open the requested storage. */ e4_Storage s(fnm, storageOptions.driver, storageOptions.modes); /* * If the storage was not opened successfully, bail out * right away. */ if (!s.IsValid()) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), fnm, ": cannot open with ", storageOptions.driver, NULL); return TCL_ERROR; } /* * Register this storage in the global storages registry. If it already * exists, the globally registered instance is returned. */ sp = T4Graph_RegisterStorage(s, fnm, storageOptions.driver); /* * Register the storage with this interpreter. */ sp->RegisterStoragePerInterp(interp); /* * Return the Tcl name as the result and export it as a command. */ if (T4Graph_MakeStorageCommand(interp, sp) == TCL_ERROR) { return TCL_ERROR; } /* * Ensure that this interpreter is set up so that all storages that * are registered within it are closed when the interpreter is deleted. */ T4Graph_RegisterInterp(interp); /* * Success -- return the name of the storage command. */ Tcl_ResetResult(interp); Tcl_SetStringObj(Tcl_GetObjResult(interp), sp->GetName(), -1); return TCL_OK; } /* * Register this interpreter so that all storages registered within it * will be properly closed when the interpreter is deleted. */ void T4Graph_RegisterInterp(Tcl_Interp *interp) { int key; /* * If the key hasn't been registered yet, do it now. */ key = (int) Tcl_GetAssocData(interp, T4_ASSOCKEY, NULL); if (key == 0) { Tcl_SetAssocData(interp, T4_ASSOCKEY, (Tcl_InterpDeleteProc *) interpDelete, (ClientData) 1); } }