#!/usr/local/bin/ulpc |
|
int errs=0; |
|
mapping efuns = all_efuns(); |
mapping pages = ([]); |
list see_also = (<>); |
|
inherit "/precompiled/regexp" : reg1; |
|
void read_page(string fname, string path) |
{ |
int headno; |
string cont, section, name, part; |
|
cont=read_bytes(path); |
if(sscanf(cont,"NAME\n\t%s -",name)) |
{ |
if((name/"/")[-1] != fname) |
{ |
perror("File name != header name for "+path+".\n"); |
errs++; |
} |
|
if(efuns[name]) |
{ |
if(pages[name]) |
{ |
perror("Double docs for "+name+" ("+pages[name]+" and "+path+")\n"); |
errs++; |
} |
pages[name]=path; |
} |
|
int partno; |
foreach(explode(cont,"============================================================================\n"),part) |
{ |
list headers = (<>); |
partno++; |
|
if(!strlen(part)) continue; |
|
foreach(explode(part,"\n\n"), section) |
{ |
if(!strlen(section)) continue; |
if(section[0]>='A' && section[0]<='Z') |
{ |
string type, rest, a, b; |
headno++; |
if(!sscanf(section,"%s\n%s",type,rest)) |
{ |
perror("Couldn't read header name in header "+headno+" in "+path+" part "+partno+".\n"); |
errs++; |
continue; |
} |
|
if(!strlen(section)) |
{ |
perror("Header "+type+" in "+path+" part "+partno+" empty.\n"); |
errs++; |
} |
|
if(headers[type]) |
{ |
perror("Double "+type+" in "+path+" part "+partno+".\n"); |
errs++; |
} |
|
headers[type]=1; |
|
if(reg1::match(rest)) |
{ |
perror("Header "+type+" in "+path+" part "+partno+" not properly indented.\n"); |
errs++; |
} |
|
switch(type) |
{ |
case "NAME": |
if(sscanf(rest,"\t%s - %s",a,b)!=2) |
{ |
perror("Error in header "+type+" in "+path+" part "+partno+".\n"); |
errs++; |
} |
if(sscanf(b,"%*s\n")) |
{ |
perror("NAME header is more than one line in header "+type+" in "+path+" part "+partno+".\n"); |
errs++; |
} |
break; |
|
case "SEE ALSO": |
rest=replace(rest,({"\n",",","\t"}),({" "," "," "})); |
see_also|=mklist((rest/" ")-({" "})); |
} |
} |
} |
|
if(!headers["NAME"]) |
{ |
perror(path+" part "+partno+" is missing NAME header.\n"); |
errs++; |
} |
|
if(!headers["DESCRIPTION"]) |
{ |
perror(path+" part "+partno+" is missing DESCRIPTION header.\n"); |
errs++; |
} |
|
if(efuns[name]) |
{ |
if(!headers["SYNTAX"]) |
{ |
perror(path+" is missing SYNTAX header.\n"); |
errs++; |
} |
} |
} |
} |
} |
|
void traversedir(string path) |
{ |
string file; |
foreach(get_dir(path) - ({"CVS","RCS"}),file) |
{ |
string tmp; |
if(file[-1]=='~') continue; |
if(file[0]=='#' && file[-1]=='#') continue; |
if(file[0]=='.' && file[1]=='#') continue; |
|
tmp=path+"/"+file; |
|
if(file_size(tmp)==-2) |
{ |
traversedir(tmp); |
}else{ |
read_page(file,tmp); |
|
if(pages[file]) |
{ |
}else{ |
} |
} |
} |
} |
|
int main(int argc, string *argv) |
{ |
string fun; |
|
if(argc < 2) |
{ |
perror("Usage: verifymanual.lpc <dir with manuals>\n"); |
exit(1); |
} |
|
reg1::create("\n[^\t]"); |
traversedir(argv[1]); |
foreach(m_indices(efuns - pages), fun) |
{ |
errs++; |
perror("No page for efun "+fun+".\n"); |
} |
|
exit(errs); |
} |
|