[BACK]Return to util.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

File: [local] / src / usr.bin / make / Attic / util.c (download)

Revision 1.6, Tue Apr 1 07:28:26 1997 UTC (27 years, 2 months ago) by millert
Branch: MAIN
CVS Tags: OPENBSD_2_1_BASE, OPENBSD_2_1
Changes since 1.5: +71 -3 lines

Sync with NetBSD (mostly by christos initial substitution/regexp from Der Mouse)

- fix the variable substitution code in make [PR/2748]
      1. change s/a/b/ so that it substitutes the first occurance of the
         pattern on each word, not only the first word.
      2. add flag '1' to the variable substitution so that the substitutions
         get performed only once.

  ***THIS IS AN INCOMPATIBLE CHANGE!***

  Unfortunately there was no way to make things consistent without
  modifying the current behavior. Fortunately none of our Makefiles
  depended on this.

            OLD:

                VAR      = aa1 aa2 aa3 aa4

                S/a/b/   = ba1 aa2 aa3 aa4
                S/a/b/g  = bb1 bb2 bb3 bb4

            NEW:
                VAR      = aa1 aa2 aa3 aa4

                S/a/b/   = ba1 ba2 ba3 ba4
                S/a/b/1  = ba1 aa2 aa3 aa4
                S/a/b/g  = bb1 bb2 bb3 bb4
                S/a/b/1g = bb1 aa2 aa3 aa4
- add regexp variable substitution via 'C/foo/bar/' [PR/2752]
- add variable quoting via the ${VAR:Q} modifier. This is useful when running
  recursive invocations of make(1):

        make VAR=${VAR:Q}

  will always work... (This may prove useful in the kernel builds...) [PR/2981]
- BSD did not traditionally have <sys/cdefs.h>; use BSD4_4 instead and include
  <sys/param.h> to grab it.
- Don't compile the regex code if MAKE_BOOTSTRAP (from gwr)
- Use explicit .c.o rule in Makefile.boot so that the bootstrap process works.
- Use only integral types in procedure arguments. [buf.c buf.h]
- Include <stdlib.h> to get getenv() prototype on SVR4
- if __STDC__ -> ifdef __STDC__ to appease SVR4
- Define const and volatile for non __STDC__
- Implement snprintf() and vsnprintf() for non BSD4_4 systems.
- Make $MACHINE_ARCH settable from the environment.
- Fix .USE directive problems: (reported by cgd)
    1. ${.*} variables did not get expanded in dependencies.
    2. expanded ${.*} variables in .USE dependencies can cause tree
       restructuring; handle it.
    3. in compat mode, expand .USE before evaluating the list of targets,
       instead of doing .USE expansions on demand, because they can cause
       tree restructuring.
- Add a .MADE directive to indicated that the children of a target are
  up-to-date, even when they are not. This is to simulate our current
  make install behavior with proper dependencies.
