Changeset 1168 for trunk/src/kmk
- Timestamp:
- Oct 1, 2007, 3:29:32 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/read.c
r1109 r1168 462 462 463 463 #ifdef CONFIG_WITH_INCLUDEDEP 464 /* no nonsense dependency file including. */ 464 /* no nonsense dependency file including. 465 466 Because nobody wants bogus dependency files to break their incremental 467 builds with hard to comprehend error messages, this function does not 468 use the normal eval routine but does all the parsing itself. This isn't, 469 as much work as it sounds, because the necessary feature set is very 470 limited. */ 465 471 void 466 472 eval_include_dep (const char *name, struct floc *f) 467 473 { 468 474 FILE *fp; 469 long max_size; 470 long size; 471 char *buf; 472 unsigned int saved_var_len; 473 char *saved_var_buf; 474 475 /* ignore non-existing dependency files. */ 475 char line_buf[8192]; 476 unsigned line_no = 0; 477 478 /* open it, ignore non-existing dependency files and don't 479 fail fataly if we cannot open it. */ 476 480 if (!file_exists_p (name)) 477 481 return; 478 479 /* open it and determin the size. */480 482 errno = 0; 481 fp = fopen (name, "r ");483 fp = fopen (name, "rb"); 482 484 if (!fp) 483 485 { … … 486 488 } 487 489 488 if (fseek (fp, 0, SEEK_END)) 489 fatal (f, "%s: fseek failed - %s", name, strerror (errno)); 490 max_size = ftell (fp); 491 if (max_size < 0) 492 fatal (f, "%s: ftell failed - %s", name, strerror (errno)); 493 if (fseek (fp, 0, SEEK_SET)) 494 fatal (f, "%s: fseek failed - %s", name, strerror (errno)); 495 496 /* ignore empty files. */ 497 if (max_size == 0) 498 { 499 fclose (fp); 500 return; 501 } 502 503 /* allocate a buffer and read the file. \r\n -> \n conversion 504 make this intersting ... */ 505 buf = xmalloc (max_size + 1); 506 size = fread (buf, 1, max_size, fp); /* FIXME: EINTR? incomplete reads? */ 507 if ( size == -1 508 || (ferror (fp) && !feof (fp))) 509 fatal (f, "%s: fread failed - %s", name, strerror (errno)); 510 if (size < max_size / 2) 511 fatal (f, "%s: fread failed - %s", name, strerror (errno)); 512 buf[size] = '\0'; 513 514 /* evaluate the buffer and cleanup. */ 515 install_variable_buffer (&saved_var_buf, &saved_var_len); 516 eval_buffer (buf); 517 restore_variable_buffer (saved_var_buf, saved_var_len); 518 519 free (buf); 490 /* parse the file line by line... */ 491 while (fgets (line_buf, sizeof (line_buf), fp)) 492 { 493 char *p; 494 char *endp; 495 496 line_no++; 497 p = line_buf; 498 while (isspace ((unsigned char)*p)) 499 ++p; 500 if (*p == '\0' || *p == '#') 501 continue; 502 503 /* define var ... endef for command tracking. */ 504 if (strneq (p, "define ", 7)) 505 { 506 size_t value_len = 0; 507 size_t value_alloc_size = 0; 508 char *value = 0; 509 int newline = 1; 510 int found_endef = 0; 511 const char *var; 512 unsigned var_len; 513 514 /* extract the variable name. */ 515 p += 7; 516 while (isblank ((unsigned char)*p)) 517 ++p; 518 endp = strchr(p, '\0'); 519 while (endp > p && isspace ((unsigned char)endp[-1])) 520 --endp; 521 var_len = endp - p; 522 if (!var_len) 523 { 524 error (f, "%s(%d): bogus define statement.", name, line_no); 525 break; 526 } 527 var = strcache_add_len (p, var_len); 528 529 /* read the define contents. */ 530 while (fgets (line_buf, sizeof (line_buf), fp)) 531 { 532 size_t len; 533 534 line_no++; 535 536 /* check for endef */ 537 if (newline) 538 { 539 p = line_buf; 540 while (isblank ((unsigned char)*p)) 541 ++p; 542 if (strneq (p, "endef", 5)) 543 { 544 p += 5; 545 while (isspace ((unsigned char)*p)) 546 p++; 547 if (*p == '\0') 548 { 549 found_endef = 1; 550 break; 551 } 552 } 553 } 554 555 /* append the line to the buffer. */ 556 len = strlen (line_buf); 557 if (value_len + len + 1 > value_alloc_size) 558 { 559 if (value_alloc_size == 0) 560 value_alloc_size = (len + 1 + 0x100) & ~(size_t)0xff; 561 else 562 { 563 value_alloc_size *= 2; 564 if (value_len + len + 1 > value_alloc_size) 565 value_alloc_size = (value_len + len * 2 + 1) & ~(size_t)0xff; 566 } 567 value = xrealloc (value, value_alloc_size); 568 } 569 memcpy (value + value_len, line_buf, len + 1); 570 value_len += len; 571 newline = len ? line_buf[len - 1] == '\n' : 0; 572 } 573 574 if (!found_endef) 575 { 576 error (f, "%s(%d): bogus define statement.", name, line_no); 577 break; 578 } 579 580 /* all that's left is to define it. */ 581 #ifdef CONFIG_WITH_VALUE_LENGTH 582 define_variable_in_set (var, var_len, value, value_len, 0 /* don't duplicate */, 583 o_file, 0 /* not recursive */, NULL /* global set */, 584 NULL /*no floc*/); 585 #else 586 define_variable_in_set (var, var_len, value, o_file, 0 /* not recursive */, 587 NULL /* global set */, NULL /*no floc*/); 588 free (value); 589 #endif 590 } 591 /* file: deps */ 592 else 593 { 594 struct nameseq *filenames = 0; 595 struct dep *deps = 0; 596 struct dep **nextdep = &deps; 597 struct dep *dep; 598 int next_line = 1; 599 char *colonp; 600 601 /* look for a colon. */ 602 colonp = strchr (p, ':'); 603 #ifdef HAVE_DOS_PATHS 604 while ( colonp 605 && (colonp[1] == '/' || colonp[1] == '\\') 606 && colonp > p 607 && isalpha ((unsigned char)colonp[-1]) 608 && ( colonp == p + 1 609 || strchr (" \t(", colonp[-2]) != 0)) 610 colonp = strchr (colonp + 1, ':'); 611 #endif 612 if (!colonp) 613 { 614 error (f, "%s(%d): no colon.", name, line_no); 615 break; 616 } 617 618 /* extract the filename, ASSUME a single one. */ 619 endp = colonp; 620 while (endp > p && isblank ((unsigned char)endp[-1])) 621 --endp; 622 if (p == endp) 623 { 624 error (f, "%s(%d): empty filename.", name, line_no); 625 break; 626 } 627 filenames = xmalloc (sizeof (struct nameseq)); 628 memset (filenames, 0, sizeof (*filenames)); 629 filenames->name = strcache_add_len (p, endp - p); 630 631 /* parse any dependencies, taking care with very long lines. */ 632 p = colonp + 1; 633 for (;;) 634 { 635 while (isblank ((unsigned char)*p)) 636 ++p; 637 638 /* eol + continuation mark? read the next line. */ 639 if (*p == '\\' 640 && ( (p[1] == '\n' && p[2] == '\0') 641 || (p[1] == '\r' && p[2] == '\n' && p[3] == '\0') 642 || p[1] == '\0')) 643 { 644 if (!fgets (line_buf, sizeof (line_buf), fp)) 645 break; 646 p = line_buf; 647 line_no++; 648 continue; 649 } 650 651 /* eol? */ 652 if ((p[0] == '\n' && p[1] == '\0') 653 || p[0] == '\0' 654 || (p[0] == '\r' && p[1] == '\n' && p[2] == '\0')) 655 break; 656 657 /* find the end of the filename */ 658 endp = p; 659 while (!isspace ((unsigned char) *endp) && *endp != '\0') 660 ++endp; 661 if (*endp == '\0' && !feof (fp)) 662 { 663 size_t len = endp - p; 664 if (len > (sizeof (line_buf) / 4) * 3) 665 { 666 error (f, "%s(%d): dependency name too long.", name, line_no); 667 break; 668 } 669 memmove (line_buf, p, len); 670 p -= len; 671 endp -= len; 672 if (!fgets (endp, sizeof (line_buf) - len, fp)) 673 break; 674 while (!isblank ((unsigned char) *endp) && *endp != '\0') 675 ++endp; 676 if (*endp == '\0' && !feof (fp)) 677 { 678 error (f, "%s(%d): dependency name too long.", name, line_no); 679 break; 680 } 681 } 682 683 /* add it to the list. */ 684 *nextdep = dep = alloc_dep (); 685 dep->name = strcache_add_len (p, endp - p); 686 nextdep = &dep->next; 687 688 p = endp; 689 } 690 691 /* enter the file with its dependencies. */ 692 record_files (filenames, NULL, NULL, deps, 0, NULL, 0, 0, NULL); 693 } 694 } /* while (fgets) */ 695 520 696 fclose (fp); 521 697 }
Note:
See TracChangeset
for help on using the changeset viewer.