TIP: | 83 |
Title: | Augment Tcl_EvalFile with Tcl_EvalChannel and Tcl_EvalUrl |
Version: | $Revision: 1.6 $ |
Authors: |
Marian Szczepkowski <marian at mail dot jozep dot com dot au> dgp at users dot sf dot net |
State: | Withdrawn |
Type: | Project |
Tcl-Version: | 8.5 |
Vote: | Pending |
Created: | Thursday, 24 January 2002 |
This TIP adds the ability to load Tcl files directly from URLs to the core, together with a basic mechanism to simply evaluate a stream of characters from a channel.
I propose to split the Tcl_EvalFile function into two components to enable the [source] command to use URL's to obtain source material.
This will mean splitting Tcl_EvalFile into Tcl_EvalFile and Tcl_EvalChannel which are the two logical entities. Maintaining Tcl_EvalFile will preserve backward compatability.
Creating Tcl_EvalChannel will provide generic functionality for future use.
Adding Tcl_EvalUrl will enable handling standard URL format strings.
This would enable this [source http://anywhere.com/file.tcl] to be used.
Code will also need to be added to Tcl_SourceObjCmd to select functionality requested.
In a corporate environment where scripts are subject to change but the interface is not, this allows scripts to be stored remotely on a central server.
This also allows Tcl to interwork in a networked environment.
Security!!!!
This may mean in the long run adding a signing layer, but don't use it if you don't want to.
I figure it looking something like this. Snipped from 8.3 source.
int Tcl_SourceObjCmd(dummy, interp, objc, objv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { char *bytes; int result; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "fileName"); return TCL_ERROR; } bytes = Tcl_GetString(objv[1]); if (strstr(ptr,"://")) { result = Tcl_EvalFile(interp, bytes); } else { result = Tcl_EvalUrl(interp, bytes); } return result; }
int Tcl_EvalFile(interp, fileName) Tcl_Interp *interp; /* Interpreter in which to process file. */ char *fileName; /* Name of file to process. Tilde-substitution * will be performed on this name. */ { int result, length; struct stat statBuf; Interp *iPtr; Tcl_DString nameString; char *name, *string; Tcl_Channel chan; Tcl_Obj *objPtr; name = Tcl_TranslateFileName(interp, fileName, &nameString); if (name == NULL) { return TCL_ERROR; } result = TCL_ERROR; if (TclStat(name, &statBuf) == -1) { Tcl_SetErrno(errno); Tcl_AppendResult(interp, "couldn't read file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); goto end; } chan = Tcl_OpenFileChannel(interp, name, "r", 0644); if (chan == (Tcl_Channel) NULL) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "couldn't read file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); goto end; } result = Tcl_EvalChannel(interp, chan); end: Tcl_DStringFree(&nameString); return result; }
int Tcl_EvalUrl(interp, fileName) Tcl_Interp *interp; /* Interpreter in which to process file. */ char *fileName; /* Name of URL to process. */ { return TCL_ERROR; }
int Tcl_EvalChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which to process file. */ Tcl_Channel chan; /* Name of file to process. */ { int result, length; struct stat statBuf; char *oldScriptFile; Interp *iPtr; char *name, *string; Tcl_Obj *objPtr; result = TCL_ERROR; objPtr = Tcl_NewObj(); if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) { Tcl_Close(interp, chan); Tcl_AppendResult(interp, "couldn't read file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); goto end; } if (Tcl_Close(interp, chan) != TCL_OK) { goto end; } iPtr = (Interp *) interp; oldScriptFile = iPtr->scriptFile; iPtr->scriptFile = fileName; string = Tcl_GetStringFromObj(objPtr, &length); result = Tcl_EvalEx(interp, string, length, 0); iPtr->scriptFile = oldScriptFile; if (result == TCL_RETURN) { result = TclUpdateReturnInfo(iPtr); } else if (result == TCL_ERROR) { char msg[200 + TCL_INTEGER_SPACE]; /* * Record information telling where the error occurred. */ sprintf(msg, "\n (file \"%.150s\" line %d)", fileName, interp->errorLine); Tcl_AddErrorInfo(interp, msg); } end: Tcl_DecrRefCount(objPtr); return result; }
The VFS extension interface of Tcl 8.4 plus the tclvfs and vfs::http packages provide the ability to [source] an URL. I believe that makes this proposal out of date.
This document has been placed in the public domain.
[Index] [History] [HTML Format] [Source Format] [LaTeX Format] [Text Format] [XML Format] [*roff Format (experimental)] [RTF Format (experimental)]
TIP AutoGenerator - written by Donal K. Fellows