ICMAKE Part 4

by Frank B. Brokken
5. Some examples.

Three examples will be given in this final section, completing our discussion of icmake. The first example illustrates a `traditional make script', used with icmake. The example was taken from the `callback utility', developed by Karel (and also available from beatrix.icce.rug.bl). The second example is a simple dos2unix script which may be used to convert DOS textfiles to Unix textfiles: it uses awk to do the hard work. Finally, the attic-move script is presented, implementing a non-destructive remove, by moving files into an `attic.zip'. More examples can be found in the icmake distribution tar.gz file. The examples are annotated by their own comment, and are presented as they are currently used.

5.1. The callback-(ic)make script.
#!/usr/local/bin/icmake -qi
#define CC              "gcc"
#define CFLAGS          "-c -Wall"
#define STRIP           "strip"
#define AR              "ar"
#define ARREPLACE       "rvs"
#define DEBUG           ""
#define CALLBACKDIR     "/conf/callback"
#define BINDIR          "/usr/local/bin"
#define VER             "1.05v
int compdir (string dir)
{
    int
        i,
        ret;
    list
        ofiles,
        cfiles;
    string
        hfile,
        curdir,
        cfile,
        ofile,
        libfile;
    curdir = chdir (".");
    libfile = "lib" + dir + ".a";
    hfile = dir + ".h";
    chdir (dir);
    if (hfile younger libfile)
        cfiles = makelist ("*.c");
    else
        cfiles = makelist ("*.c", younger, libfile);
    for (i = 0; i < sizeof (cfiles); i++)
    {
        cfile = element (i, cfiles);
        ofile = change_ext (cfile, ".o");
        if (! exists (ofile) || ofile older cfile)
            exec (CC, DEBUG, CFLAGS, cfile);
    }
    if (ofiles = makelist ("*.o"))
    {
        exec (AR, ARREPLACE, libfile, "*.o");
        exec ("rm", "*.o");
        ret = 1;
    }
    chdir (curdir);
    return (ret);
}
void linkprog (string dir)
{
    chdir (dir);
    exec (CC, DEBUG, "-o", dir, "-l" + dir, "-lrss", "-L. -L../rss");
    chdir ("..");
}
void buildprogs ()
{
    int
        cblogin,
        cbstat,
        rss;
    chdir ("src");
    cblogin = compdir ("cblogin");
    cbstat  = compdir ("cbstat");
    rss     = compdir ("rss");
    if (cblogin || rss)
        linkprog ("cblogin");
    if (cbstat || rss)
        linkprog ("cbstat");
    chdir ("..");
}
void instprog (string prog, string destdir)
{
    chdir ("src/" + prog);
    exec (STRIP, prog);
    exec ("chmod", "700", prog);
    exec ("cp", prog, destdir);
    chdir ("../..");
}
void install ()
{
    buildprogs ();
    instprog ("cblogin", CALLBACKDIR);
    instprog ("cbstat",  BINDIR);
}
void cleandir (string dir)
{
    chdir ("src/" + dir);
    exec ("rm", "-f", "*.o lib*.a", dir);
    chdir ("../..");
}
void clean ()
{
    exec ("rm", "-f", "build.bim");
    cleandir ("cblogin");
   cleandir ("cbstat");
    cleandir ("rss");
}
void makedist ()
{
    list
        examples;
    int
        i;
    clean ();
    chdir ("examples");
    examples = makelist ("*");
    for (i = 0; i < sizeof (examples); i++)
        if (exists ("/conf/callback/" + element (i, examples)) &&
            "/conf/callback/" + element (i, examples) younger
                element (i, examples))
            exec ("cp", "/conf/callback/" + element (i, examples),
                element (i, examples));
    chdir ("..");
    exec ("rm", "-f", "callback-" + VER + ".tar*");
    exec ("tar", "cvf", "callback-" + VER + ".tar", "*");
    exec ("gzip", "callback-" + VER + ".tar");
    exec ("mv", "callback-" + VER + ".tar.z",
            "callback-" + VER + ".tar.gz");
}
void main (int argc, list argv)
{
    if (element (1, argv) == "progs")
        buildprogs ();
    else if (element (1, argv) == "install")
        install ();
    else if (element (1, argv) == "clean")
        clean ();
    else if (element (1, argv) == "dist")
        makedist ();
    else
    {
        printf ("\n"
        "Usage: build progs   - builds programs\n"
        "       build install - installs program\n"
        "       build clean   - cleanup .o files etc.\n"
        "\n"
        "       build dist    - makes .tar.gz distrib file\n"
        "\n");
        exit (1);
    }
    exit (0);
}
5.2. The Dos to Unix script.
#!/usr/local/bin/icmake -qi
/*
                            DOS2UNIX
This script is used to change dos textfiles into unix textfiles.
*/
string
    pidfile;
