*! c v2.0.1 Nicholas Winter 29oct2002 program define c version 7.0 args a b local x : sysdir PERSONAL local file `"`x'directoryfile.txt"' tempname hdl cap confirm file `"`file'"' if !_rc { /* file exists -- read in the database */ capture file open `hdl' using `"`file'"' , text read if _rc==199 { di as error "Your Stata does not recognize the {cmd:file} command," di as error "probably because it is not up to date. Please" di as error "{help update} your copy of Stata and try again." exit 198 } else if _rc { error _rc } file read `hdl' line local i 0 while !r(eof) { local i=`i'+1 tokenize `"`line'"', parse("*") local key`i' `1' local dir`i' `"`3'"' file read `hdl' line } file close `hdl' } else { /* file not there */ if !("`a'"=="cur" & `"`b'"'!="") { di as error `"no database - type "c cur {it:code}" to add the current directory"' exit } local i 0 } if `"`a'"'!="" & `"`b'"'=="" { /* just a code */ local j 1 while `"`key`j''"'!=`"`a'"' & `j'<=`i' { local j=`j'+1 } if `"`key`j''"'==`"`a'"' { cd `"`dir`j''"' exit } else { di as error `"`a' is not in database"' di /* will skip to end and display the database */ local a local b } } if `"`a'"'=="cur" { if `"`b'"'=="" { di as error "must specify code to add the current directory to the database" exit 198 } forval j=1/`i' { if `"`key`j''"'==`"`b'"' { di as error `"`b' is already a code in the database"' di as error `"use "c drop `b'" to drop it"' exit 198 } } local i=`i'+1 local newdir : pwd local key`i' `b' local dir`i' `"`newdir'"' forval j=1/`i' { local list1 "`list1' `key`j''" local list2 `"`list2' "`dir`j''""' } SortEm , list1(`list1') list2(`list2') stub1(key) stub2(dir) file open `hdl' using `"`file'"', text write replace forval j=1/`i' { file write `hdl' `"`key`j''*`dir`j''"' _n } file close `hdl' di `"{res}{ralign 20:`b'}{txt}: `newdir'"' exit } if `"`a'"'=="drop" { if `"`b'"'=="" { di as error "must specify code to drop" exit 198 } file open `hdl' using `"`file'"', text write replace forval j=1/`i' { if `"`key`j''"'!=`"`b'"' { file write `hdl' `"`key`j''*`dir`j''"' _n } } file close `hdl' exit } * if `"`a'"'=="sort" { * forval j=1/`i' { * local list1 "`list1' `key`j''" * local list2 `"`list2' "`dir`j''""' * } * SortEm , list1(`list1') list2(`list2') stub1(key) stub2(dir) * * file open `hdl' using `"`file'"', text write replace * forval j=1/`i' { * local space = 19-length(`"`key`j''"') * di `"{p 0 23}{space `space'}{stata c `key`j'':`key`j''} {txt}`dir`j''{p_end}"' * file write `hdl' `"`key`j''*`dir`j''"' _n * } * file close `hdl' * SInst * exit * } if `"`a'"'=="" & `"`b'"'=="" { forval j=1/`i' { local space = 19-length(`"`key`j''"') di `"{p 0 23}{space `space'}{stata c `key`j'':`key`j''} {txt}`dir`j''{p_end}"' } SInst } end program program define SInst di di in y " c {it:code} " in g "to change directories" di in y " c cur {it:code} " in g "to add current directory to database" di in y " c drop {it:code} " in g "to drop entry" end program define SortEm version 7 syntax , list1(string) list2(string asis) stub1(string) stub2(string) local n : word count `list1' local n0 : word count `list2' if `n0' ~= `n' { di in re "number of words in lists 1 and `m' differ" exit 198 } local direct "<" forval i=1/`n' { local key`i' "`i'" } * define macros 1..n from list1 tokenize `"`list1'"' * non-recursive quicksort (Wirth 1976: 80, with modification p 82) local s 1 local stl_1 1 /* stack[s].l == stl_s */ local str_1 `n' /* stack[s].r == str_s */ while `s' > 0 { /* take top request from stack */ local l `"`stl_`s''"' local r `"`str_`s''"' local s = `s'-1 while `l' < `r' { /* split key[l] ... key[r] */ local i `l' local j `r' local ix = int((`l'+`r')/2) local x `"``key`ix'''"' while `i' <= `j' { while `"``key`i'''"' `direct' `"`x'"' { local i = `i'+1 } while `"`x'"' `direct' `"``key`j'''"' { local j = `j'-1 } if `i' <= `j' { /* swap keys for elements i and j */ local tmp `"`key`i''"' local key`i' `"`key`j''"' local key`j' `"`tmp'"' local i = `i'+1 local j = `j'-1 } } * stack request to sort either left or right partition if `j'-`l' < `r'-`i' { if `i' < `r' { /* sort right partition */ local s = `s'+1 local stl_`s' `i' local str_`s' `r' } local r `j' } else { if `l' < `j' { /* sort left partition */ local s = `s'+1 local stl_`s' `l' local str_`s' `j' } local l `i' } } /* while l < r */ } * apply sort ordering, leaving results in caller's locals forval i=1/`n' { c_local `stub1'`i' "``key`i'''" } tokenize `"`list2'"' forval i=1/`n' { c_local `stub2'`i' "``key`i'''" } end *end&