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