void usage(string prog)
{
    prog = change_ext(get_base(prog), ""); // keep the scriptname
    printf("\n"
        "ICCE ", prog,
        ": Dos to Unix textfile conversion.  Version 1.00\n"
        "Copyright (c) ICCE 1993, 1994. All rights reserved\n"
        "\n",
        prog, " by Frank B. Brokken\n"
        "\n"
        "Usage: ", prog, " file(s)\n"           // give help
        "Where:\n"
        "file(s): MS-DOS textfiles to convert to UNIX textfiles\n"
        "\n");
    exit (1);                                // and exit
}
void dos2unix(string file)
{
    if (!exists(file))
        printf("'", file, "' does not exist: skipped\n");
    else
    {
        printf("converting: ", file, "\n");
        exec("/bin/mv", file, pidfile);
        system("/usr/bin/awk 'BEGIN {FS=\"\\r\"}; {print $1}' " +
               pidfile + " > " + file);
    }
}
void process(list argv)
{
    int
        i;
                               // make general scratchname
    pidfile = "/tmp/dos2unix." + (string)getpid();
    echo(OFF);                 // no echoing of exec-ed progs
    for (i = 1; i < sizeof(argv); i++)
        dos2unix(element(i, argv));      // convert dos 2 unix
    if (exists(pidfile))
        exec("/bin/rm", pidfile);       // remove final junk
}
int main(int argc, list argv)
{
    if (argc == 1)
        usage(element(0, argv));
    process(argv);                  // process all arguments
    return (0);                    // return when ready
}
5.3. The Attic Move script.
#! /usr/local/bin/icmake -qi
/*
       This script is used to implement a non-destructive rm
*/
#define YEAR    "1993, 1994"
#define VERSION "1.10"
int
    flags_done,
    extract,
    viewmode,
    debug;
string
    home,
    attic,
    cwd,
    progname,
    recurs,
    forced,
    unzipflag;
