Home
Manual
Packages
Global Index
Keywords
Quick Reference
|
func silo_open (filename)
/* DOCUMENT silo_open, filename
or silo= silo_open(filename)
open FILENAME for later use with silo_... functions
There is a single current silo file, which is opened and set
by the first form. The other silo_... functions normally
operate on this current file, but also accept a silo= keyword,
which is a list returned by the second calling sequence for
silo_open.
SEE ALSO: silo_cd, silo_ls, silo_var, silo_close
*/
{
f= openb(filename);
vars= *get_vars(f)(1);
nvars= numberof(vars);
mask= strpart(vars,0:0)=="/";
list= where(mask);
ndirs= numberof(list);
grow, vars, vars(list)+"\377\377\377"; /* mark end of each dir */
grow, mask, array(-1, ndirs);
order= sort(vars);
vars= vars(order);
mask= mask(order);
invrs= order;
invrs(order)= indgen(nvars+ndirs);
list= invrs(list);
ends= invrs(nvars+1:nvars+ndirs);
lens= array(0,nvars+ndirs);
order= (mask<0)(psum);
lens(list)= ends - list - order(ends) + order(list);
list= where(lens);
lens= lens(list);
depth= mask(psum);
depth(list)-= 1;
list= where(mask>=0);
vars= vars(list);
depth= depth(list);
list= where(mask(list));
list= _lst(f, vars, depth, list, lens, "/");
if (am_subroutine()) {
extern silo_list;
silo_list= list;
} else {
return list;
}
}
func silo_close (void, silo=)
/* DOCUMENT silo_close
close current silo file
SEE ALSO: silo_cd, silo_ls, silo_var, silo_open
*/
{
if (is_void(silo)) {
close, _car(silo_list, 1, []);
silo_list= [];
} else {
close, _car(silo, 1, []);
}
}
func silo_cd (dir, silo=)
/* DOCUMENT silo_cd, dirname
change current silo directory to DIRNAME, which may contain
.. or . constructs as a UNIX pathname
accepts silo= keyword to operate on a silo file other than the
current silo file
SEE ALSO: silo_ls, silo_var, silo_open, silo_close
*/
{
list= is_void(silo)? silo_list : silo;
if (strpart(dir,0:0)=="/") dir= strpart(dir,1:-1);
if (strpart(dir,1:1)!="/") dir= _car(list,6) + dir;
dir= silo_simplify(dir) + "/";
if (dir=="//") dir= "/";
lst= where(dir==_car(list, 2)(_car(list, 4)));
if (!numberof(lst)) {
if (am_subroutine()) error, "no such directory as: "+dir;
return string(0);
}
_car, list, 6, dir;
return dir;
}
func silo_var (var, silo=)
/* DOCUMENT var= silo_var(varname)
return silo variable VARNAME
accepts silo= keyword to operate on a silo file other than the
current silo file
SEE ALSO: silo_ls, silo_cd, silo_open, silo_close
*/
{
list= is_void(silo)? silo_list : silo;
if (strpart(var,1:1)!="/") var= _car(list,6) + var;
return get_member(_car(list,1),silo_simplify(var));
}
func silo_ls (name, &dirname, silo=)
/* DOCUMENT silo_ls
or silo_ls, dirname
or itemlist= silo_ls(dirname)
or itemlist= silo_ls(dirname, fulldirname)
list current silo directory or DIRNAME
if called as a function, returns a 1D array of strings beginning
with ".", and optionally returns FULLDIRNAME, which is the
full path name of the directory listed
- the individual items in the list do not include the
directory path
- subdirectory names end with "/", so you can find them
using strpart(itemlist,0:0)=="/"
accepts silo= keyword to operate on a silo file other than the
current silo file
SEE ALSO: silo_ls, silo_cd, silo_open, silo_close
*/
{
list= is_void(silo)? silo_list : silo;
if (is_void(name)) name= ".";
if (strpart(name,0:0)=="/") name= strpart(name,1:-1);
if (strpart(name,1:1)!="/") name= _car(list,6) + name;
name= silo_simplify(name) + "/";
if (name=="//") name= "/";
local vars, lens;
eq_nocopy, vars, _car(list, 2);
eq_nocopy, depth, _car(list, 3);
eq_nocopy, lens, _car(list, 5);
eq_nocopy, list, _car(list, 4);
lst= where(name==vars(list));
if (!numberof(lst)) {
if (am_subroutine()) write, "no such directory as: "+name;
return [];
}
lst= lst(1);
lens= lens(lst);
list= list(lst);
vars= vars(list:list+lens);
depth= depth(list:list+lens);
dirname= vars(1); /* full directory name */
vars(1)= ".";
if (numberof(vars)>1) {
depth(1)+= 1;
vars= vars(where(depth==depth(1)));
lens= strlen(dirname);
if (numberof(vars)>1) vars(2:0)= strpart(vars(2:0),lens+1:0);
}
if (am_subroutine()) write, format=" %s\n", vars;
return vars;
}
func silo_simplify (dir)
{
if (strmatch(dir,"/.")) {
parts= array(string, 1000);
parse= strtok(dir, "/");
for (tok=parse(1),i=0 ; tok ; tok=parse(1)) {
if (tok!=".") {
if (tok=="..") i= max(0, i-1);
else parts(++i)= tok;
}
parse= strtok(parse(2), "/");
}
dir= i? "" : "/";
for (j=1 ; j<=i ; j++) dir+= "/"+parts(j);
}
return dir;
}
|