Print this page
make: fix GCC warnings
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/read.cc
+++ new/usr/src/cmd/make/bin/read.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * read.c
28 28 *
29 29 * This file contains the makefile reader.
30 30 */
31 31
32 32 /*
33 33 * Included files
34 34 */
35 35 #include <avo/avo_alloca.h> /* alloca() */
36 36 #include <errno.h> /* errno */
37 37 #include <fcntl.h> /* fcntl() */
38 38 #include <mk/defs.h>
39 39 #include <mksh/macro.h> /* expand_value(), expand_macro() */
40 40 #include <mksh/misc.h> /* getmem() */
41 41 #include <mksh/read.h> /* get_next_block_fn() */
42 42 #include <sys/uio.h> /* read() */
43 43 #include <unistd.h> /* read(), unlink() */
44 44
45 45 #if defined(HP_UX) || defined(linux)
46 46 #include <avo/types.h>
47 47 extern "C" Avo_err *avo_find_run_dir(char **dirp);
48 48 #endif
49 49
50 50 /*
51 51 * typedefs & structs
52 52 */
53 53
54 54 /*
55 55 * Static variables
56 56 */
57 57
58 58 static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
59 59
60 60 /*
61 61 * File table of contents
62 62 */
63 63 static void parse_makefile(register Name true_makefile_name, register Source source);
64 64 static Source push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source);
65 65 extern void enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen);
66 66 extern Name normalize_name(register wchar_t *name_string, register int length);
67 67
68 68 /*
69 69 * read_simple_file(makefile_name, chase_path, doname_it,
70 70 * complain, must_exist, report_file, lock_makefile)
71 71 *
72 72 * Make the makefile and setup to read it. Actually read it if it is stdio
73 73 *
74 74 * Return value:
75 75 * false if the read failed
76 76 *
77 77 * Parameters:
78 78 * makefile_name Name of the file to read
79 79 * chase_path Use the makefile path when opening file
80 80 * doname_it Call doname() to build the file first
81 81 * complain Print message if doname/open fails
82 82 * must_exist Generate fatal if file is missing
83 83 * report_file Report file when running -P
84 84 * lock_makefile Lock the makefile when reading
85 85 *
86 86 * Static variables used:
87 87 *
88 88 * Global variables used:
89 89 * do_not_exec_rule Is -n on?
90 90 * file_being_read Set to the name of the new file
91 91 * line_number The number of the current makefile line
92 92 * makefiles_used A list of all makefiles used, appended to
93 93 */
94 94
95 95
96 96 Boolean
97 97 read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile)
98 98 {
99 99 static short max_include_depth;
100 100 register Property makefile = maybe_append_prop(makefile_name,
101 101 makefile_prop);
102 102 Boolean forget_after_parse = false;
103 103 static pathpt makefile_path;
104 104 register int n;
105 105 char *path;
106 106 register Source source = ALLOC(Source);
107 107 Property orig_makefile = makefile;
108 108 Dependency *dpp;
109 109 Dependency dp;
110 110 register int length;
111 111 wchar_t *previous_file_being_read = file_being_read;
112 112 int previous_line_number = line_number;
113 113 wchar_t previous_current_makefile[MAXPATHLEN];
114 114 Makefile_type save_makefile_type;
115 115 Name normalized_makefile_name;
116 116 register wchar_t *string_start;
117 117 register wchar_t *string_end;
118 118
119 119
120 120 #if defined(HP_UX) || defined(linux)
121 121 Avo_err *findrundir_err;
122 122 char *run_dir, makerules_dir[BUFSIZ];
123 123 #endif
124 124
125 125 wchar_t * wcb = get_wstring(makefile_name->string_mb);
126 126
127 127 #ifdef NSE
128 128 if (report_file){
129 129 wscpy(previous_current_makefile, current_makefile);
130 130 wscpy(current_makefile, wcb);
131 131 }
132 132 #endif
133 133 if (max_include_depth++ >= 40) {
134 134 fatal(catgets(catd, 1, 66, "Too many nested include statements"));
135 135 }
136 136 if (makefile->body.makefile.contents != NULL) {
137 137 retmem(makefile->body.makefile.contents);
138 138 }
139 139 source->inp_buf =
140 140 source->inp_buf_ptr =
141 141 source->inp_buf_end = NULL;
142 142 source->error_converting = false;
143 143 makefile->body.makefile.contents = NULL;
144 144 makefile->body.makefile.size = 0;
145 145 if ((makefile_name->hash.length != 1) ||
146 146 (wcb[0] != (int) hyphen_char)) {
147 147 if ((makefile->body.makefile.contents == NULL) &&
148 148 (doname_it)) {
149 149 if (makefile_path == NULL) {
150 150 add_dir_to_path(".",
151 151 &makefile_path,
152 152 -1);
153 153 #ifdef SUN5_0
154 154 add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
155 155 &makefile_path,
156 156 -1);
157 157 add_dir_to_path(NOCATGETS("/etc/default"),
158 158 &makefile_path,
159 159 -1);
160 160 #elif defined(HP_UX)
161 161 findrundir_err = avo_find_run_dir(&run_dir);
162 162 if (! findrundir_err) {
163 163 (void) sprintf(makerules_dir, NOCATGETS("%s/../share/lib/make"), run_dir);
164 164 add_dir_to_path(makerules_dir,
165 165 &makefile_path,
166 166 -1);
167 167 }
168 168
169 169 add_dir_to_path(NOCATGETS("/opt/SUNWspro/share/lib/make"),
170 170 &makefile_path,
171 171 -1);
172 172 add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
173 173 &makefile_path,
174 174 -1);
175 175 #elif defined(linux)
176 176 findrundir_err = avo_find_run_dir(&run_dir);
177 177 if (! findrundir_err) {
178 178 (void) sprintf(makerules_dir, NOCATGETS("%s/../lib"), run_dir);
179 179 add_dir_to_path(makerules_dir,
180 180 &makefile_path,
181 181 -1);
182 182 }
183 183
184 184 add_dir_to_path(NOCATGETS("/usr/SUNWspro/lib"),
185 185 &makefile_path,
186 186 -1);
187 187 add_dir_to_path(NOCATGETS("/opt/SUNWspro/share/lib/make"),
188 188 &makefile_path,
189 189 -1);
190 190 add_dir_to_path(NOCATGETS("/usr/share/lib/make"),
191 191 &makefile_path,
192 192 -1);
193 193 #else
↓ open down ↓ |
193 lines elided |
↑ open up ↑ |
194 194 add_dir_to_path(NOCATGETS("/usr/include/make"),
195 195 &makefile_path,
196 196 -1);
197 197 #endif
198 198 }
199 199 save_makefile_type = makefile_type;
200 200 makefile_type = reading_nothing;
201 201 if (doname(makefile_name, true, false) == build_dont_know) {
202 202 /* Try normalized filename */
203 203 string_start=get_wstring(makefile_name->string_mb);
204 - for (string_end=string_start+1; *string_end != NULL; string_end++);
204 + for (string_end=string_start+1; *string_end != L'\0'; string_end++);
205 205 normalized_makefile_name=normalize_name(string_start, string_end - string_start);
206 206 if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) ||
207 207 (doname(normalized_makefile_name, true, false) == build_dont_know)) {
208 208 n = access_vroot(makefile_name->string_mb,
209 209 4,
210 210 chase_path ?
211 211 makefile_path : NULL,
212 212 VROOT_DEFAULT);
213 213 if (n == 0) {
214 214 get_vroot_path((char **) NULL,
215 215 &path,
216 216 (char **) NULL);
217 217 if ((path[0] == (int) period_char) &&
218 218 (path[1] == (int) slash_char)) {
219 219 path += 2;
220 220 }
221 221 MBSTOWCS(wcs_buffer, path);
222 222 makefile_name = GETNAME(wcs_buffer,
223 223 FIND_LENGTH);
224 224 }
225 225 }
226 226 retmem(string_start);
227 227 /*
228 228 * Commented out: retmem_mb(normalized_makefile_name->string_mb);
229 229 * We have to return this memory, but it seems to trigger a bug
230 230 * in dmake or in Sun C++ 5.7 compiler (it works ok if this code
231 231 * is compiled using Sun C++ 5.6).
232 232 */
233 233 // retmem_mb(normalized_makefile_name->string_mb);
234 234 }
235 235 makefile_type = save_makefile_type;
236 236 }
237 237 source->string.free_after_use = false;
238 238 source->previous = NULL;
239 239 source->already_expanded = false;
240 240 /* Lock the file for read, but not when -n. */
241 241 if (lock_makefile &&
242 242 !do_not_exec_rule) {
243 243
244 244 make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(NOCATGETS(".lock")) + 1);
245 245 (void) sprintf(make_state_lockfile,
246 246 NOCATGETS("%s.lock"),
247 247 make_state->string_mb);
248 248 (void) file_lock(make_state->string_mb,
249 249 make_state_lockfile,
250 250 (int *) &make_state_locked,
251 251 0);
252 252 if(!make_state_locked) {
253 253 printf(NOCATGETS("-- NO LOCKING for read\n"));
254 254 retmem_mb(make_state_lockfile);
255 255 make_state_lockfile = 0;
256 256 return failed;
257 257 }
258 258 }
259 259 if (makefile->body.makefile.contents == NULL) {
260 260 save_makefile_type = makefile_type;
261 261 makefile_type = reading_nothing;
262 262 if ((doname_it) &&
263 263 (doname(makefile_name, true, false) == build_failed)) {
264 264 if (complain) {
265 265 (void) fprintf(stderr,
266 266 #ifdef DISTRIBUTED
267 267 catgets(catd, 1, 67, "dmake: Couldn't dmake `%s'\n"),
268 268 #else
269 269 catgets(catd, 1, 237, "make: Couldn't make `%s'\n"),
270 270 #endif
271 271 makefile_name->string_mb);
272 272 }
273 273 max_include_depth--;
274 274 makefile_type = save_makefile_type;
275 275 return failed;
276 276 }
277 277 makefile_type = save_makefile_type;
278 278 //
279 279 // Before calling exists() make sure that we have the right timestamp
280 280 //
281 281 makefile_name->stat.time = file_no_time;
282 282
283 283 if (exists(makefile_name) == file_doesnt_exist) {
284 284 if (complain ||
285 285 (makefile_name->stat.stat_errno != ENOENT)) {
286 286 if (must_exist) {
287 287 fatal(catgets(catd, 1, 68, "Can't find `%s': %s"),
288 288 makefile_name->string_mb,
289 289 errmsg(makefile_name->
290 290 stat.stat_errno));
291 291 } else {
292 292 warning(catgets(catd, 1, 69, "Can't find `%s': %s"),
293 293 makefile_name->string_mb,
294 294 errmsg(makefile_name->
295 295 stat.stat_errno));
296 296 }
297 297 }
298 298 max_include_depth--;
299 299 if(make_state_locked && (make_state_lockfile != NULL)) {
300 300 (void) unlink(make_state_lockfile);
301 301 retmem_mb(make_state_lockfile);
302 302 make_state_lockfile = NULL;
303 303 make_state_locked = false;
304 304 }
305 305 retmem(wcb);
306 306 retmem_mb((char *)source);
307 307 return failed;
308 308 }
309 309 /*
310 310 * These values are the size and bytes of
311 311 * the MULTI-BYTE makefile.
312 312 */
313 313 orig_makefile->body.makefile.size =
314 314 makefile->body.makefile.size =
315 315 source->bytes_left_in_file =
316 316 makefile_name->stat.size;
317 317 if (report_file) {
318 318 for (dpp = &makefiles_used;
319 319 *dpp != NULL;
320 320 dpp = &(*dpp)->next);
321 321 dp = ALLOC(Dependency);
322 322 dp->next = NULL;
323 323 dp->name = makefile_name;
324 324 dp->automatic = false;
325 325 dp->stale = false;
326 326 dp->built = false;
327 327 *dpp = dp;
328 328 }
329 329 source->fd = open_vroot(makefile_name->string_mb,
330 330 O_RDONLY,
331 331 0,
332 332 NULL,
333 333 VROOT_DEFAULT);
334 334 if (source->fd < 0) {
335 335 if (complain || (errno != ENOENT)) {
336 336 if (must_exist) {
337 337 fatal(catgets(catd, 1, 70, "Can't open `%s': %s"),
338 338 makefile_name->string_mb,
339 339 errmsg(errno));
340 340 } else {
341 341 warning(catgets(catd, 1, 71, "Can't open `%s': %s"),
342 342 makefile_name->string_mb,
343 343 errmsg(errno));
344 344 }
345 345 }
346 346 max_include_depth--;
347 347 return failed;
348 348 }
349 349 (void) fcntl(source->fd, F_SETFD, 1);
350 350 orig_makefile->body.makefile.contents =
351 351 makefile->body.makefile.contents =
352 352 source->string.text.p =
353 353 source->string.buffer.start =
354 354 ALLOC_WC((int) (makefile_name->stat.size + 2));
355 355 if (makefile_type == reading_cpp_file) {
356 356 forget_after_parse = true;
357 357 }
358 358 source->string.text.end = source->string.text.p;
359 359 source->string.buffer.end =
360 360 source->string.text.p + makefile_name->stat.size;
361 361 } else {
362 362 /* Do we ever reach here? */
363 363 source->fd = -1;
364 364 source->string.text.p =
365 365 source->string.buffer.start =
366 366 makefile->body.makefile.contents;
367 367 source->string.text.end =
368 368 source->string.buffer.end =
369 369 source->string.text.p + makefile->body.makefile.size;
370 370 source->bytes_left_in_file =
371 371 makefile->body.makefile.size;
372 372 }
373 373 file_being_read = wcb;
374 374 } else {
375 375 char *stdin_text_p;
376 376 char *stdin_text_end;
377 377 char *stdin_buffer_start;
378 378 char *stdin_buffer_end;
379 379 char *p_mb;
380 380 int num_mb_chars;
381 381 size_t num_wc_chars;
382 382
383 383 MBSTOWCS(wcs_buffer, NOCATGETS("Standard in"));
384 384 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
385 385 /*
386 386 * Memory to read standard in, then convert it
387 387 * to wide char strings.
388 388 */
389 389 stdin_buffer_start =
390 390 stdin_text_p = getmem(length = 1024);
391 391 stdin_buffer_end = stdin_text_p + length;
392 392 MBSTOWCS(wcs_buffer, NOCATGETS("standard input"));
393 393 file_being_read = (wchar_t *) wsdup(wcs_buffer);
394 394 line_number = 0;
395 395 while ((n = read(fileno(stdin),
396 396 stdin_text_p,
397 397 length)) > 0) {
398 398 length -= n;
399 399 stdin_text_p += n;
400 400 if (length == 0) {
401 401 p_mb = getmem(length = 1024 +
402 402 (stdin_buffer_end -
403 403 stdin_buffer_start));
404 404 (void) strncpy(p_mb,
405 405 stdin_buffer_start,
406 406 (stdin_buffer_end -
407 407 stdin_buffer_start));
408 408 retmem_mb(stdin_buffer_start);
409 409 stdin_text_p = p_mb +
410 410 (stdin_buffer_end - stdin_buffer_start);
411 411 stdin_buffer_start = p_mb;
412 412 stdin_buffer_end =
413 413 stdin_buffer_start + length;
414 414 length = 1024;
415 415 }
416 416 }
417 417 if (n < 0) {
418 418 fatal(catgets(catd, 1, 72, "Error reading standard input: %s"),
419 419 errmsg(errno));
420 420 }
421 421 stdin_text_p = stdin_buffer_start;
422 422 stdin_text_end = stdin_buffer_end - length;
423 423 num_mb_chars = stdin_text_end - stdin_text_p;
424 424
425 425 /*
426 426 * Now, convert the sequence of multibyte chars into
427 427 * a sequence of corresponding wide character codes.
428 428 */
429 429 source->string.free_after_use = false;
430 430 source->previous = NULL;
431 431 source->bytes_left_in_file = 0;
432 432 source->fd = -1;
433 433 source->already_expanded = false;
434 434 source->string.buffer.start =
435 435 source->string.text.p = ALLOC_WC(num_mb_chars + 1);
436 436 source->string.buffer.end =
437 437 source->string.text.p + num_mb_chars;
438 438 num_wc_chars = mbstowcs(source->string.text.p,
439 439 stdin_text_p,
440 440 num_mb_chars);
441 441 if ((int) num_wc_chars >= 0) {
442 442 source->string.text.end =
443 443 source->string.text.p + num_wc_chars;
444 444 }
445 445 (void) retmem_mb(stdin_text_p);
446 446 }
447 447 line_number = 1;
448 448 if (trace_reader) {
449 449 (void) printf(catgets(catd, 1, 73, ">>>>>>>>>>>>>>>> Reading makefile %s\n"),
450 450 makefile_name->string_mb);
451 451 }
452 452 parse_makefile(makefile_name, source);
453 453 if (trace_reader) {
454 454 (void) printf(catgets(catd, 1, 74, ">>>>>>>>>>>>>>>> End of makefile %s\n"),
455 455 makefile_name->string_mb);
456 456 }
457 457 #ifdef NSE
458 458 if (report_file && (previous_current_makefile[0] != NULL)) {
459 459 wscpy(current_makefile, previous_current_makefile);
460 460 }
461 461 #endif
462 462 if(file_being_read) {
463 463 retmem(file_being_read);
464 464 }
465 465 file_being_read = previous_file_being_read;
466 466 line_number = previous_line_number;
467 467 makefile_type = reading_nothing;
468 468 max_include_depth--;
469 469 if (make_state_locked) {
470 470 /* Unlock .make.state. */
471 471 unlink(make_state_lockfile);
472 472 make_state_locked = false;
473 473 retmem_mb(make_state_lockfile);
474 474 }
475 475 if (forget_after_parse) {
476 476 retmem(makefile->body.makefile.contents);
477 477 makefile->body.makefile.contents = NULL;
478 478 }
479 479 retmem_mb((char *)source);
480 480 return succeeded;
481 481 }
482 482
483 483 /*
484 484 * parse_makefile(true_makefile_name, source)
485 485 *
486 486 * Strings are read from Sources.
487 487 * When macros are found, their values are represented by a
488 488 * Source that is pushed on a stack. At end of string
489 489 * (that is returned from GET_CHAR() as 0), the block is popped.
490 490 *
491 491 * Parameters:
492 492 * true_makefile_name The name of makefile we are parsing
493 493 * source The source block to read from
494 494 *
495 495 * Global variables used:
496 496 * do_not_exec_rule Is -n on?
497 497 * line_number The number of the current makefile line
498 498 * makefile_type What kind of makefile are we reading?
499 499 * empty_name The Name ""
500 500 */
501 501 static void
502 502 parse_makefile(register Name true_makefile_name, register Source source)
503 503 {
504 504 /*
505 505 char mb_buffer[MB_LEN_MAX];
506 506 */
507 507 register wchar_t *source_p;
508 508 register wchar_t *source_end;
509 509 register wchar_t *string_start;
510 510 wchar_t *string_end;
511 511 register Boolean macro_seen_in_string;
512 512 Boolean append;
513 513 String_rec name_string;
514 514 wchar_t name_buffer[STRING_BUFFER_LENGTH];
515 515 register int distance;
516 516 register int paren_count;
517 517 int brace_count;
518 518 int char_number;
519 519 Cmd_line command;
520 520 Cmd_line command_tail;
521 521 Name macro_value;
522 522
523 523 Name_vector_rec target;
524 524 Name_vector_rec depes;
525 525 Name_vector_rec extra_name_vector;
526 526 Name_vector current_names;
527 527 Name_vector extra_names = &extra_name_vector;
528 528 Name_vector nvp;
529 529 Boolean target_group_seen;
530 530
531 531 register Reader_state state;
532 532 register Reader_state on_eoln_state;
533 533 register Separator separator;
534 534
535 535 wchar_t buffer[4 * STRING_BUFFER_LENGTH];
536 536 Source extrap;
537 537
538 538 Boolean save_do_not_exec_rule = do_not_exec_rule;
539 539 Name makefile_name;
540 540
541 541 static Name sh_name;
542 542 static Name shell_name;
543 543 int i;
544 544
545 545 static wchar_t include_space[10];
546 546 static wchar_t include_tab[10];
547 547 int tmp_bytes_left_in_string;
548 548 Boolean tmp_maybe_include = false;
549 549 int emptycount = 0;
550 550 Boolean first_target;
551 551
552 552 String_rec include_name;
553 553 wchar_t include_buffer[STRING_BUFFER_LENGTH];
554 554
555 555 target.next = depes.next = NULL;
556 556 /* Move some values from their struct to register declared locals */
557 557 CACHE_SOURCE(0);
558 558
559 559 start_new_line:
560 560 /*
561 561 * Read whitespace on old line. Leave pointer on first char on
562 562 * next line.
563 563 */
564 564 first_target = true;
565 565 on_eoln_state = exit_state;
566 566 /*
567 567 for (WCTOMB(mb_buffer, GET_CHAR());
568 568 1;
569 569 source_p++, WCTOMB(mb_buffer, GET_CHAR()))
570 570 switch (mb_buffer[0]) {
571 571 */
572 572 for (char_number=0; 1; source_p++,char_number++) switch (GET_CHAR()) {
573 573 case nul_char:
574 574 /* End of this string. Pop it and return to the previous one */
575 575 GET_NEXT_BLOCK(source);
576 576 source_p--;
577 577 if (source == NULL) {
578 578 GOTO_STATE(on_eoln_state);
579 579 }
580 580 break;
581 581 case newline_char:
582 582 end_of_line:
583 583 source_p++;
584 584 if (source->fd >= 0) {
585 585 line_number++;
586 586 }
587 587 switch (GET_CHAR()) {
588 588 case nul_char:
589 589 GET_NEXT_BLOCK(source);
590 590 if (source == NULL) {
591 591 GOTO_STATE(on_eoln_state);
592 592 }
593 593 /* Go back to the top of this loop */
594 594 goto start_new_line;
595 595 case newline_char:
596 596 case numbersign_char:
597 597 case dollar_char:
598 598 case space_char:
599 599 case tab_char:
600 600 /*
601 601 * Go back to the top of this loop since the
602 602 * new line does not start with a regular char.
603 603 */
604 604 goto start_new_line;
605 605 default:
606 606 /* We found the first proper char on the new line */
607 607 goto start_new_line_no_skip;
608 608 }
609 609 case space_char:
610 610 if (char_number == 0)
611 611 line_started_with_space=line_number;
612 612 case tab_char:
613 613 /* Whitespace. Just keep going in this loop */
614 614 break;
615 615 case numbersign_char:
616 616 /* Comment. Skip over it */
617 617 for (; 1; source_p++) {
618 618 switch (GET_CHAR()) {
619 619 case nul_char:
620 620 GET_NEXT_BLOCK_NOCHK(source);
621 621 if (source == NULL) {
622 622 GOTO_STATE(on_eoln_state);
623 623 }
624 624 if (source->error_converting) {
625 625 // Illegal byte sequence - skip its first byte
626 626 source->inp_buf_ptr++;
627 627 }
628 628 source_p--;
629 629 break;
630 630 case backslash_char:
631 631 /* Comments can be continued */
632 632 if (*++source_p == (int) nul_char) {
633 633 GET_NEXT_BLOCK_NOCHK(source);
634 634 if (source == NULL) {
635 635 GOTO_STATE(on_eoln_state);
636 636 }
637 637 if (source->error_converting) {
638 638 // Illegal byte sequence - skip its first byte
639 639 source->inp_buf_ptr++;
640 640 source_p--;
641 641 break;
642 642 }
643 643 }
644 644 if(*source_p == (int) newline_char) {
645 645 if (source->fd >= 0) {
646 646 line_number++;
647 647 }
648 648 }
649 649 break;
650 650 case newline_char:
651 651 /*
652 652 * After we skip the comment we go to
653 653 * the end of line handler since end of
654 654 * line terminates comments.
655 655 */
656 656 goto end_of_line;
657 657 }
658 658 }
659 659 case dollar_char:
660 660 /* Macro reference */
661 661 if (source->already_expanded) {
662 662 /*
663 663 * If we are reading from the expansion of a
664 664 * macro we already expanded everything enough.
665 665 */
666 666 goto start_new_line_no_skip;
667 667 }
668 668 /*
669 669 * Expand the value and push the Source on the stack of
670 670 * things being read.
671 671 */
672 672 source_p++;
673 673 UNCACHE_SOURCE();
674 674 {
675 675 Source t = (Source) alloca((int) sizeof (Source_rec));
676 676 source = push_macro_value(t,
677 677 buffer,
678 678 sizeof buffer,
679 679 source);
680 680 }
681 681 CACHE_SOURCE(1);
682 682 break;
683 683 default:
684 684 /* We found the first proper char on the new line */
685 685 goto start_new_line_no_skip;
686 686 }
687 687
688 688 /*
689 689 * We found the first normal char (one that starts an identifier)
690 690 * on the newline.
691 691 */
692 692 start_new_line_no_skip:
693 693 /* Inspect that first char to see if it maybe is special anyway */
694 694 switch (GET_CHAR()) {
695 695 case nul_char:
696 696 GET_NEXT_BLOCK(source);
697 697 if (source == NULL) {
698 698 GOTO_STATE(on_eoln_state);
699 699 }
700 700 goto start_new_line_no_skip;
701 701 case newline_char:
702 702 /* Just in case */
703 703 goto start_new_line;
704 704 case exclam_char:
705 705 /* Evaluate the line before it is read */
706 706 string_start = source_p + 1;
707 707 macro_seen_in_string = false;
708 708 /* Stuff the line in a string so we can eval it. */
709 709 for (; 1; source_p++) {
710 710 switch (GET_CHAR()) {
711 711 case newline_char:
712 712 goto eoln_1;
713 713 case nul_char:
714 714 if (source->fd > 0) {
715 715 if (!macro_seen_in_string) {
716 716 macro_seen_in_string = true;
717 717 INIT_STRING_FROM_STACK(
718 718 name_string, name_buffer);
719 719 }
720 720 append_string(string_start,
721 721 &name_string,
722 722 source_p - string_start);
723 723 GET_NEXT_BLOCK(source);
724 724 string_start = source_p;
725 725 source_p--;
726 726 break;
727 727 }
728 728 eoln_1:
729 729 if (!macro_seen_in_string) {
730 730 INIT_STRING_FROM_STACK(name_string,
731 731 name_buffer);
732 732 }
733 733 append_string(string_start,
734 734 &name_string,
735 735 source_p - string_start);
736 736 extrap = (Source)
737 737 alloca((int) sizeof (Source_rec));
738 738 extrap->string.buffer.start = NULL;
739 739 extrap->inp_buf =
740 740 extrap->inp_buf_ptr =
741 741 extrap->inp_buf_end = NULL;
742 742 extrap->error_converting = false;
743 743 if (*source_p == (int) nul_char) {
744 744 source_p++;
745 745 }
746 746 /* Eval the macro */
747 747 expand_value(GETNAME(name_string.buffer.start,
748 748 FIND_LENGTH),
749 749 &extrap->string,
750 750 false);
751 751 if (name_string.free_after_use) {
752 752 retmem(name_string.buffer.start);
753 753 }
754 754 UNCACHE_SOURCE();
755 755 extrap->string.text.p =
756 756 extrap->string.buffer.start;
757 757 extrap->fd = -1;
758 758 /* And push the value */
759 759 extrap->previous = source;
760 760 source = extrap;
761 761 CACHE_SOURCE(0);
762 762 goto line_evald;
763 763 }
764 764 }
765 765 default:
766 766 goto line_evald;
767 767 }
768 768
769 769 /* We now have a line we can start reading */
770 770 line_evald:
771 771 if (source == NULL) {
772 772 GOTO_STATE(exit_state);
773 773 }
774 774 /* Check if this is an include command */
775 775 if ((makefile_type == reading_makefile) &&
776 776 !source->already_expanded) {
777 777 if (include_space[0] == (int) nul_char) {
778 778 MBSTOWCS(include_space, NOCATGETS("include "));
779 779 MBSTOWCS(include_tab, NOCATGETS("include\t"));
780 780 }
781 781 if ((IS_WEQUALN(source_p, include_space, 8)) ||
782 782 (IS_WEQUALN(source_p, include_tab, 8))) {
783 783 source_p += 7;
784 784 if (iswspace(*source_p)) {
785 785 Makefile_type save_makefile_type;
786 786 wchar_t *name_start;
787 787 int name_length;
788 788
789 789 /*
790 790 * Yes, this is an include.
791 791 * Skip spaces to get to the filename.
792 792 */
793 793 while (iswspace(*source_p) ||
794 794 (*source_p == (int) nul_char)) {
795 795 switch (GET_CHAR()) {
796 796 case nul_char:
797 797 GET_NEXT_BLOCK(source);
798 798 if (source == NULL) {
799 799 GOTO_STATE(on_eoln_state);
800 800 }
801 801 break;
802 802
803 803 default:
804 804 source_p++;
805 805 break;
806 806 }
807 807 }
808 808
809 809 string_start = source_p;
810 810 /* Find the end of the filename */
811 811 macro_seen_in_string = false;
812 812 while (!iswspace(*source_p) ||
813 813 (*source_p == (int) nul_char)) {
814 814 switch (GET_CHAR()) {
815 815 case nul_char:
816 816 if (!macro_seen_in_string) {
817 817 INIT_STRING_FROM_STACK(name_string,
818 818 name_buffer);
819 819 }
820 820 append_string(string_start,
821 821 &name_string,
822 822 source_p - string_start);
823 823 macro_seen_in_string = true;
824 824 GET_NEXT_BLOCK(source);
825 825 string_start = source_p;
826 826 if (source == NULL) {
827 827 GOTO_STATE(on_eoln_state);
828 828 }
829 829 break;
830 830
831 831 default:
832 832 source_p++;
833 833 break;
834 834 }
835 835 }
836 836
837 837 source->string.text.p = source_p;
838 838 if (macro_seen_in_string) {
839 839 append_string(string_start,
840 840 &name_string,
841 841 source_p - string_start);
842 842 name_start = name_string.buffer.start;
843 843 name_length = name_string.text.p - name_start;
844 844 } else {
845 845 name_start = string_start;
846 846 name_length = source_p - string_start;
847 847 }
848 848
849 849 /* Strip "./" from the head of the name */
850 850 if ((name_start[0] == (int) period_char) &&
851 851 (name_start[1] == (int) slash_char)) {
852 852 name_start += 2;
853 853 name_length -= 2;
854 854 }
855 855 /* if include file name is surrounded by double quotes */
856 856 if ((name_start[0] == (int) doublequote_char) &&
857 857 (name_start[name_length - 1] == (int) doublequote_char)) {
858 858 name_start += 1;
859 859 name_length -= 2;
860 860
861 861 /* if name does not begin with a slash char */
862 862 if (name_start[0] != (int) slash_char) {
863 863 if ((name_start[0] == (int) period_char) &&
864 864 (name_start[1] == (int) slash_char)) {
865 865 name_start += 2;
866 866 name_length -= 2;
867 867 }
868 868
869 869 INIT_STRING_FROM_STACK(include_name, include_buffer);
870 870 APPEND_NAME(true_makefile_name,
871 871 &include_name,
872 872 true_makefile_name->hash.length);
873 873
874 874 wchar_t *slash = wsrchr(include_name.buffer.start, (int) slash_char);
875 875 if (slash != NULL) {
876 876 include_name.text.p = slash + 1;
877 877 append_string(name_start,
878 878 &include_name,
879 879 name_length);
880 880
881 881 name_start = include_name.buffer.start;
882 882 name_length = include_name.text.p - name_start;
883 883 }
884 884 }
885 885 }
886 886
887 887 /* Even when we run -n we want to create makefiles */
888 888 do_not_exec_rule = false;
889 889 makefile_name = GETNAME(name_start, name_length);
890 890 if (makefile_name->dollar) {
891 891 String_rec destination;
892 892 wchar_t buffer[STRING_BUFFER_LENGTH];
893 893 wchar_t *p;
894 894 wchar_t *q;
895 895
896 896 INIT_STRING_FROM_STACK(destination, buffer);
897 897 expand_value(makefile_name,
898 898 &destination,
899 899 false);
900 900 for (p = destination.buffer.start;
901 901 (*p != (int) nul_char) && iswspace(*p);
902 902 p++);
903 903 for (q = p;
904 904 (*q != (int) nul_char) && !iswspace(*q);
905 905 q++);
906 906 makefile_name = GETNAME(p, q-p);
907 907 if (destination.free_after_use) {
908 908 retmem(destination.buffer.start);
909 909 }
910 910 }
911 911 source_p++;
912 912 UNCACHE_SOURCE();
913 913 /* Read the file */
914 914 save_makefile_type = makefile_type;
915 915 if (read_simple_file(makefile_name,
916 916 true,
917 917 true,
918 918 true,
919 919 false,
920 920 true,
921 921 false) == failed) {
922 922 fatal_reader(catgets(catd, 1, 75, "Read of include file `%s' failed"),
923 923 makefile_name->string_mb);
924 924 }
925 925 makefile_type = save_makefile_type;
926 926 do_not_exec_rule = save_do_not_exec_rule;
927 927 CACHE_SOURCE(0);
928 928 goto start_new_line;
929 929 } else {
930 930 source_p -= 7;
931 931 }
932 932 } else {
933 933 /* Check if the word include was split across 8K boundary. */
934 934
935 935 tmp_bytes_left_in_string = source->string.text.end - source_p;
936 936 if (tmp_bytes_left_in_string < 8) {
937 937 tmp_maybe_include = false;
938 938 if (IS_WEQUALN(source_p,
939 939 include_space,
940 940 tmp_bytes_left_in_string)) {
941 941 tmp_maybe_include = true;
942 942 }
943 943 if (tmp_maybe_include) {
944 944 GET_NEXT_BLOCK(source);
945 945 tmp_maybe_include = false;
946 946 goto line_evald;
947 947 }
948 948 }
949 949 }
950 950 }
951 951
952 952 /* Reset the status in preparation for the new line */
953 953 for (nvp = ⌖ nvp != NULL; nvp = nvp->next) {
954 954 nvp->used = 0;
955 955 }
956 956 for (nvp = &depes; nvp != NULL; nvp = nvp->next) {
957 957 nvp->used = 0;
958 958 }
959 959 target_group_seen = false;
960 960 command = command_tail = NULL;
961 961 macro_value = NULL;
962 962 append = false;
963 963 current_names = ⌖
964 964 SET_STATE(scan_name_state);
965 965 on_eoln_state = illegal_eoln_state;
966 966 separator = none_seen;
967 967
968 968 /* The state machine starts here */
969 969 enter_state:
970 970 while (1) switch (state) {
971 971
972 972 /****************************************************************
973 973 * Scan name state
974 974 */
975 975 case scan_name_state:
976 976 /* Scan an identifier. We skip over chars until we find a break char */
977 977 /* First skip white space. */
978 978 for (; 1; source_p++) switch (GET_CHAR()) {
979 979 case nul_char:
980 980 GET_NEXT_BLOCK(source);
981 981 source_p--;
982 982 if (source == NULL) {
983 983 GOTO_STATE(on_eoln_state);
984 984 }
985 985 break;
986 986 case newline_char:
987 987 /* We found the end of the line. */
988 988 /* Do postprocessing or return error */
989 989 source_p++;
990 990 if (source->fd >= 0) {
991 991 line_number++;
992 992 }
993 993 GOTO_STATE(on_eoln_state);
994 994 case backslash_char:
995 995 /* Continuation */
996 996 if (*++source_p == (int) nul_char) {
997 997 GET_NEXT_BLOCK(source);
998 998 if (source == NULL) {
999 999 GOTO_STATE(on_eoln_state);
1000 1000 }
1001 1001 }
1002 1002 if (*source_p == (int) newline_char) {
1003 1003 if (source->fd >= 0) {
1004 1004 line_number++;
1005 1005 }
1006 1006 } else {
1007 1007 source_p--;
1008 1008 }
1009 1009 break;
1010 1010 case tab_char:
1011 1011 case space_char:
1012 1012 /* Whitespace is skipped */
1013 1013 break;
1014 1014 case numbersign_char:
1015 1015 /* Comment. Skip over it */
1016 1016 for (; 1; source_p++) {
1017 1017 switch (GET_CHAR()) {
1018 1018 case nul_char:
1019 1019 GET_NEXT_BLOCK_NOCHK(source);
1020 1020 if (source == NULL) {
1021 1021 GOTO_STATE(on_eoln_state);
1022 1022 }
1023 1023 if (source->error_converting) {
1024 1024 // Illegal byte sequence - skip its first byte
1025 1025 source->inp_buf_ptr++;
1026 1026 }
1027 1027 source_p--;
1028 1028 break;
1029 1029 case backslash_char:
1030 1030 if (*++source_p == (int) nul_char) {
1031 1031 GET_NEXT_BLOCK_NOCHK(source);
1032 1032 if (source == NULL) {
1033 1033 GOTO_STATE(on_eoln_state);
1034 1034 }
1035 1035 if (source->error_converting) {
1036 1036 // Illegal byte sequence - skip its first byte
1037 1037 source->inp_buf_ptr++;
1038 1038 source_p--;
1039 1039 break;
1040 1040 }
1041 1041 }
1042 1042 if(*source_p == (int) newline_char) {
1043 1043 if (source->fd >= 0) {
1044 1044 line_number++;
1045 1045 }
1046 1046 }
1047 1047 break;
1048 1048 case newline_char:
1049 1049 source_p++;
1050 1050 if (source->fd >= 0) {
1051 1051 line_number++;
1052 1052 }
1053 1053 GOTO_STATE(on_eoln_state);
1054 1054 }
1055 1055 }
1056 1056 case dollar_char:
1057 1057 /* Macro reference. Expand and push value */
1058 1058 if (source->already_expanded) {
1059 1059 goto scan_name;
1060 1060 }
1061 1061 source_p++;
1062 1062 UNCACHE_SOURCE();
1063 1063 {
1064 1064 Source t = (Source) alloca((int) sizeof (Source_rec));
1065 1065 source = push_macro_value(t,
1066 1066 buffer,
1067 1067 sizeof buffer,
1068 1068 source);
1069 1069 }
1070 1070 CACHE_SOURCE(1);
1071 1071 break;
1072 1072 default:
1073 1073 /* End of white space */
1074 1074 goto scan_name;
1075 1075 }
1076 1076
1077 1077 /* First proper identifier character */
1078 1078 scan_name:
1079 1079
1080 1080 string_start = source_p;
1081 1081 paren_count = brace_count = 0;
1082 1082 macro_seen_in_string = false;
1083 1083 resume_name_scan:
1084 1084 for (; 1; source_p++) {
1085 1085 switch (GET_CHAR()) {
1086 1086 case nul_char:
1087 1087 /* Save what we have seen so far of the identifier */
1088 1088 if (source_p != string_start) {
1089 1089 if (!macro_seen_in_string) {
1090 1090 INIT_STRING_FROM_STACK(name_string,
1091 1091 name_buffer);
1092 1092 }
1093 1093 append_string(string_start,
1094 1094 &name_string,
1095 1095 source_p - string_start);
1096 1096 macro_seen_in_string = true;
1097 1097 }
1098 1098 /* Get more text to read */
1099 1099 GET_NEXT_BLOCK(source);
1100 1100 string_start = source_p;
1101 1101 source_p--;
1102 1102 if (source == NULL) {
1103 1103 GOTO_STATE(on_eoln_state);
1104 1104 }
1105 1105 break;
1106 1106 case newline_char:
1107 1107 if (paren_count > 0) {
1108 1108 fatal_reader(catgets(catd, 1, 76, "Unmatched `(' on line"));
1109 1109 }
1110 1110 if (brace_count > 0) {
1111 1111 fatal_reader(catgets(catd, 1, 77, "Unmatched `{' on line"));
1112 1112 }
1113 1113 source_p++;
1114 1114 /* Enter name */
1115 1115 current_names = enter_name(&name_string,
1116 1116 macro_seen_in_string,
1117 1117 string_start,
1118 1118 source_p - 1,
1119 1119 current_names,
1120 1120 &extra_names,
1121 1121 &target_group_seen);
1122 1122 first_target = false;
1123 1123 if (extra_names == NULL) {
1124 1124 extra_names = (Name_vector)
1125 1125 alloca((int) sizeof (Name_vector_rec));
1126 1126 }
1127 1127 /* Do postprocessing or return error */
1128 1128 if (source->fd >= 0) {
1129 1129 line_number++;
1130 1130 }
1131 1131 GOTO_STATE(on_eoln_state);
1132 1132 case backslash_char:
1133 1133 /* Check if this is a quoting backslash */
1134 1134 if (!macro_seen_in_string) {
1135 1135 INIT_STRING_FROM_STACK(name_string,
1136 1136 name_buffer);
1137 1137 macro_seen_in_string = true;
1138 1138 }
1139 1139 append_string(string_start,
1140 1140 &name_string,
1141 1141 source_p - string_start);
1142 1142 if (*++source_p == (int) nul_char) {
1143 1143 GET_NEXT_BLOCK(source);
1144 1144 if (source == NULL) {
1145 1145 GOTO_STATE(on_eoln_state);
1146 1146 }
1147 1147 }
1148 1148 if (*source_p == (int) newline_char) {
1149 1149 if (source->fd >= 0) {
1150 1150 line_number++;
1151 1151 }
1152 1152 *source_p = (int) space_char;
1153 1153 string_start = source_p;
1154 1154 goto resume_name_scan;
1155 1155 } else {
1156 1156 string_start = source_p;
1157 1157 break;
1158 1158 }
1159 1159 break;
1160 1160 case numbersign_char:
1161 1161 if (paren_count + brace_count > 0) {
1162 1162 break;
1163 1163 }
1164 1164 fatal_reader(catgets(catd, 1, 78, "Unexpected comment seen"));
1165 1165 case dollar_char:
1166 1166 if (source->already_expanded) {
1167 1167 break;
1168 1168 }
1169 1169 /* Save the identifier so far */
1170 1170 if (source_p != string_start) {
1171 1171 if (!macro_seen_in_string) {
1172 1172 INIT_STRING_FROM_STACK(name_string,
1173 1173 name_buffer);
1174 1174 }
1175 1175 append_string(string_start,
1176 1176 &name_string,
1177 1177 source_p - string_start);
1178 1178 macro_seen_in_string = true;
1179 1179 }
1180 1180 /* Eval and push the macro */
1181 1181 source_p++;
1182 1182 UNCACHE_SOURCE();
1183 1183 {
1184 1184 Source t =
1185 1185 (Source) alloca((int) sizeof (Source_rec));
1186 1186 source = push_macro_value(t,
1187 1187 buffer,
1188 1188 sizeof buffer,
1189 1189 source);
1190 1190 }
1191 1191 CACHE_SOURCE(1);
1192 1192 string_start = source_p + 1;
1193 1193 break;
1194 1194 case parenleft_char:
1195 1195 paren_count++;
1196 1196 break;
1197 1197 case parenright_char:
1198 1198 if (--paren_count < 0) {
1199 1199 fatal_reader(catgets(catd, 1, 79, "Unmatched `)' on line"));
1200 1200 }
1201 1201 break;
1202 1202 case braceleft_char:
1203 1203 brace_count++;
1204 1204 break;
1205 1205 case braceright_char:
1206 1206 if (--brace_count < 0) {
1207 1207 fatal_reader(catgets(catd, 1, 80, "Unmatched `}' on line"));
1208 1208 }
1209 1209 break;
1210 1210 case ampersand_char:
1211 1211 case greater_char:
1212 1212 case bar_char:
1213 1213 if (paren_count + brace_count == 0) {
1214 1214 source_p++;
1215 1215 }
1216 1216 /* Fall into */
1217 1217 case tab_char:
1218 1218 case space_char:
1219 1219 if (paren_count + brace_count > 0) {
1220 1220 break;
1221 1221 }
1222 1222 current_names = enter_name(&name_string,
1223 1223 macro_seen_in_string,
1224 1224 string_start,
1225 1225 source_p,
1226 1226 current_names,
1227 1227 &extra_names,
1228 1228 &target_group_seen);
1229 1229 first_target = false;
1230 1230 if (extra_names == NULL) {
1231 1231 extra_names = (Name_vector)
1232 1232 alloca((int) sizeof (Name_vector_rec));
1233 1233 }
1234 1234 goto enter_state;
1235 1235 case colon_char:
1236 1236 if (paren_count + brace_count > 0) {
1237 1237 break;
1238 1238 }
1239 1239 if (separator == conditional_seen) {
1240 1240 break;
1241 1241 }
1242 1242 /** POSIX **/
1243 1243 #if 0
1244 1244 if(posix) {
1245 1245 emptycount = 0;
1246 1246 }
1247 1247 #endif
1248 1248 /** END POSIX **/
1249 1249 /* End of the target list. We now start reading */
1250 1250 /* dependencies or a conditional assignment */
1251 1251 if (separator != none_seen) {
1252 1252 fatal_reader(catgets(catd, 1, 81, "Extra `:', `::', or `:=' on dependency line"));
1253 1253 }
1254 1254 /* Enter the last target */
1255 1255 if ((string_start != source_p) ||
1256 1256 macro_seen_in_string) {
1257 1257 current_names =
1258 1258 enter_name(&name_string,
1259 1259 macro_seen_in_string,
1260 1260 string_start,
1261 1261 source_p,
1262 1262 current_names,
1263 1263 &extra_names,
1264 1264 &target_group_seen);
1265 1265 first_target = false;
1266 1266 if (extra_names == NULL) {
1267 1267 extra_names = (Name_vector)
1268 1268 alloca((int)
1269 1269 sizeof (Name_vector_rec));
1270 1270 }
1271 1271 }
1272 1272 /* Check if it is ":" "::" or ":=" */
1273 1273 scan_colon_label:
1274 1274 switch (*++source_p) {
1275 1275 case nul_char:
1276 1276 GET_NEXT_BLOCK(source);
1277 1277 source_p--;
1278 1278 if (source == NULL) {
1279 1279 GOTO_STATE(enter_dependencies_state);
1280 1280 }
1281 1281 goto scan_colon_label;
1282 1282 case equal_char:
1283 1283 if(svr4) {
1284 1284 fatal_reader(catgets(catd, 1, 82, "syntax error"));
1285 1285 }
1286 1286 separator = conditional_seen;
1287 1287 source_p++;
1288 1288 current_names = &depes;
1289 1289 GOTO_STATE(scan_name_state);
1290 1290 case colon_char:
1291 1291 separator = two_colon;
1292 1292 source_p++;
1293 1293 break;
1294 1294 default:
1295 1295 separator = one_colon;
1296 1296 }
1297 1297 current_names = &depes;
1298 1298 on_eoln_state = enter_dependencies_state;
1299 1299 GOTO_STATE(scan_name_state);
1300 1300 case semicolon_char:
1301 1301 if (paren_count + brace_count > 0) {
1302 1302 break;
1303 1303 }
1304 1304 /* End of reading names. Start reading the rule */
1305 1305 if ((separator != one_colon) &&
1306 1306 (separator != two_colon)) {
1307 1307 fatal_reader(catgets(catd, 1, 83, "Unexpected command seen"));
1308 1308 }
1309 1309 /* Enter the last dependency */
1310 1310 if ((string_start != source_p) ||
1311 1311 macro_seen_in_string) {
1312 1312 current_names =
1313 1313 enter_name(&name_string,
1314 1314 macro_seen_in_string,
1315 1315 string_start,
1316 1316 source_p,
1317 1317 current_names,
1318 1318 &extra_names,
1319 1319 &target_group_seen);
1320 1320 first_target = false;
1321 1321 if (extra_names == NULL) {
1322 1322 extra_names = (Name_vector)
1323 1323 alloca((int)
1324 1324 sizeof (Name_vector_rec));
1325 1325 }
1326 1326 }
1327 1327 source_p++;
1328 1328 /* Make sure to enter a rule even if the is */
1329 1329 /* no text here */
1330 1330 command = command_tail = ALLOC(Cmd_line);
1331 1331 command->next = NULL;
1332 1332 command->command_line = empty_name;
1333 1333 command->make_refd = false;
1334 1334 command->ignore_command_dependency = false;
1335 1335 command->assign = false;
1336 1336 command->ignore_error = false;
1337 1337 command->silent = false;
1338 1338
1339 1339 GOTO_STATE(scan_command_state);
1340 1340 case plus_char:
1341 1341 /*
1342 1342 ** following code drops the target separator plus char if it starts
1343 1343 ** a line.
1344 1344 */
1345 1345 if(first_target && !macro_seen_in_string &&
1346 1346 source_p == string_start) {
1347 1347 for (; 1; source_p++)
1348 1348 switch (GET_CHAR()) {
1349 1349 case nul_char:
1350 1350 if (source_p != string_start) {
1351 1351 if (!macro_seen_in_string) {
1352 1352 INIT_STRING_FROM_STACK(name_string,
1353 1353 name_buffer);
1354 1354 }
1355 1355 append_string(string_start,
1356 1356 &name_string,
1357 1357 source_p - string_start);
1358 1358 macro_seen_in_string = true;
1359 1359 }
1360 1360 GET_NEXT_BLOCK(source);
1361 1361 string_start = source_p;
1362 1362 source_p--;
1363 1363 if (source == NULL) {
1364 1364 GOTO_STATE(on_eoln_state);
1365 1365 }
1366 1366 break;
1367 1367 case plus_char:
1368 1368 source_p++;
1369 1369 while (*source_p == (int) nul_char) {
1370 1370 if (source_p != string_start) {
1371 1371 if (!macro_seen_in_string) {
1372 1372 INIT_STRING_FROM_STACK(name_string,
1373 1373 name_buffer);
1374 1374 }
1375 1375 append_string(string_start,
1376 1376 &name_string,
1377 1377 source_p - string_start);
1378 1378 macro_seen_in_string = true;
1379 1379 }
1380 1380 GET_NEXT_BLOCK(source);
1381 1381 string_start = source_p;
1382 1382 if (source == NULL) {
1383 1383 GOTO_STATE(on_eoln_state);
1384 1384 }
1385 1385 }
1386 1386 if (*source_p == (int) tab_char ||
1387 1387 *source_p == (int) space_char) {
1388 1388 macro_seen_in_string = false;
1389 1389 string_start = source_p + 1;
1390 1390 } else {
1391 1391 goto resume_name_scan;
1392 1392 }
1393 1393 break;
1394 1394 case tab_char:
1395 1395 case space_char:
1396 1396 string_start = source_p + 1;
1397 1397 break;
1398 1398 default:
1399 1399 goto resume_name_scan;
1400 1400 }
1401 1401 }
1402 1402 if (paren_count + brace_count > 0) {
1403 1403 break;
1404 1404 }
1405 1405 /* We found "+=" construct */
1406 1406 if (source_p != string_start) {
1407 1407 /* "+" is not a break char. */
1408 1408 /* Ignore it if it is part of an identifier */
1409 1409 source_p++;
1410 1410 goto resume_name_scan;
1411 1411 }
1412 1412 /* Make sure the "+" is followed by a "=" */
1413 1413 scan_append:
1414 1414 switch (*++source_p) {
1415 1415 case nul_char:
1416 1416 if (!macro_seen_in_string) {
1417 1417 INIT_STRING_FROM_STACK(name_string,
1418 1418 name_buffer);
1419 1419 }
1420 1420 append_string(string_start,
1421 1421 &name_string,
1422 1422 source_p - string_start);
1423 1423 GET_NEXT_BLOCK(source);
1424 1424 source_p--;
1425 1425 string_start = source_p;
1426 1426 if (source == NULL) {
1427 1427 GOTO_STATE(illegal_eoln_state);
1428 1428 }
1429 1429 goto scan_append;
1430 1430 case equal_char:
1431 1431 if(!svr4) {
1432 1432 append = true;
1433 1433 } else {
1434 1434 fatal_reader(catgets(catd, 1, 84, "Must be a separator on rules"));
1435 1435 }
1436 1436 break;
1437 1437 default:
1438 1438 /* The "+" just starts a regular name. */
1439 1439 /* Start reading that name */
1440 1440 goto resume_name_scan;
1441 1441 }
1442 1442 /* Fall into */
1443 1443 case equal_char:
1444 1444 if (paren_count + brace_count > 0) {
1445 1445 break;
1446 1446 }
1447 1447 /* We found macro assignment. */
1448 1448 /* Check if it is legal and if it is appending */
1449 1449 switch (separator) {
1450 1450 case none_seen:
1451 1451 separator = equal_seen;
1452 1452 on_eoln_state = enter_equal_state;
1453 1453 break;
1454 1454 case conditional_seen:
1455 1455 on_eoln_state = enter_conditional_state;
1456 1456 break;
1457 1457 default:
1458 1458 /* Reader must special check for "MACRO:sh=" */
1459 1459 /* notation */
1460 1460 if (sh_name == NULL) {
1461 1461 MBSTOWCS(wcs_buffer, NOCATGETS("sh"));
1462 1462 sh_name = GETNAME(wcs_buffer, FIND_LENGTH);
1463 1463 MBSTOWCS(wcs_buffer, NOCATGETS("shell"));
1464 1464 shell_name = GETNAME(wcs_buffer, FIND_LENGTH);
1465 1465 }
1466 1466
1467 1467 if (!macro_seen_in_string) {
1468 1468 INIT_STRING_FROM_STACK(name_string,
1469 1469 name_buffer);
1470 1470 }
1471 1471 append_string(string_start,
1472 1472 &name_string,
1473 1473 source_p - string_start
1474 1474 );
1475 1475
1476 1476 if ( (((target.used == 1) &&
1477 1477 (depes.used == 1) &&
1478 1478 (depes.names[0] == sh_name)) ||
1479 1479 ((target.used == 1) &&
1480 1480 (depes.used == 0) &&
1481 1481 (separator == one_colon) &&
1482 1482 (GETNAME(name_string.buffer.start,FIND_LENGTH) == sh_name))) &&
1483 1483 (!svr4)) {
1484 1484 String_rec macro_name;
1485 1485 wchar_t buffer[100];
1486 1486
1487 1487 INIT_STRING_FROM_STACK(macro_name,
1488 1488 buffer);
1489 1489 APPEND_NAME(target.names[0],
1490 1490 ¯o_name,
1491 1491 FIND_LENGTH);
1492 1492 append_char((int) colon_char,
1493 1493 ¯o_name);
1494 1494 APPEND_NAME(sh_name,
1495 1495 ¯o_name,
1496 1496 FIND_LENGTH);
1497 1497 target.names[0] =
1498 1498 GETNAME(macro_name.buffer.start,
1499 1499 FIND_LENGTH);
1500 1500 separator = equal_seen;
1501 1501 on_eoln_state = enter_equal_state;
1502 1502 break;
1503 1503 } else if ( (((target.used == 1) &&
1504 1504 (depes.used == 1) &&
1505 1505 (depes.names[0] == shell_name)) ||
1506 1506 ((target.used == 1) &&
1507 1507 (depes.used == 0) &&
1508 1508 (separator == one_colon) &&
1509 1509 (GETNAME(name_string.buffer.start,FIND_LENGTH) == shell_name))) &&
1510 1510 (!svr4)) {
1511 1511 String_rec macro_name;
1512 1512 wchar_t buffer[100];
1513 1513
1514 1514 INIT_STRING_FROM_STACK(macro_name,
1515 1515 buffer);
1516 1516 APPEND_NAME(target.names[0],
1517 1517 ¯o_name,
1518 1518 FIND_LENGTH);
1519 1519 append_char((int) colon_char,
1520 1520 ¯o_name);
1521 1521 APPEND_NAME(shell_name,
1522 1522 ¯o_name,
1523 1523 FIND_LENGTH);
1524 1524 target.names[0] =
1525 1525 GETNAME(macro_name.buffer.start,
1526 1526 FIND_LENGTH);
1527 1527 separator = equal_seen;
1528 1528 on_eoln_state = enter_equal_state;
1529 1529 break;
1530 1530 }
1531 1531 if(svr4) {
1532 1532 fatal_reader(catgets(catd, 1, 85, "syntax error"));
1533 1533 }
1534 1534 else {
1535 1535 fatal_reader(catgets(catd, 1, 86, "Macro assignment on dependency line"));
1536 1536 }
1537 1537 }
1538 1538 if (append) {
1539 1539 source_p--;
1540 1540 }
1541 1541 /* Enter the macro name */
1542 1542 if ((string_start != source_p) ||
1543 1543 macro_seen_in_string) {
1544 1544 current_names =
1545 1545 enter_name(&name_string,
1546 1546 macro_seen_in_string,
1547 1547 string_start,
1548 1548 source_p,
1549 1549 current_names,
1550 1550 &extra_names,
1551 1551 &target_group_seen);
1552 1552 first_target = false;
1553 1553 if (extra_names == NULL) {
1554 1554 extra_names = (Name_vector)
1555 1555 alloca((int)
1556 1556 sizeof (Name_vector_rec));
1557 1557 }
1558 1558 }
1559 1559 if (append) {
1560 1560 source_p++;
1561 1561 }
1562 1562 macro_value = NULL;
1563 1563 source_p++;
1564 1564 distance = 0;
1565 1565 /* Skip whitespace to the start of the value */
1566 1566 macro_seen_in_string = false;
1567 1567 for (; 1; source_p++) {
1568 1568 switch (GET_CHAR()) {
1569 1569 case nul_char:
1570 1570 GET_NEXT_BLOCK(source);
1571 1571 source_p--;
1572 1572 if (source == NULL) {
1573 1573 GOTO_STATE(on_eoln_state);
1574 1574 }
1575 1575 break;
1576 1576 case backslash_char:
1577 1577 if (*++source_p == (int) nul_char) {
1578 1578 GET_NEXT_BLOCK(source);
1579 1579 if (source == NULL) {
1580 1580 GOTO_STATE(on_eoln_state);
1581 1581 }
1582 1582 }
1583 1583 if (*source_p != (int) newline_char) {
1584 1584 if (!macro_seen_in_string) {
1585 1585 macro_seen_in_string =
1586 1586 true;
1587 1587 INIT_STRING_FROM_STACK(name_string,
1588 1588 name_buffer);
1589 1589 }
1590 1590 append_char((int)
1591 1591 backslash_char,
1592 1592 &name_string);
1593 1593 append_char(*source_p,
1594 1594 &name_string);
1595 1595 string_start = source_p+1;
1596 1596 goto macro_value_start;
1597 1597 } else {
1598 1598 if (source->fd >= 0) {
1599 1599 line_number++;
1600 1600 }
1601 1601 }
1602 1602 break;
1603 1603 case newline_char:
1604 1604 case numbersign_char:
1605 1605 string_start = source_p;
1606 1606 goto macro_value_end;
1607 1607 case tab_char:
1608 1608 case space_char:
1609 1609 break;
1610 1610 default:
1611 1611 string_start = source_p;
1612 1612 goto macro_value_start;
1613 1613 }
1614 1614 }
1615 1615 macro_value_start:
1616 1616 /* Find the end of the value */
1617 1617 for (; 1; source_p++) {
1618 1618 if (distance != 0) {
1619 1619 *source_p = *(source_p + distance);
1620 1620 }
1621 1621 switch (GET_CHAR()) {
1622 1622 case nul_char:
1623 1623 if (!macro_seen_in_string) {
1624 1624 macro_seen_in_string = true;
1625 1625 INIT_STRING_FROM_STACK(name_string,
1626 1626 name_buffer);
1627 1627 }
1628 1628 append_string(string_start,
1629 1629 &name_string,
1630 1630 source_p - string_start);
1631 1631 GET_NEXT_BLOCK(source);
1632 1632 string_start = source_p;
1633 1633 source_p--;
1634 1634 if (source == NULL) {
1635 1635 GOTO_STATE(on_eoln_state);
1636 1636 }
1637 1637 break;
1638 1638 case backslash_char:
1639 1639 source_p++;
1640 1640 if (distance != 0) {
1641 1641 *source_p =
1642 1642 *(source_p + distance);
1643 1643 }
1644 1644 if (*source_p == (int) nul_char) {
1645 1645 if (!macro_seen_in_string) {
1646 1646 macro_seen_in_string =
1647 1647 true;
1648 1648 INIT_STRING_FROM_STACK(name_string,
1649 1649 name_buffer);
1650 1650 }
1651 1651
1652 1652 /* BID_1225561 */
1653 1653 *(source_p - 1) = (int) space_char;
1654 1654 append_string(string_start,
1655 1655 &name_string,
1656 1656 source_p -
1657 1657 string_start - 1);
1658 1658 GET_NEXT_BLOCK(source);
1659 1659 string_start = source_p;
1660 1660 if (source == NULL) {
1661 1661 GOTO_STATE(on_eoln_state);
1662 1662 }
1663 1663 if (distance != 0) {
1664 1664 *source_p =
1665 1665 *(source_p +
1666 1666 distance);
1667 1667 }
1668 1668 if (*source_p == (int) newline_char) {
1669 1669 append_char((int) space_char, &name_string);
1670 1670 } else {
1671 1671 append_char((int) backslash_char, &name_string);
1672 1672 }
1673 1673 /****************/
1674 1674 }
1675 1675 if (*source_p == (int) newline_char) {
1676 1676 source_p--;
1677 1677 line_number++;
1678 1678 distance++;
1679 1679 *source_p = (int) space_char;
1680 1680 while ((*(source_p +
1681 1681 distance + 1) ==
1682 1682 (int) tab_char) ||
1683 1683 (*(source_p +
1684 1684 distance + 1) ==
1685 1685 (int) space_char)) {
1686 1686 distance++;
1687 1687 }
1688 1688 }
1689 1689 break;
1690 1690 case newline_char:
1691 1691 case numbersign_char:
1692 1692 goto macro_value_end;
1693 1693 }
1694 1694 }
1695 1695 macro_value_end:
1696 1696 /* Complete the value in the string */
1697 1697 if (!macro_seen_in_string) {
1698 1698 macro_seen_in_string = true;
1699 1699 INIT_STRING_FROM_STACK(name_string,
1700 1700 name_buffer);
1701 1701 }
1702 1702 append_string(string_start,
1703 1703 &name_string,
1704 1704 source_p - string_start);
1705 1705 if (name_string.buffer.start != name_string.text.p) {
1706 1706 macro_value =
1707 1707 GETNAME(name_string.buffer.start,
1708 1708 FIND_LENGTH);
1709 1709 }
1710 1710 if (name_string.free_after_use) {
1711 1711 retmem(name_string.buffer.start);
1712 1712 }
1713 1713 for (; distance > 0; distance--) {
1714 1714 *source_p++ = (int) space_char;
1715 1715 }
1716 1716 GOTO_STATE(on_eoln_state);
1717 1717 }
1718 1718 }
1719 1719
1720 1720 /****************************************************************
1721 1721 * enter dependencies state
1722 1722 */
1723 1723 case enter_dependencies_state:
1724 1724 enter_dependencies_label:
1725 1725 /* Expects pointer on first non whitespace char after last dependency. (On */
1726 1726 /* next line.) We end up here after having read a "targets : dependencies" */
1727 1727 /* line. The state checks if there is a rule to read and if so dispatches */
1728 1728 /* to scan_command_state scan_command_state reads one rule line and the */
1729 1729 /* returns here */
1730 1730
1731 1731 /* First check if the first char on the next line is special */
1732 1732 switch (GET_CHAR()) {
1733 1733 case nul_char:
1734 1734 GET_NEXT_BLOCK(source);
1735 1735 if (source == NULL) {
1736 1736 break;
1737 1737 }
1738 1738 goto enter_dependencies_label;
1739 1739 case exclam_char:
1740 1740 /* The line should be evaluate before it is read */
1741 1741 macro_seen_in_string = false;
1742 1742 string_start = source_p + 1;
1743 1743 for (; 1; source_p++) {
1744 1744 switch (GET_CHAR()) {
1745 1745 case newline_char:
1746 1746 goto eoln_2;
1747 1747 case nul_char:
1748 1748 if (source->fd > 0) {
1749 1749 if (!macro_seen_in_string) {
1750 1750 macro_seen_in_string = true;
1751 1751 INIT_STRING_FROM_STACK(name_string,
1752 1752 name_buffer);
1753 1753 }
1754 1754 append_string(string_start,
1755 1755 &name_string,
1756 1756 source_p - string_start);
1757 1757 GET_NEXT_BLOCK(source);
1758 1758 string_start = source_p;
1759 1759 source_p--;
1760 1760 break;
1761 1761 }
1762 1762 eoln_2:
1763 1763 if (!macro_seen_in_string) {
1764 1764 INIT_STRING_FROM_STACK(name_string,
1765 1765 name_buffer);
1766 1766 }
1767 1767 append_string(string_start,
1768 1768 &name_string,
1769 1769 source_p - string_start);
1770 1770 extrap = (Source)
1771 1771 alloca((int) sizeof (Source_rec));
1772 1772 extrap->string.buffer.start = NULL;
1773 1773 extrap->inp_buf =
1774 1774 extrap->inp_buf_ptr =
1775 1775 extrap->inp_buf_end = NULL;
1776 1776 extrap->error_converting = false;
1777 1777 expand_value(GETNAME(name_string.buffer.start,
1778 1778 FIND_LENGTH),
1779 1779 &extrap->string,
1780 1780 false);
1781 1781 if (name_string.free_after_use) {
1782 1782 retmem(name_string.buffer.start);
1783 1783 }
1784 1784 UNCACHE_SOURCE();
1785 1785 extrap->string.text.p =
1786 1786 extrap->string.buffer.start;
1787 1787 extrap->fd = -1;
1788 1788 extrap->previous = source;
1789 1789 source = extrap;
1790 1790 CACHE_SOURCE(0);
1791 1791 goto enter_dependencies_label;
1792 1792 }
1793 1793 }
1794 1794 case dollar_char:
1795 1795 if (source->already_expanded) {
1796 1796 break;
1797 1797 }
1798 1798 source_p++;
1799 1799 UNCACHE_SOURCE();
1800 1800 {
1801 1801 Source t = (Source) alloca((int) sizeof (Source_rec));
1802 1802 source = push_macro_value(t,
1803 1803 buffer,
1804 1804 sizeof buffer,
1805 1805 source);
1806 1806 }
1807 1807 CACHE_SOURCE(0);
1808 1808 goto enter_dependencies_label;
1809 1809 case numbersign_char:
1810 1810 if (makefile_type != reading_makefile) {
1811 1811 source_p++;
1812 1812 GOTO_STATE(scan_command_state);
1813 1813 }
1814 1814 for (; 1; source_p++) {
1815 1815 switch (GET_CHAR()) {
1816 1816 case nul_char:
1817 1817 GET_NEXT_BLOCK_NOCHK(source);
1818 1818 if (source == NULL) {
1819 1819 GOTO_STATE(on_eoln_state);
1820 1820 }
1821 1821 if (source->error_converting) {
1822 1822 // Illegal byte sequence - skip its first byte
1823 1823 source->inp_buf_ptr++;
1824 1824 }
1825 1825 source_p--;
1826 1826 break;
1827 1827 case backslash_char:
1828 1828 if (*++source_p == (int) nul_char) {
1829 1829 GET_NEXT_BLOCK_NOCHK(source);
1830 1830 if (source == NULL) {
1831 1831 GOTO_STATE(on_eoln_state);
1832 1832 }
1833 1833 if (source->error_converting) {
1834 1834 // Illegal byte sequence - skip its first byte
1835 1835 source->inp_buf_ptr++;
1836 1836 source_p--;
1837 1837 break;
1838 1838 }
1839 1839 }
1840 1840 if(*source_p == (int) newline_char) {
1841 1841 if (source->fd >= 0) {
1842 1842 line_number++;
1843 1843 }
1844 1844 }
1845 1845 break;
1846 1846 case newline_char:
1847 1847 source_p++;
1848 1848 if (source->fd >= 0) {
1849 1849 line_number++;
1850 1850 }
1851 1851 goto enter_dependencies_label;
1852 1852 }
1853 1853 }
1854 1854
1855 1855 case tab_char:
1856 1856 GOTO_STATE(scan_command_state);
1857 1857 }
1858 1858
1859 1859 /* We read all the command lines for the target/dependency line. */
1860 1860 /* Enter the stuff */
1861 1861 enter_target_groups_and_dependencies( &target, &depes, command,
1862 1862 separator, target_group_seen);
1863 1863
1864 1864 goto start_new_line;
1865 1865
1866 1866 /****************************************************************
1867 1867 * scan command state
1868 1868 */
1869 1869 case scan_command_state:
1870 1870 /* We need to read one rule line. Do that and return to */
1871 1871 /* the enter dependencies state */
1872 1872 string_start = source_p;
1873 1873 macro_seen_in_string = false;
1874 1874 for (; 1; source_p++) {
1875 1875 switch (GET_CHAR()) {
1876 1876 case backslash_char:
1877 1877 if (!macro_seen_in_string) {
1878 1878 INIT_STRING_FROM_STACK(name_string,
1879 1879 name_buffer);
1880 1880 }
1881 1881 append_string(string_start,
1882 1882 &name_string,
1883 1883 source_p - string_start);
1884 1884 macro_seen_in_string = true;
1885 1885 if (*++source_p == (int) nul_char) {
1886 1886 GET_NEXT_BLOCK(source);
1887 1887 if (source == NULL) {
1888 1888 string_start = source_p;
1889 1889 goto command_newline;
1890 1890 }
1891 1891 }
1892 1892 append_char((int) backslash_char, &name_string);
1893 1893 append_char(*source_p, &name_string);
1894 1894 if (*source_p == (int) newline_char) {
1895 1895 if (source->fd >= 0) {
1896 1896 line_number++;
1897 1897 }
1898 1898 if (*++source_p == (int) nul_char) {
1899 1899 GET_NEXT_BLOCK(source);
1900 1900 if (source == NULL) {
1901 1901 string_start = source_p;
1902 1902 goto command_newline;
1903 1903 }
1904 1904 }
1905 1905 if (*source_p == (int) tab_char) {
1906 1906 source_p++;
1907 1907 }
1908 1908 } else {
1909 1909 if (*++source_p == (int) nul_char) {
1910 1910 GET_NEXT_BLOCK(source);
1911 1911 if (source == NULL) {
1912 1912 string_start = source_p;
1913 1913 goto command_newline;
1914 1914 }
1915 1915 }
1916 1916 }
1917 1917 string_start = source_p;
1918 1918 if ((*source_p == (int) newline_char) ||
1919 1919 (*source_p == (int) backslash_char) ||
1920 1920 (*source_p == (int) nul_char)) {
1921 1921 source_p--;
1922 1922 }
1923 1923 break;
1924 1924 case newline_char:
1925 1925 command_newline:
1926 1926 if ((string_start != source_p) ||
1927 1927 macro_seen_in_string) {
1928 1928 if (macro_seen_in_string) {
1929 1929 append_string(string_start,
1930 1930 &name_string,
1931 1931 source_p - string_start);
1932 1932 string_start =
1933 1933 name_string.buffer.start;
1934 1934 string_end = name_string.text.p;
1935 1935 } else {
1936 1936 string_end = source_p;
1937 1937 }
1938 1938 while ((*string_start != (int) newline_char) &&
1939 1939 iswspace(*string_start)){
1940 1940 string_start++;
1941 1941 }
1942 1942 if ((string_end > string_start) ||
1943 1943 (makefile_type == reading_statefile)) {
1944 1944 if (command_tail == NULL) {
1945 1945 command =
1946 1946 command_tail =
1947 1947 ALLOC(Cmd_line);
1948 1948 } else {
1949 1949 command_tail->next =
1950 1950 ALLOC(Cmd_line);
1951 1951 command_tail =
1952 1952 command_tail->next;
1953 1953 }
1954 1954 command_tail->next = NULL;
1955 1955 command_tail->make_refd = false;
1956 1956 command_tail->ignore_command_dependency = false;
1957 1957 command_tail->assign = false;
1958 1958 command_tail->ignore_error = false;
1959 1959 command_tail->silent = false;
1960 1960 command_tail->command_line =
1961 1961 GETNAME(string_start,
1962 1962 string_end - string_start);
1963 1963 if (macro_seen_in_string &&
1964 1964 name_string.free_after_use) {
1965 1965 retmem(name_string.
1966 1966 buffer.start);
1967 1967 }
1968 1968 }
1969 1969 }
1970 1970 do {
1971 1971 if ((source != NULL) && (source->fd >= 0)) {
1972 1972 line_number++;
1973 1973 }
1974 1974 if ((source != NULL) &&
1975 1975 (*++source_p == (int) nul_char)) {
1976 1976 GET_NEXT_BLOCK(source);
1977 1977 if (source == NULL) {
1978 1978 GOTO_STATE(on_eoln_state);
1979 1979 }
1980 1980 }
1981 1981 } while (*source_p == (int) newline_char);
1982 1982
1983 1983 GOTO_STATE(enter_dependencies_state);
1984 1984 case nul_char:
1985 1985 if (!macro_seen_in_string) {
1986 1986 INIT_STRING_FROM_STACK(name_string,
1987 1987 name_buffer);
1988 1988 }
1989 1989 append_string(string_start,
1990 1990 &name_string,
1991 1991 source_p - string_start);
1992 1992 macro_seen_in_string = true;
1993 1993 GET_NEXT_BLOCK(source);
1994 1994 string_start = source_p;
1995 1995 source_p--;
1996 1996 if (source == NULL) {
1997 1997 GOTO_STATE(enter_dependencies_state);
1998 1998 }
1999 1999 break;
2000 2000 }
2001 2001 }
2002 2002
2003 2003 /****************************************************************
2004 2004 * enter equal state
2005 2005 */
2006 2006 case enter_equal_state:
2007 2007 if (target.used != 1) {
2008 2008 GOTO_STATE(poorly_formed_macro_state);
2009 2009 }
2010 2010 enter_equal(target.names[0], macro_value, append);
2011 2011 goto start_new_line;
2012 2012
2013 2013 /****************************************************************
2014 2014 * enter conditional state
2015 2015 */
2016 2016 case enter_conditional_state:
2017 2017 if (depes.used != 1) {
2018 2018 GOTO_STATE(poorly_formed_macro_state);
2019 2019 }
2020 2020 for (nvp = ⌖ nvp != NULL; nvp = nvp->next) {
2021 2021 for (i = 0; i < nvp->used; i++) {
2022 2022 enter_conditional(nvp->names[i],
2023 2023 depes.names[0],
2024 2024 macro_value,
2025 2025 append);
2026 2026 }
2027 2027 }
2028 2028 goto start_new_line;
2029 2029
2030 2030 /****************************************************************
2031 2031 * Error states
2032 2032 */
2033 2033 case illegal_bytes_state:
2034 2034 fatal_reader(catgets(catd, 1, 340, "Invalid byte sequence"));
2035 2035 case illegal_eoln_state:
2036 2036 if (line_number > 1) {
2037 2037 if (line_started_with_space == (line_number - 1)) {
2038 2038 line_number--;
2039 2039 fatal_reader(catgets(catd, 1, 90, "Unexpected end of line seen\n\t*** missing separator (did you mean TAB instead of 8 spaces?)"));
2040 2040 }
2041 2041 }
2042 2042 fatal_reader(catgets(catd, 1, 87, "Unexpected end of line seen"));
2043 2043 case poorly_formed_macro_state:
2044 2044 fatal_reader(catgets(catd, 1, 88, "Badly formed macro assignment"));
2045 2045 case exit_state:
2046 2046 return;
2047 2047 default:
2048 2048 fatal_reader(catgets(catd, 1, 89, "Internal error. Unknown reader state"));
2049 2049 }
2050 2050 }
2051 2051
2052 2052 /*
2053 2053 * push_macro_value(bp, buffer, size, source)
2054 2054 *
2055 2055 * Macro and function that evaluates one macro
2056 2056 * and makes the reader read from the value of it
2057 2057 *
2058 2058 * Return value:
2059 2059 * The source block to read the macro from
2060 2060 *
2061 2061 * Parameters:
2062 2062 * bp The new source block to fill in
2063 2063 * buffer Buffer to read from
2064 2064 * size size of the buffer
2065 2065 * source The old source block
2066 2066 *
2067 2067 * Global variables used:
2068 2068 */
2069 2069 static Source
2070 2070 push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source)
2071 2071 {
2072 2072 bp->string.buffer.start = bp->string.text.p = buffer;
2073 2073 bp->string.text.end = NULL;
2074 2074 bp->string.buffer.end = buffer + (size/SIZEOFWCHAR_T);
2075 2075 bp->string.free_after_use = false;
2076 2076 bp->inp_buf =
2077 2077 bp->inp_buf_ptr =
2078 2078 bp->inp_buf_end = NULL;
2079 2079 bp->error_converting = false;
2080 2080 expand_macro(source, &bp->string, (wchar_t *) NULL, false);
2081 2081 bp->string.text.p = bp->string.buffer.start;
2082 2082
2083 2083 /* 4209588: 'make' doesn't understand a macro with whitespaces in the head as target.
2084 2084 * strip whitespace from the begining of the macro value
2085 2085 */
2086 2086 while (iswspace(*bp->string.text.p)) {
2087 2087 bp->string.text.p++;
2088 2088 }
2089 2089
2090 2090 bp->fd = -1;
2091 2091 bp->already_expanded = true;
2092 2092 bp->previous = source;
2093 2093 return bp;
2094 2094 }
2095 2095
2096 2096 /*
2097 2097 * enter_target_groups_and_dependencies(target, depes, command, separator,
2098 2098 * target_group_seen)
2099 2099 *
2100 2100 * Parameters:
2101 2101 * target Structure that shows the target(s) on the line
2102 2102 * we are currently parsing. This can looks like
2103 2103 * target1 .. targetN : dependencies
2104 2104 * commands
2105 2105 * or
2106 2106 * target1 + .. + targetN : dependencies
2107 2107 * commands
2108 2108 * depes Dependencies
2109 2109 * command Points to the command(s) to be executed for
2110 2110 * this target.
2111 2111 * separator : or :: or :=
2112 2112 * target_group_seen Set if we have target1 + .. + targetN
2113 2113 *
2114 2114 *
2115 2115 * After reading the command lines for a target, this routine
2116 2116 * is called to setup the dependencies and the commands for it.
2117 2117 * If the target is a % pattern or part of a target group, then
2118 2118 * the appropriate routines are called.
2119 2119 */
2120 2120
2121 2121 void
2122 2122 enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen)
2123 2123 {
2124 2124 int i;
2125 2125 Boolean reset= true;
2126 2126 Chain target_group_member;
2127 2127 Percent percent_ptr;
2128 2128
2129 2129 for (; target != NULL; target = target->next) {
2130 2130 for (i = 0; i < target->used; i++) {
2131 2131 if (target->names[i] != NULL) {
2132 2132 if (target_group_seen) {
2133 2133 target_group_member =
2134 2134 find_target_groups(target, i, reset);
2135 2135 if(target_group_member == NULL) {
2136 2136 fatal_reader(catgets(catd, 1, 328, "Unexpected '+' on dependency line"));
2137 2137 }
2138 2138 }
2139 2139 reset = false;
2140 2140
2141 2141 /* If we saw it in the makefile it must be
2142 2142 * a file */
2143 2143 target->names[i]->stat.is_file = true;
2144 2144 /* Make sure that we use dependencies
2145 2145 * entered for makefiles */
2146 2146 target->names[i]->state = build_dont_know;
2147 2147
2148 2148 /* If the target is special we delegate
2149 2149 * the processing */
2150 2150 if (target->names[i]->special_reader
2151 2151 != no_special) {
2152 2152 special_reader(target->names[i],
2153 2153 depes,
2154 2154 command);
2155 2155 }
2156 2156 /* Check if this is a "a%b : x%y" type rule */
2157 2157 else if (target->names[i]->percent) {
2158 2158 percent_ptr =
2159 2159 enter_percent(target->names[i],
2160 2160 target->target_group[i],
2161 2161 depes, command);
2162 2162 if (target_group_seen) {
2163 2163 target_group_member->percent_member =
2164 2164 percent_ptr;
2165 2165 }
2166 2166 } else if (target->names[i]->dollar) {
2167 2167 enter_dyntarget(target->names[i]);
2168 2168 enter_dependencies
2169 2169 (target->names[i],
2170 2170 target->target_group[i],
2171 2171 depes,
2172 2172 command,
2173 2173 separator);
2174 2174 } else {
2175 2175 if (target_group_seen) {
2176 2176 target_group_member->percent_member =
2177 2177 NULL;
2178 2178 }
2179 2179
2180 2180 enter_dependencies
2181 2181 (target->names[i],
2182 2182 target->target_group[i],
2183 2183 depes,
2184 2184 command,
2185 2185 separator);
2186 2186 }
2187 2187 }
2188 2188 }
2189 2189 }
2190 2190 }
2191 2191
2192 2192
↓ open down ↓ |
1978 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX