2974bc | 1997-11-10 | Mirar (Pontus Hagland) | |
import Stdio;
import Array;
mapping parse=([]);
int illustration_counter;
#define error(X) throw( ({ (X), backtrace()[0..sizeof(backtrace())-2] }) )
mapping moduleM, classM, methodM, argM, nowM, descM;
mapping focM(mapping dest,string name,int line)
{
return dest[name] || (dest[name]=(["_line":line]));
}
string stripws(string s)
{
sscanf(s,"%*[ \t\n\r]%s",s);
s=reverse(s);
sscanf(s,"%*[ \t\n\r]%s",s);
return reverse(s);
}
mapping lower_nowM()
{
if (nowM &&
(nowM==parse
|| nowM==classM
|| nowM==methodM
|| nowM==moduleM)) return nowM;
else return nowM=methodM;
}
void report(string s)
{
stderr->write(s+"\n");
}
#define complain(X) (X)
mapping keywords=
(["module":lambda(string arg,int line)
{ classM=descM=nowM=moduleM=focM(parse,stripws(arg),line);
methodM=0;
if (!nowM->classes) nowM->classes=([]);
if (!nowM->modules) nowM->modules=([]);
report("module "+arg); },
"class":lambda(string arg,int line)
{ if (!moduleM) return complain("class w/o module");
descM=nowM=classM=focM(moduleM->classes,stripws(arg),line);
methodM=0; report("class "+arg); },
"submodule":lambda(string arg,int line)
{ if (!moduleM) return complain("submodule w/o module");
classM=descM=nowM=moduleM=focM(moduleM->modules,stripws(arg),line);
methodM=0;
if (!nowM->classes) nowM->classes=([]);
if (!nowM->modules) nowM->modules=([]);
report("submodule "+arg); },
"method":lambda(string arg,int line)
{ if (!classM) return complain("method w/o class");
if (!nowM || methodM!=nowM || methodM->desc || methodM->args || descM==methodM)
{ if (!classM->methods) classM->methods=({});
classM->methods+=({methodM=nowM=(["decl":({}),"_line":line])}); }
methodM->decl+=({stripws(arg)}); descM=0; },
"arg":lambda(string arg,int line)
{
if (!methodM) return complain("arg w/o method");
if (!methodM->args) methodM->args=({});
methodM->args+=({argM=nowM=(["args":({}),"_line":line])});
argM->args+=({arg}); descM=argM;
},
"note":lambda(string arg,int line)
{
if (!lower_nowM())
return complain("note w/o method, class or module");
descM=nowM->note||(nowM->note=(["_line":line]));
},
"bugs":lambda(string arg,int line)
{
if (!lower_nowM())
return complain("bugs w/o method, class or module");
descM=nowM->bugs||(nowM->bugs=(["_line":line]));
},
"see":lambda(string arg,int line)
{
if (arg[0..4]!="also:")
return complain("see w/o 'also:'\n");
if (!lower_nowM())
return complain("see also w/o method, class or module");
nowM["see also"]=map(arg[5..]/",",stripws);
},
"returns":lambda(string arg)
{
if (!methodM)
return complain("returns w/o method");
methodM->returns=stripws(arg);
descM=0; nowM=0;
}
]);
string getridoftabs(string s)
{
string res="";
for (;;)
{
int i;
if ((i=search(s,"\t"))==-1) return res+s;
res+=s[0..i-1];
s=s[i+1..];
res+=" "[(strlen(res)%8)..7];
}
}
object(File) make_file(string filename)
{
stderr->write("creating "+filename+"...\n");
if (file_size(filename)>0)
{
rm(filename+"~");
mv(filename,filename+"~");
}
object f=File();
if (!f->open(filename,"wtc"))
{
stderr->write("failed.");
exit(1);
}
return f;
}
string synopsis_to_html(string s)
{
string type,name,arg;
if (sscanf(s,"%s%*[ \t]%s(%s",type,name,arg)!=4)
sscanf(s,"%s(%s",name,arg),type="";
return
type+" <b>"+name+"</b>("+
replace(arg,({","," "}),({", ","\240"}));
}
string htmlify(string s)
{
#define HTMLIFY(S) \
(replace((S),({"->","&","\240"}),({"->","&"," "})))
string t="",u,v;
while (sscanf(s,"%s<%s>%s",u,v,s)==3)
t+=HTMLIFY(u)+"<"+v+">";
return t+HTMLIFY(s);
}
#define linkify(S) (replace((S),({"->","()"}),({".",""})))
string make_nice_reference(string what,string prefix)
{
string q;
if (search(what,".")==-1 &&
search(what,"->")==-1 &&
!parse[what])
q=prefix+what;
else
q=what;
return "<link to="+linkify(q)+">"+what+"</link>";
}
string fixdesc(string s,string prefix,string where)
{
s=stripws(s);
string t,u,v;
t=s; s="";
while (sscanf(t,"%s<ref>%s</ref>%s",t,u,v)==3)
{
s+=t+make_nice_reference(u,prefix);
t=v;
}
s+=t;
t=s; s="";
while (sscanf(t,"%s<illustration>%s</illustration>%s",t,u,v)==3)
{
s+=htmlify(replace(t,"\n\n","\n\n<p>"));
s+="<illustration __from__='"+where+"' src=lena.gif>\n"
+replace(u,"lena()","src")+"</illustration>";
t=v;
}
s+=htmlify(replace(t,"\n\n","\n\n<p>"));
return s;
}
multiset(string) get_method_names(string *decls)
{
string decl,name;
multiset(string) names=(<>);
foreach (decls,decl)
{
sscanf(decl,"%*s%*[\t ]%s%*[\t (]%*s",name);
names[name]=1;
}
return names;
}
|
2974bc | 1997-11-10 | Mirar (Pontus Hagland) | | {
f->write("\n\n\n<section title=\""+prefix+n+"\">\n");
document(huh->modules[n],
prefix+n,prefix+n+".",f);
f->write("</section title=\""+prefix+n+"\">\n");
}
}
foreach (names,string n)
f->write("</anchor name="+linkify(n)+">\n");
f->write("\n\n\n");
}
void make_doc_files()
{
stderr->write("modules: "+sort(indices(parse))*", "+"\n");
foreach (sort(indices(parse)),string module)
document(parse[module],module,module+".",stdout);
}
int main(int ac,string *files)
{
string s,t;
int line;
string *ss=({""});
object f;
string currentfile;
nowM=parse;
stderr->write("reading and parsing data...\n");
files=files[1..];
for (;;)
{
int i;
if (!f)
{
if (!sizeof(files)) break;
stderr->write("reading "+files[0]+"...\n");
f=File();
currentfile=files[0];
files=files[1..];
if (!f->open(currentfile,"r")) { f=0; continue; }
t=0;
ss=({""});
line=0;
}
if (sizeof(ss)<2)
{
if (t=="") { f=0; continue; }
t=f->read(8192);
s=ss[0];
ss=t/"\n";
ss[0]=s+ss[0];
}
s=ss[0]; ss=ss[1..];
line++;
if ((i=search(s,"**!"))!=-1)
{
string kw,arg;
sscanf(s[i+3..],"%*[ \t]%s%*[ \t]%s",kw,arg);
if (keywords[kw])
{
string err;
if ( (err=keywords[kw](arg,currentfile+" line "+line)) )
{
stderr->write(currentfile+" line "+line+": "+err+"\n");
return 1;
}
}
else
{
if (!descM) descM=methodM;
if (!descM)
{
stderr->write("Error on line "+line+": illegal description position\n");
return 1;
}
if (!descM->desc) descM->desc="";
else descM->desc+="\n";
s=getridoftabs(s);
descM->desc+=s[search(s,"**!")+3..];
}
}
}
stderr->write("making docs...\n\n");
make_doc_files();
return 0;
}
|