regexp engine now undestands some character classes (like :space:) and non-greedy ops
[k8jam.git] / src / timestamp.c
blob6362110d1c12e3c43e346315920b4d8d157d937b
1 /*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6 /*
7 * timestamp.c - get the timestamp of a file or archive member
9 * 09/22/00 (seiwald) - downshift names on OS2, too
10 * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan
11 * 11/04/02 (seiwald) - const-ing for string literals
13 #include "jam.h"
14 #include "hash.h"
15 #include "filesys.h"
16 #include "pathsys.h"
17 #include "timestamp.h"
18 #include "newstr.h"
22 * BINDING - all known files
25 #define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
27 enum {
28 BIND_INIT, /* never seen */
29 BIND_NOENTRY, /* timestamp requested but file never found */
30 BIND_SPOTTED, /* file found but not timed yet */
31 BIND_MISSING, /* file found but can't get timestamp */
32 BIND_FOUND /* file found and time stamped */
36 typedef struct _binding BINDING;
37 struct _binding {
38 const char *name;
39 short flags; // BIND_SCANNED
40 short progress; // enum
41 time_t time; /* update time - 0 if not exist */
45 static struct hash *bindhash = 0;
46 static void time_enter (void *, const char *, int, time_t);
49 static const char *time_progress[] = {
50 "INIT",
51 "NOENTRY",
52 "SPOTTED",
53 "MISSING",
54 "FOUND"
59 * timestamp() - return timestamp on a file, if present
61 void timestamp (char *target, time_t *time) {
62 PATHNAME f1, f2;
63 BINDING binding, *b = &binding;
64 char buf[MAXJPATH];
65 #ifdef DOWNSHIFT_PATHS
66 char path[MAXJPATH];
67 char *p = path;
69 do { *p++ = tolower(*target); } while (*target++) ;
70 target = path;
71 #endif
73 if (!bindhash) bindhash = hashinit(sizeof(BINDING), "bindings");
74 /* quick path: is it there? */
75 b->name = target;
76 b->time = b->flags = 0;
77 b->progress = BIND_INIT;
78 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(target); /* never freed */
79 if (b->progress != BIND_INIT) goto afterscanning;
80 b->progress = BIND_NOENTRY;
81 /* not found: have to scan for it */
82 path_parse(target, &f1);
83 /* scan directory if not already done so */
85 BINDING binding, *b = &binding;
87 f2 = f1;
88 f2.f_grist.len = 0;
89 path_parent(&f2);
90 path_build(&f2, buf, 0);
91 b->name = buf;
92 b->time = b->flags = 0;
93 b->progress = BIND_INIT;
94 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(buf); /* never freed */
95 if (!(b->flags & BIND_SCANNED)) {
96 file_dirscan(buf, time_enter, bindhash);
97 b->flags |= BIND_SCANNED;
100 /* scan archive if not already done so */
101 if (f1.f_member.len) {
102 BINDING binding, *b = &binding;
104 f2 = f1;
105 f2.f_grist.len = 0;
106 f2.f_member.len = 0;
107 path_build(&f2, buf, 0);
108 b->name = buf;
109 b->time = b->flags = 0;
110 b->progress = BIND_INIT;
111 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(buf); /* never freed */
112 if (!(b->flags & BIND_SCANNED)) {
113 file_archscan(buf, time_enter, bindhash);
114 b->flags |= BIND_SCANNED;
117 afterscanning:
118 if (b->progress == BIND_SPOTTED) {
119 if (file_time(b->name, &b->time) < 0) b->progress = BIND_MISSING;
120 else b->progress = BIND_FOUND;
122 *time = b->progress == BIND_FOUND ? b->time : 0;
126 static void time_enter (void *closure, const char *target, int found, time_t time) {
127 BINDING binding, *b = &binding;
128 struct hash *bindhash = (struct hash *)closure;
129 #ifdef DOWNSHIFT_PATHS
130 char path[MAXJPATH];
131 char *p = path;
133 do { *p++ = tolower(*target); } while (*target++) ;
134 target = path;
135 #endif
136 b->name = target;
137 b->flags = 0;
138 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(target); /* never freed */
139 b->time = time;
140 b->progress = found ? BIND_FOUND : BIND_SPOTTED;
141 if (DEBUG_BINDSCAN) printf("time ( %s ) : %s\n", target, time_progress[b->progress]);
146 * donestamps() - free timestamp tables
148 void donestamps (void) {
149 hashdone(bindhash);