[Tizen_6_build] Fixed 32-bit arm build with gcc 9
[platform/upstream/boost-jam.git] / timestamp.c
1 /*
2  * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3  *
4  * This file is part of Jam - see jam.c for Copyright information.
5  */
6
7 /*  This file is ALSO:
8  *  Copyright 2001-2004 David Abrahams.
9  *  Distributed under the Boost Software License, Version 1.0.
10  *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11  */
12
13 # include "jam.h"
14
15 # include "hash.h"
16 # include "filesys.h"
17 # include "pathsys.h"
18 # include "timestamp.h"
19 # include "newstr.h"
20 # include "strings.h"
21
22 /*
23  * timestamp.c - get the timestamp of a file or archive member
24  *
25  * 09/22/00 (seiwald) - downshift names on OS2, too
26  */
27
28 /*
29  * BINDING - all known files
30  */
31
32 typedef struct _binding BINDING;
33
34 struct _binding {
35     char    *name;
36     short   flags;
37
38 # define BIND_SCANNED   0x01    /* if directory or arch, has been scanned */
39
40     short   progress;
41
42 # define BIND_INIT  0   /* never seen */
43 # define BIND_NOENTRY   1   /* timestamp requested but file never found */
44 # define BIND_SPOTTED   2   /* file found but not timed yet */
45 # define BIND_MISSING   3   /* file found but can't get timestamp */
46 # define BIND_FOUND 4   /* file found and time stamped */
47
48     time_t  time;       /* update time - 0 if not exist */
49 };
50
51 static struct hash * bindhash = 0;
52 static void time_enter( void *, char *, int, time_t );
53
54 static char * time_progress[] =
55 {
56     "INIT",
57     "NOENTRY",
58     "SPOTTED",
59     "MISSING",
60     "FOUND"
61 };
62
63
64 /*
65  * timestamp() - return timestamp on a file, if present.
66  */
67
68 void timestamp( char * target, time_t * time )
69 {
70     PROFILE_ENTER( timestamp );
71
72     PATHNAME   f1;
73     PATHNAME   f2;
74     BINDING    binding;
75     BINDING  * b = &binding;
76     string     buf[ 1 ];
77 #ifdef DOWNSHIFT_PATHS
78     string     path;
79     char     * p;
80 #endif
81
82 #ifdef DOWNSHIFT_PATHS
83     string_copy( &path, target );
84     p = path.value;
85
86     do
87     {
88         *p = tolower( *p );
89 #ifdef NT
90         /* On NT, we must use backslashes or the file will not be found. */
91         if ( *p == '/' )
92             *p = PATH_DELIM;
93 #endif
94     }
95     while ( *p++ );
96
97     target = path.value;
98 #endif  /* #ifdef DOWNSHIFT_PATHS */
99     string_new( buf );
100
101     if ( !bindhash )
102         bindhash = hashinit( sizeof( BINDING ), "bindings" );
103
104     /* Quick path - is it there? */
105     b->name = target;
106     b->time = b->flags = 0;
107     b->progress = BIND_INIT;
108
109     if ( hashenter( bindhash, (HASHDATA * *)&b ) )
110         b->name = newstr( target );  /* never freed */
111
112     if ( b->progress != BIND_INIT )
113         goto afterscanning;
114
115     b->progress = BIND_NOENTRY;
116
117     /* Not found - have to scan for it. */
118     path_parse( target, &f1 );
119
120     /* Scan directory if not already done so. */
121     {
122         BINDING binding;
123         BINDING * b = &binding;
124
125         f2 = f1;
126         f2.f_grist.len = 0;
127         path_parent( &f2 );
128         path_build( &f2, buf, 0 );
129
130         b->name = buf->value;
131         b->time = b->flags = 0;
132         b->progress = BIND_INIT;
133
134         if ( hashenter( bindhash, (HASHDATA * *)&b ) )
135             b->name = newstr( buf->value );  /* never freed */
136
137         if ( !( b->flags & BIND_SCANNED ) )
138         {
139             file_dirscan( buf->value, time_enter, bindhash );
140             b->flags |= BIND_SCANNED;
141         }
142     }
143
144     /* Scan archive if not already done so. */
145     if ( f1.f_member.len )
146     {
147         BINDING binding;
148         BINDING * b = &binding;
149
150         f2 = f1;
151         f2.f_grist.len = 0;
152         f2.f_member.len = 0;
153         string_truncate( buf, 0 );
154         path_build( &f2, buf, 0 );
155
156         b->name = buf->value;
157         b->time = b->flags = 0;
158         b->progress = BIND_INIT;
159
160         if ( hashenter( bindhash, (HASHDATA * *)&b ) )
161             b->name = newstr( buf->value );  /* never freed */
162
163         if ( !( b->flags & BIND_SCANNED ) )
164         {
165             file_archscan( buf->value, time_enter, bindhash );
166             b->flags |= BIND_SCANNED;
167         }
168     }
169
170     afterscanning:
171
172     if ( b->progress == BIND_SPOTTED )
173     {
174          b->progress = file_time( b->name, &b->time ) < 0
175             ? BIND_MISSING
176             : BIND_FOUND;
177     }
178
179     *time = b->progress == BIND_FOUND ? b->time : 0;
180         string_free( buf );
181 #ifdef DOWNSHIFT_PATHS
182     string_free( &path );
183 #endif
184
185     PROFILE_EXIT( timestamp );
186 }
187
188
189 static void time_enter( void * closure, char * target, int found, time_t time )
190 {
191     BINDING binding;
192     BINDING * b = &binding;
193     struct hash * bindhash = (struct hash *)closure;
194
195 #ifdef DOWNSHIFT_PATHS
196     char path[ MAXJPATH ];
197     char * p = path;
198
199     do *p++ = tolower( *target );
200     while ( *target++ );
201
202     target = path;
203 #endif
204
205     b->name = target;
206     b->flags = 0;
207
208     if ( hashenter( bindhash, (HASHDATA * *)&b ) )
209         b->name = newstr( target );  /* never freed */
210
211     b->time = time;
212     b->progress = found ? BIND_FOUND : BIND_SPOTTED;
213
214     if ( DEBUG_BINDSCAN )
215         printf( "time ( %s ) : %s\n", target, time_progress[ b->progress ] );
216 }
217
218
219 /*
220  * stamps_done() - free timestamp tables.
221  */
222
223 void stamps_done()
224 {
225     hashdone( bindhash );
226 }