/* * Replaces the princ and related functions with functions that redirect the script log to a file. To use this, * - Modify the outputFileName in the LogDirect class definition to a file whose containing directory exists * - Add the script to the list of scripts that loads when the DataHub starts. * - Press Apply to ensure that the configuration is saved * - Restart the DataHub or run the script using the Script Editor or by selecting it and pressing "Load Now" * * This does not capture the output of an interactive command typed into the Script Log entry field. */ require ("Application"); class LogRedirect Application { outputFileName = "C:/Users/mholbach/Desktop/script.log"; outputFile; orig_princ; orig_print; orig_pretty_princ; orig_pretty_print; orig_terpri; static: my_princ; my_print; my_pretty_princ; my_pretty_print; my_terpri; } // Modify the global script environment to replace the specified function with // my own function. Keep track of the original function so we can undo what we // do here when the script is stopped. method LogRedirect.redirect(funcName, newFunction) { local sym = symbol(funcName); local mysym = symbol(string("my_", funcName)); local origsym = symbol(string("orig_", funcName)); local origfunc = eval(sym); ..origsym = origfunc; ..mysym = newFunction; set (sym, newFunction); } // Reset the specified function back to the way it was before this script ran. method LogRedirect.reset(funcName) { local sym = symbol(funcName); local origsym = symbol(string("orig_", funcName)); local origfunc = ..origsym; if (origfunc) set(sym, origfunc); } // Write the output to the script log using the appropriate function, and also write // it to the log file using the file-based equivalent function. method LogRedirect.output(printFunction, writeFunction, args) { if (!.outputFile) { .outputFile = open (.outputFileName, "a"); } if (.outputFile) { funcall(writeFunction, cons(.outputFile, args)); flush(.outputFile); } funcall(printFunction, args); } // Replace princ, print, pretty_princ, pretty_print and terpri with my own functions. // In the case of terpri, do not call my own function if the caller has specified a // target output file. method LogRedirect.constructor () { .redirect ("princ", function (args...) { LogRedirector.output(LogRedirector.orig_princ, writec, args); }); .redirect ("print", function (args...) { LogRedirector.output(LogRedirector.orig_print, write, args); }); .redirect ("pretty_princ", function (args...) { LogRedirector.output(LogRedirector.orig_pretty_princ, pretty_writec, args); }); .redirect ("pretty_print", function (args...) { LogRedirector.output(LogRedirector.orig_pretty_print, pretty_write, args); }); .redirect ("terpri", function (args...?=nil) { if (args != nil) funcall(LogRedirector.orig_terpri, args); else LogRedirector.output(LogRedirector.orig_terpri, LogRedirector.orig_terpri, args); }); } // When the script stops, reset the function redirections method LogRedirect.destructor () { .reset("princ"); .reset("print"); .reset("pretty_princ"); .reset("pretty_print"); .reset("terpri"); if (.outputFile) close(.outputFile); } // We do not use these for anything. They are just here in case we mess up the script and need // to recover an original function. internal_print := print; internal_pretty_print := pretty_print; internal_princ := princ; internal_pretty_princ := pretty_princ; internal_terpri := terpri; LogRedirector = ApplicationSingleton (LogRedirect);