Changeset 1169 for trunk/src/kmk/read.c
- Timestamp:
- Oct 1, 2007, 5:32:06 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/read.c
r1168 r1169 34 34 # include "kbuild.h" 35 35 #endif 36 36 #ifdef CONFIG_WITH_INCLUDEDEP 37 # ifdef HAVE_FCNTL_H 38 # include <fcntl.h> 39 # else 40 # include <sys/file.h> 41 #endif 42 # ifdef WINDOWS32 43 # include <io.h> 44 # endif 45 #endif 37 46 38 47 #ifndef WINDOWS32 … … 472 481 eval_include_dep (const char *name, struct floc *f) 473 482 { 474 FILE *fp; 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. */ 483 int fd; 484 char *file_base; 485 const char *file_end, *cur, *endp; 486 struct stat st; 487 unsigned line_no; 488 489 /* open and read it into memory. ignore non-existing dependency files 490 or that we can't read. */ 480 491 if (!file_exists_p (name)) 481 492 return; 482 493 errno = 0; 483 fp = fopen (name, "rb"); 484 if (!fp) 494 #ifdef O_BINARY 495 fd = open (name, O_RDONLY | O_BINARY, 0); 496 #else 497 fd = open (name, O_RDONLY, 0); 498 #endif 499 if (fd < 0) 485 500 { 486 501 error (f, "%s: %s", name, strerror (errno)); 487 502 return; 488 503 } 489 490 /* parse the file line by line... */ 491 while (fgets (line_buf, sizeof (line_buf), fp)) 504 if (fstat (fd, &st)) 492 505 { 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; 506 error (f, "%s: fstat: %s", name, strerror (errno)); 507 close (fd); 508 return; 509 } 510 file_base = xmalloc (st.st_size + 1); 511 if (read (fd, file_base, st.st_size) != st.st_size) 512 { 513 error (f, "%s: read: %s", name, strerror (errno)); 514 close (fd); 515 free (file_base); 516 return; 517 } 518 close (fd); 519 file_end = file_base + st.st_size; 520 file_base[st.st_size] = '\0'; 521 522 /* now parse the file. */ 523 line_no = 1; 524 cur = file_base; 525 while (cur < file_end) 526 { 527 /* skip empty lines */ 528 while (cur < file_end && isspace ((unsigned char)*cur) && *cur != '\n') 529 ++cur; 530 if (cur >= file_end) 531 break; 532 if (*cur == '#') 533 { 534 cur = memchr (cur, '\n', file_end - cur); 535 if (!cur) 536 break; 537 } 538 if (*cur == '\n') 539 { 540 cur++; 541 line_no++; 542 continue; 543 } 502 544 503 545 /* define var ... endef for command tracking. */ 504 if (strneq ( p, "define ", 7))546 if (strneq (cur, "define ", 7)) 505 547 { 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 548 const char *var; 512 549 unsigned var_len; 550 const char *value_start; 551 const char *value_end; 552 char *value; 553 unsigned value_len; 554 int found_endef = 0; 513 555 514 556 /* 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])) 557 cur += 7; 558 while (isblank ((unsigned char)*cur)) 559 ++cur; 560 value_start = endp = memchr (cur, '\n', file_end - cur); 561 if (!endp) 562 endp = cur; 563 while (endp > cur && isspace ((unsigned char)endp[-1])) 520 564 --endp; 521 var_len = endp - p;565 var_len = endp - cur; 522 566 if (!var_len) 523 567 { … … 525 569 break; 526 570 } 527 var = strcache_add_len (p, var_len); 528 529 /* read the define contents. */ 530 while (fgets (line_buf, sizeof (line_buf), fp)) 571 var = strcache_add_len (cur, var_len); 572 573 /* find the end of the variable. */ 574 cur = value_end = value_start = value_start + 1; 575 ++line_no; 576 while (cur < file_end) 531 577 { 532 size_t len; 533 534 line_no++; 535 536 /* check for endef */ 537 if (newline) 578 /* check for endef, don't bother with skipping leading spaces. */ 579 if ( file_end - cur >= 5 580 && strneq (cur, "endef", 5)) 538 581 { 539 p = line_buf;540 while ( isblank ((unsigned char)*p))541 ++p;542 if ( strneq (p, "endef", 5))582 endp = cur + 5; 583 while (endp < file_end && isspace ((unsigned char)*endp) && *endp != '\n') 584 endp++; 585 if (endp >= file_end || *endp == '\n') 543 586 { 544 p += 5; 545 while (isspace ((unsigned char)*p)) 546 p++; 547 if (*p == '\0') 548 { 549 found_endef = 1; 550 break; 551 } 587 found_endef = 1; 588 cur = endp >= file_end ? file_end : endp + 1; 589 break; 552 590 } 553 591 } 554 592 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; 593 /* skip a line ahead. */ 594 cur = value_end = memchr (cur, '\n', file_end - cur); 595 if (cur != NULL) 596 ++cur; 597 else 598 cur = value_end = file_end; 599 ++line_no; 572 600 } 573 601 … … 578 606 } 579 607 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 608 /* make a copy of the value, converting \r\n to \n, and define it. */ 609 value_len = value_end - value_start; 610 value = xmalloc (value_len + 1); 611 endp = memchr (value_start, '\r', value_len); 612 if (endp) 613 { 614 const char *src = value_start; 615 char *dst = value; 616 for (;;) 617 { 618 size_t len = endp - src; 619 memcpy (dst, src, len); 620 dst += len; 621 src = endp; 622 if (src + 1 < file_end && src[1] == '\n') 623 src++; /* skip the '\r' */ 624 if (src >= value_end) 625 break; 626 endp = memchr (endp + 1, '\r', src - value_end); 627 if (!endp) 628 endp = value_end; 629 } 630 value_len = dst - value; 631 } 632 else 633 memcpy (value, value_start, value_len); 634 value [value_len] = '\0'; 635 636 define_variable_in_set (var, var_len, value, value_len, 637 0 /* don't duplicate */, o_file, 638 0 /* defines are recursive but this is faster */, 639 NULL /* global set */, f); 590 640 } 591 641 /* file: deps */ … … 599 649 char *colonp; 600 650 601 /* look for a colon . */602 colonp = strchr (p, ':');651 /* look for a colon, ASSUME it's on the same line. */ 652 colonp = memchr (cur, ':', file_end - cur); 603 653 #ifdef HAVE_DOS_PATHS 604 654 while ( colonp 605 655 && (colonp[1] == '/' || colonp[1] == '\\') 606 && colonp > p656 && colonp > cur 607 657 && isalpha ((unsigned char)colonp[-1]) 608 && ( colonp == p+ 1658 && ( colonp == cur + 1 609 659 || strchr (" \t(", colonp[-2]) != 0)) 610 colonp = strchr (colonp + 1, ':');611 #endif 612 if (!colonp )660 colonp = memchr (colonp + 1, ':', file_end - (colonp + 1)); 661 #endif 662 if (!colonp || memchr (cur, '\n', colonp - cur)) 613 663 { 614 664 error (f, "%s(%d): no colon.", name, line_no); … … 618 668 /* extract the filename, ASSUME a single one. */ 619 669 endp = colonp; 620 while (endp > p&& isblank ((unsigned char)endp[-1]))670 while (endp > cur && isblank ((unsigned char)endp[-1])) 621 671 --endp; 622 if ( p== endp)672 if (cur == endp) 623 673 { 624 674 error (f, "%s(%d): empty filename.", name, line_no); … … 627 677 filenames = xmalloc (sizeof (struct nameseq)); 628 678 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 (;;)679 filenames->name = strcache_add_len (cur, endp - cur); 680 681 /* parse any dependencies. */ 682 cur = colonp + 1; 683 while (cur < file_end) 634 684 { 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')) 685 /* skip blanks and count lines. */ 686 while (cur < file_end && isspace ((unsigned char)*cur) && *cur != '\n') 687 ++cur; 688 if (cur >= file_end) 689 break; 690 if (*cur == '\n') 643 691 { 644 if (!fgets (line_buf, sizeof (line_buf), fp)) 645 break; 646 p = line_buf; 692 cur++; 647 693 line_no++; 648 continue;694 break; 649 695 } 650 696 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)) 697 /* continuation + eol? */ 698 if (*cur == '\\') 662 699 { 663 size_t len = endp - p; 664 if (len > (sizeof (line_buf) / 4) * 3) 700 unsigned eol_len = (file_end - cur > 1 && cur[1] == '\n') ? 2 701 : (file_end - cur > 2 && cur[1] == '\r' && cur[2] == '\n') ? 3 702 : (file_end - cur == 1) ? 1 : 0; 703 if (eol_len) 665 704 { 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; 705 cur += eol_len; 706 line_no++; 707 continue; 680 708 } 681 709 } 682 710 711 /* find the end of the filename */ 712 endp = cur; 713 while (endp < file_end && !isspace ((unsigned char)*endp)) 714 ++endp; 715 683 716 /* add it to the list. */ 684 717 *nextdep = dep = alloc_dep (); 685 dep->name = strcache_add_len ( p, endp - p);718 dep->name = strcache_add_len (cur, endp - cur); 686 719 nextdep = &dep->next; 687 720 688 p= endp;721 cur = endp; 689 722 } 690 723 691 724 /* enter the file with its dependencies. */ 692 record_files (filenames, NULL, NULL, deps, 0, NULL, 0, 0, NULL);725 record_files (filenames, NULL, NULL, deps, 0, NULL, 0, 0, f); 693 726 } 694 } /* while (fgets) */ 695 696 fclose (fp); 727 } 728 free (file_base); 697 729 } 698 730 #endif /* CONFIG_WITH_INCLUDEDEP */
Note:
See TracChangeset
for help on using the changeset viewer.