void kill(string s)
{
    printf(s, "\n\n");
    exit(1);
}
void preamble(list argv, list envp)
{
    int
        index;
    cwd = chdir(".");                       // get cwd
    for (index = 0; home = element(index, envp); index += 2)
    {
        if (home == "HOME")                 // HOME found
        {                                   // get it
            home = element(index + 1, envp);
            break;                          // and done
        }
    }
if (!home)
        kill("$HOME not found");
    progname = change_ext(element(0, argv), "");
    attic = home + "/attic";      // set $HOME/attic, change to
}
void check_attic()
{
    if (!exists(attic))              // attic should exist
    {
        printf(attic, " does not exist. Create it [y/n] ? ");
        if (getch() != "y")         // not a "y" ?
            kill("ok.");
        system("mkdir " + attic);   // make the attic subdir
        exec("chmod", 700, attic);  // private use
    }                             // else attic must be dir
    else if (!((int)element(0, stat(attic)) & S_IFDIR))
        kill("'" + attic + "' is not a directory");
    attic += "/attic";              // append the zip-name
    chdir("/");                    // go to the root
}
void set_flags(string arg)
{
    int
        index;
    string
        flag;
                              // process all arguments
    for (index = 1; flag = element(index, arg); index++)
    {
        if (flag == "r")       // process encountered options
            recurs = "-r";
        if (flag == "d")
            debug++;
        else if (flag == "f")
            forced = "-f";
        else if (flag == "x")
            extract++;
        else if (flag == "v")
        {
            extract++;
            viewmode++;
            unzipflag = "-l ";
        }
        else
            kill("Unrecognized flag '-" +
                 flag +
                 "': " +
                 progname +
                 "aborted");
    }
    if (extract && unzipflag == "")
        unzipflag = "-u ";         // use proper unzip flag
}
list options(int argc, list argv)
{
    int
        index;
    list
        ret;
    string
        arg;
for (index = 0; index < argc; index++)
    {
        arg = element(index, argv); // get next argument
        if (element(0, arg) == "-") // first element is a - ?
            set_flags(arg);        // then set flags
        else
            ret += (list)arg;     // or add to list to return
    }
    return (ret);                   // returned list
}
void usage()
{
    printf
    (
        "\n"
        "ICCE AM (Attic Move) non-destructive remove. Version "
        VERSION "\n"
        "Copyright (c) ICCE " YEAR ". All Rights Reserved\n"
        "\n"
        "AM by Frank B. Brokken\n"
        "\n"
        "Usage: ", progname, " [options] file(s)\n"
        "Where:\n"
        "   options:\n"
        "      -d: Debug mode: no execution but display of commands\n"
        "      -f: Forced processing of indicated files\n"
        "      -r: Recursive removal of directory contents\n"
        "      -v: View current contents of the attic\n"
        "      -x: Extract files from the attic to their original place\n"
        "          (i.e., if you are permitted to do so...\n"
        "\n"
        "   file(s): names of files and directories to move to/from
        the attic\n"
        "\n"
        "   ", home, "/attic/attic.zip is used to store the files.\n"
        "\n"
    );
    exit (1);
}
string prefix_path(string file)
{
    string
        el,
        ret;
    int
        index;
    if (element(0, file) != "/")  // if file isn't an absolute path
        file = cwd + file;       // then make an absolute path
    for (index = 1; el = element(index, file); index++)
        ret += el;         // remove first char from abs path
    return (ret);                  // return modified string
}
void retrieve(string file)
{
    string
        cmd;
    cmd = "unzip "                  // update only
        + unzipflag
        + attic;
if (!viewmode)
        cmd += " "
             + prefix_path(file);  // and the file (+ path prefix)
    if (debug)
        printf("( cd /; ", cmd, " )\n");  // debug: show command
    else
        system(cmd);                     // else exec cmd
}
void remove(string file)
{
    string
        cmd;
    cmd = "zip -my "         // remove, remove links as links
        + forced             // maybe forced
        + " "
        + recurs             // maybe recursive
        + " "
        + attic              // target zip
        + " "
        + prefix_path(file);  // and the file (+ path prefix)
    if (debug)
        printf("( cd /; ", cmd, " )\n");  // debug: show command
    else
        system(cmd);          // else exec cmd
}
void one_file(string file)
{
    if (extract)                 // either retrieve or remove
        retrieve(file);           // the file
    else
        remove(file);
}
void process(int argc, list argv)
{
    int
        index;
    for (index = 1; index < argc; index++)
        one_file(element(index, argv));    // process one file
}
int main(int argc, list argv, list envp)
{
    echo (OFF);
    preamble(argv, envp);       // set progname and attic dir.
    argv = options(argc, argv); // get the options
    argc = sizeof(argv);       // determine remaining arguments
    if (argc == 1 && !viewmode) // none left and no viewmode?
        usage();               // give usage and exit 1
    check_attic();             // check accessability of attic
    if (viewmode)              // view contents
        retrieve("");
    else                      // or
        process(argc, argv);    // process remaining arguments
    return (0);                // done
}
Load Disqus comments