📄 checkhlpfiles.ado
字号:
drop _merge
sort hfn
merge hfn using "`noref'", nokeep
drop if _merge==3
drop _merge
rename hfn ref
}
di as txt "{title:`title': exist but not referenced}"
di as txt " (hlpnotused.maint references removed)"
list ref
}
restore, preserve
qui count if _merge==1
if r(N) {
quietly {
keep if _merge==1
drop _merge
sort ref
rename ref hfn
merge hfn using "`noref'", nokeep
keep if _merge==3
drop _merge
rename hfn ref
}
if _N {
di as txt
di as txt ///
"{title:`title': referenced but should not be}"
list ref
}
}
end
program CheckHlpFile, rclass
args hfn hlpdta path refed_o refed_y
ret scalar leaf = 0
GetFFN ffn : `"`path'"' "`hfn'"
ReadHlpFile `"`path'"' "`hfn'"
/* Extract `"`ffn'"' "help" "helpb" <-- replaced with next line */
ExtractHlp `"`ffn'"'
CleanHlpArg
UpdateRef "`hfn'" "`refed_o'" "`refed_y'"
if _N==0 {
ret scalar leaf = 1
exit
}
quietly {
sort ref
by ref: keep if _n==1
merge ref using "`hlpdta'", nokeep
drop if _merge==3
}
if _N==0 {
exit
}
sort ref
di as txt _n as res `"`ffn': "' ///
as txt "unmatched help references:"
list ref
end
program UpdateRef
args hfn ref_o ref_y
if _N==0 {
exit
}
preserve
quietly {
if substr("`hfn'",1,2)=="y_" | "`hfn'"=="contents.hlp" {
local fn "`ref_y'"
}
else local fn "`ref_o'"
append using "`fn'"
sort ref
by ref: keep if _n==1
save "`fn'", replace
}
end
program CleanHlpArg
if _N==0 {
exit
}
// if first and last chars are double quotes, drop them
quietly replace ref = substr(ref,2,length(ref)-2) ///
if substr(ref,1,1) == `"""' & substr(ref,-1,1) == `"""'
// this allows things like "help r(2)" or "help r(663)"
// and strips the "r(663)" to just "663"
tempvar x
quietly {
replace ref=lower(ref)
gen `x' = substr(ref,1,2)=="r(" & substr(ref,-1,1)==")"
replace ref = substr(ref,3,.) if `x'
replace ref = substr(ref, 1, length(ref)-1) if `x'
replace ref = substr(ref,2,.) if substr(ref,1,1)=="#"
compress ref
sort ref
by ref: keep if _n==1
}
// drop any "|" and whatever follows it
quietly {
replace `x' = strpos(ref,"|")
replace ref = substr(ref,1,`x'-1) if `x'
}
// drop any "##" and whatever follows it
// (maybe someday make this more sophisticated so it verifies markers
// instead of ignoring the markers)
quietly {
replace `x' = strpos(ref,"##")
replace ref = substr(ref,1,`x'-1) if `x'
}
// Change "mata whatever()" to "mf_whatever"
quietly {
replace `x' = substr(ref,1,5)=="mata " & substr(ref,-2,2)=="()"
replace ref = "mf_" + substr(ref,6,length(ref)-7) if `x'
}
// Change "whatever()" to "f_whatever"
quietly {
replace `x' = substr(ref,-2,2)=="()"
replace ref = "f_" + substr(ref,1,length(ref)-2) if `x'
}
// replace colon and 1 or 2 spaces combo with single underscore
qui replace ref=subinstr(ref,": ","_",.)
qui replace ref=subinstr(ref,": ","_",.)
// replace colon with underscore
qui replace ref=subinstr(ref,":","_",.)
// replace space with underscore
qui replace ref=subinstr(ref," ","_",.)
// replace dash with underscore
qui replace ref=subinstr(ref,"-","_",.)
// replace % with nothing if in first position (think of %fmt)
qui replace ref=substr(ref,2,.) if substr(ref,1,1)=="%"
end
program ExtractHlp
args ffn
quietly {
gen lino = _n
gen str1 ref = ""
gen byte used = 0
while (1) {
gen int pos1 = strpos(contents,"{help ") if used==0
gen int pos2 = strpos(contents,"{helpb ") if used==0
gen int pos3 = strpos(contents,"{manhelp ") if used==0
gen int pos4 = strpos(contents,"{manhelpi ") if used==0
gen int pos5 = strpos(contents,"{opth ") if used==0
replace pos1 = 32700 if pos1==0 & used==0
replace pos2 = 32700 if pos2==0 & used==0
replace pos3 = 32700 if pos3==0 & used==0
replace pos4 = 32700 if pos4==0 & used==0
replace pos5 = 32700 if pos5==0 & used==0
gen int pos = min(pos1,pos2,pos3,pos4,pos5) if used==0
replace pos = 0 if pos==32700 & used==0
keep if used | pos
if _N==0 {
drop _all
exit
}
capture assert used==1
if _rc==0 {
keep ref
compress
exit
}
gen int len=0 if used==0
gen byte kind=0 if used==0
replace kind=1 if strpos(contents,"{help ")==pos ///
& pos & used==0
replace len=6 if strpos(contents,"{help ")==pos ///
& pos & used==0
replace kind=1 if strpos(contents,"{helpb ")==pos ///
& pos & used==0
replace len=7 if strpos(contents,"{helpb ")==pos ///
& pos & used==0
replace kind=2 if strpos(contents,"{manhelp ")==pos ///
& pos & used==0
replace len=9 if strpos(contents,"{manhelp ")==pos ///
& pos & used==0
replace kind=2 if strpos(contents,"{manhelpi ")==pos ///
& pos & used==0
replace len=10 if strpos(contents,"{manhelpi ")==pos ///
& pos & used==0
replace kind=3 if strpos(contents,"{opth ")==pos ///
& pos & used==0
replace len=6 if strpos(contents,"{opth ")==pos ///
& pos & used==0
replace contents=trim(substr(contents,pos+len,.)) ///
if used==0
replace pos = strpos(contents, "}") if used==0
gen byte bad = pos==0 & used==0
ReportError `"`ffn'"' bad lino "no close brace"
drop if bad
drop bad
// for now ref gets everything up to closing brace
replace ref=trim(substr(contents,1,pos-1)) if used==0
// and contents gets whatever is left after it
replace contents = trim(substr(contents,pos+1,.)) ///
if used==0
// ---------------------------------------------------
// deal with kind==1 (help and helpb)
// now we trim any excess from ref
// For instance whatever:clickme
// should have the colon and clickme trimmed off
// However, with something like
// "svy: regress":click me
// we should skip over the quoted part and trim the
// second colon and what follows it.
gen int col2 = 1 if used==0 & kind==1
replace col2 = strpos(substr(ref,2,.),`"""') ///
if substr(ref,1,1)==`"""' & used==0 & kind==1
gen byte bad = col2==0 & used==0 & kind==1
ReportError ///
`"`ffn'"' bad lino "open quote without close quote"
drop if bad
drop bad
replace col2 = col2+2 ///
if substr(ref,1,1)==`"""' & used==0 & kind==1
gen str tmp = substr(ref,col2,.) if used==0 & kind==1
replace ref = substr(ref,1,col2-1) if used==0 & kind==1
replace col2 = strpos(tmp, ":") if used==0 & kind==1
replace col2 = strlen(tmp)+1 ///
if col2==0 & used==0 & kind==1
replace ref = ref + substr(tmp,1,col2-1) ///
if used==0 & kind==1
drop col2 tmp
// ---------------------------------------------------
// deal with kind==2 (manhelp and manhelpi)
gen int col2 = 1 if used==0 & kind==2
replace col2 = strpos(substr(ref,2,.),`"""') ///
if substr(ref,1,1)==`"""' & used==0 & kind==2
gen byte bad = col2==0 & used==0 & kind==2
ReportError ///
`"`ffn'"' bad lino "open quote without close quote"
drop if bad
drop bad
replace col2 = col2+2 ///
if substr(ref,1,1)==`"""' & used==0 & kind==2
replace col2 = strpos(ref," ") ///
if col2==1 & used==0 & kind==2
replace ref = substr(ref,1,col2-1) if used==0 & kind==2
drop col2
// ---------------------------------------------------
// deal with kind==3 (opth)
gen int col1 = strpos(ref,"(") if used==0 & kind==3
gen int col2 = strpos(ref,")") if used==0 & kind==3
gen byte bad = col1==0 & used==0 & kind==3
ReportError ///
`"`ffn'"' bad lino "missing opening paren in opth"
drop if bad
drop bad
gen byte bad = col2==0 & used==0 & kind==3
ReportError ///
`"`ffn'"' bad lino "missing closing paren in opth"
drop if bad
drop bad
gen byte bad = col2<col1 & used==0 & kind==3
ReportError `"`ffn'"' bad lino ///
"closing paren before opening in opth"
drop if bad
drop bad
replace ref = trim(substr(ref,col1+1,col2-col1-1)) ///
if used==0 & kind==3
// with kind==3 we now have the insides of the parens
// kill off colon and after if not quoted at first
gen int colpos = strpos(ref,":") ///
if substr(ref,1,1)!=`"""' & used==0 & kind==3
replace ref = substr(ref,1,colpos-1) ///
if substr(ref,1,1)!=`"""' ///
& used==0 & kind==3 & colpos!=0
// keep inside part of quoted part if quoted at first
replace ref = substr(ref,2, ///
strpos(substr(ref,2,.),`"""')-1) ///
if substr(ref,1,1)==`"""' & used==0 & kind==3
drop col1 col2 colpos
//----------------------------------------------------
local n = _N
expand 2 if used==0
replace contents="" if used==0 in 1/`n'
replace used = 1 if used==0 in 1/`n'
if `n' < _N {
replace ref="" in `++n'/l
}
drop pos1 pos2 pos3 pos4 pos5 pos len kind
}
}
/*NOTREACHED*/
end
program Extract
args ffn smcla smclb
local lena = length("`smcla'")
if "`smclb'" != "" {
local lenb = length("`smclb'")
}
quietly {
gen lino = _n
gen str1 ref = ""
gen byte used = 0
while (1) {
gen int cola = strpos(contents,"{`smcla' ") if used==0
if "`smclb'" != "" {
gen int colb = strpos(contents,"{`smclb' ") ///
if used==0
}
gen int len = 0 if used==0
gen int col = cola if used==0
replace len = `lena' if cola & used==0
if "`smclb'" != "" {
replace col = colb ///
if colb & (!cola | colb<cola) & used==0
replace len = `lenb' ///
if colb & (!cola | colb<cola) & used==0
}
keep if used | col
if _N==0 {
drop _all
exit
}
capture assert used==1
if _rc==0 {
keep ref
compress
exit
}
replace contents= ///
trim(substr(contents, col+len+2, .)) ///
if used==0
replace col = strpos(contents, "}") if used==0
gen byte bad = col==0 & used==0
ReportError `"`ffn'"' bad lino "no close brace"
drop if bad
drop bad
// for now ref gets everything up to closing brace
replace ref = trim(substr(contents,1,col-1)) ///
if used==0
// and contents gets whatever is left after it
replace contents = trim(substr(contents,col+1,.)) ///
if used==0
// now we trim any excess from ref
// For instance whatever:clickme
// should have the colon and clickme trimmed off
// However, with something like
// "svy: regress":click me
// we should skip over the quoted part and trim the
// second colon and what follows it.
gen col2 = 1 if used == 0
replace col2 = strpos(substr(ref,2,.),`"""') ///
if substr(ref,1,1)==`"""' & used==0
gen byte bad = col2==0 & used==0
ReportError ///
`"`ffn'"' bad lino "open quote without close quote"
drop if bad
drop bad
replace col2 = col2+2 ///
if substr(ref,1,1)==`"""' & used==0
gen str tmp = substr(ref,col2,.) if used==0
replace ref = substr(ref,1,col2-1) if used==0
replace col2 = strpos(tmp, ":") if used==0
replace col2 = strlen(tmp)+1 if col2==0 & used==0
replace ref = ref + substr(tmp,1,col2-1) if used==0
local n = _N
expand 2 if used==0
replace contents="" if used==0 in 1/`n'
replace used = 1 if used==0 in 1/`n'
if `n' < _N {
replace ref="" in `++n'/l
}
drop col col2 tmp cola len
capture drop colb
}
}
/*NOTREACHED*/
end
program ExtractColon
args ffn smclcmd
local len = length("`smclcmd'")
quietly {
gen lino = _n
gen str1 ref = ""
gen byte used = 0
while (1) {
gen int col = strpos(contents, "{`smclcmd':") if used==0
keep if used | col
if _N==0 {
drop _all
exit
}
capture assert used==1
if _rc==0 {
keep ref
compress
exit
}
replace contents= ///
trim(substr(contents, col+`len'+2, .)) ///
if used==0
replace col = strpos(contents, "}") if used==0
gen byte bad = col==0 & used==0
ReportError `"`ffn'"' bad lino "no close brace"
drop if bad
drop bad
replace ref = trim(substr(contents,1,col-1)) ///
if used==0
replace contents = trim(substr(contents,col+1,.)) ///
if used==0
local n = _N
expand 2 if used==0
replace contents="" if used==0 in 1/`n'
replace used = 1 if used==0 in 1/`n'
if `n' < _N {
replace ref="" in `++n'/l
}
drop col
}
}
/*NOTREACHED*/
end
program ReportError
args hfn bad tolist msg
capture assert `bad'==0
if _rc==0 {
exit
}
preserve
di as txt _n `"`msg'"'
keep if `bad'
list `tolist'
end
program GetFFN
args ffn colon path fn
if "`colon'" != ":" {
exit 198
}
qui findfile "`fn'", path("`path'")
c_local `ffn' `"`r(fn)'"'
end
program ReadHlpFile
args path hfn
GetFFN ffn : `"`path'"' "`hfn'"
quietly {
drop _all
infix str contents 1-240 using `"`ffn'"'
compress
}
end
program MakeHlpFileDataset
local n : word count `0'
quietly {
drop _all
set obs `n'
gen str1 hfn = ""
local i 1
foreach el of local 0 {
replace hfn = `"`el'"' in `i++'
}
gen i = strpos(hfn, ".hlp")
replace hfn = substr(hfn, 1, i-1) if i
drop i
sort hfn
}
end
program MakeDlgFileDataset
local n : word count `0'
quietly {
drop _all
set obs `n'
gen str1 dfn = ""
local i 1
foreach el of local 0 {
replace dfn = `"`el'"' in `i++'
}
gen i = strpos(dfn, ".dlg")
replace dfn = substr(dfn, 1, i-1) if i
drop i
sort dfn
}
end
program GetAliases, rclass
args result colon path
tempfile afile
ReadHlpFile `"`path'"' _help_alias.maint
qui save `"`afile'"'
foreach ltr in a b c d e f g h i j k l m n o p q r s t u v w x y z {
ReadHlpFile `"`path'"' `ltr'help_alias.maint
qui append using `"`afile'"'
qui save `"`afile'"', replace
}
quietly {
gen str alias = trim(word(contents,1))
keep alias
}
local n = _N
forvalues i=1(1)`n' {
local el = alias[`i']
local list `list' `el'
}
qui drop _all
c_local `result' `list'
local na : word count `list'
ret scalar n = `na'
di as txt "(`na' aliases)"
end
program GetFiles, rclass
args result colon suffix path
local subdirs "_ a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9"
gettoken d path : path, parse(" ;")
while `"`d'"' != "" {
if `"`d'"' != ";" {
local d : sysdir `"`d'"'
capture local x : dir "`d'" files "*`suffix'"
if _rc==0 {
local list : list list | x
}
foreach l of local subdirs {
capture local x : dir "`d'`l'" files "*`suffix'"
if _rc==0 {
local list : list list | x
}
}
}
gettoken d path : path, parse(" ;")
}
local list : list clean list
c_local `result' : list sort list
local n : word count `list'
ret scalar n = `n'
di as txt "(`n' `suffix' files)"
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -