Changeset 280 in kBuild for branches/GNU/src/gmake/function.c
- Timestamp:
- May 16, 2005 4:54:02 PM (20 years ago)
- Location:
- branches/GNU/src/gmake
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/gmake
- Property svn:ignore
-
old new 34 34 README.DOS 35 35 README.W32 36 README.OS2 36 37 aclocal.m4 37 38 autom4te.cache
-
- Property svn:ignore
-
branches/GNU/src/gmake/function.c
r153 r280 74 74 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is 75 75 nonzero, substitutions are done only on matches which are complete 76 whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are 77 done only at the ends of whitespace-delimited words. */ 76 whitespace-delimited words. */ 78 77 79 78 char * 80 79 subst_expand (char *o, char *text, char *subst, char *replace, 81 unsigned int slen, unsigned int rlen, 82 int by_word, int suffix_only) 80 unsigned int slen, unsigned int rlen, int by_word) 83 81 { 84 82 char *t = text; 85 unsigned int tlen = strlen (text);86 83 char *p; 87 84 88 if (slen == 0 && !by_word && !suffix_only)85 if (slen == 0 && !by_word) 89 86 { 90 87 /* The first occurrence of "" in any string is its end. */ 91 o = variable_buffer_output (o, t, tlen);88 o = variable_buffer_output (o, t, strlen (t)); 92 89 if (rlen > 0) 93 90 o = variable_buffer_output (o, replace, rlen); … … 97 94 do 98 95 { 99 if ( (by_word | suffix_only)&& slen == 0)96 if (by_word && slen == 0) 100 97 /* When matching by words, the empty string should match 101 98 the end of each word, rather than the end of the whole text. */ … … 103 100 else 104 101 { 105 p = s index (t, tlen, subst, slen);102 p = strstr (t, subst); 106 103 if (p == 0) 107 104 { 108 105 /* No more matches. Output everything left on the end. */ 109 o = variable_buffer_output (o, t, tlen);106 o = variable_buffer_output (o, t, strlen (t)); 110 107 return o; 111 108 } … … 118 115 /* If we're substituting only by fully matched words, 119 116 or only at the ends of words, check that this case qualifies. */ 120 if ((by_word 121 && ((p > t && !isblank ((unsigned char)p[-1])) 122 || (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) 123 || (suffix_only 124 && (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) 117 if (by_word 118 && ((p > text && !isblank ((unsigned char)p[-1])) 119 || (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) 125 120 /* Struck out. Output the rest of the string that is 126 121 no longer to be replaced. */ … … 130 125 o = variable_buffer_output (o, replace, rlen); 131 126 132 /* Advance T past the string to be replaced ; adjust tlen. */127 /* Advance T past the string to be replaced. */ 133 128 { 134 129 char *nt = p + slen; 135 tlen -= nt - t;136 130 t = nt; 137 131 } … … 140 134 return o; 141 135 } 136 142 137 143 138 … … 147 142 run through find_percent, and PATTERN_PERCENT is the result. 148 143 If REPLACE_PERCENT is not nil, REPLACE has already been 149 run through find_percent, and REPLACE_PERCENT is the result. */ 144 run through find_percent, and REPLACE_PERCENT is the result. 145 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the 146 character _AFTER_ the %, not to the % itself. 147 */ 150 148 151 149 char * … … 154 152 { 155 153 unsigned int pattern_prepercent_len, pattern_postpercent_len; 156 unsigned int replace_prepercent_len, replace_postpercent_len = 0;154 unsigned int replace_prepercent_len, replace_postpercent_len; 157 155 char *t; 158 156 unsigned int len; … … 161 159 /* We call find_percent on REPLACE before checking PATTERN so that REPLACE 162 160 will be collapsed before we call subst_expand if PATTERN has no %. */ 163 if (replace_percent == 0) 164 replace_percent = find_percent (replace); 165 if (replace_percent != 0) 166 { 167 /* Record the length of REPLACE before and after the % so 168 we don't have to compute these lengths more than once. */ 169 replace_prepercent_len = replace_percent - replace; 170 replace_postpercent_len = strlen (replace_percent + 1); 161 if (!replace_percent) 162 { 163 replace_percent = find_percent (replace); 164 if (replace_percent) 165 ++replace_percent; 166 } 167 168 /* Record the length of REPLACE before and after the % so we don't have to 169 compute these lengths more than once. */ 170 if (replace_percent) 171 { 172 replace_prepercent_len = replace_percent - replace - 1; 173 replace_postpercent_len = strlen (replace_percent); 171 174 } 172 175 else 173 /* We store the length of the replacement 174 so we only need to compute it once. */ 175 replace_prepercent_len = strlen (replace); 176 177 if (pattern_percent == 0) 178 pattern_percent = find_percent (pattern); 179 if (pattern_percent == 0) 176 { 177 replace_prepercent_len = strlen (replace); 178 replace_postpercent_len = 0; 179 } 180 181 if (!pattern_percent) 182 { 183 pattern_percent = find_percent (pattern); 184 if (pattern_percent) 185 ++pattern_percent; 186 } 187 if (!pattern_percent) 180 188 /* With no % in the pattern, this is just a simple substitution. */ 181 189 return subst_expand (o, text, pattern, replace, 182 strlen (pattern), strlen (replace), 1 , 0);190 strlen (pattern), strlen (replace), 1); 183 191 184 192 /* Record the length of PATTERN before and after the % 185 193 so we don't have to compute it more than once. */ 186 pattern_prepercent_len = pattern_percent - pattern ;187 pattern_postpercent_len = strlen (pattern_percent + 1);194 pattern_prepercent_len = pattern_percent - pattern - 1; 195 pattern_postpercent_len = strlen (pattern_percent); 188 196 189 197 while ((t = find_next_token (&text, &len)) != 0) … … 198 206 if (!fail && pattern_prepercent_len > 0 199 207 && (*t != *pattern 200 || t[pattern_prepercent_len - 1] != pattern_percent[- 1]208 || t[pattern_prepercent_len - 1] != pattern_percent[-2] 201 209 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1))) 202 210 fail = 1; … … 204 212 /* Does the suffix match? */ 205 213 if (!fail && pattern_postpercent_len > 0 206 && (t[len - 1] != pattern_percent[pattern_postpercent_len ]207 || t[len - pattern_postpercent_len] != pattern_percent[1]214 && (t[len - 1] != pattern_percent[pattern_postpercent_len - 1] 215 || t[len - pattern_postpercent_len] != *pattern_percent 208 216 || !strneq (&t[len - pattern_postpercent_len], 209 &pattern_percent[1], pattern_postpercent_len - 1)))217 pattern_percent, pattern_postpercent_len - 1))) 210 218 fail = 1; 211 219 … … 228 236 + pattern_postpercent_len)); 229 237 /* Output the part of the replacement after the %. */ 230 o = variable_buffer_output (o, replace_percent + 1,238 o = variable_buffer_output (o, replace_percent, 231 239 replace_postpercent_len); 232 240 } … … 648 656 { 649 657 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]), 650 strlen (argv[1]), 0 , 0);658 strlen (argv[1]), 0); 651 659 652 660 return o; … … 667 675 } 668 676 677 static char * 678 func_lastword (char *o, char **argv, const char *funcname UNUSED) 679 { 680 unsigned int i; 681 char *words = argv[0]; /* Use a temp variable for find_next_token */ 682 char *p = 0; 683 char *t; 684 685 while ((t = find_next_token (&words, &i))) 686 p = t; 687 688 if (p != 0) 689 o = variable_buffer_output (o, p, i); 690 691 return o; 692 } 669 693 670 694 static char * … … 690 714 * begpp-1. 691 715 */ 692 staticchar *716 char * 693 717 strip_whitespace (const char **begpp, const char **endpp) 694 718 { … … 755 779 756 780 start = atoi (argv[0]); 781 if (start < 1) 782 fatal (reading_file, 783 "invalid first argument to `wordlist' function: `%d'", start); 784 757 785 count = atoi (argv[1]) - start + 1; 758 786 … … 784 812 { 785 813 /* Find the first occurrence of the first string in the second. */ 786 int i = strlen (argv[0]); 787 if (sindex (argv[1], 0, argv[0], i) != 0) 788 o = variable_buffer_output (o, argv[0], i); 814 if (strstr (argv[1], argv[0]) != 0) 815 o = variable_buffer_output (o, argv[0], strlen (argv[0])); 789 816 790 817 return o; … … 1067 1094 strcpy (p, *argvp); 1068 1095 1069 if (*funcname == 'e') 1070 fatal (reading_file, "%s", msg); 1096 switch (*funcname) { 1097 case 'e': 1098 fatal (reading_file, "%s", msg); 1099 1100 case 'w': 1101 error (reading_file, "%s", msg); 1102 break; 1103 1104 case 'i': 1105 printf ("%s\n", msg); 1106 break; 1107 1108 default: 1109 fatal (reading_file, "Internal error: func_error: '%s'", funcname); 1110 } 1071 1111 1072 1112 /* The warning function expands to the empty string. */ 1073 error (reading_file, "%s", msg);1074 1075 1113 return o; 1076 1114 } … … 1457 1495 1458 1496 /* For error messages. */ 1459 if (reading_file != 0)1497 if (reading_file && reading_file->filenm) 1460 1498 { 1461 1499 error_prefix = (char *) alloca (strlen (reading_file->filenm)+11+4); … … 1700 1738 */ 1701 1739 static char * 1702 func_eq (char *o, char **argv, char *funcname)1740 func_eq (char *o, char **argv, char *funcname) 1703 1741 { 1704 1742 int result = ! strcmp (argv[0], argv[1]); … … 1712 1750 */ 1713 1751 static char * 1714 func_not (char *o, char **argv, char *funcname)1715 { 1716 char * 1752 func_not (char *o, char **argv, char *funcname) 1753 { 1754 char *s = argv[0]; 1717 1755 int result = 0; 1718 1756 while (isspace ((unsigned char)*s)) … … 1726 1764 1727 1765 1766 /* Return the absolute name of file NAME which does not contain any `.', 1767 `..' components nor any repeated path separators ('/'). */ 1768 1769 static char * 1770 abspath (const char *name, char *apath) 1771 { 1772 char *dest; 1773 const char *start, *end, *apath_limit; 1774 1775 if (name[0] == '\0' || apath == NULL) 1776 return NULL; 1777 1778 apath_limit = apath + GET_PATH_MAX; 1779 1780 if (name[0] != '/') 1781 { 1782 /* It is unlikely we would make it until here but just to make sure. */ 1783 if (!starting_directory) 1784 return NULL; 1785 1786 strcpy (apath, starting_directory); 1787 1788 dest = strchr (apath, '\0'); 1789 } 1790 else 1791 { 1792 apath[0] = '/'; 1793 dest = apath + 1; 1794 } 1795 1796 for (start = end = name; *start != '\0'; start = end) 1797 { 1798 unsigned long len; 1799 1800 /* Skip sequence of multiple path-separators. */ 1801 while (*start == '/') 1802 ++start; 1803 1804 /* Find end of path component. */ 1805 for (end = start; *end != '\0' && *end != '/'; ++end) 1806 ; 1807 1808 len = end - start; 1809 1810 if (len == 0) 1811 break; 1812 else if (len == 1 && start[0] == '.') 1813 /* nothing */; 1814 else if (len == 2 && start[0] == '.' && start[1] == '.') 1815 { 1816 /* Back up to previous component, ignore if at root already. */ 1817 if (dest > apath + 1) 1818 while ((--dest)[-1] != '/'); 1819 } 1820 else 1821 { 1822 if (dest[-1] != '/') 1823 *dest++ = '/'; 1824 1825 if (dest + len >= apath_limit) 1826 return NULL; 1827 1828 dest = memcpy (dest, start, len); 1829 dest += len; 1830 *dest = '\0'; 1831 } 1832 } 1833 1834 /* Unless it is root strip trailing separator. */ 1835 if (dest > apath + 1 && dest[-1] == '/') 1836 --dest; 1837 1838 *dest = '\0'; 1839 1840 return apath; 1841 } 1842 1843 1844 static char * 1845 func_realpath (char *o, char **argv, const char *funcname UNUSED) 1846 { 1847 /* Expand the argument. */ 1848 char *p = argv[0]; 1849 char *path = 0; 1850 int doneany = 0; 1851 unsigned int len = 0; 1852 PATH_VAR (in); 1853 PATH_VAR (out); 1854 1855 while ((path = find_next_token (&p, &len)) != 0) 1856 { 1857 if (len < GET_PATH_MAX) 1858 { 1859 strncpy (in, path, len); 1860 in[len] = '\0'; 1861 1862 if 1863 ( 1864 #ifdef HAVE_REALPATH 1865 realpath (in, out) 1866 #else 1867 abspath (in, out) 1868 #endif 1869 ) 1870 { 1871 o = variable_buffer_output (o, out, strlen (out)); 1872 o = variable_buffer_output (o, " ", 1); 1873 doneany = 1; 1874 } 1875 } 1876 } 1877 1878 /* Kill last space. */ 1879 if (doneany) 1880 --o; 1881 1882 return o; 1883 } 1884 1885 static char * 1886 func_abspath (char *o, char **argv, const char *funcname UNUSED) 1887 { 1888 /* Expand the argument. */ 1889 char *p = argv[0]; 1890 char *path = 0; 1891 int doneany = 0; 1892 unsigned int len = 0; 1893 PATH_VAR (in); 1894 PATH_VAR (out); 1895 1896 while ((path = find_next_token (&p, &len)) != 0) 1897 { 1898 if (len < GET_PATH_MAX) 1899 { 1900 strncpy (in, path, len); 1901 in[len] = '\0'; 1902 1903 if (abspath (in, out)) 1904 { 1905 o = variable_buffer_output (o, out, strlen (out)); 1906 o = variable_buffer_output (o, " ", 1); 1907 doneany = 1; 1908 } 1909 } 1910 } 1911 1912 /* Kill last space. */ 1913 if (doneany) 1914 --o; 1915 1916 return o; 1917 } 1918 1728 1919 /* Lookup table for builtin functions. 1729 1920 … … 1744 1935 { 1745 1936 /* Name/size */ /* MIN MAX EXP? Function */ 1937 { STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath}, 1746 1938 { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix}, 1747 1939 { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix}, … … 1756 1948 { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword}, 1757 1949 { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, 1950 { STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword}, 1758 1951 { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, 1952 { STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath}, 1759 1953 { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell}, 1760 1954 { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort}, … … 1767 1961 { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach}, 1768 1962 { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call}, 1963 { STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error}, 1769 1964 { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error}, 1770 1965 { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
Note:
See TracChangeset
for help on using the changeset viewer.