Author: Marian Szczepkowski <marian@mail.jozep.com.au>
Author: <dgp@users.sf.net>
State: Withdrawn
Type: Project
Vote: Pending
Created: 24-Jan-2002
Post-History:
Tcl-Version: 8.5
Abstract
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.
Proposal
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.
Pro.
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.
Con.
Security!!!!
This may mean in the long run adding a signing layer, but don't use it if you don't want to.
Sample
I figure it looking something like this. Snipped from 8.3 source.
Tcl_SourceObjCmd
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;
}
Tcl_EvalFile
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;
}
Tcl_EvalUrl
int
Tcl_EvalUrl(interp, fileName)
Tcl_Interp *interp; /* Interpreter in which to process file. */
char *fileName; /* Name of URL to process. */
{
return TCL_ERROR;
}
Tcl_EvalChannel
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;
}
Comments
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.
Copyright
This document has been placed in the public domain.