/* * Programs to allow for reading and writing of a log file which * will record all output from both XSPEC and TCL. */ #include "xstcl.h" #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include Tcl_Channel XS_Stdout_Chan; Tcl_Channel XS_Stderr_Chan; Tcl_Channel XS_Logfile_Chan; char* xs_log_out = "LogOut"; char* xs_log_err = "ErrOut"; #include #ifdef __cplusplus } #endif /* * xs_input_log -- Dummy input routine for data logging channel. */ int xs_input_log(ClientData cdata,char * buf,int bufsize,int * errcode ) { return TCL_OK; } /* * xs_close_log -- Procedure for closing the data logging channel. */ int xs_close_log(ClientData cdata,Tcl_Interp * interp ) { return TCL_OK; } /* * xs_output_log -- */ int xs_output_log(ClientData cdata, char* buf,int bufsize,int* errcode ) { /* * First write to the log file. */ if( Tcl_Write(XS_Logfile_Chan, buf, bufsize) != bufsize ) { *errcode = Tcl_GetErrno(); return TCL_ERROR; } if( Tcl_Flush(XS_Logfile_Chan) != TCL_OK) { *errcode = Tcl_GetErrno(); return TCL_ERROR; } /* * Now write either to stadard out or error, depending on oufile. */ if( (char *)cdata == xs_log_out ) { if( Tcl_Write(XS_Stdout_Chan, buf, bufsize) != bufsize ) { *errcode = Tcl_GetErrno(); return TCL_ERROR; } if( Tcl_Flush(XS_Stdout_Chan) != TCL_OK) { *errcode = Tcl_GetErrno(); return TCL_ERROR; } } else if( (char *)cdata == xs_log_err ) { if( Tcl_Write(XS_Stderr_Chan, buf, bufsize) != bufsize ) { *errcode = Tcl_GetErrno(); return TCL_ERROR; } if( Tcl_Flush(XS_Stderr_Chan) != TCL_OK) { *errcode = Tcl_GetErrno(); return TCL_ERROR; } } return bufsize; } /* * xs_watch_log -- */ int xs_watch_log(ClientData cdata,int mask) { int error=TCL_OK; if( mask | TCL_WRITABLE ) { if( (char *)cdata == xs_log_out ) Tcl_NotifyChannel(XS_Stdout_Chan,mask); if( (char *)cdata == xs_log_err ) Tcl_NotifyChannel(XS_Stderr_Chan,mask); Tcl_NotifyChannel(XS_Logfile_Chan,mask); } return error; } /* * xs_handle_log -- */ int xs_handle_log(ClientData cdata,int direct,ClientData* handler) { if( (char *)cdata == xs_log_out ) { return Tcl_GetChannelHandle(XS_Stdout_Chan, TCL_WRITABLE, handler); } else if ((char *)cdata == xs_log_err) { return Tcl_GetChannelHandle(XS_Stderr_Chan, TCL_WRITABLE, handler); } else return TCL_OK; } /* * xs_log -- * Routine which sets everything up for writing a log file */ int xs_log(ClientData cdata,Tcl_Interp* interp,int objc,Tcl_Obj* CONST objv[] ) { Tcl_Channel Logging_Chan; char logfile[1024]; time_t clock; int objlen = 0; int iarg, stamp = 0; static Tcl_ChannelType *LogPtr; strcpy(logfile,"xspec"); for(iarg=1; iargtypeName = "file"; LogPtr->version = (Tcl_ChannelTypeVersion) TCL_CHANNEL_VERSION_2; LogPtr->closeProc = (Tcl_DriverCloseProc *)xs_close_log; LogPtr->inputProc = (Tcl_DriverInputProc *)xs_input_log; LogPtr->outputProc = (Tcl_DriverOutputProc *)xs_output_log; LogPtr->seekProc = (Tcl_DriverSeekProc *)NULL; LogPtr->setOptionProc = (Tcl_DriverSetOptionProc *)NULL; LogPtr->getOptionProc = (Tcl_DriverGetOptionProc *)NULL; /* * Create the channel getting input from gnu readline. * Updated B.Dorman. 11/98 for compatibility with tcl8.0 * * Channel drivers revised in tcl8.3.2 8/2000. * */ LogPtr->watchProc = (Tcl_DriverWatchProc *)xs_watch_log; LogPtr->getHandleProc = (Tcl_DriverGetHandleProc *)xs_handle_log; LogPtr->close2Proc = (Tcl_DriverClose2Proc *)NULL; LogPtr->blockModeProc = (Tcl_DriverBlockModeProc *)NULL; LogPtr->flushProc = (Tcl_DriverFlushProc *)NULL; LogPtr->handlerProc = (Tcl_DriverHandlerProc *)NULL; Logging_Chan = Tcl_CreateChannel( LogPtr, xs_log_out, (ClientData)xs_log_out, TCL_WRITABLE); if( Logging_Chan == NULL ) return TCL_ERROR; Tcl_RegisterChannel(interp, Logging_Chan); if (Tcl_SetChannelOption(interp, Logging_Chan, "-buffering", "line") != TCL_OK ) return TCL_ERROR; /* * Now switch it around to be the standard channel for output, * after saving the value of the old channel so we can restore it. */ XS_Stdout_Chan = Tcl_GetStdChannel(TCL_STDOUT); Tcl_SetStdChannel(Logging_Chan, TCL_STDOUT); /* * Now do the same for the standard error */ Logging_Chan = Tcl_CreateChannel( LogPtr, xs_log_err,(ClientData)xs_log_err, TCL_WRITABLE); if( Logging_Chan == NULL ) return TCL_ERROR; Tcl_RegisterChannel(interp, Logging_Chan); if( Tcl_SetChannelOption(interp, Logging_Chan, "-buffering", "line") != TCL_OK ) return TCL_ERROR; XS_Stderr_Chan = Tcl_GetStdChannel(TCL_STDERR); Tcl_SetStdChannel(Logging_Chan, TCL_STDERR); /* * Finished */ Tcl_AppendResult(interp, "Logging to file: ", logfile, (char *)NULL); return TCL_OK; }