~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/plugins/compilergcc/depslib/src/filent.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* *** This file was borrowed from jam 2.5. The copyright statement from
 
2
 * *** jam.c appears below.
 
3
 */
 
4
/*
 
5
 * /+\
 
6
 * +\   Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
 
7
 * \+/
 
8
 *
 
9
 * This file is part of jam.
 
10
 *
 
11
 * License is hereby granted to use this software and distribute it
 
12
 * freely, as long as this copyright notice is retained and modifications 
 
13
 * are clearly marked.
 
14
 *
 
15
 * ALL WARRANTIES ARE HEREBY DISCLAIMED.
 
16
 */
 
17
 
 
18
/*
 
19
 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
 
20
 *
 
21
 * This file is part of Jam - see jam.c for Copyright information.
 
22
 */
 
23
 
 
24
/*
 
25
 * filent.c - scan directories and archives on NT
 
26
 *
 
27
 * External routines:
 
28
 *
 
29
 *      file_dirscan() - scan a directory for files
 
30
 *      file_time() - get timestamp of file, if not done by file_dirscan()
 
31
 *      file_archscan() - scan an archive for files
 
32
 *
 
33
 * File_dirscan() and file_archscan() call back a caller provided function
 
34
 * for each file found.  A flag to this callback function lets file_dirscan()
 
35
 * and file_archscan() indicate that a timestamp is being provided with the
 
36
 * file.   If file_dirscan() or file_archscan() do not provide the file's
 
37
 * timestamp, interested parties may later call file_time().
 
38
 *
 
39
 * 07/10/95 (taylor)  Findfirst() returns the first file on NT.
 
40
 * 05/03/96 (seiwald) split apart into pathnt.c
 
41
 * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C
 
42
 * 10/03/00 (anton) - Porting for Borland C++ 5.5
 
43
 * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan
 
44
 * 11/04/02 (seiwald) - const-ing for string literals
 
45
 * 01/23/03 (seiwald) - long long handles for NT IA64
 
46
 */
 
47
 
 
48
# include "jam.h"
 
49
# include "filesys.h"
 
50
# include "pathsys.h"
 
51
 
 
52
# ifdef OS_NT
 
53
 
 
54
# ifdef __BORLANDC__
 
55
# if __BORLANDC__ < 0x550
 
56
# include <dir.h>
 
57
# include <dos.h>
 
58
# endif
 
59
# undef PATHNAME        /* cpp namespace collision */
 
60
# define _finddata_t ffblk
 
61
# endif
 
62
 
 
63
# include <io.h>
 
64
# include <sys/stat.h>
 
65
 
 
66
/*
 
67
 * file_dirscan() - scan a directory for files
 
68
 */
 
69
 
 
70
# ifdef _M_IA64
 
71
# define FINDTYPE long long
 
72
# else
 
73
# define FINDTYPE long
 
74
# endif
 
75
 
 
76
void
 
77
file_dirscan( 
 
78
        const char *dir,
 
79
        scanback func,
 
80
        void    *closure )
 
