summaryrefslogtreecommitdiff
authorkergoth <kergoth>2002-11-01 16:20:04 (UTC)
committer kergoth <kergoth>2002-11-01 16:20:04 (UTC)
commit4c9df59925da5a67d884f8ffb37a263d85948951 (patch) (unidiff)
tree278796d7d27a06243e584a05f443dbb23eaf028c
parentebd6adcd2f72935f0ee7af7485c75c34ac3389a3 (diff)
downloadopie-4c9df59925da5a67d884f8ffb37a263d85948951.zip
opie-4c9df59925da5a67d884f8ffb37a263d85948951.tar.gz
opie-4c9df59925da5a67d884f8ffb37a263d85948951.tar.bz2
Make qmake obey QMAKESPECSDIR if set.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/project.cpp23
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;
61static void qmake_error_msg(const char *msg) 61static 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
66static QString varMap(const QString &x) 66static 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
75static QStringList split_arg_list(const QString &params) 75static QStringList split_arg_list(const QString &params)
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
99static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE) 99static 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
120QMakeProject::QMakeProject() 120QMakeProject::QMakeProject()
121{ 121{
122} 122}
123 123
124bool 124bool
125QMakeProject::parse(QString t, QMap<QString, QStringList> &place) 125QMakeProject::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
357bool 357bool
358QMakeProject::read(QString file, QMap<QString, QStringList> &place) 358QMakeProject::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
410bool 410bool
411QMakeProject::read(QString project, QString) 411QMakeProject::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
574bool 581bool
575QMakeProject::isActiveConfig(const QString &x) 582QMakeProject::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
627bool 634bool
628QMakeProject::doProjectTest(QString func, const QString &params, QMap<QString, QStringList> &place) 635QMakeProject::doProjectTest(QString func, const QString &params, 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
639bool 646bool
640QMakeProject::doProjectTest(QString func, QStringList args, QMap<QString, QStringList> &place) 647QMakeProject::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
828bool 835bool
829QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place) 836QMakeProject::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 {