files.cpp revision 4f85cc54b3347e00e32a07cae4fd5473987b71af
1b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include "files.h"
2b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <stdio.h>
34f85cc54b3347e00e32a07cae4fd5473987b71afThe Android Open Source Project#include <string.h>
44f85cc54b3347e00e32a07cae4fd5473987b71afThe Android Open Source Project#include <stdlib.h>
5b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <errno.h>
6b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <sys/stat.h>
7b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <unistd.h>
8b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <dirent.h>
9b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#include <fnmatch.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
105dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Projectstatic string
106dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Projectreplace_variables(const string& input,
107dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                  const map<string, string>& variables,
108dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                  bool* error) {
109dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    if (variables.empty()) {
110dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        return input;
111dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    }
112dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
113dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    // Abort if the variable prefix is not found
114dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    if (input.find("${") == string::npos) {
115dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        return input;
116dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    }
117dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
118dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    string result = input;
119dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
120dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    // Note: rather than be fancy to detect recursive replacements,
121dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    // we simply iterate till a given threshold is met.
122dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
123dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    int retries = 1000;
124dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    bool did_replace;
125dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
126dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    do {
127dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        did_replace = false;
128dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        for (map<string, string>::const_iterator it = variables.begin();
129dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project             it != variables.end(); ++it) {
130dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            string::size_type pos = 0;
131dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            while((pos = result.find(it->first, pos)) != string::npos) {
132dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                result = result.replace(pos, it->first.length(), it->second);
133dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                pos += it->second.length();
134dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                did_replace = true;
135dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            }
136dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        }
137dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        if (did_replace && --retries == 0) {
138dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            *error = true;
139dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            fprintf(stderr, "Recursive replacement detected during variables "
140dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                    "substitution. Full list of variables is: ");
141dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
142dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            for (map<string, string>::const_iterator it = variables.begin();
143dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                 it != variables.end(); ++it) {
144dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                fprintf(stderr, "  %s=%s\n",
145dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                        it->first.c_str(), it->second.c_str());
146dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            }
147dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
148dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project            return result;
149dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project        }
150dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    } while (did_replace);
151dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
152dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project    return result;
153dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project}
154dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project
155b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
156dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Projectread_list_file(const string& filename,
157dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project               const map<string, string>& variables,
158dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project               vector<FileRecord>* files,
159dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project               vector<string>* excludes)
160b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
161b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err = 0;
162b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    FILE* f = NULL;
163b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    long size;
164b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    char* buf = NULL;
165b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    char *p, *q;
166b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int i, lineCount;
167b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
168b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    f = fopen(filename.c_str(), "r");
169b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (f == NULL) {
170b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "Could not open list file (%s): %s\n",
171b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
172b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
173b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
174b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
175b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
176b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = fseek(f, 0, SEEK_END);
177b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err != 0) {
178b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "Could not seek to the end of file %s. (%s)\n",
179b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
180b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
181b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
182b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
183b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
184b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    size = ftell(f);
185b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
186b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = fseek(f, 0, SEEK_SET);
187b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err != 0) {
188b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "Could not seek to the beginning of file %s. (%s)\n",
189b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
190b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
191b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
192b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
193b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
194b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    buf = (char*)malloc(size+1);
195b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (buf == NULL) {
196b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        // (potentially large)
197b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "out of memory (%ld)\n", size);
198b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = ENOMEM;
199b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
200b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
201b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
202b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (1 != fread(buf, size, 1, f)) {
203b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fprintf(stderr, "error reading file %s. (%s)\n",
204b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                    filename.c_str(), strerror(errno));
205b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = errno;
206b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        goto cleanup;
207b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
208b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
209b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    // split on lines
210b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    p = buf;
211b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    q = buf+size;
212b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    lineCount = 0;
213b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (p<q) {
214b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (*p == '\r' || *p == '\n') {
215b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            *p = '\0';
216b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            lineCount++;
217b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
218b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p++;
219b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
220b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
221b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    // read lines
222b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    p = buf;
223b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (i=0; i<lineCount; i++) {
224b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        int len = strlen(p);
225b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        q = p + len + 1;
226b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (is_whitespace_line(p) || is_comment_line(p)) {
227b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            ;
228b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
229b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else if (is_exclude_line(p)) {
230b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            while (*p != '-') p++;
231b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            p++;
232b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            excludes->push_back(string(p));
233b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
234b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        else {
235b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            vector<string> words;
236b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
237b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            split_line(p, &words);
238b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
239b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#if 0
240b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            printf("[ ");
241b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            for (size_t k=0; k<words.size(); k++) {
242b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                printf("'%s' ", words[k].c_str());
243b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
244b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            printf("]\n");
245b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#endif
246b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
247b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            if (words.size() == 1) {
248b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                // pattern: DEST
249dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                bool error = false;
250dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                string w0 = replace_variables(words[0], variables, &error);
251dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                if (error) {
252dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                    err = 1;
253dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                    goto cleanup;
254dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                }
255dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                add_file(files, filename, i+1, w0, w0);
256b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
257b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            else if (words.size() == 2) {
258b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                // pattern: SRC DEST
259dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                bool error = false;
260dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                string w0, w1;
261dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                w0 = replace_variables(words[0], variables, &error);
262dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                if (!error) {
263dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                    w1 = replace_variables(words[1], variables, &error);
264dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                }
265dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                if (error) {
266dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                    err = 1;
267dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                    goto cleanup;
268dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                }
269dcc08f073b6873c69ab891d4f69f7c568e282df7The Android Open Source Project                add_file(files, filename, i+1, w0, w1);
270b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
271b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            else {
272b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                fprintf(stderr, "%s:%d: bad format: %s\n", filename.c_str(),
273b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                        i+1, p);
274b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                err = 1;
275b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            }
276b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
277b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        p = q;
278b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
279b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
280b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectcleanup:
281b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (buf != NULL) {
282b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        free(buf);
283b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
284b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (f != NULL) {
285b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        fclose(f);
286b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
287b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return err;
288b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
289b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
290b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
291b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
292b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectlocate(FileRecord* rec, const vector<string>& search)
293b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
294b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
295b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
296b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (vector<string>::const_iterator it=search.begin();
297b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                it!=search.end(); it++) {
298b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        string full = path_append(*it, rec->sourceName);
299b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        struct stat st;
300b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        err = stat(full.c_str(), &st);
301b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (err == 0) {
302b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourceBase = *it;
303b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourcePath = full;
304b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourceMod = st.st_mtime;
305b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            rec->sourceIsDir = S_ISDIR(st.st_mode);
306b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return 0;
307b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
308b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
309b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
310b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    fprintf(stderr, "%s:%d: couldn't locate source file: %s\n",
311b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                rec->listFile.c_str(), rec->listLine, rec->sourceName.c_str());
312b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return 1;
313b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
314b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
315b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectvoid
316b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstat_out(const string& base, FileRecord* rec)
317b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
318b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    rec->outPath = path_append(base, rec->outName);
319b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
320b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
321b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct stat st;
322b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    err = stat(rec->outPath.c_str(), &st);
323b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err == 0) {
324b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outMod = st.st_mtime;
325b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outIsDir = S_ISDIR(st.st_mode);
326b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    } else {
327b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outMod = 0;
328b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        rec->outIsDir = false;
329b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
330b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
331b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
332b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstring
333b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectdir_part(const string& filename)
334b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
335b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int pos = filename.rfind('/');
336b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (pos <= 0) {
337b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return ".";
338b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
339b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return filename.substr(0, pos);
340b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
341b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
342b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic void
343b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectadd_more(const string& entry, bool isDir,
344b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project         const FileRecord& rec, vector<FileRecord>*more)
345b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
346b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    FileRecord r;
347b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.listFile = rec.listFile;
348b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.listLine = rec.listLine;
349b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.sourceName = path_append(rec.sourceName, entry);
350b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.sourcePath = path_append(rec.sourceBase, r.sourceName);
351b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct stat st;
352b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err = stat(r.sourcePath.c_str(), &st);
353b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (err == 0) {
354b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        r.sourceMod = st.st_mtime;
355b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
356b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.sourceIsDir = isDir;
357b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    r.outName = path_append(rec.outName, entry);
358b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    more->push_back(r);
359b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
360b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
361b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic bool
362b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectmatches_excludes(const char* file, const vector<string>& excludes)
363b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
364b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (vector<string>::const_iterator it=excludes.begin();
365b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            it!=excludes.end(); it++) {
366b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (0 == fnmatch(it->c_str(), file, FNM_PERIOD)) {
367b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            return true;
368b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
369b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
370b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return false;
371b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
372b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
373b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectstatic int
374b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectlist_dir(const string& path, const FileRecord& rec,
375b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                const vector<string>& excludes,
376b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                vector<FileRecord>* more)
377b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
378b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    int err;
379b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
380b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    string full = path_append(rec.sourceBase, rec.sourceName);
381b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    full = path_append(full, path);
382b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
383b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    DIR *d = opendir(full.c_str());
384b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    if (d == NULL) {
385b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        return errno;
386b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
387b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
388b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    vector<string> dirs;
389b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
390b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    struct dirent *ent;
391b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    while (NULL != (ent = readdir(d))) {
392b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (0 == strcmp(".", ent->d_name)
393b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project                || 0 == strcmp("..", ent->d_name)) {
394b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            continue;
395b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
396b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (matches_excludes(ent->d_name, excludes)) {
397b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            continue;
398b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
399b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        string entry = path_append(path, ent->d_name);
400b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#ifdef HAVE_DIRENT_D_TYPE
401b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		bool is_directory = (ent->d_type == DT_DIR);
402b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#else
403b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project	    // If dirent.d_type is missing, then use stat instead
404b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		struct stat stat_buf;
405b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		stat(entry.c_str(), &stat_buf);
406b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project		bool is_directory = S_ISDIR(stat_buf.st_mode);
407b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project#endif
408b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        add_more(entry, is_directory, rec, more);
409b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        if (is_directory) {
410b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            dirs.push_back(entry);
411b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        }
412b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
413b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    closedir(d);
414b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
415b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) {
416b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project        list_dir(*it, rec, excludes, more);
417b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    }
418b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
419b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return 0;
420b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
421b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project
422b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectint
423b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Projectlist_dir(const FileRecord& rec, const vector<string>& excludes,
424b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project            vector<FileRecord>* files)
425b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project{
426b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project    return list_dir("", rec, excludes, files);
427b6c1cf6de79035f58b512f4400db458c8401379The Android Open Source Project}
428