81
{
 
82
        PATHNAME f;
 
83
        char filespec[ MAXJPATH ];
 
84
        char filename[ MAXJPATH ];
 
85
        FINDTYPE handle;
 
86
        int ret;
 
87
        struct _finddata_t finfo[1];
 
88
 
 
89
        /* First enter directory itself */
 
90
 
 
91
        memset( (char *)&f, '\0', sizeof( f ) );
 
92
 
 
93
        f.f_dir.ptr = dir;
 
94
        f.f_dir.len = strlen(dir);
 
95
 
 
96
        dir = *dir ? dir : ".";
 
97
 
 
98
        /* Special case \ or d:\ : enter it */
 
99
 
 
100
        if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
 
101
            (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
 
102
        else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
 
103
            (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
 
104
 
 
105
        /* Now enter contents of directory */
 
106
 
 
107
        sprintf( filespec, "%s/*", dir );
 
108
 
 
109
        if( DEBUG_BINDSCAN )
 
110
            printf( "scan directory %s\n", dir );
 
111
 
 
112
# if defined(__BORLANDC__) && __BORLANDC__ < 0x550
 
113
        if ( ret = findfirst( filespec, finfo, FA_NORMAL | FA_DIREC ) )
 
114
            return;
 
115
 
 
116
        while( !ret )
 
117
        {
 
118
            time_t time_write = finfo->ff_fdate;
 
119
 
 
120
            time_write = (time_write << 16) | finfo->ff_ftime;
 
121
            f.f_base.ptr = finfo->ff_name;
 
122
            f.f_base.len = strlen( finfo->ff_name );
 
123
 
 
124
            path_build( &f, filename );
 
125
 
 
126
            (*func)( closure, filename, 1 /* stat()'ed */, time_write );
 
127
 
 
128
            ret = findnext( finfo );
 
129
        }
 
130
# else
 
131
        handle = _findfirst( filespec, finfo );
 
132
 
 
133
        if( ( ret = ( handle == (FINDTYPE)(-1) ) ) ) /* TNB */
 
134
            return;
 
135
 
 
136
        while( !ret )
 
137
        {
 
138
            f.f_base.ptr = finfo->name;
 
139
            f.f_base.len = strlen( finfo->name );
 
140
 
 
141
            path_build( &f, filename, 0 );
 
142
 
 
143
            (*func)( closure, filename, 1 /* stat()'ed */, finfo->time_write );
 
144
 
 
145
            ret = _findnext( handle, finfo );
 
146
        }
 
147
 
 
148
        _findclose( handle );
 
149
# endif
 
150
 
 
151
}
 
152
 
 
153
/*
 
154
 * file_time() - get timestamp of file, if not done by file_dirscan()
 
155
 */
 
156
 
 
157
int
 
158
file_time(
 
159
        const char *filename,
 
160
        time_t  *time )
 
161
{
 
162
        /* On NT this is called only for C:/ */
 
163
 
 
164
        struct stat statbuf;
 
165
 
 
166
        if( stat( filename, &statbuf ) < 0 )
 
167
            return -1;
 
168
 
 
169
        *time = statbuf.st_mtime;
 
170
 
 
171
        return 0;
 
172
}
 
173
 
 
174
/*
 
175
 * file_archscan() - scan an archive for files
 
176
 */
 
177
 
 
178
/* Straight from SunOS */
 
179
 
 
180
#define ARMAG   "!<arch>\n"
 
181
#define SARMAG  8
 
182
 
 
183
#define ARFMAG  "`\n"
 
184
 
 
185
struct ar_hdr {
 
186
        char    ar_name[16];
 
187
        char    ar_date[12];
 
188
        char    ar_uid[6];
 
189
        char    ar_gid[6];
 
190
        char    ar_mode[8];
 
191
        char    ar_size[10];
 
192
        char    ar_fmag[2];
 
193
};
 
194
 
 
195
# define SARFMAG 2
 
196
# define SARHDR sizeof( struct ar_hdr )
 
197
 
 
198
void
 
199
file_archscan(
 
200
        const char *archive,
 
201
        scanback func,
 
202
        void    *closure )
 
203
{
 
204
        struct ar_hdr ar_hdr;
 
205
        char *string_table = 0;
 
206
        char buf[ MAXJPATH ];
 
207
        long offset;
 
208
        int fd;
 
209
 
 
210
        if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
 
211
            return;
 
212
 
 
213
        if( read( fd, buf, SARMAG ) != SARMAG ||
 
214
            strncmp( ARMAG, buf, SARMAG ) )
 
215
        {
 
216
            close( fd );
 
217
            return;
 
218
        }
 
219
 
 
220
        offset = SARMAG;
 
221
 
 
222
        if( DEBUG_BINDSCAN )
 
223
            printf( "scan archive %s\n", archive );
 
224
 
 
225
        while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
 
226
               !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
 
227
        {
 
228
            long    lar_date;
 
229
            long    lar_size;
 
230
            char    *name = 0;
 
231
            char    *endname;
 
232
            char    *c;
 
233
 
 
234
            sscanf( ar_hdr.ar_date, "%ld", &lar_date );
 
235
            sscanf( ar_hdr.ar_size, "%ld", &lar_size );
 
236
 
 
237
            lar_size = ( lar_size + 1 ) & ~1;
 
238
 
 
239
            if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' )
 
240
            {
 
241
                /* this is the "string table" entry of the symbol table,
 
242
                ** which holds strings of filenames that are longer than
 
243
                ** 15 characters (ie. don't fit into a ar_name
 
244
                */
 
245
 
 
246
                string_table = malloc(lar_size);
 
247
                if (read(fd, string_table, lar_size) != lar_size)
 
248
                    printf("error reading string table\n");
 
249
                offset += SARHDR + lar_size;
 
250
                continue;
 
251
            }
 
252
            else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ')
 
253
            {
 
254
                /* Long filenames are recognized by "/nnnn" where nnnn is
 
255
                ** the offset of the string in the string table represented
 
256
                ** in ASCII decimals.
 
257
                */
 
258
 
 
259
                name = string_table + atoi( ar_hdr.ar_name + 1 );
 
260
                endname = name + strlen( name );
 
261
            }
 
262
            else
 
263
            {
 
264
                /* normal name */
 
265
                name = ar_hdr.ar_name;
 
266
                endname = name + sizeof( ar_hdr.ar_name );
 
267
            }
 
268
 
 
269
            /* strip trailing space, slashes, and backslashes */
 
270
 
 
271
            while( endname-- > name )
 
272
                if( *endname != ' ' && *endname != '\\' && *endname != '/' )
 
273
                    break;
 
274
            *++endname = 0;
 
275
 
 
276
            /* strip leading directory names, an NT specialty */
 
277
 
 
278
            if( ( c = strrchr( name, '/' ) ) ) /* TNB */
 
279
                name = c + 1;
 
280
            if( ( c = strrchr( name, '\\' ) ) ) /* TNB */
 
281
                name = c + 1;
 
282
 
 
283
            sprintf( buf, "%s(%.*s)", archive, endname - name, name );
 
284
            (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
 
285
 
 
286
            offset += SARHDR + lar_size;
 
287
            lseek( fd, offset, 0 );
 
288
        }
 
289
 
 
290
        close( fd );
 
291
}
 
292
 
 
293
# endif /* NT */