- Fix problems in the RE substitution error handling.
- Locate all the children of a node marked as MADE.
- Do not compile-in ${MACHINE} (as per NetBSD PR#3386)
- Disable globbing for targets/dependencies when POSIX is defined.
- Fix globbing so that patterns that don't have a matching number of [] or {}
  don't get expanded. (before the [ case got expanded to nothing!) This is
  disabled.
- Make sure that the children of nodes that are marked .MADE, are marked
  UPTODATE and their timestamps are consistent.
- Don't disable wildcards completely; they are used by other Makefiles.

/*	$OpenBSD: util.c,v 1.6 1997/04/01 07:28:26 millert Exp $	*/
/*	$NetBSD: util.c,v 1.10 1996/12/31 17:56:04 christos Exp $	*/

/*
 * Missing stuff from OS's
 */

#ifndef lint
static char rcsid[] = "$OpenBSD: util.c,v 1.6 1997/04/01 07:28:26 millert Exp $";
#endif

#include <stdio.h>
#include "make.h"
#include <sys/param.h>

#if !__STDC__
# ifndef const
#  define const
# endif
#endif

#ifdef sun



extern int errno, sys_nerr;
extern char *sys_errlist[];

char *
strerror(e)
    int e;
{
    static char buf[100];
    if (e < 0 || e >= sys_nerr) {
	sprintf(buf, "Unknown error %d", e);
	return buf;
    }
    else
	return sys_errlist[e];
}
#endif

#ifdef ultrix
#include <string.h>

/* strdup
 *
 * Make a duplicate of a string.
 * For systems which lack this function.
 */
char *
strdup(str)
    const char *str;
{
    size_t len;
    char *p;

    if (str == NULL)
	return NULL;
    len = strlen(str) + 1;
    if ((p = malloc(len)) == NULL)
	return NULL;

    return memcpy(p, str, len);
}

#endif

#if defined(sun) || defined(__hpux) || defined(__sgi)

int
setenv(name, value, dum)
    const char *name;
    const char *value;
    int dum;
{
    register char *p;
    int len = strlen(name) + strlen(value) + 2; /* = \0 */
    char *ptr = (char*) malloc(len);

    (void) dum;

    if (ptr == NULL)
	return -1;

    p = ptr;

    while (*name)
	*p++ = *name++;

    *p++ = '=';

    while (*value)
	*p++ = *value++;

    *p = '\0';

    len = putenv(ptr);
/*    free(ptr); */
    return len;
}
#endif

#ifdef __hpux
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syscall.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>


int
killpg(pid, sig)
    int pid, sig;
{
    return kill(-pid, sig);
}

void
srandom(seed)
    long seed;
{
    srand48(seed);
}

long
random()
{
    return lrand48();
}

/* turn into bsd signals */
void (*
signal(s, a)) ()
    int     s;
    void (*a)();
{
    struct sigvec osv, sv;

    (void) sigvector(s, (struct sigvec *) 0, &osv);
    sv = osv;
    sv.sv_handler = a;
#ifdef SV_BSDSIG
    sv.sv_flags = SV_BSDSIG;
#endif

    if (sigvector(s, &sv, (struct sigvec *) 0) == -1)
        return (BADSIG);
    return (osv.sv_handler);
}

#if !defined(BSD) && !defined(d_fileno)
# define d_fileno d_ino
#endif

#ifndef DEV_DEV_COMPARE
# define DEV_DEV_COMPARE(a, b) ((a) == (b))
#endif
#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))


/* strrcpy():
 *	Like strcpy, going backwards and returning the new pointer
 */
static char *
strrcpy(ptr, str)
    register char *ptr, *str;
{
    register int len = strlen(str);

    while (len)
	*--ptr = str[--len];

    return (ptr);
} /* end strrcpy */


char   *
getwd(pathname)
    char   *pathname;
{
    DIR    *dp;
    struct dirent *d;
    extern int errno;

    struct stat st_root, st_cur, st_next, st_dotdot;
    char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
    char   *pathptr, *nextpathptr, *cur_name_add;

    /* find the inode of root */
    if (stat("/", &st_root) == -1) {
	(void) sprintf(pathname,
			"getwd: Cannot stat \"/\" (%s)", strerror(errno));
	return (NULL);
    }
    pathbuf[MAXPATHLEN - 1] = '\0';
    pathptr = &pathbuf[MAXPATHLEN - 1];
    nextpathbuf[MAXPATHLEN - 1] = '\0';
    cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];

    /* find the inode of the current directory */
    if (lstat(".", &st_cur) == -1) {
	(void) sprintf(pathname,
			"getwd: Cannot stat \".\" (%s)", strerror(errno));
	return (NULL);
    }
    nextpathptr = strrcpy(nextpathptr, "../");

    /* Descend to root */
    for (;;) {

	/* look if we found root yet */
	if (st_cur.st_ino == st_root.st_ino &&
	    DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
	    (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
	    return (pathname);
	}

	/* open the parent directory */
	if (stat(nextpathptr, &st_dotdot) == -1) {
	    (void) sprintf(pathname,
			    "getwd: Cannot stat directory \"%s\" (%s)",
			    nextpathptr, strerror(errno));
	    return (NULL);
	}
	if ((dp = opendir(nextpathptr)) == NULL) {
	    (void) sprintf(pathname,
			    "getwd: Cannot open directory \"%s\" (%s)",
			    nextpathptr, strerror(errno));
	    return (NULL);
	}

	/* look in the parent for the entry with the same inode */
	if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
	    /* Parent has same device. No need to stat every member */
	    for (d = readdir(dp); d != NULL; d = readdir(dp))
		if (d->d_fileno == st_cur.st_ino)
		    break;
	}
	else {
	    /*
	     * Parent has a different device. This is a mount point so we
	     * need to stat every member
	     */
	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
		if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
		    continue;
		(void) strcpy(cur_name_add, d->d_name);
		if (lstat(nextpathptr, &st_next) == -1) {
		    (void) sprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
				    d->d_name, strerror(errno));
		    (void) closedir(dp);
		    return (NULL);
		}
		/* check if we found it yet */
		if (st_next.st_ino == st_cur.st_ino &&
		    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
		    break;
	    }
	}
	if (d == NULL) {
	    (void) sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
	    (void) closedir(dp);
	    return (NULL);
	}
	st_cur = st_dotdot;
	pathptr = strrcpy(pathptr, d->d_name);
	pathptr = strrcpy(pathptr, "/");
	nextpathptr = strrcpy(nextpathptr, "../");
	(void) closedir(dp);
	*cur_name_add = '\0';
    }
} /* end getwd */


