string stringlist(string path, string subdir, string pattern)
{
    list lst;
    string entry;
    int idx;
    string ret;

    path += subdir + "/";
    chdir(subdir);

    lst = makelist(O_SUBDIR, "*");

    for (idx = listlen(lst); idx--; )
        ret += stringlist(path, element(idx, lst), pattern);

    lst = makelist(pattern);

    for (idx = listlen(lst); idx--; )
        ret +=  path + element(idx, lst) + " ";

    chdir("..");

    return ret;
}

void cleanup(string task, string files)
{
    list filelist;
    int idx;

    filelist = strtok(files, " ");
    
    for (idx = listlen(filelist); idx--; )
        system("tmp/bin/" + task + " -q " + element(idx, filelist));
}

void txtdoc()
{
    if (!exists("tmp/docs/txt/cplusplus.txt"))
    {
        md("tmp/docs/txt");
        chdir("yo");
        system("yodl2txt --no-warnings "
                "-o ../tmp/docs/txt/cplusplus.txt -l3 cplusplus");
        chdir("..");
    }
}

void htmldoc()
{
    list htmlList;
    int idx;
    string html;

    md("tmp/docs/html");

                                    // cp necessary files for HTML
    if (!exists("tmp/docs/html/annotations.gif"))
        system("cp -r html/* tmp/docs/html");

                                    // convert .yo to .html
    if (!exists("tmp/docs/html/cplusplus.html"))
    {
        chdir("yo");
        system("yodl2html --no-warnings -l3 cplusplus ");

        system("mv *.html ../tmp/docs/html");
        system("cp cplusplus.css ../tmp/docs/html");
        chdir("..");
    }

    chdir("tmp/docs/html");

        // only in 2024
    system("../../../tmp/bin/celeb cplusplus.html");

                                    // index.html is the file holding the
                                    // <iframe>s: add it and related files
                                    // to tmp/docs/html
    if (!exists("index.html"))          
        system("cp ../../../single/* .");

    htmlList = (list)"cplusplus.html" + makelist("cplusplus??.html");

                                    // patch the html-files
    for (idx = listlen(htmlList); idx--; )
    {
        html = element(idx, htmlList);
        system("../../../scripts/patchhtml < " + html + " > _" + html);
        system("mv _" + html + " " + html);
    }

                                    // create the contents page
    system("../../../scripts/htmlcontentspage > contents.html");

                                    // write index entries to cplusplus.index
                                    // and create cppindex.html
    system("grep '^<index' cplusplus.html cplusplus??.html > "
                                                        "cplusplus.index");
    system("../../bin/htmlindex < cplusplus.index > cppindex.html");

                                    // remove the <index> entries from the
                                    // html files
    for (idx = listlen(htmlList); idx--; )
    {
        html = element(idx, htmlList);
        system("../../bin/rmindexlines < " + html + " > _" + html);
        system("mv _" + html + " " + html);
    }

    chdir(g_cwd);
}

void pspdf(string basename, string us)
{
    string pdfname;
    string psname;
    string papersizeoption = "a4";

    chdir("tmp/docs/latex");

    if (us != "")
        papersizeoption = "letter";

    psname = basename + ".ps";
    if (basename + ".dvi" younger psname)
        system("dvips -t " + papersizeoption + " -o" + psname + " " + basename);

    pdfname = basename + ".pdf";
    if (psname younger pdfname)
        system("ps2pdf -sPAPERSIZE=" + papersizeoption + " " + psname + " " + pdfname);

    chdir(g_cwd);
}

void runps()
{
    pspdf("cplusplus", "");
    pspdf("cplusplusus", "us");

    exit(0);
}

void latexdoc(string us, int makeps)
{
    string basename;
    string dvistamp;
    string latexname;
    string latexstamp;
    string ulatexname;
    string ulatexstamp;
    string yodldefine;

    md("tmp/docs/latex");

                                    // cp necessary files for LaTeX   
    if (!exists("tmp/docs/latex/cplusplus.sty"))
        system("cp -r latex/* tmp/docs/latex");

                                    // assign file name variables
    basename = "cplusplus" + us;
    latexname = basename + ".latex";
    ulatexname = "_" + latexname;

    ulatexstamp = "tmp/_" + basename + "-stamp";

                                    // create the _xxx.latex file
    if (!exists(ulatexstamp))
    {
        chdir("yo");

        if (us != "")
            yodldefine = "--define " + us;

        system("yodl2latex --no-warnings -l3 " 
                "-DAPATH=" + g_cwd + "tmp/bin/ " +
                yodldefine + " -o ../tmp/docs/latex/" + 
                ulatexname + " cplusplus");
        chdir("..");
        system("touch " + ulatexstamp);
    }


    chdir("tmp/docs/latex");
    latexstamp = "../../../tmp/" + basename + "-stamp";

                                    // rm blanks around verb() statements
    if (!exists(latexstamp))
    {
        system("../../../scripts/patchlatexverb <" + ulatexname +
                                               ">" + latexname);

        // kludge used until yodl can prevent SUBSTs in verbatim text
        //
        system("/bin/sed -i 's/+latexcommand(\\(..\\){\\(.\\)})/\\1\\2/' " + 
                    latexname);

        system("touch " + latexstamp);
    }
     
                                    // make dvi-file   
    dvistamp = "../../../tmp/dvi" + us + "-stamp";

    if (!exists(dvistamp))
    {        
            // only in 2024
        system("../../../tmp/bin/celeb " + latexname);

        system("latex " + latexname);
        system("latex " + latexname);

        system("sed 's/\\!/\"\\!/g' " + basename + ".idx |"
                    " makeindex -i -o " + basename + ".ind");

//        system("../../../scripts/patchlatexidx " + us);

        system("latex " + latexname);
        system("latex " + latexname);

        system("rm _* *.out");
        system("touch " + dvistamp);
    }

    chdir(g_cwd);

    if (makeps)
        pspdf(basename, us);
}

void runtxt()
{ 
    system("rm -f tmp/docs/txt/cplusplus.txt");
    txtdoc();
    exit(0);
}

void runhtml()
{
    system("rm -rf tmp/docs/html tmp/html*-stamp");
    htmldoc();
    exit(0);
}
   
void docs()
{
    man();

    programs(1);

    txtdoc();
    htmldoc();
    latexdoc("", 1);
    latexdoc("us", 1);

    exit(0);
}
