+ Addition of function prototypes and include files. + Change function definitions to ANSI C style. + Initial support for CMake
		
			
				
	
	
		
			308 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *  Do the actual making for make
 | 
						|
 *
 | 
						|
 *  $Header$
 | 
						|
 */
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <time.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <errno.h>
 | 
						|
/* UNIX specific */
 | 
						|
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
 | 
						|
#ifndef unix
 | 
						|
#define unix
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(__MINGW32__) || defined(__MINGW64__)
 | 
						|
#ifndef unix
 | 
						|
#define unix
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#ifdef unix
 | 
						|
#include <unistd.h>
 | 
						|
#include <utime.h>
 | 
						|
#endif
 | 
						|
#include "h.h"
 | 
						|
 | 
						|
void docmds(struct name *np);
 | 
						|
 | 
						|
#ifndef max
 | 
						|
#define max(a,b)    ((a)>(b)?(a):(b))
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  Exec a shell that returns exit status correctly (/bin/esh).
 | 
						|
 *  The standard EON shell returns the process number of the last
 | 
						|
 *  async command, used by the debugger (ugg).
 | 
						|
 *  [exec on eon is like a fork+exec on unix]
 | 
						|
 */
 | 
						|
static int dosh(char *string, char *shell)
 | 
						|
{
 | 
						|
    return system(string);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  Do commands to make a target
 | 
						|
 */
 | 
						|
static void docmds1(struct name *np, struct line *lp)
 | 
						|
{
 | 
						|
    bool            ssilent;
 | 
						|
    bool            signore;
 | 
						|
    int         estat;
 | 
						|
    register char *     q;
 | 
						|
    register char *     p;
 | 
						|
    char *          shell;
 | 
						|
    register struct cmd *   cp;
 | 
						|
 | 
						|
 | 
						|
    if (*(shell = getmacro("SHELL")) == '\0')
 | 
						|
#ifdef unix
 | 
						|
        shell = "/bin/sh";
 | 
						|
#endif
 | 
						|
    for (cp = lp->l_cmd; cp; cp = cp->c_next)
 | 
						|
    {
 | 
						|
        strcpy(str1, cp->c_cmd);
 | 
						|
        expand(str1);
 | 
						|
        q = str1;
 | 
						|
        ssilent = silent;
 | 
						|
        signore = ignore;
 | 
						|
        while ((*q == '@') || (*q == '-'))
 | 
						|
        {
 | 
						|
            if (*q == '@')     /*  Specific silent  */
 | 
						|
                ssilent = TRUE;
 | 
						|
            else           /*  Specific ignore  */
 | 
						|
                signore = TRUE;
 | 
						|
            q++;           /*  Not part of the command  */
 | 
						|
        }
 | 
						|
 | 
						|
        if (!domake)
 | 
						|
            ssilent = 0;
 | 
						|
 | 
						|
        if (!ssilent)
 | 
						|
            fputs("    ", stdout);
 | 
						|
 | 
						|
        for (p=q; *p; p++)
 | 
						|
        {
 | 
						|
            if (*p == '\n' && p[1] != '\0')
 | 
						|
            {
 | 
						|
                *p = ' ';
 | 
						|
                if (!ssilent)
 | 
						|
                    fputs("\\\n", stdout);
 | 
						|
            }
 | 
						|
            else if (!ssilent)
 | 
						|
                putchar(*p);
 | 
						|
        }
 | 
						|
        if (!ssilent) {
 | 
						|
            putchar('\n');
 | 
						|
            fflush(stdout);
 | 
						|
        }
 | 
						|
 | 
						|
        if (domake)
 | 
						|
        {           /*  Get the shell to execute it  */
 | 
						|
            if ((estat = dosh(q, shell)) != 0)
 | 
						|
            {
 | 
						|
                if (estat == -1)
 | 
						|
                    fatal("Couldn't execute %s", shell);
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    printf("%s: Error code %d", myname, estat);
 | 
						|
                    if (signore)
 | 
						|
                        fputs(" (Ignored)\n", stdout);
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        putchar('\n');
 | 
						|
                        if (!(np->n_flag & N_PREC))
 | 
						|
                            if (remove(np->n_name) == 0)
 | 
						|
                                printf("%s: '%s' removed.\n", myname, np->n_name);
 | 
						|
                        exit(1);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                fflush(stdout);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void docmds(struct name *np)
 | 
						|
{
 | 
						|
    register struct line *  lp;
 | 
						|
 | 
						|
 | 
						|
    for (lp = np->n_line; lp; lp = lp->l_next)
 | 
						|
        docmds1(np, lp);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  Get the modification time of a file.  If the first
 | 
						|
 *  doesn't exist, it's modtime is set to 0.
 | 
						|
 */
 | 
						|
void modtime(struct name *np)
 | 
						|
{
 | 
						|
    struct stat     info;
 | 
						|
 | 
						|
    if (stat(np->n_name, &info) < 0)
 | 
						|
    {
 | 
						|
        if (errno != ENOENT)
 | 
						|
	    fatal("Can't open %s", np->n_name);
 | 
						|
 | 
						|
        np->n_time = 0L;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        np->n_time = info.st_mtime;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  Update the mod time of a file to now.
 | 
						|
 */
 | 
						|
void touch(struct name *np)
 | 
						|
{
 | 
						|
#ifdef unix
 | 
						|
    if (!domake || !silent)
 | 
						|
        printf("    touch(%s)\n", np->n_name);
 | 
						|
 | 
						|
    if (domake)
 | 
						|
    {
 | 
						|
        struct utimbuf a;
 | 
						|
        time_t timeval;
 | 
						|
 | 
						|
        a.actime = a.modtime = time(&timeval);
 | 
						|
        if (utime(np->n_name, &a) < 0)
 | 
						|
            printf("%s: '%s' not touched - non-existant\n",
 | 
						|
                    myname, np->n_name);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static void make1(struct name *np, struct line *lp, struct depend *qdp)
 | 
						|
{
 | 
						|
    register struct depend *    dp;
 | 
						|
    register char *p;
 | 
						|
 | 
						|
    if (dotouch)
 | 
						|
        touch(np);
 | 
						|
    else
 | 
						|
    {
 | 
						|
        strcpy(str1, "");
 | 
						|
        for (dp = qdp; dp; dp = qdp)
 | 
						|
        {
 | 
						|
            if (strlen(str1))
 | 
						|
                strcat(str1, " ");
 | 
						|
            strcat(str1, dp->d_name->n_name);
 | 
						|
            qdp = dp->d_next;
 | 
						|
            free((char *)dp);
 | 
						|
        }
 | 
						|
        setmacro("?", str1, 4);
 | 
						|
        setmacro("@", np->n_name, 4);
 | 
						|
        p = strrchr(np->n_name, '.');
 | 
						|
        if (p) *p = 0;
 | 
						|
        setmacro("*", np->n_name, 4);
 | 
						|
        if (p) *p = '.';
 | 
						|
        if (lp)     /* lp set if doing a :: rule */
 | 
						|
            docmds1(np, lp);
 | 
						|
        else
 | 
						|
            docmds(np);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  Recursive routine to make a target.
 | 
						|
 */
 | 
						|
int make(struct name *np, int level)
 | 
						|
{
 | 
						|
    register struct depend *    dp;
 | 
						|
    register struct line *      lp;
 | 
						|
    register struct depend *    qdp;
 | 
						|
    time_t              dtime = 1;
 | 
						|
    bool                didsomething = 0;
 | 
						|
    int             dynamic = 0;
 | 
						|
 | 
						|
 | 
						|
    if (np->n_flag & N_DONE)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    if (!np->n_time)
 | 
						|
        modtime(np);        /*  Gets modtime of this file  */
 | 
						|
 | 
						|
    if (rules)
 | 
						|
    {
 | 
						|
        for (lp = np->n_line; lp; lp = lp->l_next)
 | 
						|
            if (lp->l_cmd)
 | 
						|
                break;
 | 
						|
        if (!lp) {
 | 
						|
            dyndep(np);
 | 
						|
            dynamic = 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!(np->n_flag & N_TARG) && np->n_time == 0L)
 | 
						|
        fatal("Don't know how to make %s", np->n_name);
 | 
						|
 | 
						|
    for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
 | 
						|
    {
 | 
						|
        for (dp = lp->l_dep; dp; dp = dp->d_next)
 | 
						|
        {
 | 
						|
            char *sv = 0;
 | 
						|
            if (dynamic) {
 | 
						|
                char *s = getmacro("<");
 | 
						|
 | 
						|
                if (s) {
 | 
						|
                    sv = malloc((unsigned)(strlen(s)+1));
 | 
						|
                    if (!sv) {
 | 
						|
                        fatal("no space for saved $<",NULL);
 | 
						|
                    }
 | 
						|
                    strcpy(sv, s);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            make(dp->d_name, level+1);
 | 
						|
            if (dynamic && sv) {
 | 
						|
                setmacro("<", sv, 4);
 | 
						|
                free(sv);
 | 
						|
            }
 | 
						|
            if (np->n_time < dp->d_name->n_time)
 | 
						|
                qdp = newdep(dp->d_name, qdp);
 | 
						|
            dtime = max(dtime, dp->d_name->n_time);
 | 
						|
        }
 | 
						|
        if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
 | 
						|
        {
 | 
						|
            make1(np, lp, qdp); /* free()'s qdp */
 | 
						|
            dtime = 1;
 | 
						|
            qdp = (struct depend *)0;
 | 
						|
            didsomething++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    np->n_flag |= N_DONE;
 | 
						|
 | 
						|
    if (quest)
 | 
						|
    {
 | 
						|
        long        t;
 | 
						|
 | 
						|
        t = np->n_time;
 | 
						|
        time(&np->n_time);
 | 
						|
        return t < dtime;
 | 
						|
    }
 | 
						|
    else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
 | 
						|
    {
 | 
						|
        make1(np, (struct line *)0, qdp);   /* free()'s qdp */
 | 
						|
        time(&np->n_time);
 | 
						|
    }
 | 
						|
    else if (level == 0 && !didsomething)
 | 
						|
        printf("%s: '%s' is up to date\n", myname, np->n_name);
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
 |