#!BINDIR/icmake -qt /tmp/unix

/*

    If you want to use this file, it is assumed that you have icmake (at
    least version 6.20) installed (in the locations defined in
    def/destinations) . If icmake is stored elsewhere, then
    please adapt the path /usr/bin in the line above accordingly.

        FBB
*/

// #define VERBOSE       // for babbling script
// #define USE_DEBUG

#include "def/programs"

/*      
        The remainder of this script should not be altered, unless
    you know what you're doing
*/

#include "def/destinations"
#include "VERSION"

#define LIB_ICRSS   "libicrss.a"
#define LIB_ICMAKE  "libicmake.a"
#define LIB_ICMPP   "libicmpp.a"
#define LIB_ICMCOMP "libicmcomp.a"
#define LIB_ICMEXEC "libicmexec.a"
#define LIB_ICMUN   "libicmun.a"

list
        examples;

    
void check(string subdir)
{
    if (!exists(subdir))
    {
#ifdef VERBOSE
        printf("Creating subdirectory: ");
#endif
        exec(MKDIR, subdir);
    }
}    

void initialize()
{
    examples = 
    (list)"am"      +
    (list)"backup"  +
    (list)"bup"     +
    (list)"ftpxfer" +
    (list)"ds"      +
    (list)"idir"    +
    (list)"keep"    +
        (list)"r"       +
    (list)"tolower";

    check("bin");
    check("binlinux");
}           
            
void makelib (string dir, string lib)
{
    list
        cfiles,
        ofiles;
    string
        ofile,
        cfile;
    int
        i;

#ifdef VERBOSE
    printf ("---- Directory: ", dir, " ----\n");
#endif
    chdir (dir);

#ifdef VERBOSE
    printf ("Checking .c files against library ", lib, "\n");       
#endif
    cfiles = makelist ("*.c");
    for (i = sizeof (cfiles) - 1; i >= 0; i--)
    {
        cfile = element (i, cfiles);
        ofile = change_ext (cfile, ".o");
        if 
    (
        cfile older lib 
        ||
            (exists (ofile) && ofile younger cfile)
        )
            cfiles -= (list) cfile;
    }
    for (i = 0; i < sizeof (cfiles); i++)
        exec (CC, CFLAGS, 
#ifdef USE_DEBUG
                "-DYYDEBUG=1",
#endif
                    element (i, cfiles));
    
#ifdef VERBOSE
    printf ("Checking .o files against library ", lib, "\n");
#endif
    ofiles = makelist ("*.o");
    if (ofiles)
    {
        exec (AR, ARFLAGS, lib, "*.o");
        exec (RM, "*.o");
    }
    
    chdir ("..");
}

void makelibs ()
{
#ifdef VERBOSE
    printf ("\nMaking Run Time Support System library\n");
#endif
    makelib ("rss", LIB_ICRSS);
    
#ifdef VERBOSE
    printf ("\nMaking lib for shell program icmake\n");
#endif
    makelib ("make", LIB_ICMAKE);
    
#ifdef VERBOSE
    printf ("\nMaking lib for preprocessor icm-pp\n");
#endif
    makelib ("pp", LIB_ICMPP);
    
#ifdef VERBOSE
    printf ("\nMaking lib for compiler icm-comp\n");
#endif
    chdir ("comp");

    if ("parser" younger "parser.c")
        system("bison -d -o parser.c parser");

    if ("lexer" younger "lexer.c" || "parser" younger "lexer.c")
        system("flex -o lexer.c lexer");

    chdir("..");

    makelib ("comp", LIB_ICMCOMP);
    
#ifdef VERBOSE
    printf ("\nMaking lib for executor icm-exec\n");
#endif
    chdir("exec");
    system("./build lib");
    chdir("..");
    
#ifdef VERBOSE
    printf ("\nMaking lib for unassembler icmun\n");
#endif
    makelib ("un", LIB_ICMUN);
}

void makeprog (string dir, string lib, string prog)
{
    string
        rsslib;
        
    rsslib = "../rss/libicrss.a";

#ifdef VERBOSE
    printf ("---- Directory: ", dir, " ----\n");
#endif
    chdir (dir);
    
#ifdef VERBOSE
    printf ("Checking prog ", prog, " against libs ", lib, 
            " and ", rsslib, "\n");
#endif

    if (lib younger prog || rsslib younger prog)
    {
        exec (CC, 
#ifdef USE_DEBUG
                "-DYYDEBUG=1",
#endif
                "-o ../bin/" + prog, lib, rsslib);

        exec (STRIP, "../bin/" + prog);
        printf("Stripped version of ", prog, " in icmake/bin\n");
    }           
        
    chdir ("..");
}

