author | kergoth <kergoth> | 2002-11-01 16:20:04 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-11-01 16:20:04 (UTC) |
commit | 4c9df59925da5a67d884f8ffb37a263d85948951 (patch) (unidiff) | |
tree | 278796d7d27a06243e584a05f443dbb23eaf028c | |
parent | ebd6adcd2f72935f0ee7af7485c75c34ac3389a3 (diff) | |
download | opie-4c9df59925da5a67d884f8ffb37a263d85948951.zip opie-4c9df59925da5a67d884f8ffb37a263d85948951.tar.gz opie-4c9df59925da5a67d884f8ffb37a263d85948951.tar.bz2 |
Make qmake obey QMAKESPECSDIR if set.
-rw-r--r-- | qmake/project.cpp | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/qmake/project.cpp b/qmake/project.cpp index ae24193..96cdad8 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp | |||
@@ -60,789 +60,796 @@ struct parser_info { | |||
60 | } parser; | 60 | } parser; |
61 | static void qmake_error_msg(const char *msg) | 61 | static void qmake_error_msg(const char *msg) |
62 | { | 62 | { |
63 | fprintf(stderr, "%s:%d: %s\n", parser.file.latin1(), parser.line_no, msg); | 63 | fprintf(stderr, "%s:%d: %s\n", parser.file.latin1(), parser.line_no, msg); |
64 | } | 64 | } |
65 | 65 | ||
66 | static QString varMap(const QString &x) | 66 | static QString varMap(const QString &x) |
67 | { | 67 | { |
68 | QString ret(x); | 68 | QString ret(x); |
69 | ret.replace(QRegExp("^TMAKE"), "QMAKE"); | 69 | ret.replace(QRegExp("^TMAKE"), "QMAKE"); |
70 | if(ret == "INTERFACES") | 70 | if(ret == "INTERFACES") |
71 | ret = "FORMS"; | 71 | ret = "FORMS"; |
72 | return ret; | 72 | return ret; |
73 | } | 73 | } |
74 | 74 | ||
75 | static QStringList split_arg_list(const QString ¶ms) | 75 | static QStringList split_arg_list(const QString ¶ms) |
76 | { | 76 | { |
77 | QStringList args; | 77 | QStringList args; |
78 | int last = 0, parens = 0; | 78 | int last = 0, parens = 0; |
79 | QChar quote = 0; | 79 | QChar quote = 0; |
80 | for(int x = 0; x < (int)params.length(); x++) { | 80 | for(int x = 0; x < (int)params.length(); x++) { |
81 | if(params[x] == ')') { | 81 | if(params[x] == ')') { |
82 | parens--; | 82 | parens--; |
83 | } else if(params[x] == '(') { | 83 | } else if(params[x] == '(') { |
84 | parens++; | 84 | parens++; |
85 | } else if(params[x] == quote) { | 85 | } else if(params[x] == quote) { |
86 | quote = 0; | 86 | quote = 0; |
87 | } else if(params[x] == '\'' || params[x] == '"') { | 87 | } else if(params[x] == '\'' || params[x] == '"') { |
88 | quote = params[x]; | 88 | quote = params[x]; |
89 | } else if(!parens && !quote && params[x] == ',') { | 89 | } else if(!parens && !quote && params[x] == ',') { |
90 | args << params.mid(last, x - last); | 90 | args << params.mid(last, x - last); |
91 | last = x+1; | 91 | last = x+1; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | if(last != (int)params.length()) | 94 | if(last != (int)params.length()) |
95 | args << params.mid(last); | 95 | args << params.mid(last); |
96 | return args; | 96 | return args; |
97 | } | 97 | } |
98 | 98 | ||
99 | static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE) | 99 | static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE) |
100 | { | 100 | { |
101 | int last = 0; | 101 | int last = 0; |
102 | QStringList ret; | 102 | QStringList ret; |
103 | QValueStack<QChar> quote; | 103 | QValueStack<QChar> quote; |
104 | for(int x = 0; x < (int)vals.length(); x++) { | 104 | for(int x = 0; x < (int)vals.length(); x++) { |
105 | if(!quote.isEmpty() && vals[x] == quote.top()) { | 105 | if(!quote.isEmpty() && vals[x] == quote.top()) { |
106 | quote.pop(); | 106 | quote.pop(); |
107 | } else if(vals[x] == '\'' || vals[x] == '"') { | 107 | } else if(vals[x] == '\'' || vals[x] == '"') { |
108 | quote.push(vals[x]); | 108 | quote.push(vals[x]); |
109 | } else if(quote.isEmpty() && | 109 | } else if(quote.isEmpty() && |
110 | ((do_semicolon && vals[x] == ';') || vals[x] == ' ')) { | 110 | ((do_semicolon && vals[x] == ';') || vals[x] == ' ')) { |
111 | ret << vals.mid(last, x - last); | 111 | ret << vals.mid(last, x - last); |
112 | last = x+1; | 112 | last = x+1; |
113 | } | 113 | } |
114 | } | 114 | } |
115 | if(last != (int)vals.length()) | 115 | if(last != (int)vals.length()) |
116 | ret << vals.mid(last); | 116 | ret << vals.mid(last); |
117 | return ret; | 117 | return ret; |
118 | } | 118 | } |
119 | 119 | ||
120 | QMakeProject::QMakeProject() | 120 | QMakeProject::QMakeProject() |
121 | { | 121 | { |
122 | } | 122 | } |
123 | 123 | ||
124 | bool | 124 | bool |
125 | QMakeProject::parse(QString t, QMap<QString, QStringList> &place) | 125 | QMakeProject::parse(QString t, QMap<QString, QStringList> &place) |
126 | { | 126 | { |
127 | QString s = t.simplifyWhiteSpace(); | 127 | QString s = t.simplifyWhiteSpace(); |
128 | s.replace(QRegExp("#.*$"), ""); /* bye comments */ | 128 | s.replace(QRegExp("#.*$"), ""); /* bye comments */ |
129 | if(s.isEmpty()) /* blank_line */ | 129 | if(s.isEmpty()) /* blank_line */ |
130 | return TRUE; | 130 | return TRUE; |
131 | 131 | ||
132 | if(s.stripWhiteSpace().left(1) == "}") { | 132 | if(s.stripWhiteSpace().left(1) == "}") { |
133 | debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), | 133 | debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), |
134 | parser.line_no, scope_block); | 134 | parser.line_no, scope_block); |
135 | test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek); | 135 | test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek); |
136 | scope_block--; | 136 | scope_block--; |
137 | s = s.mid(1).stripWhiteSpace(); | 137 | s = s.mid(1).stripWhiteSpace(); |
138 | if(s.isEmpty()) | 138 | if(s.isEmpty()) |
139 | return TRUE; | 139 | return TRUE; |
140 | } | 140 | } |
141 | if(!(scope_flag & (0x01 << scope_block))) { | 141 | if(!(scope_flag & (0x01 << scope_block))) { |
142 | /* adjust scope for each block which appears on a single line */ | 142 | /* adjust scope for each block which appears on a single line */ |
143 | for(int i = (s.contains('{')-s.contains('}')); i; i--) | 143 | for(int i = (s.contains('{')-s.contains('}')); i; i--) |
144 | scope_flag &= ~(0x01 << (++scope_block)); | 144 | scope_flag &= ~(0x01 << (++scope_block)); |
145 | debug_msg(1, "Project Parser: %s:%d : Ignored due to block being false.", | 145 | debug_msg(1, "Project Parser: %s:%d : Ignored due to block being false.", |
146 | parser.file.latin1(), parser.line_no); | 146 | parser.file.latin1(), parser.line_no); |
147 | return TRUE; | 147 | return TRUE; |
148 | } | 148 | } |
149 | 149 | ||
150 | QString scope, var, op; | 150 | QString scope, var, op; |
151 | QStringList val; | 151 | QStringList val; |
152 | #define SKIP_WS(d) while(*d && (*d == ' ' || *d == '\t')) d++ | 152 | #define SKIP_WS(d) while(*d && (*d == ' ' || *d == '\t')) d++ |
153 | const char *d = s.latin1(); | 153 | const char *d = s.latin1(); |
154 | SKIP_WS(d); | 154 | SKIP_WS(d); |
155 | bool scope_failed = FALSE, else_line = FALSE, or_op=FALSE; | 155 | bool scope_failed = FALSE, else_line = FALSE, or_op=FALSE; |
156 | int parens = 0, scope_count=0; | 156 | int parens = 0, scope_count=0; |
157 | while(*d && *d != '=') { | 157 | while(*d && *d != '=') { |
158 | if((*d == '+' || *d == '-' || *d == '*' || *d == '~')) { | 158 | if((*d == '+' || *d == '-' || *d == '*' || *d == '~')) { |
159 | if(*(d+1) == '=') { | 159 | if(*(d+1) == '=') { |
160 | break; | 160 | break; |
161 | } else if(*(d+1) == ' ') { | 161 | } else if(*(d+1) == ' ') { |
162 | const char *k = d + 1; | 162 | const char *k = d + 1; |
163 | SKIP_WS(k); | 163 | SKIP_WS(k); |
164 | if(*k == '=') { | 164 | if(*k == '=') { |
165 | QString msg; | 165 | QString msg; |
166 | qmake_error_msg(*d + "must be followed immediatly by ="); | 166 | qmake_error_msg(*d + "must be followed immediatly by ="); |
167 | return FALSE; | 167 | return FALSE; |
168 | } | 168 | } |
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | if ( *d == '(' ) | 172 | if ( *d == '(' ) |
173 | ++parens; | 173 | ++parens; |
174 | else if ( *d == ')' ) | 174 | else if ( *d == ')' ) |
175 | --parens; | 175 | --parens; |
176 | 176 | ||
177 | if(!parens && (*d == ':' || *d == '{' || *d == ')' || *d == '|')) { | 177 | if(!parens && (*d == ':' || *d == '{' || *d == ')' || *d == '|')) { |
178 | scope_count++; | 178 | scope_count++; |
179 | scope = var.stripWhiteSpace(); | 179 | scope = var.stripWhiteSpace(); |
180 | if ( *d == ')' ) | 180 | if ( *d == ')' ) |
181 | scope += *d; /* need this */ | 181 | scope += *d; /* need this */ |
182 | var = ""; | 182 | var = ""; |
183 | 183 | ||
184 | bool test = scope_failed; | 184 | bool test = scope_failed; |
185 | if(scope.lower() == "else") { | 185 | if(scope.lower() == "else") { |
186 | if(scope_count != 1 || test_status == TestNone) { | 186 | if(scope_count != 1 || test_status == TestNone) { |
187 | qmake_error_msg("Unexpected " + scope + " ('" + s + "')"); | 187 | qmake_error_msg("Unexpected " + scope + " ('" + s + "')"); |
188 | return FALSE; | 188 | return FALSE; |
189 | } | 189 | } |
190 | else_line = TRUE; | 190 | else_line = TRUE; |
191 | test = (test_status == TestSeek); | 191 | test = (test_status == TestSeek); |
192 | debug_msg(1, "Project Parser: %s:%d : Else%s %s.", parser.file.latin1(), parser.line_no, | 192 | debug_msg(1, "Project Parser: %s:%d : Else%s %s.", parser.file.latin1(), parser.line_no, |
193 | scope == "else" ? "" : QString(" (" + scope + ")").latin1(), | 193 | scope == "else" ? "" : QString(" (" + scope + ")").latin1(), |
194 | test ? "considered" : "excluded"); | 194 | test ? "considered" : "excluded"); |
195 | } else { | 195 | } else { |
196 | QString comp_scope = scope; | 196 | QString comp_scope = scope; |
197 | bool invert_test = (comp_scope.left(1) == "!"); | 197 | bool invert_test = (comp_scope.left(1) == "!"); |
198 | if(invert_test) | 198 | if(invert_test) |
199 | comp_scope = comp_scope.right(comp_scope.length()-1); | 199 | comp_scope = comp_scope.right(comp_scope.length()-1); |
200 | int lparen = comp_scope.find('('); | 200 | int lparen = comp_scope.find('('); |
201 | if(or_op || !scope_failed) { | 201 | if(or_op || !scope_failed) { |
202 | if(lparen != -1) { /* if there is an lparen in the scope, it IS a function */ | 202 | if(lparen != -1) { /* if there is an lparen in the scope, it IS a function */ |
203 | int rparen = comp_scope.findRev(')'); | 203 | int rparen = comp_scope.findRev(')'); |
204 | if(rparen == -1) { | 204 | if(rparen == -1) { |
205 | QCString error; | 205 | QCString error; |
206 | error.sprintf("Function missing right paren: %s ('%s')", | 206 | error.sprintf("Function missing right paren: %s ('%s')", |
207 | comp_scope.latin1(), s.latin1()); | 207 | comp_scope.latin1(), s.latin1()); |
208 | qmake_error_msg(error); | 208 | qmake_error_msg(error); |
209 | return FALSE; | 209 | return FALSE; |
210 | } | 210 | } |
211 | QString func = comp_scope.left(lparen); | 211 | QString func = comp_scope.left(lparen); |
212 | test = doProjectTest(func, comp_scope.mid(lparen+1, rparen - lparen - 1), place); | 212 | test = doProjectTest(func, comp_scope.mid(lparen+1, rparen - lparen - 1), place); |
213 | if ( *d == ')' && !*(d+1) ) { | 213 | if ( *d == ')' && !*(d+1) ) { |
214 | if(invert_test) | 214 | if(invert_test) |
215 | test = !test; | 215 | test = !test; |
216 | test_status = (test ? TestFound : TestSeek); | 216 | test_status = (test ? TestFound : TestSeek); |
217 | return TRUE; /* assume we are done */ | 217 | return TRUE; /* assume we are done */ |
218 | } | 218 | } |
219 | } else { | 219 | } else { |
220 | test = isActiveConfig(comp_scope.stripWhiteSpace()); | 220 | test = isActiveConfig(comp_scope.stripWhiteSpace()); |
221 | } | 221 | } |
222 | if(invert_test) | 222 | if(invert_test) |
223 | test = !test; | 223 | test = !test; |
224 | } | 224 | } |
225 | } | 225 | } |
226 | if(!test && !scope_failed) | 226 | if(!test && !scope_failed) |
227 | debug_msg(1, "Project Parser: %s:%d : Test (%s) failed.", parser.file.latin1(), | 227 | debug_msg(1, "Project Parser: %s:%d : Test (%s) failed.", parser.file.latin1(), |
228 | parser.line_no, scope.latin1()); | 228 | parser.line_no, scope.latin1()); |
229 | if(test == or_op) | 229 | if(test == or_op) |
230 | scope_failed = !test; | 230 | scope_failed = !test; |
231 | or_op = (*d == '|'); | 231 | or_op = (*d == '|'); |
232 | if(*d == '{') { /* scoping block */ | 232 | if(*d == '{') { /* scoping block */ |
233 | if(!scope_failed) | 233 | if(!scope_failed) |
234 | scope_flag |= (0x01 << (++scope_block)); | 234 | scope_flag |= (0x01 << (++scope_block)); |
235 | else | 235 | else |
236 | scope_flag &= ~(0x01 << (++scope_block)); | 236 | scope_flag &= ~(0x01 << (++scope_block)); |
237 | debug_msg(1, "Project Parser: %s:%d : Entering block %d (%d).", parser.file.latin1(), | 237 | debug_msg(1, "Project Parser: %s:%d : Entering block %d (%d).", parser.file.latin1(), |
238 | parser.line_no, scope_block, !scope_failed); | 238 | parser.line_no, scope_block, !scope_failed); |
239 | } | 239 | } |
240 | } else { | 240 | } else { |
241 | var += *d; | 241 | var += *d; |
242 | } | 242 | } |
243 | d++; | 243 | d++; |
244 | } | 244 | } |
245 | if(!scope_count || (scope_count == 1 && else_line)) | 245 | if(!scope_count || (scope_count == 1 && else_line)) |
246 | test_status = TestNone; | 246 | test_status = TestNone; |
247 | else if(!else_line || test_status != TestFound) | 247 | else if(!else_line || test_status != TestFound) |
248 | test_status = (scope_failed ? TestSeek : TestFound); | 248 | test_status = (scope_failed ? TestSeek : TestFound); |
249 | if(scope_failed) | 249 | if(scope_failed) |
250 | return TRUE; /* oh well */ | 250 | return TRUE; /* oh well */ |
251 | if(!*d) { | 251 | if(!*d) { |
252 | if(!var.isEmpty()) | 252 | if(!var.isEmpty()) |
253 | qmake_error_msg("Parse Error ('" + s + "')"); | 253 | qmake_error_msg("Parse Error ('" + s + "')"); |
254 | return var.isEmpty(); /* allow just a scope */ | 254 | return var.isEmpty(); /* allow just a scope */ |
255 | } | 255 | } |
256 | 256 | ||
257 | SKIP_WS(d); | 257 | SKIP_WS(d); |
258 | for( ; *d && op.find('=') == -1; op += *(d++)); | 258 | for( ; *d && op.find('=') == -1; op += *(d++)); |
259 | op.replace(QRegExp("\\s"), ""); | 259 | op.replace(QRegExp("\\s"), ""); |
260 | 260 | ||
261 | SKIP_WS(d); | 261 | SKIP_WS(d); |
262 | QString vals(d); /* vals now contains the space separated list of values */ | 262 | QString vals(d); /* vals now contains the space separated list of values */ |
263 | int rbraces = vals.contains('}'), lbraces = vals.contains('{'); | 263 | int rbraces = vals.contains('}'), lbraces = vals.contains('{'); |
264 | if(scope_block && rbraces - lbraces == 1) { | 264 | if(scope_block && rbraces - lbraces == 1) { |
265 | debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), | 265 | debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), |
266 | parser.line_no, scope_block); | 266 | parser.line_no, scope_block); |
267 | test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek); | 267 | test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek); |
268 | scope_block--; | 268 | scope_block--; |
269 | vals.truncate(vals.length()-1); | 269 | vals.truncate(vals.length()-1); |
270 | } else if(rbraces != lbraces) { | 270 | } else if(rbraces != lbraces) { |
271 | warn_msg(WarnParser, "Possible braces mismatch {%s} %s:%d", | 271 | warn_msg(WarnParser, "Possible braces mismatch {%s} %s:%d", |
272 | vals.latin1(), parser.file.latin1(), parser.line_no); | 272 | vals.latin1(), parser.file.latin1(), parser.line_no); |
273 | } | 273 | } |
274 | doVariableReplace(vals, place); | 274 | doVariableReplace(vals, place); |
275 | 275 | ||
276 | var = var.stripWhiteSpace(); | 276 | var = var.stripWhiteSpace(); |
277 | #undef SKIP_WS | 277 | #undef SKIP_WS |
278 | 278 | ||
279 | if(!var.isEmpty() && Option::mkfile::do_preprocess) { | 279 | if(!var.isEmpty() && Option::mkfile::do_preprocess) { |
280 | static QString last_file("*none*"); | 280 | static QString last_file("*none*"); |
281 | if(parser.file != last_file) { | 281 | if(parser.file != last_file) { |
282 | fprintf(stderr, "#file %s:%d\n", parser.file.latin1(), parser.line_no); | 282 | fprintf(stderr, "#file %s:%d\n", parser.file.latin1(), parser.line_no); |
283 | last_file = parser.file; | 283 | last_file = parser.file; |
284 | } | 284 | } |
285 | fprintf(stderr, "%s %s %s\n", var.latin1(), op.latin1(), vals.latin1()); | 285 | fprintf(stderr, "%s %s %s\n", var.latin1(), op.latin1(), vals.latin1()); |
286 | } | 286 | } |
287 | var = varMap(var); //backwards compatability | 287 | var = varMap(var); //backwards compatability |
288 | 288 | ||
289 | /* vallist is the broken up list of values */ | 289 | /* vallist is the broken up list of values */ |
290 | QStringList vallist = split_value_list(vals, (var == "DEPENDPATH" || var == "INCLUDEPATH")); | 290 | QStringList vallist = split_value_list(vals, (var == "DEPENDPATH" || var == "INCLUDEPATH")); |
291 | if(!vallist.grep("=").isEmpty()) | 291 | if(!vallist.grep("=").isEmpty()) |
292 | warn_msg(WarnParser, "Detected possible line continuation: {%s} %s:%d", | 292 | warn_msg(WarnParser, "Detected possible line continuation: {%s} %s:%d", |
293 | var.latin1(), parser.file.latin1(), parser.line_no); | 293 | var.latin1(), parser.file.latin1(), parser.line_no); |
294 | 294 | ||
295 | QStringList &varlist = place[var]; /* varlist is the list in the symbol table */ | 295 | QStringList &varlist = place[var]; /* varlist is the list in the symbol table */ |
296 | debug_msg(1, "Project Parser: %s:%d :%s: :%s: (%s)", parser.file.latin1(), parser.line_no, | 296 | debug_msg(1, "Project Parser: %s:%d :%s: :%s: (%s)", parser.file.latin1(), parser.line_no, |
297 | var.latin1(), op.latin1(), vallist.join(" :: ").latin1()); | 297 | var.latin1(), op.latin1(), vallist.join(" :: ").latin1()); |
298 | 298 | ||
299 | /* now do the operation */ | 299 | /* now do the operation */ |
300 | if(op == "~=") { | 300 | if(op == "~=") { |
301 | if(vallist.count() != 1) { | 301 | if(vallist.count() != 1) { |
302 | qmake_error_msg("~= operator only accepts one right hand paramater ('" + | 302 | qmake_error_msg("~= operator only accepts one right hand paramater ('" + |
303 | s + "')"); | 303 | s + "')"); |
304 | return FALSE; | 304 | return FALSE; |
305 | } | 305 | } |
306 | QString val(vallist.first()); | 306 | QString val(vallist.first()); |
307 | if(val.length() < 4 || val.at(0) != 's') { | 307 | if(val.length() < 4 || val.at(0) != 's') { |
308 | qmake_error_msg("~= operator only can handle s/// function ('" + | 308 | qmake_error_msg("~= operator only can handle s/// function ('" + |
309 | s + "')"); | 309 | s + "')"); |
310 | return FALSE; | 310 | return FALSE; |
311 | } | 311 | } |
312 | QChar sep = val.at(1); | 312 | QChar sep = val.at(1); |
313 | QStringList func = QStringList::split(sep, val, TRUE); | 313 | QStringList func = QStringList::split(sep, val, TRUE); |
314 | if(func.count() < 3 || func.count() > 4) { | 314 | if(func.count() < 3 || func.count() > 4) { |
315 | qmake_error_msg("~= operator only can handle s/// function ('" + | 315 | qmake_error_msg("~= operator only can handle s/// function ('" + |
316 | s + "')"); | 316 | s + "')"); |
317 | return FALSE; | 317 | return FALSE; |
318 | } | 318 | } |
319 | bool global = FALSE, case_sense = TRUE; | 319 | bool global = FALSE, case_sense = TRUE; |
320 | if(func.count() == 4) { | 320 | if(func.count() == 4) { |
321 | global = func[3].find('g') != -1; | 321 | global = func[3].find('g') != -1; |
322 | case_sense = func[3].find('i') == -1; | 322 | case_sense = func[3].find('i') == -1; |
323 | } | 323 | } |
324 | QRegExp regexp(func[1], case_sense); | 324 | QRegExp regexp(func[1], case_sense); |
325 | for(QStringList::Iterator varit = varlist.begin(); | 325 | for(QStringList::Iterator varit = varlist.begin(); |
326 | varit != varlist.end(); ++varit) { | 326 | varit != varlist.end(); ++varit) { |
327 | if((*varit).contains(regexp)) { | 327 | if((*varit).contains(regexp)) { |
328 | (*varit) = (*varit).replace(regexp, func[2]); | 328 | (*varit) = (*varit).replace(regexp, func[2]); |
329 | if(!global) | 329 | if(!global) |
330 | break; | 330 | break; |
331 | } | 331 | } |
332 | } | 332 | } |
333 | } else { | 333 | } else { |
334 | if(op == "=") { | 334 | if(op == "=") { |
335 | if(!varlist.isEmpty()) | 335 | if(!varlist.isEmpty()) |
336 | warn_msg(WarnParser, "Operator=(%s) clears variables previously set: %s:%d", | 336 | warn_msg(WarnParser, "Operator=(%s) clears variables previously set: %s:%d", |
337 | var.latin1(), parser.file.latin1(), parser.line_no); | 337 | var.latin1(), parser.file.latin1(), parser.line_no); |
338 | varlist.clear(); | 338 | varlist.clear(); |
339 | } | 339 | } |
340 | for(QStringList::Iterator valit = vallist.begin(); | 340 | for(QStringList::Iterator valit = vallist.begin(); |
341 | valit != vallist.end(); ++valit) { | 341 | valit != vallist.end(); ++valit) { |
342 | if((*valit).isEmpty()) | 342 | if((*valit).isEmpty()) |
343 | continue; | 343 | continue; |
344 | if((op == "*=" && !(*varlist.find((*valit)))) || | 344 | if((op == "*=" && !(*varlist.find((*valit)))) || |
345 | op == "=" || op == "+=") | 345 | op == "=" || op == "+=") |
346 | varlist.append((*valit)); | 346 | varlist.append((*valit)); |
347 | else if(op == "-=") | 347 | else if(op == "-=") |
348 | varlist.remove((*valit)); | 348 | varlist.remove((*valit)); |
349 | } | 349 | } |
350 | } | 350 | } |
351 | if(var == "REQUIRES") /* special case to get communicated to backends! */ | 351 | if(var == "REQUIRES") /* special case to get communicated to backends! */ |
352 | doProjectCheckReqs(vallist, place); | 352 | doProjectCheckReqs(vallist, place); |
353 | 353 | ||
354 | return TRUE; | 354 | return TRUE; |
355 | } | 355 | } |
356 | 356 | ||
357 | bool | 357 | bool |
358 | QMakeProject::read(QString file, QMap<QString, QStringList> &place) | 358 | QMakeProject::read(QString file, QMap<QString, QStringList> &place) |
359 | { | 359 | { |
360 | parser_info pi = parser; | 360 | parser_info pi = parser; |
361 | /* scope blocks start at true */ | 361 | /* scope blocks start at true */ |
362 | test_status = TestNone; | 362 | test_status = TestNone; |
363 | scope_flag = 0x01; | 363 | scope_flag = 0x01; |
364 | scope_block = 0; | 364 | scope_block = 0; |
365 | 365 | ||
366 | file = Option::fixPathToLocalOS(file); | 366 | file = Option::fixPathToLocalOS(file); |
367 | doVariableReplace(file, place); | 367 | doVariableReplace(file, place); |
368 | bool ret = FALSE, using_stdin = FALSE; | 368 | bool ret = FALSE, using_stdin = FALSE; |
369 | QFile qfile; | 369 | QFile qfile; |
370 | if(!strcmp(file, "-")) { | 370 | if(!strcmp(file, "-")) { |
371 | qfile.setName(""); | 371 | qfile.setName(""); |
372 | ret = qfile.open(IO_ReadOnly, stdin); | 372 | ret = qfile.open(IO_ReadOnly, stdin); |
373 | using_stdin = TRUE; | 373 | using_stdin = TRUE; |
374 | } else { | 374 | } else { |
375 | qfile.setName(file); | 375 | qfile.setName(file); |
376 | ret = qfile.open(IO_ReadOnly); | 376 | ret = qfile.open(IO_ReadOnly); |
377 | } | 377 | } |
378 | if ( ret ) { | 378 | if ( ret ) { |
379 | QTextStream t( &qfile ); | 379 | QTextStream t( &qfile ); |
380 | QString s, line; | 380 | QString s, line; |
381 | parser.file = file; | 381 | parser.file = file; |
382 | parser.line_no = 0; | 382 | parser.line_no = 0; |
383 | while ( !t.eof() ) { | 383 | while ( !t.eof() ) { |
384 | parser.line_no++; | 384 | parser.line_no++; |
385 | line = t.readLine().stripWhiteSpace(); | 385 | line = t.readLine().stripWhiteSpace(); |
386 | int prelen = line.length(); | 386 | int prelen = line.length(); |
387 | line.replace(QRegExp("#.*$"), ""); // bye comments | 387 | line.replace(QRegExp("#.*$"), ""); // bye comments |
388 | if(!line.isEmpty() && line.right(1) == "\\") { | 388 | if(!line.isEmpty() && line.right(1) == "\\") { |
389 | line.truncate(line.length() - 1); | 389 | line.truncate(line.length() - 1); |
390 | s += line + " "; | 390 | s += line + " "; |
391 | } else if(!line.isEmpty() || (line.isEmpty() && !prelen)) { | 391 | } else if(!line.isEmpty() || (line.isEmpty() && !prelen)) { |
392 | if(s.isEmpty() && line.isEmpty()) | 392 | if(s.isEmpty() && line.isEmpty()) |
393 | continue; | 393 | continue; |
394 | if(!line.isEmpty()) | 394 | if(!line.isEmpty()) |
395 | s += line; | 395 | s += line; |
396 | if(!s.isEmpty()) { | 396 | if(!s.isEmpty()) { |
397 | if(!(ret = parse(s, place))) | 397 | if(!(ret = parse(s, place))) |
398 | break; | 398 | break; |
399 | s = ""; | 399 | s = ""; |
400 | } | 400 | } |
401 | } | 401 | } |
402 | } | 402 | } |
403 | if(!using_stdin) | 403 | if(!using_stdin) |
404 | qfile.close(); | 404 | qfile.close(); |
405 | } | 405 | } |
406 | parser = pi; | 406 | parser = pi; |
407 | return ret; | 407 | return ret; |
408 | } | 408 | } |
409 | 409 | ||
410 | bool | 410 | bool |
411 | QMakeProject::read(QString project, QString) | 411 | QMakeProject::read(QString project, QString) |
412 | { | 412 | { |
413 | if(cfile.isEmpty()) { | 413 | if(cfile.isEmpty()) { |
414 | // hack to get the Option stuff in there | 414 | // hack to get the Option stuff in there |
415 | base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; | 415 | base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; |
416 | base_vars["QMAKE_EXT_H"] = Option::h_ext; | 416 | base_vars["QMAKE_EXT_H"] = Option::h_ext; |
417 | 417 | ||
418 | /* parse the cache */ | 418 | /* parse the cache */ |
419 | if(Option::mkfile::do_cache) { | 419 | if(Option::mkfile::do_cache) { |
420 | if(Option::mkfile::cachefile.isEmpty()) { //find it as it has not been specified | 420 | if(Option::mkfile::cachefile.isEmpty()) { //find it as it has not been specified |
421 | QString dir = QDir::convertSeparators(Option::output_dir); | 421 | QString dir = QDir::convertSeparators(Option::output_dir); |
422 | while(!QFile::exists((Option::mkfile::cachefile = dir + | 422 | while(!QFile::exists((Option::mkfile::cachefile = dir + |
423 | QDir::separator() + ".qmake.cache"))) { | 423 | QDir::separator() + ".qmake.cache"))) { |
424 | dir = dir.left(dir.findRev(QDir::separator())); | 424 | dir = dir.left(dir.findRev(QDir::separator())); |
425 | if(dir.isEmpty() || dir.find(QDir::separator()) == -1) { | 425 | if(dir.isEmpty() || dir.find(QDir::separator()) == -1) { |
426 | Option::mkfile::cachefile = ""; | 426 | Option::mkfile::cachefile = ""; |
427 | break; | 427 | break; |
428 | } | 428 | } |
429 | if(Option::mkfile::cachefile_depth == -1) | 429 | if(Option::mkfile::cachefile_depth == -1) |
430 | Option::mkfile::cachefile_depth = 1; | 430 | Option::mkfile::cachefile_depth = 1; |
431 | else | 431 | else |
432 | Option::mkfile::cachefile_depth++; | 432 | Option::mkfile::cachefile_depth++; |
433 | } | 433 | } |
434 | } | 434 | } |
435 | if(!Option::mkfile::cachefile.isEmpty()) { | 435 | if(!Option::mkfile::cachefile.isEmpty()) { |
436 | read(Option::mkfile::cachefile, cache); | 436 | read(Option::mkfile::cachefile, cache); |
437 | if(Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty()) | 437 | if(Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty()) |
438 | Option::mkfile::qmakespec = cache["QMAKESPEC"].first(); | 438 | Option::mkfile::qmakespec = cache["QMAKESPEC"].first(); |
439 | } | 439 | } |
440 | } | 440 | } |
441 | /* parse mkspec */ | 441 | /* parse mkspec */ |
442 | QStringList mkspec_roots; | 442 | QStringList mkspec_roots; |
443 | /* prefer $QTDIR if it is set */ | 443 | /* prefer $QTDIR if it is set */ |
444 | /* minor hack here, prefer QMAKESPECDIR -cl */ | 444 | /* prefer QMAKESPECSDIR -cl */ |
445 | 445 | ||
446 | if (getenv("QMAKESPECDIR")){ | 446 | if (getenv("QTDIR")) { |
447 | mkspec_roots << getenv("QMAKESPECDIR"); | ||
448 | } else if (getenv("QTDIR")) { | ||
449 | mkspec_roots << getenv("QTDIR"); | 447 | mkspec_roots << getenv("QTDIR"); |
450 | } | 448 | } |
451 | mkspec_roots << qInstallPathData(); | 449 | mkspec_roots << qInstallPathData(); |
450 | |||
451 | if (getenv("QMAKESPECSDIR")){ | ||
452 | QString mkspec = QString(getenv("QMAKESPECSDIR")) + QDir::separator() + | ||
453 | QDir::separator() + "default"; | ||
454 | if(QFile::exists(mkspec)) | ||
455 | Option::mkfile::qmakespec = mkspec; | ||
456 | } | ||
457 | |||
452 | if(Option::mkfile::qmakespec.isEmpty()) { | 458 | if(Option::mkfile::qmakespec.isEmpty()) { |
453 | for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { | 459 | for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { |
454 | QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + | 460 | QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + |
455 | QDir::separator() + "default"; | 461 | QDir::separator() + "default"; |
456 | if(QFile::exists(mkspec)) { | 462 | if(QFile::exists(mkspec)) { |
457 | Option::mkfile::qmakespec = mkspec; | 463 | Option::mkfile::qmakespec = mkspec; |
458 | break; | 464 | break; |
459 | } | 465 | } |
460 | } | 466 | } |
461 | if(Option::mkfile::qmakespec.isEmpty()) { | 467 | } |
462 | fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); | 468 | |
463 | return FALSE; | 469 | if(Option::mkfile::qmakespec.isEmpty()) { |
464 | } | 470 | fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); |
471 | return FALSE; | ||
465 | } | 472 | } |
466 | 473 | ||
467 | if(QDir::isRelativePath(Option::mkfile::qmakespec)) { | 474 | if(QDir::isRelativePath(Option::mkfile::qmakespec)) { |
468 | bool found_mkspec = FALSE; | 475 | bool found_mkspec = FALSE; |
469 | for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { | 476 | for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { |
470 | QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + | 477 | QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + |
471 | QDir::separator() + Option::mkfile::qmakespec; | 478 | QDir::separator() + Option::mkfile::qmakespec; |
472 | if(QFile::exists(mkspec)) { | 479 | if(QFile::exists(mkspec)) { |
473 | found_mkspec = TRUE; | 480 | found_mkspec = TRUE; |
474 | Option::mkfile::qmakespec = mkspec; | 481 | Option::mkfile::qmakespec = mkspec; |
475 | break; | 482 | break; |
476 | } | 483 | } |
477 | } | 484 | } |
478 | if(!found_mkspec) { | 485 | if(!found_mkspec) { |
479 | fprintf(stderr, "Could not find mkspecs for your QMAKESPEC after trying:\n\t%s\n", | 486 | fprintf(stderr, "Could not find mkspecs for your QMAKESPEC after trying:\n\t%s\n", |
480 | mkspec_roots.join("\n\t").latin1()); | 487 | mkspec_roots.join("\n\t").latin1()); |
481 | return FALSE; | 488 | return FALSE; |
482 | } | 489 | } |
483 | } | 490 | } |
484 | 491 | ||
485 | /* parse qmake configuration */ | 492 | /* parse qmake configuration */ |
486 | QString spec = Option::mkfile::qmakespec + QDir::separator() + "qmake.conf"; | 493 | QString spec = Option::mkfile::qmakespec + QDir::separator() + "qmake.conf"; |
487 | debug_msg(1, "QMAKESPEC conf: reading %s", spec.latin1()); | 494 | debug_msg(1, "QMAKESPEC conf: reading %s", spec.latin1()); |
488 | if(!read(spec, base_vars)) { | 495 | if(!read(spec, base_vars)) { |
489 | fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.latin1()); | 496 | fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.latin1()); |
490 | return FALSE; | 497 | return FALSE; |
491 | } | 498 | } |
492 | if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) { | 499 | if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) { |
493 | debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.latin1()); | 500 | debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.latin1()); |
494 | read(Option::mkfile::cachefile, base_vars); | 501 | read(Option::mkfile::cachefile, base_vars); |
495 | } | 502 | } |
496 | 503 | ||
497 | /* commandline */ | 504 | /* commandline */ |
498 | cfile = project; | 505 | cfile = project; |
499 | parser.line_no = 1; //really arg count now.. duh | 506 | parser.line_no = 1; //really arg count now.. duh |
500 | parser.file = "(internal)"; | 507 | parser.file = "(internal)"; |
501 | for(QStringList::Iterator it = Option::before_user_vars.begin(); | 508 | for(QStringList::Iterator it = Option::before_user_vars.begin(); |
502 | it != Option::before_user_vars.end(); ++it) { | 509 | it != Option::before_user_vars.end(); ++it) { |
503 | if(!parse((*it), base_vars)) { | 510 | if(!parse((*it), base_vars)) { |
504 | fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); | 511 | fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); |
505 | return FALSE; | 512 | return FALSE; |
506 | } | 513 | } |
507 | parser.line_no++; | 514 | parser.line_no++; |
508 | } | 515 | } |
509 | } | 516 | } |
510 | 517 | ||
511 | /* parse project file */ | 518 | /* parse project file */ |
512 | debug_msg(1, "Project file: reading %s", project.latin1()); | 519 | debug_msg(1, "Project file: reading %s", project.latin1()); |
513 | vars = base_vars; /* start with the base */ | 520 | vars = base_vars; /* start with the base */ |
514 | 521 | ||
515 | pfile = project; | 522 | pfile = project; |
516 | if(pfile != "-" && !QFile::exists(pfile) && pfile.right(4) != ".pro") | 523 | if(pfile != "-" && !QFile::exists(pfile) && pfile.right(4) != ".pro") |
517 | pfile += ".pro"; | 524 | pfile += ".pro"; |
518 | 525 | ||
519 | if(!read(pfile, vars)) | 526 | if(!read(pfile, vars)) |
520 | return FALSE; | 527 | return FALSE; |
521 | 528 | ||
522 | parser.line_no = 1; //really arg count now.. duh | 529 | parser.line_no = 1; //really arg count now.. duh |
523 | parser.file = "(internal)"; | 530 | parser.file = "(internal)"; |
524 | for(QStringList::Iterator it = Option::after_user_vars.begin(); | 531 | for(QStringList::Iterator it = Option::after_user_vars.begin(); |
525 | it != Option::after_user_vars.end(); ++it) { | 532 | it != Option::after_user_vars.end(); ++it) { |
526 | if(!parse((*it), vars)) { | 533 | if(!parse((*it), vars)) { |
527 | fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); | 534 | fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); |
528 | return FALSE; | 535 | return FALSE; |
529 | } | 536 | } |
530 | parser.line_no++; | 537 | parser.line_no++; |
531 | } | 538 | } |
532 | 539 | ||
533 | /* now let the user override the template from an option.. */ | 540 | /* now let the user override the template from an option.. */ |
534 | if(!Option::user_template.isEmpty()) { | 541 | if(!Option::user_template.isEmpty()) { |
535 | debug_msg(1, "Overriding TEMPLATE (%s) with: %s", vars["TEMPLATE"].first().latin1(), Option::user_template.latin1()); | 542 | debug_msg(1, "Overriding TEMPLATE (%s) with: %s", vars["TEMPLATE"].first().latin1(), Option::user_template.latin1()); |
536 | vars["TEMPLATE"].clear(); | 543 | vars["TEMPLATE"].clear(); |
537 | vars["TEMPLATE"].append(Option::user_template); | 544 | vars["TEMPLATE"].append(Option::user_template); |
538 | } | 545 | } |
539 | 546 | ||
540 | if(vars["TEMPLATE"].isEmpty()) | 547 | if(vars["TEMPLATE"].isEmpty()) |
541 | vars["TEMPLATE"].append(QString("app")); | 548 | vars["TEMPLATE"].append(QString("app")); |
542 | else | 549 | else |
543 | vars["TEMPLATE"].first().replace(QRegExp("\\.t$"), ""); | 550 | vars["TEMPLATE"].first().replace(QRegExp("\\.t$"), ""); |
544 | if(!Option::user_template_prefix.isEmpty()) | 551 | if(!Option::user_template_prefix.isEmpty()) |
545 | vars["TEMPLATE"].first().prepend(Option::user_template_prefix); | 552 | vars["TEMPLATE"].first().prepend(Option::user_template_prefix); |
546 | 553 | ||
547 | if(vars["TARGET"].isEmpty()) { | 554 | if(vars["TARGET"].isEmpty()) { |
548 | // ### why not simply use: | 555 | // ### why not simply use: |
549 | // QFileInfo fi(pfile); | 556 | // QFileInfo fi(pfile); |
550 | // fi.baseName(); | 557 | // fi.baseName(); |
551 | QString tmp = pfile; | 558 | QString tmp = pfile; |
552 | if(tmp.findRev('/') != -1) | 559 | if(tmp.findRev('/') != -1) |
553 | tmp = tmp.right( tmp.length() - tmp.findRev('/') - 1 ); | 560 | tmp = tmp.right( tmp.length() - tmp.findRev('/') - 1 ); |
554 | if(tmp.findRev('.') != -1) | 561 | if(tmp.findRev('.') != -1) |
555 | tmp = tmp.left(tmp.findRev('.')); | 562 | tmp = tmp.left(tmp.findRev('.')); |
556 | vars["TARGET"].append(tmp); | 563 | vars["TARGET"].append(tmp); |
557 | } | 564 | } |
558 | 565 | ||
559 | QString test_version = getenv("QTESTVERSION"); | 566 | QString test_version = getenv("QTESTVERSION"); |
560 | if (!test_version.isEmpty()) { | 567 | if (!test_version.isEmpty()) { |
561 | QString s = vars["TARGET"].first(); | 568 | QString s = vars["TARGET"].first(); |
562 | if (s == "qt" || s == "qt-mt" || s == "qte" || s == "qte-mt") { | 569 | if (s == "qt" || s == "qt-mt" || s == "qte" || s == "qte-mt") { |
563 | QString &ver = vars["VERSION"].first(); | 570 | QString &ver = vars["VERSION"].first(); |
564 | // fprintf(stderr,"Current QT version number: " + ver + "\n"); | 571 | // fprintf(stderr,"Current QT version number: " + ver + "\n"); |
565 | if (ver != "" && ver != test_version) { | 572 | if (ver != "" && ver != test_version) { |
566 | ver = test_version; | 573 | ver = test_version; |
567 | fprintf(stderr,"Changed QT version number to " + test_version + "!\n"); | 574 | fprintf(stderr,"Changed QT version number to " + test_version + "!\n"); |
568 | } | 575 | } |
569 | } | 576 | } |
570 | } | 577 | } |
571 | return TRUE; | 578 | return TRUE; |
572 | } | 579 | } |
573 | 580 | ||
574 | bool | 581 | bool |
575 | QMakeProject::isActiveConfig(const QString &x) | 582 | QMakeProject::isActiveConfig(const QString &x) |
576 | { | 583 | { |
577 | if(x.isEmpty()) | 584 | if(x.isEmpty()) |
578 | return TRUE; | 585 | return TRUE; |
579 | 586 | ||
580 | QRegExp re(x, FALSE, TRUE); | 587 | QRegExp re(x, FALSE, TRUE); |
581 | if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_UNIX_MODE) && | 588 | if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_UNIX_MODE) && |
582 | x == "unix") | 589 | x == "unix") |
583 | return TRUE; | 590 | return TRUE; |
584 | else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx") | 591 | else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx") |
585 | return TRUE; | 592 | return TRUE; |
586 | else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6") | 593 | else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6") |
587 | return TRUE; | 594 | return TRUE; |
588 | else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9") | 595 | else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9") |
589 | return TRUE; | 596 | return TRUE; |
590 | else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) && | 597 | else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) && |
591 | x == "mac") | 598 | x == "mac") |
592 | return TRUE; | 599 | return TRUE; |
593 | else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32") | 600 | else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32") |
594 | return TRUE; | 601 | return TRUE; |
595 | 602 | ||
596 | 603 | ||
597 | QString spec = Option::mkfile::qmakespec.right(Option::mkfile::qmakespec.length() - | 604 | QString spec = Option::mkfile::qmakespec.right(Option::mkfile::qmakespec.length() - |
598 | (Option::mkfile::qmakespec.findRev(QDir::separator())+1)); | 605 | (Option::mkfile::qmakespec.findRev(QDir::separator())+1)); |
599 | if(re.exactMatch(spec)) | 606 | if(re.exactMatch(spec)) |
600 | return TRUE; | 607 | return TRUE; |
601 | #ifdef Q_OS_UNIX | 608 | #ifdef Q_OS_UNIX |
602 | else if(spec == "default") { | 609 | else if(spec == "default") { |
603 | static char *buffer = NULL; | 610 | static char *buffer = NULL; |
604 | if(!buffer) | 611 | if(!buffer) |
605 | buffer = (char *)malloc(1024); | 612 | buffer = (char *)malloc(1024); |
606 | int l = readlink(Option::mkfile::qmakespec, buffer, 1024); | 613 | int l = readlink(Option::mkfile::qmakespec, buffer, 1024); |
607 | if(l != -1) { | 614 | if(l != -1) { |
608 | buffer[l] = '\0'; | 615 | buffer[l] = '\0'; |
609 | QString r = buffer; | 616 | QString r = buffer; |
610 | if(r.findRev('/') != -1) | 617 | if(r.findRev('/') != -1) |
611 | r = r.mid(r.findRev('/') + 1); | 618 | r = r.mid(r.findRev('/') + 1); |
612 | if(re.exactMatch(r)) | 619 | if(re.exactMatch(r)) |
613 | return TRUE; | 620 | return TRUE; |
614 | } | 621 | } |
615 | } | 622 | } |
616 | #endif | 623 | #endif |
617 | 624 | ||
618 | 625 | ||
619 | QStringList &configs = vars["CONFIG"]; | 626 | QStringList &configs = vars["CONFIG"]; |
620 | for(QStringList::Iterator it = configs.begin(); it != configs.end(); ++it) { | 627 | for(QStringList::Iterator it = configs.begin(); it != configs.end(); ++it) { |
621 | if(re.exactMatch((*it))) | 628 | if(re.exactMatch((*it))) |
622 | return TRUE; | 629 | return TRUE; |
623 | } | 630 | } |
624 | return FALSE; | 631 | return FALSE; |
625 | } | 632 | } |
626 | 633 | ||
627 | bool | 634 | bool |
628 | QMakeProject::doProjectTest(QString func, const QString ¶ms, QMap<QString, QStringList> &place) | 635 | QMakeProject::doProjectTest(QString func, const QString ¶ms, QMap<QString, QStringList> &place) |
629 | { | 636 | { |
630 | QStringList args = split_arg_list(params); | 637 | QStringList args = split_arg_list(params); |
631 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { | 638 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { |
632 | QString tmp = (*arit).stripWhiteSpace(); | 639 | QString tmp = (*arit).stripWhiteSpace(); |
633 | if((tmp[0] == '\'' || tmp[0] == '"') && tmp.right(1) == tmp.left(1)) | 640 | if((tmp[0] == '\'' || tmp[0] == '"') && tmp.right(1) == tmp.left(1)) |
634 | tmp = tmp.mid(1, tmp.length() - 2); | 641 | tmp = tmp.mid(1, tmp.length() - 2); |
635 | } | 642 | } |
636 | return doProjectTest(func.stripWhiteSpace(), args, place); | 643 | return doProjectTest(func.stripWhiteSpace(), args, place); |
637 | } | 644 | } |
638 | 645 | ||
639 | bool | 646 | bool |
640 | QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place) | 647 | QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place) |
641 | { | 648 | { |
642 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { | 649 | for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { |
643 | (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space | 650 | (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space |
644 | doVariableReplace((*arit), place); | 651 | doVariableReplace((*arit), place); |
645 | } | 652 | } |
646 | debug_msg(1, "Running project test: %s( %s )", func.latin1(), args.join("::").latin1()); | 653 | debug_msg(1, "Running project test: %s( %s )", func.latin1(), args.join("::").latin1()); |
647 | 654 | ||
648 | if(func == "requires") { | 655 | if(func == "requires") { |
649 | return doProjectCheckReqs(args, place); | 656 | return doProjectCheckReqs(args, place); |
650 | } else if(func == "exists") { | 657 | } else if(func == "exists") { |
651 | if(args.count() != 1) { | 658 | if(args.count() != 1) { |
652 | fprintf(stderr, "%s:%d: exists(file) requires one argument.\n", parser.file.latin1(), | 659 | fprintf(stderr, "%s:%d: exists(file) requires one argument.\n", parser.file.latin1(), |
653 | parser.line_no); | 660 | parser.line_no); |
654 | return FALSE; | 661 | return FALSE; |
655 | } | 662 | } |
656 | QString file = args.first(); | 663 | QString file = args.first(); |
657 | file = Option::fixPathToLocalOS(file); | 664 | file = Option::fixPathToLocalOS(file); |
658 | doVariableReplace(file, place); | 665 | doVariableReplace(file, place); |
659 | 666 | ||
660 | if(QFile::exists(file)) | 667 | if(QFile::exists(file)) |
661 | return TRUE; | 668 | return TRUE; |
662 | //regular expression I guess | 669 | //regular expression I guess |
663 | QString dirstr = QDir::currentDirPath(); | 670 | QString dirstr = QDir::currentDirPath(); |
664 | int slsh = file.findRev(Option::dir_sep); | 671 | int slsh = file.findRev(Option::dir_sep); |
665 | if(slsh != -1) { | 672 | if(slsh != -1) { |
666 | dirstr = file.left(slsh+1); | 673 | dirstr = file.left(slsh+1); |
667 | file = file.right(file.length() - slsh - 1); | 674 | file = file.right(file.length() - slsh - 1); |
668 | } | 675 | } |
669 | QDir dir(dirstr, file); | 676 | QDir dir(dirstr, file); |
670 | return dir.count() != 0; | 677 | return dir.count() != 0; |
671 | } else if(func == "system") { | 678 | } else if(func == "system") { |
672 | if(args.count() != 1) { | 679 | if(args.count() != 1) { |
673 | fprintf(stderr, "%s:%d: system(exec) requires one argument.\n", parser.file.latin1(), | 680 | fprintf(stderr, "%s:%d: system(exec) requires one argument.\n", parser.file.latin1(), |
674 | parser.line_no); | 681 | parser.line_no); |
675 | return FALSE; | 682 | return FALSE; |
676 | } | 683 | } |
677 | return system(args.first().latin1()) == 0; | 684 | return system(args.first().latin1()) == 0; |
678 | } else if(func == "contains") { | 685 | } else if(func == "contains") { |
679 | if(args.count() != 2) { | 686 | if(args.count() != 2) { |
680 | fprintf(stderr, "%s:%d: contains(var, val) requires two arguments.\n", parser.file.latin1(), | 687 | fprintf(stderr, "%s:%d: contains(var, val) requires two arguments.\n", parser.file.latin1(), |
681 | parser.line_no); | 688 | parser.line_no); |
682 | return FALSE; | 689 | return FALSE; |
683 | } | 690 | } |
684 | QRegExp regx(args[1]); | 691 | QRegExp regx(args[1]); |
685 | QStringList &l = place[args[0]]; | 692 | QStringList &l = place[args[0]]; |
686 | for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { | 693 | for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { |
687 | if(regx.exactMatch((*it))) | 694 | if(regx.exactMatch((*it))) |
688 | return TRUE; | 695 | return TRUE; |
689 | } | 696 | } |
690 | return FALSE; | 697 | return FALSE; |
691 | } else if(func == "infile") { | 698 | } else if(func == "infile") { |
692 | if(args.count() < 2 || args.count() > 3) { | 699 | if(args.count() < 2 || args.count() > 3) { |
693 | fprintf(stderr, "%s:%d: infile(file, var, val) requires at least 2 arguments.\n", | 700 | fprintf(stderr, "%s:%d: infile(file, var, val) requires at least 2 arguments.\n", |
694 | parser.file.latin1(), parser.line_no); | 701 | parser.file.latin1(), parser.line_no); |
695 | return FALSE; | 702 | return FALSE; |
696 | } | 703 | } |
697 | QMakeProject proj; | 704 | QMakeProject proj; |
698 | QString file = args[0]; | 705 | QString file = args[0]; |
699 | doVariableReplace(file, place); | 706 | doVariableReplace(file, place); |
700 | fixEnvVariables(file); | 707 | fixEnvVariables(file); |
701 | int di = file.findRev(Option::dir_sep); | 708 | int di = file.findRev(Option::dir_sep); |
702 | QDir sunworkshop42workaround = QDir::current(); | 709 | QDir sunworkshop42workaround = QDir::current(); |
703 | QString oldpwd = sunworkshop42workaround.currentDirPath(); | 710 | QString oldpwd = sunworkshop42workaround.currentDirPath(); |
704 | if(di != -1) { | 711 | if(di != -1) { |
705 | if(!QDir::setCurrent(file.left(file.findRev(Option::dir_sep)))) { | 712 | if(!QDir::setCurrent(file.left(file.findRev(Option::dir_sep)))) { |
706 | fprintf(stderr, "Cannot find directory: %s\n", file.left(di).latin1()); | 713 | fprintf(stderr, "Cannot find directory: %s\n", file.left(di).latin1()); |
707 | return FALSE; | 714 | return FALSE; |
708 | } | 715 | } |
709 | file = file.right(file.length() - di - 1); | 716 | file = file.right(file.length() - di - 1); |
710 | } | 717 | } |
711 | parser_info pi = parser; | 718 | parser_info pi = parser; |
712 | bool ret = !proj.read(file, oldpwd); | 719 | bool ret = !proj.read(file, oldpwd); |
713 | parser = pi; | 720 | parser = pi; |
714 | if(ret) { | 721 | if(ret) { |
715 | fprintf(stderr, "Error processing project file: %s\n", file.latin1()); | 722 | fprintf(stderr, "Error processing project file: %s\n", file.latin1()); |
716 | QDir::setCurrent(oldpwd); | 723 | QDir::setCurrent(oldpwd); |
717 | return FALSE; | 724 | return FALSE; |
718 | } | 725 | } |
719 | if(args.count() == 2) { | 726 | if(args.count() == 2) { |
720 | ret = !proj.isEmpty(args[1]); | 727 | ret = !proj.isEmpty(args[1]); |
721 | } else { | 728 | } else { |
722 | QRegExp regx(args[2]); | 729 | QRegExp regx(args[2]); |
723 | QStringList &l = proj.values(args[1]); | 730 | QStringList &l = proj.values(args[1]); |
724 | for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { | 731 | for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { |
725 | if(regx.exactMatch((*it))) { | 732 | if(regx.exactMatch((*it))) { |
726 | ret = TRUE; | 733 | ret = TRUE; |
727 | break; | 734 | break; |
728 | } | 735 | } |
729 | } | 736 | } |
730 | } | 737 | } |
731 | QDir::setCurrent(oldpwd); | 738 | QDir::setCurrent(oldpwd); |
732 | return ret; | 739 | return ret; |
733 | } else if(func == "count") { | 740 | } else if(func == "count") { |
734 | if(args.count() != 2) { | 741 | if(args.count() != 2) { |
735 | fprintf(stderr, "%s:%d: count(var, count) requires two arguments.\n", parser.file.latin1(), | 742 | fprintf(stderr, "%s:%d: count(var, count) requires two arguments.\n", parser.file.latin1(), |
736 | parser.line_no); | 743 | parser.line_no); |
737 | return FALSE; | 744 | return FALSE; |
738 | } | 745 | } |
739 | return vars[args[0]].count() == args[1].toUInt(); | 746 | return vars[args[0]].count() == args[1].toUInt(); |
740 | } else if(func == "isEmpty") { | 747 | } else if(func == "isEmpty") { |
741 | if(args.count() != 1) { | 748 | if(args.count() != 1) { |
742 | fprintf(stderr, "%s:%d: isEmpty(var) requires one argument.\n", parser.file.latin1(), | 749 | fprintf(stderr, "%s:%d: isEmpty(var) requires one argument.\n", parser.file.latin1(), |
743 | parser.line_no); | 750 | parser.line_no); |
744 | return FALSE; | 751 | return FALSE; |
745 | } | 752 | } |
746 | return vars[args[0]].isEmpty(); | 753 | return vars[args[0]].isEmpty(); |
747 | } else if(func == "include" || func == "load") { | 754 | } else if(func == "include" || func == "load") { |
748 | if(args.count() != 1) { | 755 | if(args.count() != 1) { |
749 | QString func_desc = "include(file)"; | 756 | QString func_desc = "include(file)"; |
750 | if(func == "load") | 757 | if(func == "load") |
751 | func_desc = "load(feature)"; | 758 | func_desc = "load(feature)"; |
752 | fprintf(stderr, "%s:%d: %s requires one argument.\n", parser.file.latin1(), | 759 | fprintf(stderr, "%s:%d: %s requires one argument.\n", parser.file.latin1(), |
753 | parser.line_no, func_desc.latin1()); | 760 | parser.line_no, func_desc.latin1()); |
754 | return FALSE; | 761 | return FALSE; |
755 | } | 762 | } |
756 | 763 | ||
757 | QString file = args.first(); | 764 | QString file = args.first(); |
758 | file = Option::fixPathToLocalOS(file); | 765 | file = Option::fixPathToLocalOS(file); |
759 | file.replace("\"", ""); | 766 | file.replace("\"", ""); |
760 | doVariableReplace(file, place); | 767 | doVariableReplace(file, place); |
761 | if(func == "load") { | 768 | if(func == "load") { |
762 | if(!file.endsWith(Option::prf_ext)) | 769 | if(!file.endsWith(Option::prf_ext)) |
763 | file += Option::prf_ext; | 770 | file += Option::prf_ext; |
764 | if(file.find(Option::dir_sep) == -1 || !QFile::exists(file)) { | 771 | if(file.find(Option::dir_sep) == -1 || !QFile::exists(file)) { |
765 | if(QFile::exists(Option::mkfile::qmakespec + QDir::separator() + file)) { | 772 | if(QFile::exists(Option::mkfile::qmakespec + QDir::separator() + file)) { |
766 | file.prepend(Option::mkfile::qmakespec + QDir::separator()); | 773 | file.prepend(Option::mkfile::qmakespec + QDir::separator()); |
767 | } else { | 774 | } else { |
768 | bool found = FALSE; | 775 | bool found = FALSE; |
769 | QStringList feature_roots; | 776 | QStringList feature_roots; |
770 | if(getenv("QTDIR")) | 777 | if(getenv("QTDIR")) |
771 | feature_roots << getenv("QTDIR"); | 778 | feature_roots << getenv("QTDIR"); |
772 | #ifdef QT_INSTALL_PREFIX | 779 | #ifdef QT_INSTALL_PREFIX |
773 | feature_roots << QT_INSTALL_PREFIX; | 780 | feature_roots << QT_INSTALL_PREFIX; |
774 | #endif | 781 | #endif |
775 | #ifdef QT_INSTALL_DATA | 782 | #ifdef QT_INSTALL_DATA |
776 | feature_roots << QT_INSTALL_DATA; | 783 | feature_roots << QT_INSTALL_DATA; |
777 | #endif | 784 | #endif |
778 | for(QStringList::Iterator it = feature_roots.begin(); it != feature_roots.end(); ++it) { | 785 | for(QStringList::Iterator it = feature_roots.begin(); it != feature_roots.end(); ++it) { |
779 | QString prf = (*it) + QDir::separator() + QString("mkspecs") + | 786 | QString prf = (*it) + QDir::separator() + QString("mkspecs") + |
780 | QDir::separator() + QString("features") + QDir::separator() + file; | 787 | QDir::separator() + QString("features") + QDir::separator() + file; |
781 | if(QFile::exists(prf)) { | 788 | if(QFile::exists(prf)) { |
782 | found = TRUE; | 789 | found = TRUE; |
783 | file = prf; | 790 | file = prf; |
784 | break; | 791 | break; |
785 | } | 792 | } |
786 | } | 793 | } |
787 | if(!found) { | 794 | if(!found) { |
788 | printf("Project LOAD(): Feature %s cannot be found.\n", args.first().latin1()); | 795 | printf("Project LOAD(): Feature %s cannot be found.\n", args.first().latin1()); |
789 | exit(3); | 796 | exit(3); |
790 | } | 797 | } |
791 | } | 798 | } |
792 | } | 799 | } |
793 | } | 800 | } |
794 | 801 | ||
795 | debug_msg(1, "Project Parser: %s'ing file %s.", func.latin1(), file.latin1()); | 802 | debug_msg(1, "Project Parser: %s'ing file %s.", func.latin1(), file.latin1()); |
796 | parser_info pi = parser; | 803 | parser_info pi = parser; |
797 | int sb = scope_block; | 804 | int sb = scope_block; |
798 | int sf = scope_flag; | 805 | int sf = scope_flag; |
799 | TestStatus sc = test_status; | 806 | TestStatus sc = test_status; |
800 | bool r = read(file.latin1(), place); | 807 | bool r = read(file.latin1(), place); |
801 | if(r) | 808 | if(r) |
802 | vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(file); | 809 | vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(file); |
803 | parser = pi; | 810 | parser = pi; |
804 | test_status = sc; | 811 | test_status = sc; |
805 | scope_flag = sf; | 812 | scope_flag = sf; |
806 | scope_block = sb; | 813 | scope_block = sb; |
807 | return r; | 814 | return r; |
808 | } else if(func == "error" || func == "message") { | 815 | } else if(func == "error" || func == "message") { |
809 | if(args.count() != 1) { | 816 | if(args.count() != 1) { |
810 | fprintf(stderr, "%s:%d: %s(message) requires one argument.\n", parser.file.latin1(), | 817 | fprintf(stderr, "%s:%d: %s(message) requires one argument.\n", parser.file.latin1(), |
811 | parser.line_no, func.latin1()); | 818 | parser.line_no, func.latin1()); |
812 | return FALSE; | 819 | return FALSE; |
813 | } | 820 | } |
814 | QString msg = args.first(); | 821 | QString msg = args.first(); |
815 | doVariableReplace(msg, place); | 822 | doVariableReplace(msg, place); |
816 | fixEnvVariables(msg); | 823 | fixEnvVariables(msg); |
817 | printf("Project %s: %s\n", func.upper().latin1(), msg.latin1()); | 824 | printf("Project %s: %s\n", func.upper().latin1(), msg.latin1()); |
818 | if(func == "message") | 825 | if(func == "message") |
819 | return TRUE; | 826 | return TRUE; |
820 | exit(2); | 827 | exit(2); |
821 | } else { | 828 | } else { |
822 | fprintf(stderr, "%s:%d: Unknown test function: %s\n", parser.file.latin1(), parser.line_no, | 829 | fprintf(stderr, "%s:%d: Unknown test function: %s\n", parser.file.latin1(), parser.line_no, |
823 | func.latin1()); | 830 | func.latin1()); |
824 | } | 831 | } |
825 | return FALSE; | 832 | return FALSE; |
826 | } | 833 | } |
827 | 834 | ||
828 | bool | 835 | bool |
829 | QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place) | 836 | QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place) |
830 | { | 837 | { |
831 | bool ret = FALSE; | 838 | bool ret = FALSE; |
832 | for(QStringList::ConstIterator it = deps.begin(); it != deps.end(); ++it) { | 839 | for(QStringList::ConstIterator it = deps.begin(); it != deps.end(); ++it) { |
833 | QString chk = (*it); | 840 | QString chk = (*it); |
834 | if(chk.isEmpty()) | 841 | if(chk.isEmpty()) |
835 | continue; | 842 | continue; |
836 | bool invert_test = (chk.left(1) == "!"); | 843 | bool invert_test = (chk.left(1) == "!"); |
837 | if(invert_test) | 844 | if(invert_test) |
838 | chk = chk.right(chk.length() - 1); | 845 | chk = chk.right(chk.length() - 1); |
839 | 846 | ||
840 | bool test; | 847 | bool test; |
841 | int lparen = chk.find('('); | 848 | int lparen = chk.find('('); |
842 | if(lparen != -1) { /* if there is an lparen in the chk, it IS a function */ | 849 | if(lparen != -1) { /* if there is an lparen in the chk, it IS a function */ |
843 | int rparen = chk.findRev(')'); | 850 | int rparen = chk.findRev(')'); |
844 | if(rparen == -1) { | 851 | if(rparen == -1) { |
845 | QCString error; | 852 | QCString error; |
846 | error.sprintf("Function (in REQUIRES) missing right paren: %s", chk.latin1()); | 853 | error.sprintf("Function (in REQUIRES) missing right paren: %s", chk.latin1()); |
847 | qmake_error_msg(error); | 854 | qmake_error_msg(error); |
848 | } else { | 855 | } else { |