char    *sys_siglist[] = {
        "Signal 0",
        "Hangup",                       /* SIGHUP    */
        "Interrupt",                    /* SIGINT    */
        "Quit",                         /* SIGQUIT   */
        "Illegal instruction",          /* SIGILL    */
        "Trace/BPT trap",               /* SIGTRAP   */
        "IOT trap",                     /* SIGIOT    */
        "EMT trap",                     /* SIGEMT    */
        "Floating point exception",     /* SIGFPE    */
        "Killed",                       /* SIGKILL   */
        "Bus error",                    /* SIGBUS    */
        "Segmentation fault",           /* SIGSEGV   */
        "Bad system call",              /* SIGSYS    */
        "Broken pipe",                  /* SIGPIPE   */
        "Alarm clock",                  /* SIGALRM   */
        "Terminated",                   /* SIGTERM   */
        "User defined signal 1",        /* SIGUSR1   */
        "User defined signal 2",        /* SIGUSR2   */
        "Child exited",                 /* SIGCLD    */
        "Power-fail restart",           /* SIGPWR    */
        "Virtual timer expired",        /* SIGVTALRM */
        "Profiling timer expired",      /* SIGPROF   */
        "I/O possible",                 /* SIGIO     */
        "Window size changes",          /* SIGWINDOW */
        "Stopped (signal)",             /* SIGSTOP   */
        "Stopped",                      /* SIGTSTP   */
        "Continued",                    /* SIGCONT   */
        "Stopped (tty input)",          /* SIGTTIN   */
        "Stopped (tty output)",         /* SIGTTOU   */
        "Urgent I/O condition",         /* SIGURG    */
        "Remote lock lost (NFS)",       /* SIGLOST   */
        "Signal 31",                    /* reserved  */
        "DIL signal"                    /* SIGDIL    */
};

int
utimes(file, tvp)
    char *file;
    struct timeval tvp[2];
{
    struct utimbuf t;

    t.actime  = tvp[0].tv_sec;
    t.modtime = tvp[1].tv_sec;
    return(utime(file, &t));
}


#endif /* __hpux */

#if defined(sun) && defined(__svr4__)
#include <signal.h>

/* turn into bsd signals */
void (*
signal(s, a)) ()
    int     s;
    void (*a)();
{
    struct sigaction sa, osa;

    sa.sa_handler = a;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;

    if (sigaction(s, &sa, &osa) == -1)
	return SIG_ERR;
    else
	return osa.sa_handler;
}

#endif

#ifndef BSD4_4
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif

#ifdef _IOSTRG
#define STRFLAG	(_IOSTRG|_IOWRT)	/* no _IOWRT: avoid stdio bug */
#else
#define STRFLAG	(_IOREAD)		/* XXX: Assume svr4 stdio */
#endif

int
vsnprintf(s, n, fmt, args)
	char *s;
	size_t n;
	const char *fmt;
	va_list args;
{
	FILE fakebuf;

	fakebuf._flag = STRFLAG;
	/*
	 * Some os's are char * _ptr, others are unsigned char *_ptr...
	 * We cast to void * to make everyone happy.
	 */
	fakebuf._ptr = (void *) s;
	fakebuf._cnt = n-1;
	fakebuf._file = -1;
	_doprnt(fmt, args, &fakebuf);
	fakebuf._cnt++;
	putc('\0', &fakebuf);
	if (fakebuf._cnt<0)
	    fakebuf._cnt = 0;
	return (n-fakebuf._cnt-1);
}

int
#ifdef __STDC__
snprintf(char *s, size_t n, const char *fmt, ...)
#else
snprintf(va_alist)
	va_dcl
#endif
{
	va_list ap;
	int rv;
#ifdef __STDC__
	va_start(ap, fmt);
#else
	char *s;
	size_t n;
	const char *fmt;

	va_start(ap);

	s = va_arg(ap, char *);
	n = va_arg(ap, size_t);
	fmt = va_arg(ap, const char *);
#endif
	rv = vsnprintf(s, n, fmt, ap);
	va_end(ap);
	return rv;
}
#endif