option.c: fixed warnings
[k8jam.git] / src / timestamp.c
blobf8eea0dcd38438b171949c5a76e4fbfa87e2477b
1 /*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 * This file is part of Jam - see jam.c for Copyright information.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * timestamp.c - get the timestamp of a file or archive member
20 #include "jam.h"
21 #include "hash.h"
22 #include "filesys.h"
23 #include "pathsys.h"
24 #include "timestamp.h"
25 #include "newstr.h"
29 * BINDING - all known files
32 #define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */
34 enum {
35 BIND_INIT, /* never seen */
36 BIND_NOENTRY, /* timestamp requested but file never found */
37 BIND_SPOTTED, /* file found but not timed yet */
38 BIND_MISSING, /* file found but can't get timestamp */
39 BIND_FOUND /* file found and time stamped */
43 typedef struct _binding BINDING;
44 struct _binding {
45 const char *name;
46 short flags; // BIND_SCANNED
47 short progress; // enum
48 time_t time; /* update time - 0 if not exist */
52 static struct hash *bindhash = 0;
53 static void time_enter (void *, const char *, int, time_t);
56 static const char *time_progress[] = {
57 "INIT",
58 "NOENTRY",
59 "SPOTTED",
60 "MISSING",
61 "FOUND"
66 * timestamp() - return timestamp on a file, if present
68 void timestamp (char *target, time_t *time) {
69 PATHNAME f1, f2;
70 BINDING binding, *b = &binding;
71 static char buf[MAXJPATH];
72 #ifdef DOWNSHIFT_PATHS
73 static char path[MAXJPATH];
74 char *p = path;
75 do { *p++ = tolower(*target); } while (*target++) ;
76 target = path;
77 #endif
78 if (!bindhash) bindhash = hashinit(sizeof(BINDING), "bindings");
79 /* quick path: is it there? */
80 b->name = target;
81 b->time = b->flags = 0;
82 b->progress = BIND_INIT;
83 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(target); /* never freed */
84 if (b->progress != BIND_INIT) goto afterscanning;
85 b->progress = BIND_NOENTRY;
86 /* not found: have to scan for it */
87 path_parse(target, &f1);
88 /* scan directory if not already done so */
90 BINDING binding, *b = &binding;
92 f2 = f1;
93 f2.f_grist.len = 0;
94 path_parent(&f2);
95 path_build(buf, &f2);
96 b->name = buf;
97 b->time = b->flags = 0;
98 b->progress = BIND_INIT;
99 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(buf); /* never freed */
100 if (!(b->flags&BIND_SCANNED)) {
101 file_dirscan(buf, time_enter, bindhash);
102 b->flags |= BIND_SCANNED;
105 /* scan archive if not already done so */
106 if (f1.f_member.len) {
107 BINDING binding, *b = &binding;
108 f2 = f1;
109 f2.f_grist.len = 0;
110 f2.f_member.len = 0;
111 path_build(buf, &f2);
112 b->name = buf;
113 b->time = b->flags = 0;
114 b->progress = BIND_INIT;
115 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(buf); /* never freed */
116 if (!(b->flags&BIND_SCANNED)) {
117 file_archscan(buf, time_enter, bindhash);
118 b->flags |= BIND_SCANNED;
121 afterscanning:
122 if (b->progress == BIND_SPOTTED) {
123 if (file_time(b->name, &b->time) < 0) b->progress = BIND_MISSING;
124 else b->progress = BIND_FOUND;
126 *time = b->progress == BIND_FOUND ? b->time : 0;
130 static void time_enter (void *closure, const char *target, int found, time_t time) {
131 BINDING binding, *b = &binding;
132 struct hash *bindhash = (struct hash *)closure;
133 #ifdef DOWNSHIFT_PATHS
134 static char path[MAXJPATH];
135 char *p = path;
136 do { *p++ = tolower(*target); } while (*target++) ;
137 target = path;
138 #endif
139 b->name = target;
140 b->flags = 0;
141 if (hashenter(bindhash, (HASHDATA **)&b)) b->name = newstr(target); /* never freed */
142 b->time = time;
143 b->progress = found ? BIND_FOUND : BIND_SPOTTED;
144 if (DEBUG_BINDSCAN) printf("time ( %s ) : %s\n", target, time_progress[b->progress]);
149 * donestamps() - free timestamp tables
151 void donestamps (void) {
152 hashdone(bindhash);