files.cpp revision 8ae3ad5802c7fe78d6b353b0d9090276a4f6a210
1b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include "files.h"
2b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <stdio.h>
3b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <errno.h>
4b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <sys/stat.h>
5b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <unistd.h>
6b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <dirent.h>
7b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <fnmatch.h>
88ae3ad5802c7fe78d6b353b0d9090276a4f6a210Alexey Zaytsev#include <string.h>
98ae3ad5802c7fe78d6b353b0d9090276a4f6a210Alexey Zaytsev#include <stdlib.h>
10b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
11b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic bool
12b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectis_comment_line(const char* p)
13b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
14b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (*p && isspace(*p)) {
15b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p++;
16b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
17b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return *p == '#';
18b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
19b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
20b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic string
21b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectpath_append(const string& base, const string& leaf)
22b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
23b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    string full = base;
24b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (base.length() > 0 && leaf.length() > 0) {
25b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        full += '/';
26b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
27b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    full += leaf;
28b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return full;
29b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
30b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
31b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic bool
32b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectis_whitespace_line(const char* p)
33b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
34b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (*p) {
35b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (!isspace(*p)) {
36b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return false;
37b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
38b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p++;
39b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
40b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return true;
41b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
42b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
43b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic bool
44b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectis_exclude_line(const char* p) {
45b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (*p) {
46b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (*p == '-') {
47b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return true;
48b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
49b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else if (isspace(*p)) {
50b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            p++;
51b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
52b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else {
53b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return false;
54b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
55b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
56b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return false;
57b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
58b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
59b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectvoid
60b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectsplit_line(const char* p, vector<string>* out)
61b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
62b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    const char* q = p;
63b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    enum { WHITE, TEXT } state = WHITE;
64b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (*p) {
65b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (*p == '#') {
66b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            break;
67b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
68b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
69b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        switch (state)
70b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        {
71b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            case WHITE:
72b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                if (!isspace(*p)) {
73b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    q = p;
74b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    state = TEXT;
75b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                }
76b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                break;
77b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            case TEXT:
78b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                if (isspace(*p)) {
79b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    if (q != p) {
80b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                        out->push_back(string(q, p-q));
81b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    }
82b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    state = WHITE;
83b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                }
84b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                break;
85b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
86b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p++;
87b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
88b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (state == TEXT) {
89b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        out->push_back(string(q, p-q));
90b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
91b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
92b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
93b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic void
94b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectadd_file(vector<FileRecord>* files, const string& listFile, int listLine,
95b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            const string& sourceName, const string& outName)
96b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
97b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    FileRecord rec;
98b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    rec.listFile = listFile;
99b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    rec.listLine = listLine;
100b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    rec.sourceName = sourceName;
101b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    rec.outName = outName;
102b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    files->push_back(rec);
103b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
104b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
105b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
106b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectread_list_file(const string& filename, vector<FileRecord>* files,
107b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    vector<string>* excludes)
108b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
109b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err = 0;
110b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    FILE* f = NULL;
111b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    long size;
112b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    char* buf = NULL;
113b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    char *p, *q;
114b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int i, lineCount;
115b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
116b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    f = fopen(filename.c_str(), "r");
117b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (f == NULL) {
118b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "Could not open list file (%s): %s\n",
119b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
120b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
121b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
122b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
123b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
124b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = fseek(f, 0, SEEK_END);
125b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err != 0) {
126b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "Could not seek to the end of file %s. (%s)\n",
127b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
128b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
129b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
130b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
131b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
132b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    size = ftell(f);
133b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
134b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = fseek(f, 0, SEEK_SET);
135b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err != 0) {
136b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "Could not seek to the beginning of file %s. (%s)\n",
137b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
138b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
139b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
140b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
141b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
142b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    buf = (char*)malloc(size+1);
143b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (buf == NULL) {
144b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        // (potentially large)
145b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "out of memory (%ld)\n", size);
146b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = ENOMEM;
147b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
148b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
149b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
150b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (1 != fread(buf, size, 1, f)) {
151b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "error reading file %s. (%s)\n",
152b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
153b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
154b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
155b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
156b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
157b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    // split on lines
158b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    p = buf;
159b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    q = buf+size;
160b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    lineCount = 0;
161b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (p<q) {
162b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (*p == '\r' || *p == '\n') {
163b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            *p = '\0';
164b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            lineCount++;
165b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
166b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p++;
167b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
168b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
169b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    // read lines
170b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    p = buf;
171b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (i=0; i<lineCount; i++) {
172b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        int len = strlen(p);
173b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        q = p + len + 1;
174b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (is_whitespace_line(p) || is_comment_line(p)) {
175b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            ;
176b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
177b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else if (is_exclude_line(p)) {
178b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            while (*p != '-') p++;
179b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            p++;
180b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            excludes->push_back(string(p));
181b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
182b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else {
183b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            vector<string> words;
184b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
185b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            split_line(p, &words);
186b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
187b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#if 0
188b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            printf("[ ");
189b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            for (size_t k=0; k<words.size(); k++) {
190b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                printf("'%s' ", words[k].c_str());
191b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
192b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            printf("]\n");
193b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#endif
194b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
195b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (words.size() == 1) {
196b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                // pattern: DEST
197b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                add_file(files, filename, i+1, words[0], words[0]);
198b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
199b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            else if (words.size() == 2) {
200b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                // pattern: SRC DEST
201b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                add_file(files, filename, i+1, words[0], words[1]);
202b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
203b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            else {
204b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                fprintf(stderr, "%s:%d: bad format: %s\n", filename.c_str(),
205b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                        i+1, p);
206b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                err = 1;
207b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
208b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
209b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p = q;
210b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
211b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
212b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectcleanup:
213b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (buf != NULL) {
214b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        free(buf);
215b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
216b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (f != NULL) {
217b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fclose(f);
218b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
219b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return err;
220b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
221b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
222b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
223b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
224b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectlocate(FileRecord* rec, const vector<string>& search)
225b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
226b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
227b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
228b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (vector<string>::const_iterator it=search.begin();
229b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                it!=search.end(); it++) {
230b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        string full = path_append(*it, rec->sourceName);
231b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        struct stat st;
232b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = stat(full.c_str(), &st);
233b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (err == 0) {
234b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourceBase = *it;
235b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourcePath = full;
236b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourceMod = st.st_mtime;
237b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourceIsDir = S_ISDIR(st.st_mode);
238b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return 0;
239b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
240b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
241b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
242b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    fprintf(stderr, "%s:%d: couldn't locate source file: %s\n",
243b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                rec->listFile.c_str(), rec->listLine, rec->sourceName.c_str());
244b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return 1;
245b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
246b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
247b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectvoid
248b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstat_out(const string& base, FileRecord* rec)
249b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
250b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    rec->outPath = path_append(base, rec->outName);
251b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
252b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
253b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct stat st;
254b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = stat(rec->outPath.c_str(), &st);
255b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err == 0) {
256b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outMod = st.st_mtime;
257b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outIsDir = S_ISDIR(st.st_mode);
258b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    } else {
259b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outMod = 0;
260b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outIsDir = false;
261b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
262b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
263b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
264b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstring
265b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectdir_part(const string& filename)
266b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
267b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int pos = filename.rfind('/');
268b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (pos <= 0) {
269b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return ".";
270b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
271b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return filename.substr(0, pos);
272b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
273b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
274b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic void
275b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectadd_more(const string& entry, bool isDir,
276b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project         const FileRecord& rec, vector<FileRecord>*more)
277b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
278b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    FileRecord r;
279b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.listFile = rec.listFile;
280b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.listLine = rec.listLine;
281b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.sourceName = path_append(rec.sourceName, entry);
282b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.sourcePath = path_append(rec.sourceBase, r.sourceName);
283b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct stat st;
284b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err = stat(r.sourcePath.c_str(), &st);
285b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err == 0) {
286b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        r.sourceMod = st.st_mtime;
287b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
288b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.sourceIsDir = isDir;
289b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.outName = path_append(rec.outName, entry);
290b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    more->push_back(r);
291b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
292b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
293b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic bool
294b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectmatches_excludes(const char* file, const vector<string>& excludes)
295b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
296b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (vector<string>::const_iterator it=excludes.begin();
297b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            it!=excludes.end(); it++) {
298b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (0 == fnmatch(it->c_str(), file, FNM_PERIOD)) {
299b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return true;
300b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
301b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
302b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return false;
303b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
304b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
305b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic int
306b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectlist_dir(const string& path, const FileRecord& rec,
307b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                const vector<string>& excludes,
308b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                vector<FileRecord>* more)
309b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
310b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
311b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
312b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    string full = path_append(rec.sourceBase, rec.sourceName);
313b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    full = path_append(full, path);
314b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
315b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    DIR *d = opendir(full.c_str());
316b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (d == NULL) {
317b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return errno;
318b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
319b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
320b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    vector<string> dirs;
321b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
322b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct dirent *ent;
323b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (NULL != (ent = readdir(d))) {
324b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (0 == strcmp(".", ent->d_name)
325b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                || 0 == strcmp("..", ent->d_name)) {
326b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            continue;
327b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
328b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (matches_excludes(ent->d_name, excludes)) {
329b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            continue;
330b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
331b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        string entry = path_append(path, ent->d_name);
332b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#ifdef HAVE_DIRENT_D_TYPE
333b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		bool is_directory = (ent->d_type == DT_DIR);
334b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#else
335b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project	    // If dirent.d_type is missing, then use stat instead
336b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		struct stat stat_buf;
337b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		stat(entry.c_str(), &stat_buf);
338b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		bool is_directory = S_ISDIR(stat_buf.st_mode);
339b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#endif
340b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        add_more(entry, is_directory, rec, more);
341b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (is_directory) {
342b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            dirs.push_back(entry);
343b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
344b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
345b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    closedir(d);
346b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
347b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) {
348b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        list_dir(*it, rec, excludes, more);
349b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
350b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
351b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return 0;
352b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
353b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
354b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
355b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectlist_dir(const FileRecord& rec, const vector<string>& excludes,
356b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            vector<FileRecord>* files)
357b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
358b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return list_dir("", rec, excludes, files);
359b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
360