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.
570 lines
12 KiB
Plaintext
570 lines
12 KiB
Plaintext
9 months ago
|
*! version 1.1.13 06may2003
|
||
|
program define sjlog_7
|
||
|
version 7
|
||
|
local vv : di "version " _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" {
|
||
|
`vv' LogDo `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 7.0
|
||
|
local vv : display "version " _caller() ":"
|
||
|
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 {
|
||
|
initMacros
|
||
|
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'
|
||
|
}
|
||
|
}
|
||
|
local rc = _rc
|
||
|
|
||
|
/* close files */
|
||
|
file close `wf'
|
||
|
file close `rf'
|
||
|
|
||
|
removeMacros `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
|
||
|
|
||
|
program define initMacros
|
||
|
global SJL_maxn 10
|
||
|
global SJL_n 0
|
||
|
global SJL_parity 0
|
||
|
end
|
||
|
|
||
|
program define removeMacros
|
||
|
args rc
|
||
|
|
||
|
if "$SJL_parity" != "0" & "$SJL_parity" != "" {
|
||
|
di as err "$SJL_parity nonempty global macros"
|
||
|
forval i = 1/$SJL_maxn {
|
||
|
if `"${SJL_`i'}"' != "" {
|
||
|
di _asis as txt /*
|
||
|
*/ `"SJL_`i' is |${SJL_`i'}{reset}{text}|"'
|
||
|
}
|
||
|
global SJL_`i'
|
||
|
}
|
||
|
if ! `rc' {
|
||
|
local rc 459
|
||
|
}
|
||
|
}
|
||
|
global SJL_parity
|
||
|
global SJL_maxn
|
||
|
global SJL_n
|
||
|
|
||
|
exit `rc'
|
||
|
end
|
||
|
|
||
|
program define removeLine
|
||
|
args line
|
||
|
|
||
|
global `line'
|
||
|
/* decrease number of lines read */
|
||
|
global SJL_parity = $SJL_parity - 1
|
||
|
end
|
||
|
|
||
|
program define FileRead
|
||
|
args hh c_line
|
||
|
|
||
|
/* read in line */
|
||
|
file read `hh' rline
|
||
|
|
||
|
/* increase number of lines read */
|
||
|
local n = mod($SJL_n,$SJL_maxn) + 1
|
||
|
|
||
|
/* increase parity index */
|
||
|
global SJL_parity = $SJL_parity + 1
|
||
|
|
||
|
/* escape quotes */
|
||
|
local qline : /*
|
||
|
*/ subinstr local rline "\`" "\\\`" , all count(local qc)
|
||
|
|
||
|
/* escape dollars */
|
||
|
global SJL_`n' : /*
|
||
|
*/ subinstr local qline "\$" "\\\$" , all count(local dc)
|
||
|
|
||
|
/* return name of global macro containing new line */
|
||
|
c_local `c_line' SJL_`n'
|
||
|
|
||
|
/* save number of lines read */
|
||
|
global SJL_n `n'
|
||
|
end
|
||
|
|
||
|
program define FileWrite
|
||
|
args hh line
|
||
|
|
||
|
/* write contents of global to file */
|
||
|
file write `hh' `"${`line'}"' _n
|
||
|
|
||
|
removeLine `line'
|
||
|
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 */
|
||
|
FileRead `rf' line1
|
||
|
if `"${`line1'}"' == "{smcl}" {
|
||
|
/* skip next line too, it is part of the smcl header */
|
||
|
removeLine `line1'
|
||
|
FileRead `rf' line1
|
||
|
removeLine `line1'
|
||
|
}
|
||
|
else {
|
||
|
FileWrite `wf' `line1'
|
||
|
}
|
||
|
|
||
|
FileRead `rf' line1
|
||
|
FileRead `rf' line2
|
||
|
local break 0
|
||
|
while r(eof)==0 {
|
||
|
if substr(`"${`line2'}"',-14,.) == "end of do-file" {
|
||
|
local break 1
|
||
|
continue, break
|
||
|
}
|
||
|
FileWrite `wf' `line1'
|
||
|
local line1 `line2'
|
||
|
FileRead `rf' line2
|
||
|
}
|
||
|
if ! `break' {
|
||
|
FileWrite `wf' `line1'
|
||
|
removeLine `line2'
|
||
|
}
|
||
|
else {
|
||
|
removeLine `line1'
|
||
|
removeLine `line2'
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by -sjlog using- and -sjlog close-. */
|
||
|
|
||
|
program define CleanSJLog
|
||
|
args rf wf
|
||
|
|
||
|
CleanLogUsingHeader `rf'
|
||
|
|
||
|
/* skip the smcl header lines */
|
||
|
FileRead `rf' line1
|
||
|
if `"${`line1'}"' == "{smcl}" {
|
||
|
/* skip next line too, it is part of the smcl header */
|
||
|
removeLine `line1'
|
||
|
FileRead `rf' line1
|
||
|
removeLine `line1'
|
||
|
}
|
||
|
else {
|
||
|
FileWrite `wf' `line1'
|
||
|
}
|
||
|
|
||
|
FileRead `rf' line1
|
||
|
FileRead `rf' line2
|
||
|
local break 0
|
||
|
while r(eof)==0 {
|
||
|
if index(`"${`line2'}"',". sjlog close") {
|
||
|
local break 1
|
||
|
continue, break
|
||
|
}
|
||
|
FileWrite `wf' `line1'
|
||
|
local line1 `line2'
|
||
|
FileRead `rf' line2
|
||
|
}
|
||
|
if ! `break' {
|
||
|
FileWrite `wf' `line1'
|
||
|
removeLine `line2'
|
||
|
}
|
||
|
else {
|
||
|
removeLine `line1'
|
||
|
removeLine `line2'
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by Stata's -log using- and -log close- commands. */
|
||
|
|
||
|
program define CleanLog
|
||
|
args rf wf
|
||
|
|
||
|
CleanLogUsingHeader `rf'
|
||
|
|
||
|
FileRead `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
|
||
|
}
|
||
|
FileWrite `wf' `line'
|
||
|
FileRead `rf' line
|
||
|
}
|
||
|
if `break' {
|
||
|
removeLine `line'
|
||
|
}
|
||
|
end
|
||
|
|
||
|
/* Clean log produced by Stata's -log using- command and -logclose-. */
|
||
|
|
||
|
program define CleanLogclose
|
||
|
args rf wf
|
||
|
|
||
|
CleanLogUsingHeader `rf'
|
||
|
|
||
|
FileRead `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
|
||
|
}
|
||
|
FileWrite `wf' `line'
|
||
|
FileRead `rf' line
|
||
|
}
|
||
|
if `break' {
|
||
|
removeLine `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
|
||
|
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
|
||
|
syntax anything(name=file id="filename") [, /*
|
||
|
*/ replace /*
|
||
|
*/ find /*
|
||
|
*/ path(passthru) /*
|
||
|
*/ logfile /*
|
||
|
*/ ]
|
||
|
|
||
|
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'
|
||
|
if "`logfile'" == "logfile" {
|
||
|
copy `"`tt'.log"' `"`dbase'.log"', `replace'
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
local rc = _rc
|
||
|
capture erase `"`tt'.smcl"'
|
||
|
capture erase `"`tt'.log.tex"'
|
||
|
exit `rc'
|
||
|
end
|
||
|
|
||
|
exit
|