- Timestamp:
- Apr 16, 2020 10:23:49 PM (5 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kbuild.c
r3278 r3322 382 382 kbuild_apply_defpath(struct variable *pDefPath, char **ppsz, unsigned int *pcch, unsigned int *pcchAlloc, int fCanFree) 383 383 { 384 const char *pszIterator;385 const char *pszInCur;386 384 unsigned int cchInCur; 387 385 unsigned int cchMaxRelative = 0; 388 unsigned int cRelativePaths;386 const char *pszInCur; 389 387 390 388 /* 391 389 * The first pass, count the relative paths. 392 390 */ 393 cRelativePaths = 0; 394 pszIterator = *ppsz; 395 while ((pszInCur = find_next_token(&pszIterator, &cchInCur)) != NULL) 391 const char *pszIterator = *ppsz; 392 const char * const pszEos = pszIterator + *pcch; 393 unsigned int cRelativePaths = 0; 394 assert(*pszEos == '\0'); 395 while ((pszInCur = find_next_file_token(&pszIterator, pszEos, &cchInCur)) != NULL) 396 396 { 397 397 /* is relative? */ … … 438 438 cRelativePaths = 0; 439 439 pszIterator = *ppsz; 440 while ((pszInCur = find_next_ token(&pszIterator, &cchInCur)))440 while ((pszInCur = find_next_file_token(&pszIterator, pszEos, &cchInCur))) 441 441 { 442 442 /* is relative? */ -
trunk/src/kmk/makeint.h
r3273 r3322 679 679 #ifdef KMK 680 680 char *find_next_token_eos (const char **ptr, const char *eos, unsigned int *lengthptr); 681 char *find_next_file_token (const char **ptr, const char *eos, unsigned int *lengthptr); 681 682 #endif 682 683 #ifndef CONFIG_WITH_VALUE_LENGTH -
trunk/src/kmk/misc.c
r3230 r3322 600 600 #endif 601 601 } 602 602 603 #ifdef KMK 604 /* Finds the ends of the variable expansion starting at S, stopping at EOS if 605 not found before. */ 606 static char *find_end_of_variable_expansion (const char *s, char const *eos) 607 { 608 char const openparen = s[1]; 609 char const closeparen = openparen == '(' ? ')' : '}'; 610 int levels = 0; 611 612 assert (s[0] == '$'); 613 assert (s[1] == '(' || s[1] == '{'); 614 615 s += 2; 616 while (s != eos) 617 { 618 unsigned char ch = *s; 619 if (ch != '\0') 620 { 621 if (ch != closeparen) 622 { 623 if (ch != openparen) 624 { /* likely */ } 625 else 626 levels++; 627 } 628 else if (levels <= 1) 629 break; 630 else 631 levels--; 632 } 633 else 634 break; 635 s++; 636 } 637 638 return (char *)s; 639 } 603 640 604 641 /* Same as find_next_token with two exception: … … 611 648 const char *p = *ptr; 612 649 const char *e; 613 int level = 0;614 650 615 651 /* skip blanks */ 616 for (; p != eos; p++) 617 { 618 unsigned char ch = *p; 619 if (!MY_IS_BLANK(ch)) 620 { 621 if (!ch) 622 return NULL; 623 break; 624 } 652 while (p != eos) 653 { 654 unsigned char const ch = *p; 655 unsigned int const map = stopchar_map[ch] & (MAP_NUL | MAP_BLANK); 656 if (map & MAP_BLANK) 657 p++; 658 else if (!(map & MAP_NUL)) 659 break; 660 else 661 return NULL; 625 662 } 626 663 if (p == eos) … … 628 665 629 666 /* skip ahead until EOS or blanks. */ 630 for (e = p; e != eos; e++) 631 { 632 unsigned char ch = *e; 633 if (MY_IS_BLANK_OR_EOS(ch)) 634 { 635 if (!ch || level == 0) 667 e = p; 668 while (e != eos) 669 { 670 unsigned char const ch = *e; 671 unsigned int const map = stopchar_map[ch] & (MAP_NUL | MAP_BLANK | MAP_VARIABLE); 672 if (!map) 673 e++; /* likely */ 674 /* Dollar can be escaped by duplication ($$) and when not, they need to 675 be skipped over. */ 676 else if (map & MAP_VARIABLE) 677 { 678 e++; 679 if (&e[1] != eos) 680 { 681 unsigned ch2 = *e; 682 if (ch2 == ch) 683 e++; /* escaped */ 684 else if (ch == '(' || ch == '}') 685 e = find_end_of_variable_expansion (e - 1, eos); 686 } 687 else 636 688 break; 637 689 } 638 else if (ch == '$') 639 { 640 if (&e[1] != eos && (e[1] == '(' || e[1] == '{')) 690 else 691 break; /* MAP_NUL or MAP_BLANK */ 692 } 693 694 *ptr = e; 695 if (lengthptr != 0) 696 *lengthptr = e - p; 697 698 return (char *)p; 699 } 700 701 /* Same as find_next_token_eos but takes GNU make quoting into account, 702 but without doing any unquoting like find_char_unquote & parse_file_seq. */ 703 704 char * 705 find_next_file_token (const char **ptr, const char *eos, unsigned int *lengthptr) 706 { 707 const char *p = *ptr; 708 const char *e; 709 710 /* skip blanks */ 711 while (p != eos) 712 { 713 unsigned char const ch = *p; 714 unsigned int const map = stopchar_map[ch] & (MAP_NUL | MAP_BLANK); 715 if (map & MAP_BLANK) 716 p++; 717 else if (!(map & MAP_NUL)) 718 break; 719 else 720 return NULL; 721 } 722 if (p == eos) 723 return NULL; 724 725 /* skip ahead until EOS or blanks. */ 726 e = p; 727 while (e != eos) 728 { 729 unsigned char const ch = *e; 730 unsigned int const map = stopchar_map[ch] & (MAP_NUL | MAP_BLANK | MAP_VARIABLE); 731 if (!map) 732 e++; /* likely */ 733 /* Dollar can be escaped by duplication ($$) and when not, they need to 734 be skipped over. */ 735 else if (map & MAP_VARIABLE) 736 { 737 e++; 738 if (&e[1] != eos) 641 739 { 642 level++; 643 e++; 740 unsigned ch2 = *e; 741 if (ch2 == ch) 742 e++; /* escaped */ 743 else if (ch == '(' || ch == '}') 744 e = find_end_of_variable_expansion (e - 1, eos); 644 745 } 645 } 646 else if ((ch == ')' || ch == '}') && level > 0) 647 level--; 746 else 747 break; 748 } 749 else if (map & MAP_NUL) 750 break; 751 /* A blank can be escaped using a backslash. */ 752 else if (e[-1] != '\\') 753 break; 754 else 755 { 756 int slashes = 1; 757 while (&e[-slashes] != p && e[-slashes - 1] == '\\') 758 slashes++; 759 if (slashes & 1) 760 e++; 761 else 762 break; 763 } 648 764 } 649 765
Note:
See TracChangeset
for help on using the changeset viewer.