You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
502 lines
11 KiB
Plaintext
502 lines
11 KiB
Plaintext
8 months ago
|
*! version 1.2.11 18feb2010
|
||
|
program define sjlog
|
||
|
if _caller() < 8.0 {
|
||
|
sjlog_7 `0'
|
||
|
exit
|
||
|
}
|
||
|
version 8.0
|
||
|
local vv : display _caller()
|
||
|
|
||
|
gettoken cmd 0 : 0, parse(" ,")
|
||
|
local l = length(`"`cmd'"')
|
||
|
if `"`cmd'"' == "using" | `"`cmd'"' == "open" {
|
||
|
LogOpen `0'
|
||
|
}
|
||
|
else if `"`cmd'"' == "close" {
|
||
|
LogClose `0'
|
||
|
}
|
||
|
else if `"`cmd'"' == "do" {
|
||
|
LogDo `vv' `0'
|
||
|
}
|
||
|
else if `"`cmd'"' == "clean" {
|
||
|
LogClean `0'
|
||
|
}
|
||
|
else if `"`cmd'"' == "type" {
|
||
|
LogType `0'
|
||
|
}
|
||
|
else if `"`cmd'"' == substr("basename",1,`l') {
|
||
|
LogBaseName `0'
|
||
|
}
|
||
|
else if `"`cmd'"' == "" {
|
||
|
log
|
||
|
}
|
||
|
else {
|
||
|
di as err "`cmd' invalid"
|
||
|
exit 198
|
||
|
}
|
||
|
end
|
||
|
|
||
|
program define LogSetup
|
||
|
syntax [, clear ]
|
||
|
if "`clear'" != "" {
|
||
|
clear
|
||
|
program drop _all
|
||
|
}
|
||
|
capture log close
|
||
|
set rmsg off
|
||
|
set more off
|
||
|
set trace off
|
||
|
end
|
||
|
|
||
|
program define StripQuotes
|
||
|
syntax anything(name=name id="name") [, string(string) ]
|
||
|
c_local `name' `"`string'"'
|
||
|
end
|
||
|
|
||
|
/* basename *****************************************************************/
|
||
|
|
||
|
program define LogBaseName, rclass
|
||
|
syntax anything(name=file id="filename") [, Display ]
|
||
|
|
||
|
StripQuotes file , string(`file')
|
||
|
local dirsep "/"
|
||
|
|
||
|
/* strip off the directory path */
|
||
|
gettoken dir rest : file, parse("/\:")
|
||
|
while `"`rest'"' != "" {
|
||
|
if `"`dir'"' == "\" {
|
||
|
local dir `"`dirsep'"'
|
||
|
}
|
||
|
local dirname `"`dirname'`dir'"'
|
||
|
gettoken dir rest : rest , parse("\/:")
|
||
|
}
|
||
|
if `"`dirname'"' == "" {
|
||
|
local dirname .`dirsep'
|
||
|
}
|
||
|
|
||
|
/* strip off the extension */
|
||
|
gettoken ext rest : dir, parse(".")
|
||
|
while `"`rest'"' != "" {
|
||
|
local basename `basename'`ext'
|
||
|
gettoken ext rest : rest , parse(".")
|
||
|
}
|
||
|
if `"`basename'"' == "" {
|
||
|
local basename `ext'
|
||
|
local ext
|
||
|
}
|
||
|
else {
|
||
|
/* remove the last "." from `basename' */
|
||
|
local l = length(`"`basename'"') - 1
|
||
|
local basename = substr(`"`basename'"',1,`l')
|
||
|
}
|
||
|
|
||
|
/* saved results */
|
||
|
return local ext = cond(`"`ext'"'=="","",".") + `"`ext'"'
|
||
|
return local base `"`basename'"'
|
||
|
return local dir `"`dirname'"'
|
||
|
return local fn `"`file'"'
|
||
|
|
||
|
if `"`display'"' != "" {
|
||
|
display as txt `"fn: `return(fn)'"'
|
||
|
display as txt `"dir: `return(dir)'"'
|
||
|
display as txt `"base: `return(base)'"'
|
||
|
display as txt `"ext: `return(ext)'"'
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* using/close/do: subroutines **********************************************/
|
||
|
|
||
|
program define LogOpen
|
||
|
syntax anything(name=file id="filename") [, append replace ]
|
||
|
|
||
|
LogSetup
|
||
|
|
||
|
LogBaseName `file'
|
||
|
local ext `"`r(ext)'"'
|
||
|
if `"`ext'"' != ".smcl" {
|
||
|
local file `"`r(fn)'.smcl"'
|
||
|
}
|
||
|
|
||
|
quietly log using `"`file'"', smcl `append' `replace'
|
||
|
end
|
||
|
|
||
|
program define LogClose, rclass
|
||
|
syntax [, /*
|
||
|
*/ book /*
|
||
|
*/ replace /*
|
||
|
*/ noCLEAN /*
|
||
|
*/ noLOGfile /*
|
||
|
*/ sjlogdo /* internal only, NOT documented
|
||
|
*/ ]
|
||
|
|
||
|
if `"`sjlogdo'"' == "" {
|
||
|
local logtype sjlog
|
||
|
}
|
||
|
else local logtype `sjlogdo'
|
||
|
|
||
|
quietly log
|
||
|
|
||
|
LogBaseName `"`r(filename)'"'
|
||
|
local dir `"`r(dir)'"'
|
||
|
local base `"`r(base)'"'
|
||
|
local ext `"`r(ext)'"'
|
||
|
local file `"`r(fn)'"'
|
||
|
local dbase `"`dir'`base'"'
|
||
|
|
||
|
quietly log close
|
||
|
|
||
|
/* log assumed to be a smcl file */
|
||
|
if `"`ext'"' != ".smcl" {
|
||
|
di in red "assumption failed -- log file not smcl"
|
||
|
exit 198
|
||
|
}
|
||
|
if `"`clean'"' == "" {
|
||
|
LogClean `"`file'"', `logtype'
|
||
|
erase `"`r(fnbak)'"'
|
||
|
}
|
||
|
|
||
|
/* get TeX version of log */
|
||
|
qui log texman `"`file'"' `"`dbase'.log.tex"', `replace' `book'
|
||
|
if `"`logfile'"' == "" {
|
||
|
/* get plain text version of log */
|
||
|
qui translate `"`file'"' `"`dbase'.log"', `replace'
|
||
|
}
|
||
|
|
||
|
/* saved results */
|
||
|
if `"`logfile'"' == "" {
|
||
|
return local fn_log `"`dbase'.log"'
|
||
|
}
|
||
|
return local fn_tex `"`dbase'.log.tex"'
|
||
|
return local fn_smcl `"`dbase'.smcl"'
|
||
|
end
|
||
|
|
||
|
program define LogDo
|
||
|
version 8.0
|
||
|
gettoken vv 0 : 0
|
||
|
local vv "version `vv':"
|
||
|
syntax anything(name=file id="filename") [, ///
|
||
|
clear ///
|
||
|
replace ///
|
||
|
book ///
|
||
|
nostop ///
|
||
|
SAVing(string) ///
|
||
|
]
|
||
|
|
||
|
if "`saving'" != "" {
|
||
|
capture confirm name `saving'
|
||
|
if _rc {
|
||
|
di as err ///
|
||
|
"'`saving'' found where saving() option requires a valid name"
|
||
|
exit 198
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LogSetup, `clear'
|
||
|
|
||
|
LogBaseName `file'
|
||
|
local base = cond("`saving'"=="","`r(base)'","`saving'")
|
||
|
local dbase `"`r(dir)'`base'"'
|
||
|
local ext `"`r(ext)'"'
|
||
|
local file `"`r(fn)'"'
|
||
|
if `"`ext'"' != ".do" {
|
||
|
local dbase `"`dbase'`ext'"'
|
||
|
}
|
||
|
|
||
|
LogOpen `dbase', `replace'
|
||
|
capture noisily `vv' do `file', `stop'
|
||
|
local rc = _rc
|
||
|
if `rc' {
|
||
|
local cap capture
|
||
|
}
|
||
|
`cap' LogClose, `replace' sjlogdo `book'
|
||
|
exit `rc'
|
||
|
end
|
||
|
|
||
|
/* clean: subroutines *******************************************************/
|
||
|
|
||
|
program define LogClean, rclass
|
||
|
syntax anything(name=file id="filename") [, /*
|
||
|
*/ log /*
|
||
|
*/ logclose /*
|
||
|
*/ sjlog /*
|
||
|
*/ sjlogdo /*
|
||
|
*/ ]
|
||
|
|
||
|
/* validate arguments and options */
|
||
|
local logsrc `log' `logclose' `sjlog' `sjlogdo'
|
||
|
local wc : word count `logsrc'
|
||
|
if `wc' > 1 {
|
||
|
di as err "options `logsrc' may not be combined"
|
||
|
exit 198
|
||
|
}
|
||
|
StripQuotes file , string(`file')
|
||
|
confirm file `"`file'"'
|
||
|
|
||
|
/* open files */
|
||
|
tempname rf wf
|
||
|
tempfile newfile
|
||
|
file open `rf' using `"`file'"', read text
|
||
|
file open `wf' using `"`newfile'"', write text
|
||
|
|
||
|
/* clean file */
|
||
|
capture noisily {
|
||
|
if `"`logsrc'"' == "logclose" {
|
||
|
CleanLogclose `rf' `wf'
|
||
|
}
|
||
|
else if `"`logsrc'"' == "sjlog" {
|
||
|
CleanSJLog `rf' `wf'
|
||
|
}
|
||
|
else if `"`logsrc'"' == "sjlogdo" {
|
||
|
CleanSJLogDo `rf' `wf'
|
||
|
}
|
||
|
else { /* Default: `"`logsrc'"' == "log" */
|
||
|
CleanLog `rf' `wf'
|
||
|
}
|
||
|
} // capture noisily
|
||
|
local rc = _rc
|
||
|
|
||
|
/* close files */
|
||
|
file close `wf'
|
||
|
file close `rf'
|
||
|
|
||
|
if (`rc') exit `rc'
|
||
|
|
||
|
/* make a backup copy of the input file (rf) and save the output file
|
||
|
* (wf) using the given filename
|
||
|
*/
|
||
|
|
||
|
local backup `file'.bak
|
||
|
copy `"`file'"' `"`backup'"', replace
|
||
|
copy `"`newfile'"' `"`file'"', replace
|
||
|
|
||
|
/* saved results */
|
||
|
return local fnbak `"`backup'"'
|
||
|
return local fn `"`file'"'
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by -sjlog do-.
|
||
|
*
|
||
|
* This subroutine has a 3 line buffer; the end of a log from -sjlog do- will
|
||
|
* always have:
|
||
|
*
|
||
|
* 1. a blank line
|
||
|
* 2. a line with the text: "."
|
||
|
* 3. a line with the text: "end of do-file"
|
||
|
*
|
||
|
* This subroutine also works with smcl files, and TeX files generated from
|
||
|
* smcl files using -log texman- (its original purpose).
|
||
|
*/
|
||
|
|
||
|
program define CleanSJLogDo
|
||
|
args rf wf
|
||
|
|
||
|
/* skip the smcl header lines */
|
||
|
file read `rf' line1
|
||
|
if `"`line1'"' == "{smcl}" {
|
||
|
file read `rf' line1
|
||
|
/* skip next line too, if is part of the smcl header */
|
||
|
if `"`line1'"' == "{com}{sf}{ul off}{txt}" {
|
||
|
file read `rf' line1
|
||
|
}
|
||
|
file read `rf' line2
|
||
|
}
|
||
|
else {
|
||
|
file read `rf' line2
|
||
|
}
|
||
|
|
||
|
file read `rf' line3
|
||
|
local break 0
|
||
|
while r(eof)==0 {
|
||
|
if substr(`"`line3'"',-14,.) == "end of do-file" {
|
||
|
local break 1
|
||
|
continue, break
|
||
|
}
|
||
|
file write `wf' `"`macval(line1)'"' _n
|
||
|
local line1 `"`macval(line2)'"'
|
||
|
local line2 `"`macval(line3)'"'
|
||
|
file read `rf' line3
|
||
|
}
|
||
|
if ! `break' {
|
||
|
file write `wf' `"`macval(line1)'"' _n
|
||
|
file write `wf' `"`macval(line2)'"' _n
|
||
|
}
|
||
|
else {
|
||
|
if !inlist(`"`macval(line1)'"',"{txt}","{res}{txt}") {
|
||
|
file write `wf' `"`macval(line1)'"' _n
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by -sjlog using- and -sjlog close-. */
|
||
|
|
||
|
program define CleanSJLog
|
||
|
args rf wf
|
||
|
|
||
|
CleanLogUsingHeader `rf'
|
||
|
|
||
|
/* skip the smcl header lines */
|
||
|
file read `rf' line1
|
||
|
if `"`line1'"' == "{smcl}" {
|
||
|
file read `rf' line1
|
||
|
/* skip next line too, if is part of the smcl header */
|
||
|
if `"`line1'"' == "{com}{sf}{ul off}{txt}" {
|
||
|
file read `rf' line1
|
||
|
}
|
||
|
file read `rf' line2
|
||
|
}
|
||
|
else {
|
||
|
file read `rf' line2
|
||
|
}
|
||
|
|
||
|
local break 0
|
||
|
while r(eof)==0 {
|
||
|
if index(`"`line2'"',". sjlog close") {
|
||
|
local break 1
|
||
|
continue, break
|
||
|
}
|
||
|
file write `wf' `"`macval(line1)'"' _n
|
||
|
local line1 `"`macval(line2)'"'
|
||
|
file read `rf' line2
|
||
|
}
|
||
|
if ! `break' | !inlist(`"`macval(line1)'"', "", "{res}{txt}") {
|
||
|
file write `wf' `"`macval(line1)'"' _n
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by Stata's -log using- and -log close- commands. */
|
||
|
|
||
|
program define CleanLog
|
||
|
args rf wf
|
||
|
|
||
|
CleanLogUsingHeader `rf'
|
||
|
|
||
|
file read `rf' line
|
||
|
local break 0
|
||
|
while r(eof)==0 {
|
||
|
/* stop when we encounter the -log close- command. */
|
||
|
if substr(`"`line'"',-11,.) == ". log close" {
|
||
|
local break 1
|
||
|
continue, break
|
||
|
}
|
||
|
file write `wf' `"`macval(line)'"' _n
|
||
|
file read `rf' line
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by Stata's -log using- command and -logclose-. */
|
||
|
|
||
|
program define CleanLogclose
|
||
|
args rf wf
|
||
|
|
||
|
CleanLogUsingHeader `rf'
|
||
|
|
||
|
file read `rf' line
|
||
|
local break 0
|
||
|
while r(eof)==0 {
|
||
|
/* stop when we encounter the -log close- command. */
|
||
|
if substr(`"`line'"',-10,.) == ". logclose" {
|
||
|
local break 1
|
||
|
continue, break
|
||
|
}
|
||
|
file write `wf' `"`macval(line)'"' _n
|
||
|
file read `rf' line
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Skip first 5 lines comprising the header output from -log using-. */
|
||
|
|
||
|
program define CleanLogUsingHeader
|
||
|
args rf
|
||
|
|
||
|
/* hline */
|
||
|
file read `rf' line
|
||
|
if `"`line'"' == "{smcl}" {
|
||
|
file read `rf' line
|
||
|
file read `rf' line
|
||
|
}
|
||
|
else if index(`"`line'"', "-----") {
|
||
|
file read `rf' line
|
||
|
}
|
||
|
if ! index(`"`line'"', "log:") {
|
||
|
file seek `rf' tof
|
||
|
exit
|
||
|
}
|
||
|
|
||
|
file read `rf' line
|
||
|
if ! index(`"`line'"', "log type:") {
|
||
|
file seek `rf' tof
|
||
|
exit
|
||
|
}
|
||
|
|
||
|
file read `rf' line
|
||
|
if ! index(`"`line'"', "opened on:") {
|
||
|
file seek `rf' tof
|
||
|
exit
|
||
|
}
|
||
|
|
||
|
/* blank line */
|
||
|
file read `rf' line
|
||
|
end
|
||
|
|
||
|
/* type: subroutines ********************************************************/
|
||
|
|
||
|
program define LogType, rclass
|
||
|
syntax anything(name=file id="filename") [, /*
|
||
|
*/ replace /*
|
||
|
*/ find /*
|
||
|
*/ path(passthru) /*
|
||
|
*/ LOGfile /*
|
||
|
*/ SMCLfile /*
|
||
|
*/ ]
|
||
|
|
||
|
LogSetup
|
||
|
|
||
|
if "`logfile'" == "" {
|
||
|
local logfile nologfile
|
||
|
}
|
||
|
StripQuotes file , string(`file')
|
||
|
if `"`find'"' != "" {
|
||
|
capture which findfile
|
||
|
if _rc {
|
||
|
di as err "option find requires Stata 8 or later"
|
||
|
exit 111
|
||
|
}
|
||
|
quietly findfile `"`file'"', `path'
|
||
|
local file `r(fn)'
|
||
|
}
|
||
|
|
||
|
LogBaseName `file'
|
||
|
local file `"`r(fn)'"'
|
||
|
local dbase `"`r(dir)'`r(base)'"'
|
||
|
local ext `"`r(ext)'"'
|
||
|
if ! inlist(`"`ext'"',".smcl",".hlp") {
|
||
|
local dbase `"`dbase'`ext'"'
|
||
|
}
|
||
|
|
||
|
capture noisily {
|
||
|
|
||
|
tempfile tt
|
||
|
LogOpen `tt'
|
||
|
type `"`file'"'
|
||
|
LogClose, noclean `logfile'
|
||
|
copy `"`tt'.log.tex"' `"`dbase'.log.tex"', `replace'
|
||
|
return local fn_tex `"`dbase'.log.tex"'
|
||
|
if "`logfile'" == "logfile" {
|
||
|
copy `"`tt'.log"' `"`dbase'.log"', `replace'
|
||
|
return local fn_log `"`dbase'.log"'
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
local rc = _rc
|
||
|
if "`smclfile'" != "" {
|
||
|
copy `"`tt'.smcl"' `"`dbase'.smcl"', `replace'
|
||
|
return local fn_smcl `"`dbase'.smcl"'
|
||
|
}
|
||
|
capture erase `"`tt'.smcl"'
|
||
|
capture erase `"`tt'.log.tex"'
|
||
|
exit `rc'
|
||
|
end
|
||
|
|
||
|
exit
|