Select Git revision
-
Henrik (Grubba) Grubbström authored
Rev: src/errors.h:1.13
Henrik (Grubba) Grubbström authoredRev: src/errors.h:1.13
manpages 6.12 KiB
// -*- Pike -*-
// $Id: manpages,v 1.20 1999/04/17 15:55:36 grubba Exp $
#include "types.h"
#if __VERSION__ >= 0.6
import ".";
#endif /* __VERSION__ >= 0.6 */
inherit Stdio.File : out;
int verbose = 0;
string globalbase;
object windex;
object whatis;
// Conversion table:
//
// "*" "\\(**"
// "\\" "\\e"
// "()" "(\\|)"
// " - " " \\- "
// "..." "\&.\|.\|."
string quote_text(string s)
{
s=replace(s,({">","&","<"}),
({">","&","<"}));
return(replace(s, ({ "*", "\\", "()", " - ", "..." }),
({ "\\(**", "\\e", "(\\|)", " \\- ", "\&.\|.\|." })));
}
// Some versions of nroff don't like 8-bit chars at all.
string strip_eightbit(string s)
{
return(s & String.strmult("\177", sizeof(s)));
}
string strip_empty_lines(string s)
{
return(Array.filter(s/"\n", lambda(string line) {
return(replace(line,
({ "\t", " " }),
({ "", "" })) != "");
})*"\n");
}
void make_page(string base, TAG tag, string ind, string fbase);
void mkdirhier(string what)
{
string d=".";
foreach (what/"/",string add)
{
d+="/"+add;
mkdir(d);
}
}
int stripws=1;
string make_manpage(string base, SGML data, string ind, string fbase)
{
string res="";
if (verbose) {
werror(sprintf("data:%O\n", data));
}
if (stringp(data)) {
if (stripws) {
sscanf(data,"%*[ \t\n\r]%s",data);
}
mixed d = data; // Fool Pikes type-checker.
res+=quote_text(d);
} else if(arrayp(data)) {
foreach (data, TAG tag) {
if (objectp(tag)) {
if (verbose) {
werror(sprintf("tag:%O, params:%O\n", tag->tag, tag->params));
}
switch (tag->tag) {
case "method":
case "function":
case "constant":
case "class":
case "module":
case "variable":
make_page(base,tag,ind,fbase);
continue;
case "man_title":
res+="\n.SH "+quote_text(tag->params->title)+"\n";
stripws=1;
break;
case "p":
res+="\n.PP\n";
stripws=1;
break;
case "br":
case "ex_br":
res+="\n.br\n";
if (tag->params->keep_ws) {
stripws = 0;
} else {
stripws=1;
}
break;
case "ex_indent":
res += " ";
continue;
case "link":
case "i":
case "emboss":
// case "ex_identifier":
res+="\\f2"+make_manpage(base,tag->data,ind,fbase)+"\\f1";
continue;
case "b":
case "strong":
case "ex_keyword":
res+="\\f3"+make_manpage(base,tag->data,ind,fbase)+"\\f1";
continue;
case "pre":
case "tt":
case "example":
int ows = stripws;
stripws=0;
res+="\n.nf\n"+
make_manpage(base,tag->data,ind,fbase)+
"\n.fi\n";
stripws = ows;
continue;
}
res+=make_manpage(base,tag->data,ind,fbase);
} else if (stringp(tag)) {
if (stripws) sscanf(tag,"%*[ \t\n\r]%s",tag);
res+=quote_text(tag);
stripws=0;
}
}
}
return res;
}
int pages=0;
void make_page(string base, TAG tag, string ind, string fbase)
{
// werror(ind+tag->tag+" "+tag->params->name+"\n");
werror("manpage "+(++pages)+"...\r");
mixed err = catch {
string *outfiles,*names,*s_outfiles;
string obase=base;
string q;
// werror(sprintf("%s %s %s %s \n", tag->params->name, fbase, globalbase, base));
outfiles=Array.map(names=tag->params->name/",",
lambda(string s,string t,string u,string base)
{
s=replace(s,"->",".");
// We want the man pages to be Image.image.foo for example... a man page for "create" is kinda uninteresting...
// sscanf(s,t+".%s",s);
return u+"/"+s+"."+base;
},fbase,globalbase,base);
sscanf(outfiles[0],"%*s/man%*s/%s",q);
if (q) {
array(string) a = q/".";
if (sizeof(a) > 1) {
q = a[..sizeof(a)-2]*".";
}
}
// werror("files: "+outfiles*", "+"\n");
if (tag->params->mansuffix)
{
base+=tag->params->mansuffix;
fbase=(tag->params->name/",")[0];
// mkdirhier(globalbase+base);
}
// verbose = ((names*",") == "Thread.Mutex");
string page=strip_empty_lines(make_manpage(base,tag->data,ind+" ",fbase));
// werror("creating "+outfiles[0]+"...\n");
object f=Stdio.File(outfiles[0],"wtc");
string t=ctime(time());
f->write(strip_eightbit(".\\\" t\n"
".\\\" automatically generated from wmml\n"
".TH " + names*"," + " " + upper_case(obase) +
" \"" + t[8..9] + t[3..7] + t[20..23] + "\""
" Pike \"Pike Manual\" Pike\n" +
page + "\n"));
f->close();
foreach (outfiles[1..], string s)
{
string name;
sscanf(outfiles[0], "man/%s", name);
// werror("creating "+s+" -> "+name+"...\n");
object f=Stdio.File(s, "wtc");
f->write(".so "+name+"\n");
f->close();
}
foreach (({q})+names, string s) {
windex->write(sprintf("%-15s %-15s - %s\n",
s,q+" ("+obase+")",
tag->params->title || (names*", ")));
whatis->write(sprintf("%-23s - %s\n", s + " (" + obase + ")",
tag->params->title || (names*", ")));
}
};
if (err) {
werror("Error while making manpage for "+tag->name+" ("+base+"):\n"
+master()->describe_backtrace(err));
}
}
void make_pages(string base, SGML data, string ind, string fbase)
{
if (arrayp(data))
foreach (data, TAG tag)
if (objectp(tag))
if ((<"method","function","class","module">)[tag->tag])
make_page(base,tag,ind,fbase);
else
make_pages(base,tag->data,ind,fbase);
}
void output(string base, WMML data)
{
globalbase="man/man3";
// mkdirhier("man/man3p");
mkdirhier("man/man3");
windex=Stdio.File("man/windex", "wtc");
whatis=Stdio.File("man/whatis", "wtc");
// make_pages("3p", data->data, "", "");
make_pages("3p", data->data, "", "");
werror("\n");
// Used by Xman.
// NB The Xman(1) man-page describes only the old file-format.
// The format is either (old format)
// <section suffix (one char)><section name><lf>
// or
// <section suffix><tab><section name>[<tab>suffix|fold|foldsuffix]<lf>
// The latter is the only one usable for us.
object mandesc = Stdio.File("man/mandesc", "wtc");
mandesc->write("3p\t(3P) Pike Library Functions\n"
"3pi\t(3PI) Pike Image Module\n"
"3pii\t(3PII) Pike Image.image Class\n");
mandesc->close();
}