void makeprogs ()
{
    makelibs ();
    
#ifdef VERBOSE
    printf ("\nMaking shell program icmake\n");
#endif
    makeprog ("make", LIB_ICMAKE, "icmake");
    
#ifdef VERBOSE
    printf ("\nMaking unassembler program icmun\n");
#endif
    makeprog ("un", LIB_ICMUN, "icmun");

#ifdef VERBOSE
    printf ("\nMaking unassembler program icm-pp\n");
#endif
    makeprog ("pp", LIB_ICMPP, "icm-pp");
    
#ifdef VERBOSE
    printf ("\nMaking compiler program icm-comp\n");
#endif
    makeprog ("comp", LIB_ICMCOMP, "icm-comp");
    
#ifdef VERBOSE
    printf ("\nMaking executor program icm-exec\n");
#endif

    chdir("exec");
    system("build program ../bin/icm-exec");
    chdir("..");
}

void inst (string prog)
{
    string
        dest;

#ifdef VERBOSE
    printf ("---- Directory: icmake/bin ----\n");
#endif

    chdir ("bin");
    dest = BINDIR + "/" + prog;
    
    if (dest older prog)
    {
        if (prog == "icm-exec")
        printf("Since icm-exec itself is running, you have to copy\n"
            "icm-exec by hand.\n"
            "Give the command\n"
            "\t", CP, " bin/icm-exec ", BINDIR, "\n"
            "on completion of 'icmake unix -- install'\n");
        else
            exec (CP, prog, BINDIR);
    }
    
    chdir ("..");
}

void install ()
{
    makeprogs ();
    
    #ifdef VERBOSE
        printf ("\nInstalling shell program icmake\n");
    #endif
    inst ("icmake");
    
#ifdef VERBOSE
    printf ("\nInstalling unassembler program icmun\n");
#endif
    inst ("icmun");
    
#ifdef VERBOSE
    printf ("\nInstalling unassembler program icm-pp\n");
#endif
    inst ("icm-pp");
    
#ifdef VERBOSE
    printf ("\nInstalling compiler program icm-comp\n");
#endif
    inst ("icm-comp");
    
#ifdef VERBOSE
    printf ("\nUSE HAND-INSTALLATION OF EXECUTOR PROGRAM ICM-EXEC\n");
#endif
    inst ("icm-exec");
}

void clean (string dir)       
{
#ifdef VERBOSE
    printf ("---- Directory: ", dir, " ----\n");
#endif
    chdir (dir);
    exec (RM, "-f", "*.o", "*/*.o");
    chdir ("..");
}

void cleanup ()
{
    clean ("rss"); 
    clean ("make");
    clean ("pp"); 
    clean ("comp");
    clean ("exec");
    clean ("un"); 
}

void realclean (string dir, string lib)
{
#ifdef VERBOSE
    printf ("---- Directory: ", dir, " ----\n");
#endif
    chdir (dir);
    exec (RM, "-f", lib,  "*.o", "*/*.o");
    chdir ("..");
}

void realcleanup (int all)
{
    realclean ("rss",  LIB_ICRSS); 
    realclean ("make", LIB_ICMAKE);
    realclean ("pp", LIB_ICMPP);
    realclean ("comp", LIB_ICMCOMP);

    if (all)
    {
        chdir("comp");
        system("rm -f parser.c parser.h lexer.c");
        chdir("..");
    }

    realclean ("exec", LIB_ICMEXEC);
    system("rm -rf exec/tmp bin/*");

    realclean ("un", LIB_ICMUN);

    system(P_NOCHECK, "rm -rf */o */*/o bin/*");
}

void manpage(string manpage)
{
    string src,
           dest;
        
    src   = "doc"   + "/" + manpage;
    dest  = MANDIR  + "/" + manpage;
    
    exec (CP, src, MANDIR);
    exec (GZIP, "-9", dest);
}

void man ()
{
    system("mkdir -p " MANDIR);
    manpage("icmake.1");
    manpage("icmbuild.1");
    manpage("icmstart.1");
}

void skel()
{
    system("mkdir -p " SKELDIR);
    system("cp -r usr/share/icmake/* " SKELDIR);
}

void main (int argc, list argv)
{
    string
        av1;
    
    initialize();   
        
    av1 = element (1, argv);
    if (av1 == "libs")
        makelibs ();
    else if (av1 == "progs")
        makeprogs ();
    else if (av1 == "clean")
        cleanup ();
    else if (av1 == "realclean")
        realcleanup (0);
    else if (av1 == "REALCLEAN")
        realcleanup (1);
    else if (av1 == "man")
        man ();
    else if (av1 == "skel")
        skel();
    else
        printf ("\n"
        "Select one of the following:\n"
        "    \"unix clean\" to remove old mush (libs are kept)\n"
        "    \"unix libs\" to make libraries\n"
        "    \"unix man\" to install man pages\n"
        "    \"unix progs\" to make programs\n"
        "    \"unix realclean\" to remove old mush (including libs)\n"
        "    \"unix skel\" to install the skeleton files\n"
        "\n"
        "    \"unix REALCLEAN\" realclean + remove lexer.c parser.[ch]\n"
        "       DO NOT USE THIS UNLESS YOU KNOW WHAT YOU'RE DOING\n"
            "\n");
}



