summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2000-09-14 13:52:43 +0000
committerMarc Espie <espie@cvs.openbsd.org>2000-09-14 13:52:43 +0000
commit52f00e4396ef3d5f47122233da72feb932ce3f8e (patch)
tree3eb6b0c9bff2378bef6d289969deac7e031da6cc
parentcc11fcd76306cd4861949984c169afd9d9b1f759 (diff)
Introduce a few macros to handle timestamps in an abstract way.
Replace the time stamp hash in dir.c with an open hashing structure. In doing so, remove some nasty casts, simplify code a bit: Dir_MTime can return a modification time, since make does not make a distinction between out-of-date and non-existent files.
-rw-r--r--usr.bin/make/arch.c17
-rw-r--r--usr.bin/make/compat.c11
-rw-r--r--usr.bin/make/dir.c138
-rw-r--r--usr.bin/make/dir.h4
-rw-r--r--usr.bin/make/extern.h4
-rw-r--r--usr.bin/make/job.c6
-rw-r--r--usr.bin/make/make.c11
-rw-r--r--usr.bin/make/make.h21
-rw-r--r--usr.bin/make/targ.c5
9 files changed, 133 insertions, 84 deletions
diff --git a/usr.bin/make/arch.c b/usr.bin/make/arch.c
index 959641603ef..30df6314ee0 100644
--- a/usr.bin/make/arch.c
+++ b/usr.bin/make/arch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arch.c,v 1.33 2000/09/14 13:46:44 espie Exp $ */
+/* $OpenBSD: arch.c,v 1.34 2000/09/14 13:52:41 espie Exp $ */
/* $NetBSD: arch.c,v 1.17 1996/11/06 17:58:59 christos Exp $ */
/*
@@ -109,7 +109,7 @@
static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: arch.c,v 1.33 2000/09/14 13:46:44 espie Exp $";
+static char rcsid[] = "$OpenBSD: arch.c,v 1.34 2000/09/14 13:52:41 espie Exp $";
#endif
#endif /* not lint */
@@ -998,15 +998,14 @@ Arch_TouchLib (gn)
* Return the modification time of a member of an archive.
*
* Results:
- * TRUE if found.
+ * The modification time (seconds).
*
* Side Effects:
* The mtime field of the given node is filled in with the value
* returned by the function.
- *
*-----------------------------------------------------------------------
*/
-Boolean
+TIMESTAMP
Arch_MTime (gn)
GNode *gn; /* Node describing archive member */
{
@@ -1015,13 +1014,11 @@ Arch_MTime (gn)
arhPtr = ArchStatMember(Varq_Value(ARCHIVE_INDEX, gn),
Varq_Value(MEMBER_INDEX, gn),
TRUE);
- if (arhPtr != NULL) {
+ if (arhPtr != NULL)
gn->mtime = (time_t) strtol(arhPtr->ar_date, NULL, 10);
- return TRUE;
- } else {
+ else
gn->mtime = OUT_OF_DATE;
- return FALSE;
- }
+ return gn->mtime;
}
/*-
diff --git a/usr.bin/make/compat.c b/usr.bin/make/compat.c
index 6e8d066c6c8..18671d4a0f0 100644
--- a/usr.bin/make/compat.c
+++ b/usr.bin/make/compat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.c,v 1.34 2000/09/14 13:46:44 espie Exp $ */
+/* $OpenBSD: compat.c,v 1.35 2000/09/14 13:52:41 espie Exp $ */
/* $NetBSD: compat.c,v 1.14 1996/11/06 17:59:01 christos Exp $ */
/*
@@ -70,7 +70,7 @@
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: compat.c,v 1.34 2000/09/14 13:46:44 espie Exp $";
+static char rcsid[] = "$OpenBSD: compat.c,v 1.35 2000/09/14 13:52:41 espie Exp $";
#endif
#endif /* not lint */
@@ -443,7 +443,7 @@ CompatMake(gnp, pgnp)
GNode *pgn = (GNode *) pgnp;
if (pgn->type & OP_MADE) {
- (void) Dir_MTime(gn);
+ (void)Dir_MTime(gn);
gn->made = UPTODATE;
}
@@ -589,10 +589,9 @@ CompatMake(gnp, pgnp)
* ok.
* -- ardeb 1/12/88
*/
- if (noExecute || Dir_MTime(gn) == FALSE) {
+ if (noExecute || is_out_of_date(Dir_MTime(gn)))
gn->mtime = now;
- }
- if (gn->cmtime > gn->mtime)
+ if (is_before(gn->mtime, gn->cmtime))
gn->mtime = gn->cmtime;
if (DEBUG(MAKE)) {
printf("update time: %s\n", Targ_FmtTime(gn->mtime));
diff --git a/usr.bin/make/dir.c b/usr.bin/make/dir.c
index 4f345ec90b6..645e1ab2bdf 100644
--- a/usr.bin/make/dir.c
+++ b/usr.bin/make/dir.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dir.c,v 1.26 2000/09/14 13:46:44 espie Exp $ */
+/* $OpenBSD: dir.c,v 1.27 2000/09/14 13:52:41 espie Exp $ */
/* $NetBSD: dir.c,v 1.14 1997/03/29 16:51:26 christos Exp $ */
/*
@@ -88,7 +88,6 @@
#include <dirent.h>
#include <sys/stat.h>
#include "make.h"
-#include "hash.h"
#include "ohash.h"
#include "dir.h"
@@ -97,7 +96,7 @@
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: dir.c,v 1.26 2000/09/14 13:46:44 espie Exp $";
+static char rcsid[] = "$OpenBSD: dir.c,v 1.27 2000/09/14 13:52:41 espie Exp $";
#endif
#endif /* not lint */
@@ -184,7 +183,13 @@ static int hits, /* Found in directory cache */
bigmisses; /* Sought by itself */
static Path *dot; /* contents of current directory */
-static Hash_Table mtimes; /* Results of doing a last-resort stat in
+
+struct file_stamp {
+ TIMESTAMP mtime; /* time stamp... */
+ char name[1]; /* ...for that file. */
+};
+
+static struct hash mtimes; /* Results of doing a last-resort stat in
* Dir_FindFile -- if we have to go to the
* system to find the file, we might as well
* have its mtime on record. XXX: If this is done
@@ -194,14 +199,23 @@ static Hash_Table mtimes; /* Results of doing a last-resort stat in
* be two rules to update a single file, so this
* should be ok, but... */
+/* There are three distinct hash structures:
+ * - to collate files's last modification times (global mtimes)
+ * - to collate file names (in each Path structure)
+ * - to collate known directories (global openDirectories). */
+static struct hash_info stamp_info = { offsetof(struct file_stamp, name),
+ NULL, hash_alloc, hash_free, element_alloc };
+
static struct hash_info file_info = { 0,
NULL, hash_alloc, hash_free, element_alloc };
static struct hash_info dir_info = { offsetof(Path, name),
NULL, hash_alloc, hash_free, element_alloc };
+static void record_stamp __P((const char *, TIMESTAMP));
static void add_file __P((Path *, const char *));
static char *find_file_hash __P((Path *, const char *, const char *, u_int32_t));
+static struct file_stamp *find_stamp __P((const char *));
static void free_hash __P((struct hash *));
static Path *DirReaddir __P((const char *, const char *));
@@ -212,6 +226,33 @@ static void DirPrintWord __P((void *));
static void DirPrintDir __P((void *));
static void
+record_stamp(file, t)
+ const char *file;
+ TIMESTAMP t;
+{
+ unsigned slot;
+ const char *end = NULL;
+ struct file_stamp *n;
+
+ slot = hash_qlookupi(&mtimes, file, &end);
+ n = hash_find(&mtimes, slot);
+ if (n)
+ n->mtime = t;
+ else {
+ n = hash_create_entry(&stamp_info, file, &end);
+ n->mtime = t;
+ hash_insert(&mtimes, slot, n);
+ }
+}
+
+static struct file_stamp *
+find_stamp(file)
+ const char *file;
+{
+ return hash_find(&mtimes, hash_qlookup(&mtimes, file));
+}
+
+static void
add_file(p, file)
Path *p;
const char *file;
@@ -270,7 +311,7 @@ Dir_Init()
{
Lst_Init(&dirSearchPath);
hash_init(&openDirectories, 4, &dir_info);
- Hash_InitTable(&mtimes, 0);
+ hash_init(&mtimes, 4, &stamp_info);
dot = DirReaddir(".", NULL);
@@ -687,9 +728,10 @@ Dir_FindFile(name, path)
register char *cp; /* index of first slash, if any */
Boolean hasSlash; /* true if 'name' contains a / */
struct stat stb; /* Buffer for stat, if necessary */
+ struct file_stamp
+ *entry; /* Entry for mtimes table */
const char *e;
u_int32_t hv;
- Hash_Entry *entry;
/*
* Find the final component of the name and note whether it has a
@@ -817,6 +859,9 @@ Dir_FindFile(name, path)
printf("checking %s...", file);
if (stat(file, &stb) == 0) {
+ TIMESTAMP mtime;
+
+ grab_stat(stb, mtime);
if (DEBUG(DIR))
printf("got it.\n");
@@ -835,10 +880,7 @@ Dir_FindFile(name, path)
if (DEBUG(DIR))
printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
file);
- entry = Hash_CreateEntry(&mtimes, (char *) file,
- (Boolean *)NULL);
- /* XXX */
- Hash_SetValue(entry, (void *)((long)stb.st_mtime));
+ record_stamp(file, mtime);
nearmisses += 1;
return file;
} else
@@ -890,18 +932,19 @@ Dir_FindFile(name, path)
printf("Looking for \"%s\"...", name);
bigmisses += 1;
- entry = Hash_FindEntry(&mtimes, name);
- if (entry != (Hash_Entry *)NULL) {
+ entry = find_stamp(name);
+ if (entry != NULL) {
if (DEBUG(DIR))
printf("got it (in mtime cache)\n");
return estrdup(name);
} else if (stat(name, &stb) == 0) {
- entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL);
+ TIMESTAMP mtime;
+
+ grab_stat(stb, mtime);
if (DEBUG(DIR))
printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
name);
- /* XXX */
- Hash_SetValue(entry, (void *)(long)stb.st_mtime);
+ record_stamp(name, mtime);
return estrdup(name);
} else {
if (DEBUG(DIR))
@@ -918,7 +961,7 @@ Dir_FindFile(name, path)
* search path dirSearchPath.
*
* Results:
- * TRUE if file exists.
+ * The modification time or OUT_OF_DATE if it doesn't exist
*
* Side Effects:
* The modification time is placed in the node's mtime slot.
@@ -926,63 +969,54 @@ Dir_FindFile(name, path)
* found one for it, the full name is placed in the path slot.
*-----------------------------------------------------------------------
*/
-Boolean
+TIMESTAMP
Dir_MTime(gn)
GNode *gn; /* the file whose modification time is
* desired */
{
char *fullName; /* the full pathname of name */
struct stat stb; /* buffer for finding the mod time */
- Hash_Entry *entry;
- Boolean exists;
+ struct file_stamp
+ *entry;
+ unsigned int slot;
+ TIMESTAMP mtime;
if (gn->type & OP_ARCHV)
return Arch_MTime(gn);
- else if (gn->path == NULL)
+ if (gn->path == NULL) {
fullName = Dir_FindFile(gn->name, &dirSearchPath);
- else
+ if (fullName == NULL)
+ fullName = estrdup(gn->name);
+ } else
fullName = gn->path;
- if (fullName == (char *)NULL) {
- fullName = estrdup(gn->name);
- }
-
- entry = Hash_FindEntry(&mtimes, fullName);
- if (entry != (Hash_Entry *)NULL) {
- /*
- * Only do this once -- the second time folks are checking to
+ slot = hash_qlookup(&mtimes, fullName);
+ entry = hash_find(&mtimes, slot);
+ if (entry != NULL) {
+ /* Only do this once -- the second time folks are checking to
* see if the file was actually updated, so we need to actually go
- * to the file system.
- */
- if (DEBUG(DIR)) {
+ * to the file system. */
+ if (DEBUG(DIR))
printf("Using cached time %s for %s\n",
- Targ_FmtTime((time_t)(long)Hash_GetValue(entry)), fullName);
- }
- stb.st_mtime = (time_t)(long)Hash_GetValue(entry);
- Hash_DeleteEntry(&mtimes, entry);
- exists = TRUE;
- } else if (stat (fullName, &stb) == 0) {
- /* XXX forces make to differentiate between the epoch and
- * non-existent files by kludging the timestamp slightly. */
- if (stb.st_mtime == OUT_OF_DATE)
- stb.st_mtime++;
- exists = TRUE;
- } else {
+ Targ_FmtTime(entry->mtime), fullName);
+ mtime = entry->mtime;
+ free(entry);
+ hash_remove(&mtimes, slot);
+ } else if (stat(fullName, &stb) == 0)
+ grab_stat(stb, mtime);
+ else {
if (gn->type & OP_MEMBER) {
if (fullName != gn->path)
free(fullName);
return Arch_MemMTime (gn);
- } else {
- stb.st_mtime = OUT_OF_DATE;
- exists = FALSE;
- }
+ } else
+ set_out_of_date(mtime);
}
- if (fullName && gn->path == (char *)NULL) {
+ if (fullName && gn->path == NULL)
gn->path = fullName;
- }
- gn->mtime = stb.st_mtime;
- return exists;
+ gn->mtime = mtime;
+ return gn->mtime;
}
/* Read a directory, either from the disk, or from the cache. */
diff --git a/usr.bin/make/dir.h b/usr.bin/make/dir.h
index 29de013dbaf..679225be602 100644
--- a/usr.bin/make/dir.h
+++ b/usr.bin/make/dir.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dir.h,v 1.9 2000/09/14 13:46:45 espie Exp $ */
+/* $OpenBSD: dir.h,v 1.10 2000/09/14 13:52:41 espie Exp $ */
/* $NetBSD: dir.h,v 1.4 1996/11/06 17:59:05 christos Exp $ */
/*
@@ -60,7 +60,7 @@ extern void Dir_End __P((void));
extern Boolean Dir_HasWildcards __P((char *));
extern void Dir_Expand __P((char *, Lst, Lst));
extern char *Dir_FindFile __P((char *, Lst));
-extern Boolean Dir_MTime __P((GNode *));
+extern TIMESTAMP Dir_MTime __P((GNode *));
extern void Dir_AddDir __P((Lst, const char *, const char *));
extern char *Dir_MakeFlags __P((char *, Lst));
extern void Dir_ClearPath __P((Lst));
diff --git a/usr.bin/make/extern.h b/usr.bin/make/extern.h
index 1569bf277a3..52aa630b61a 100644
--- a/usr.bin/make/extern.h
+++ b/usr.bin/make/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.32 2000/09/14 13:40:03 espie Exp $ */
+/* $OpenBSD: extern.h,v 1.33 2000/09/14 13:52:42 espie Exp $ */
/* $NetBSD: nonints.h,v 1.12 1996/11/06 17:59:19 christos Exp $ */
/*-
@@ -45,7 +45,7 @@
extern ReturnStatus Arch_ParseArchive __P((char **, Lst, SymTable *));
extern void Arch_Touch __P((GNode *));
extern void Arch_TouchLib __P((GNode *));
-extern Boolean Arch_MTime __P((GNode *));
+extern TIMESTAMP Arch_MTime __P((GNode *));
extern Boolean Arch_MemMTime __P((GNode *));
extern void Arch_FindLib __P((GNode *, Lst));
extern Boolean Arch_LibOODate __P((GNode *));
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index 91081d8fd1e..83cc5c4615e 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: job.c,v 1.36 2000/09/14 13:46:45 espie Exp $ */
+/* $OpenBSD: job.c,v 1.37 2000/09/14 13:52:42 espie Exp $ */
/* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */
/*
@@ -126,7 +126,7 @@
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: job.c,v 1.36 2000/09/14 13:46:45 espie Exp $";
+static char rcsid[] = "$OpenBSD: job.c,v 1.37 2000/09/14 13:52:42 espie Exp $";
#endif
#endif /* not lint */
@@ -1099,7 +1099,7 @@ Job_CheckCommands(gn, abortProc)
*/
Make_HandleUse(DEFAULT, gn);
Varq_Set(IMPSRC_INDEX, Varq_Value(TARGET_INDEX, gn), gn);
- } else if (Dir_MTime(gn) == 0) {
+ } else if (is_out_of_date(Dir_MTime(gn))) {
/*
* The node wasn't the target of an operator we have no .DEFAULT
* rule to go on and the target doesn't already exist. There's
diff --git a/usr.bin/make/make.c b/usr.bin/make/make.c
index 0b48083bf51..6f8e2c1d279 100644
--- a/usr.bin/make/make.c
+++ b/usr.bin/make/make.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: make.c,v 1.22 2000/09/14 13:46:45 espie Exp $ */
+/* $OpenBSD: make.c,v 1.23 2000/09/14 13:52:42 espie Exp $ */
/* $NetBSD: make.c,v 1.10 1996/11/06 17:59:15 christos Exp $ */
/*
@@ -82,7 +82,7 @@
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
#else
UNUSED
-static char rcsid[] = "$OpenBSD: make.c,v 1.22 2000/09/14 13:46:45 espie Exp $";
+static char rcsid[] = "$OpenBSD: make.c,v 1.23 2000/09/14 13:52:42 espie Exp $";
#endif
#endif /* not lint */
@@ -161,9 +161,9 @@ Make_OODate (gn)
* doesn't depend on their modification time...
*/
if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
- (void) Dir_MTime (gn);
+ (void)Dir_MTime(gn);
if (DEBUG(MAKE)) {
- if (gn->mtime != OUT_OF_DATE) {
+ if (!is_out_of_date(gn->mtime)) {
printf ("modified %s...", Targ_FmtTime(gn->mtime));
} else {
printf ("non-existent...");
@@ -461,7 +461,8 @@ Make_Update (cgn)
* the target is made now. Otherwise archives with ... rules
* don't work!
*/
- if (noExecute || (cgn->type & OP_SAVE_CMDS) || Dir_MTime(cgn) == FALSE) {
+ if (noExecute || (cgn->type & OP_SAVE_CMDS) ||
+ is_out_of_date(Dir_MTime(cgn))) {
cgn->mtime = now;
}
if (DEBUG(MAKE)) {
diff --git a/usr.bin/make/make.h b/usr.bin/make/make.h
index 386ba0b8c65..9592bfeb28d 100644
--- a/usr.bin/make/make.h
+++ b/usr.bin/make/make.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: make.h,v 1.26 2000/09/14 13:40:03 espie Exp $ */
+/* $OpenBSD: make.h,v 1.27 2000/09/14 13:52:42 espie Exp $ */
/* $NetBSD: make.h,v 1.15 1997/03/10 21:20:00 christos Exp $ */
/*
@@ -90,6 +90,25 @@
#include "config.h"
#include "buf.h"
+typedef time_t TIMESTAMP;
+#define is_out_of_date(t) ((t) == INT_MIN)
+#define set_out_of_date(t) (t) = INT_MIN
+#define grab_stat(s, t) \
+do { \
+ (t) = (s).st_mtime; \
+ if (is_out_of_date(t)) \
+ (t)++; \
+} while (0)
+#define is_before(t1, t2) ((t1) < (t2))
+#define grab_date(d, t) \
+do { \
+ (t) = d; \
+ if (is_out_of_date(t)) \
+ (t)++; \
+} while (0)
+#define grab(n) time(&(n))
+#define timestamp2time_t(t) (t)
+
#define OUT_OF_DATE INT_MIN
/* Variables that are kept in local GNodes. */
diff --git a/usr.bin/make/targ.c b/usr.bin/make/targ.c
index 5abf9aa147e..35386ab521b 100644
--- a/usr.bin/make/targ.c
+++ b/usr.bin/make/targ.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: targ.c,v 1.27 2000/09/14 13:40:03 espie Exp $ */
+/* $OpenBSD: targ.c,v 1.28 2000/09/14 13:52:42 espie Exp $ */
/* $NetBSD: targ.c,v 1.11 1997/02/20 16:51:50 christos Exp $ */
/*
@@ -80,7 +80,6 @@
#include <time.h>
#include "make.h"
#include "ohash.h"
-#include "hash.h"
#include "dir.h"
#ifndef lint
@@ -88,7 +87,7 @@
static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
#else
UNUSED
-static char *rcsid = "$OpenBSD: targ.c,v 1.27 2000/09/14 13:40:03 espie Exp $";
+static char *rcsid = "$OpenBSD: targ.c,v 1.28 2000/09/14 13:52:42 espie Exp $";
#endif
#endif /* not lint */