- Timestamp:
- Apr 1, 2020 7:05:32 AM (5 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/incdep.c
r3316 r3318 1303 1303 */ 1304 1304 static const char * 1305 incdep_unescape_and_cache_filename(struct incdep *curdep, 1306 char *start, const char *end, const char **nextp) 1307 { 1308 int const is_dep = nextp == NULL; 1305 incdep_unescape_and_cache_filename(struct incdep *curdep, char *start, const char *end, 1306 int const is_dep, const char **nextp, unsigned int *linenop) 1307 { 1309 1308 unsigned const esc_mask = MAP_BLANK /* ' ' + '\t' */ 1310 1309 | MAP_COLON /* ':' */ … … 1316 1315 : MAP_PERCENT); /* '%' */ 1317 1316 unsigned const all_esc_mask = esc_mask | MAP_BLANK | MAP_NEWLINE; 1318 unsigned const stop_mask = nextp ? MAP_BLANK | MAP_NEWLINE | MAP_COLON: 0;1317 unsigned const stop_mask = nextp ? MAP_BLANK | MAP_NEWLINE | (!is_dep ? MAP_COLON : 0) : 0; 1319 1318 char volatile *src; 1320 1319 char volatile *dst; … … 1387 1386 else 1388 1387 { 1389 c onst char ch2 = *src++; /* No bounds checking to handle "/dir/file\ : ..." when end points at " :". */1388 char ch2 = *src++; /* No bounds checking to handle "/dir/file\ : ..." when end points at " :". */ 1390 1389 if (ch == '$') 1391 1390 { … … 1396 1395 else 1397 1396 { 1398 unsigned int const ch2_map = stopchar_map[(unsigned char)ch2]; 1397 unsigned int ch2_map; 1398 1399 /* Eat all the slashes and see what's at the end of them as that's all 1400 that's relevant. If there is an escapable char, we'll emit half of 1401 the slashes. */ 1402 size_t const max_slashes = src - start - 1; 1403 size_t slashes = 1; 1404 while (ch2 == '\\') 1405 { 1406 ch2 = *src++; 1407 slashes++; 1408 } 1409 1410 /* Is it escapable? */ 1411 ch2_map = stopchar_map[(unsigned char)ch2]; 1399 1412 if (ch2_map & all_esc_mask) 1400 1413 { 1401 /* Count preceeding slashes, unwind half of them regardless of odd/even count. */1402 size_t const max_slashes = src - start - 1;1403 size_t slashes = 1;1404 while (slashes < max_slashes && src[-2 - slashes] == '\\')1405 slashes++;1406 1407 1414 /* Non-whitespace is simple: Slash slashes, output or stop. */ 1408 1415 if (!(ch2_map & (MAP_BLANK | MAP_NEWLINE))) 1409 1416 { 1410 1417 assert(ch2_map & esc_mask); 1411 dst -= slashes / 2; 1412 if ((slashes & 1) || !(stop_mask & ch2_map)) 1418 while (slashes >= 2) 1419 { 1420 *dst++ = '\\'; 1421 slashes -= 2; 1422 } 1423 if (slashes || !(stop_mask & ch2_map)) 1413 1424 *dst++ = ch2; 1414 1425 else … … 1440 1451 if (ch3 == '\\' && src[1] == '\n') 1441 1452 src += 2; /* Escaped blank & newline joins into single space. */ 1442 else if (ch3 == '\\' && src[1] == '\r' && src[ 1] == '\n')1453 else if (ch3 == '\\' && src[1] == '\r' && src[2] == '\n') 1443 1454 src += 3; /* -> Join the escaped newline code below on the next line. */ 1455 else if (STOP_SET(ch3, stop_mask & MAP_NEWLINE)) 1456 { /* last thing on the line, no blanks to escape. */ 1457 while (slashes-- > 0) 1458 *dst++ = '\\'; 1459 break; 1460 } 1444 1461 else 1445 1462 { 1446 1463 src = src_saved; 1447 dst -= slashes / 2; 1448 if (slashes & 1) 1464 while (slashes >= 2) 1465 { 1466 *dst++ = '\\'; 1467 slashes -= 2; 1468 } 1469 if (slashes) 1449 1470 { 1450 1471 *dst++ = ch2; 1451 1472 continue; 1452 1473 } 1453 assert (nextp);1474 assert (nextp || (uintptr_t)src >= (uintptr_t)end); 1454 1475 break; 1455 1476 } … … 1464 1485 else 1465 1486 { 1466 assert (ch2_map & MAP_NEWLINE);1487 assert (ch2_map & MAP_NEWLINE); 1467 1488 if (ch2 == '\r' && *src == '\n') 1468 1489 src++; … … 1472 1493 for (;;) 1473 1494 { 1495 if (linenop) 1496 *linenop += 1; 1474 1497 while ((uintptr_t)src < (uintptr_t)end && ISBLANK(*src)) 1475 1498 src++; … … 1485 1508 if (ch3 == '\n') 1486 1509 src += 2; 1487 else if (ch3 == '\r' && src[ 1] == '\n')1510 else if (ch3 == '\r' && src[2] == '\n') 1488 1511 src += 3; 1489 1512 else … … 1491 1514 } 1492 1515 1493 if (!ch3 && is_dep) 1494 break; /* last thing on the line. */ 1495 dst -= slashes / 2; 1496 if (slashes & 1) 1516 if (is_dep && STOP_SET(ch3, stop_mask | MAP_NUL)) 1517 { /* last thing on the line, no blanks to escape. */ 1518 while (slashes-- > 0) 1519 *dst++ = '\\'; 1520 break; 1521 } 1522 while (slashes >= 2) 1523 { 1524 *dst++ = '\\'; 1525 slashes -= 2; 1526 } 1527 if (slashes) 1497 1528 *dst++ = ' '; 1498 1529 else 1499 1530 { 1500 assert (nextp);1531 assert (nextp || (uintptr_t)src >= (uintptr_t)end); 1501 1532 break; 1502 1533 } … … 1507 1538 { 1508 1539 src--; 1540 while (slashes-- > 0) 1541 *dst++ = '\\'; 1509 1542 *dst++ = ch; 1510 1543 } … … 1854 1887 1855 1888 /* Locate the next file colon. If it's not within the bounds of 1856 the current line, check that all new line chars are escaped, 1857 and simplify them while we're at it. */ 1889 the current line, check that all new line chars are escaped. */ 1858 1890 1859 1891 colonp = memchr (cur, ':', file_end - cur); … … 1878 1910 break; 1879 1911 } 1880 if ((uintptr_t)colonp >= (uintptr_t)eol) 1912 1913 if ((uintptr_t)colonp < (uintptr_t)eol) 1914 unescape_filename = memchr (cur, '\\', colonp - cur) != NULL 1915 || memchr (cur, '$', colonp - cur) != NULL; 1916 else if (memchr (eol, '=', colonp - eol)) 1881 1917 { 1882 const char *sol; 1883 1884 if (memchr (eol, '=', colonp - eol)) 1885 { 1886 incdep_warn (curdep, line_no, "multi line assignment / dependency confusion."); 1887 break; 1888 } 1889 1890 sol = cur; 1918 incdep_warn (curdep, line_no, "multi line assignment / dependency confusion."); 1919 break; 1920 } 1921 else 1922 { 1923 const char *sol = cur; 1891 1924 do 1892 1925 { … … 1900 1933 else 1901 1934 { 1902 eol2[0] = ' ';1903 eol2[1] = ' ';1904 if (eol2 != eol - 1)1905 eol2[2] = ' ';1906 1935 line_no++; 1907 1908 1936 sol = eol + 1; 1909 1937 eol = memchr (sol, '\n', colonp - sol); … … 1916 1944 if (!sol) 1917 1945 break; 1946 unescape_filename = 1; 1918 1947 } 1919 1948 … … 1928 1957 } 1929 1958 fnnext = cur; 1930 if ( !memchr (cur, '\\', fnend - cur) 1931 && !memchr (cur, '$', fnend - cur)) 1959 if (!unescape_filename) 1932 1960 { 1933 1961 while (fnnext != fnend && !ISBLANK (*fnnext)) … … 1936 1964 } 1937 1965 else 1938 { 1939 filename = incdep_unescape_and_cache_filename (curdep, (char *)fnnext, fnend, &fnnext); 1940 unescape_filename = 1; 1941 } 1966 filename = incdep_unescape_and_cache_filename (curdep, (char *)fnnext, fnend, 0, &fnnext, NULL); 1942 1967 1943 1968 /* parse any dependencies. */ … … 1945 1970 while ((uintptr_t)cur < (uintptr_t)file_end) 1946 1971 { 1972 const char *dep_file; 1973 1947 1974 /* skip blanks and count lines. */ 1948 while ((uintptr_t)cur < (uintptr_t)file_end && ISSPACE (*cur) && *cur != '\n') 1975 char ch = 0; 1976 while ((uintptr_t)cur < (uintptr_t)file_end && ISSPACE ((ch = *cur)) && ch != '\n') 1949 1977 ++cur; 1950 1978 if ((uintptr_t)cur >= (uintptr_t)file_end) 1951 1979 break; 1952 if ( *cur== '\n')1980 if (ch == '\n') 1953 1981 { 1954 1982 cur++; … … 1958 1986 1959 1987 /* continuation + eol? */ 1960 if ( *cur== '\\')1988 if (ch == '\\') 1961 1989 { 1962 1990 unsigned eol_len = (file_end - cur > 1 && cur[1] == '\n') ? 2 … … 1971 1999 } 1972 2000 1973 /* find the end of the filename */ 2001 /* find the end of the filename and cache it */ 2002 dep_file = NULL; 1974 2003 endp = cur; 1975 while ( (uintptr_t)endp < (uintptr_t)file_end 1976 && ( !ISSPACE (*endp) 1977 || (endp[-1] == '\\' && incdep_count_slashes_backwards(&endp[-1], cur) & 1))) 1978 ++endp; 2004 for (;;) 2005 if ((uintptr_t)endp < (uintptr_t)file_end) 2006 { 2007 ch = *endp; 2008 if (ch != '\\' && ch != '$' ) 2009 { 2010 if (!ISSPACE (ch)) 2011 endp++; 2012 else 2013 { 2014 dep_file = incdep_dep_strcache(curdep, cur, endp - cur); 2015 break; 2016 } 2017 } 2018 else 2019 { 2020 /* potential escape sequence, let the unescaper do the rest. */ 2021 dep_file = incdep_unescape_and_cache_filename (curdep, (char *)cur, file_end, 1, &endp, &line_no); 2022 break; 2023 } 2024 } 2025 else 2026 { 2027 dep_file = incdep_dep_strcache(curdep, cur, endp - cur); 2028 break; 2029 } 1979 2030 1980 2031 /* add it to the list. */ 1981 2032 *nextdep = dep = incdep_alloc_dep (curdep); 1982 2033 dep->includedep = 1; 1983 if ( !memchr (cur, '\\', endp - cur) 1984 && !memchr (cur, '$', endp - cur)) 1985 dep->name = incdep_dep_strcache(curdep, cur, endp - cur); 1986 else 1987 dep->name = incdep_unescape_and_cache_filename (curdep, (char *)cur, endp, NULL); 2034 dep->name = dep_file; 1988 2035 nextdep = &dep->next; 1989 2036 … … 2003 2050 if (fnnext == fnend) 2004 2051 break; 2052 if (*fnnext == '\\') 2053 { 2054 if (fnnext[1] == '\n') 2055 { 2056 line_no++; 2057 fnnext += 2; 2058 continue; 2059 } 2060 if (fnnext[1] == '\r' && fnnext[2] == '\n') 2061 { 2062 line_no++; 2063 fnnext += 3; 2064 continue; 2065 } 2066 } 2005 2067 2006 2068 if (!unescape_filename) … … 2012 2074 } 2013 2075 else 2014 filename = incdep_unescape_and_cache_filename (curdep, (char *)fnnext, fnend, &fnnext);2076 filename = incdep_unescape_and_cache_filename (curdep, (char *)fnnext, fnend, 0, &fnnext, NULL); 2015 2077 if (filename != filename_prev) /* clang optimization. */ 2016 2078 incdep_record_file (curdep, filename, incdep_dup_dep_list (curdep, deps), f); -
trunk/src/kmk/testcase-includedep-esc-sub.kmk
r3316 r3318 31 31 /phoney/header-file-with-two-spaces\ \ .h 32 32 33 34 # 35 # From example-spaces.kmk 36 # 37 /phoney-dep-ignore: 38 39 phoney\ space\ \ 1: /phoney-dep\ space\ \ 1 40 41 phoney\ colon\:\ 2: /phoney-dep\ colon\:\ 2 \ 42 43 phoney\ hash\#\ 3 : /phoney-dep\ hash\#\ 3 44 45 phoney\ dollar$$\ 4 : /phoney-dep\ dollar$$\ 4 \ 46 47 phoney\ slash-space\\\ 5: /phoney-dep\ slash-space\\\ 5 48 49 phoney\ slash-hash\\\#\ 6: /phoney-dep\ slash-hash\\\#\ 6 \ 50 51 phoney\ slash-slash-hash\\\\\#\ 7: /phoney-dep\ slash-slash-hash\\\\\#\ 7 52 53 phoney\ equal\=\ 8: /phoney-dep\ equal\=\ 8 54 55 phoney\ semI\;\ 9: /phoney-dep\ semi\;\ 9 56 57 # Note! The percent is only escaped on the target side! 58 phoney\ percent\%\ 10: /phoney-dep\ percent%\ 10 \ 59 60 # Note! The pipe is only escaped on the dependency list side! 61 phoney\ pipe|\ 11: /phoney-dep\ pipe\|\ 11 62 63 phoney\ plus+\ 12: \ 64 /phoney-dep\ plus+\ 12 65 66 phoney\ trailing-slash13\\: /phoney-dep\ trailing-slash13\ \ 67 68 phoney\ trailing-slash13b\\: /phoney-dep\ trailing-slash13b\ \ 69 \ 70 \ 71 \ 72 73 phoney\ trailing-slash14\\: \ 74 /phoney-dep\ trailing-slash14\\ \ 75 /phoney-dep-ignore 76 77 phoney\ 15-trailing-space\ : /phoney-dep\ 15-trailing-space\ /phoney-dep-ignore 78 79 # Note! No stripping spaces! Trailing space here that gets stripped instead of escaped. 80 phoney\ 16-no-trailing-space\\: /phoney-dep\ 16-no-trailing-space\ 81 82 phoney\ 17-3x-escaped-newlines\ becomes-single-space: /phoney-dep\ 17-3x-escaped-newlines\ \ 83 \ 84 \ 85 becomes-single-space 86 87 # Note! Must have a trailing space or comment. 88 phoney\ 18-3x-escaped-trailing-spaces-no-newline\ \ \\: \ 89 /phoney-dep\ 18-3x-escaped-trailing-spaces-no-newline\ \ \ 90 91 phoney\ 19-target-trailing-space-with-padding\ : /phoney-dep\ 19-target-trailing-space-with-padding\ /phoney-dep-ignore 92 93 phoney\ 20-target-trailing-space-with-newline-padding\ \ 94 \ 95 : /phoney-dep\ 20-target-trailing-space-with-newline-padding\ /phoney-dep-ignore 96 97 phoney\ 21-target-trailing-space-with-newline-padding-and-tail\ \ 98 \ 99 \ 100 \ 101 my-tail-21: /phoney-dep\ 21-target-trailing-space-with-newline-padding-and-tail\ \ 102 \ 103 \ 104 my-tail-21 105 106 107 all-trailing-slashes1: /phoney-dep\ trailing-slash13\ \ 108 109 all-trailing-slashes2: /phoney-dep\ trailing-slash13b\ \ 110 \ 111 \ 112 \ 113 -
trunk/src/kmk/testcase-includedep-esc.kmk
r3316 r3318 24 24 # 25 25 26 all_recursive: 27 $(ECHO) "includedep works fine" 28 29 # Include before header to avoid secondary expansion in the noraml 30 # include scenario. 31 ifndef USE_NORMAL_INCLUDE 32 includedep testcase-includedep-esc-sub.kmk 33 else 34 include testcase-includedep-esc-sub.kmk 35 endif 36 37 # We need the header for variables for special characters. 26 38 DEPTH = ../.. 27 39 include $(PATH_KBUILD)/header.kmk 28 40 29 includedep testcase-includedep-esc-sub.kmk30 41 42 ifneq ("$(deps-all /phoney/file-with-two-spaces .c)","/phoney/header-file-with-two-spaces .h") 43 $(error /phoney/file-with-two-spaces .c: $(deps-all /phoney/file-with-two-spaces .c)) 44 endif 31 45 32 all_recursive: 33 $(ECHO) "includedep works fine $(deps-all /phoney/file-with-two-spaces .c)" 46 ifneq ("$(deps-all phoney space 1)","/phoney-dep space 1") 47 $(error phoney space 1: $(deps-all phoney space 1)) 48 endif 34 49 50 ifneq ("$(deps-all phoney colon: 2)","/phoney-dep colon: 2") 51 $(error phoney colon: 2: $(deps-all phoney colon: 2)) 52 endif 53 54 ifneq ("$(deps-all phoney hash$(HASH) 3)","/phoney-dep hash$(HASH) 3") 55 $(error phoney hash$(HASH) 3: $(deps-all phoney hash$(HASH) 3)) 56 endif 57 58 ifeq ("$(deps-all phoney dollar$$ 4)","$/phoney-dep dollar$(DOLLAR) 4") 59 $(error phoney dollar$$ 4: $(deps-all phoney dollar$$ 4)) 60 endif 61 62 ifneq ("$(deps-all phoney slash-space\ 5)","/phoney-dep slash-space\ 5") 63 $(error phoney slash-space\ 5: $(deps-all phoney slash-space\ 5)) 64 endif 65 66 ifneq ("$(deps-all phoney slash-hash\$(HASH) 6)","/phoney-dep slash-hash\$(HASH) 6") 67 $(error phoney slash-hash\$(HASH) 6: $(deps-all phoney slash-hash\$(HASH) 6)) 68 endif 69 70 ifneq ("$(deps-all phoney slash-slash-hash\\$(HASH) 7)","/phoney-dep slash-slash-hash\\$(HASH) 7") 71 $(error phoney slash-slash-hash\\$(HASH) 7: $(deps-all phoney slash-slash-hash\\$(HASH) 7)) 72 endif 73 74 ifneq ("$(deps-all phoney equal= 8)","/phoney-dep equal= 8") 75 $(error phoney equal= 8: $(deps-all phoney equal= 8)) 76 endif 77 78 ifneq ("$(deps-all phoney semI; 9)","/phoney-dep semi; 9") 79 $(error phoney semI; 9: $(deps-all phoney semI; 9)) 80 endif 81 82 ifneq ("$(deps-all phoney percent% 10)","/phoney-dep percent% 10") 83 $(error phoney percent% 10: $(deps-all phoney percent% 10)) 84 endif 85 86 ifneq ("$(deps-all phoney pipe| 11)","/phoney-dep pipe| 11") 87 $(error phoney pipe| 11: $(deps-all phoney pipe| 11)) 88 endif 89 90 ifneq ("$(deps-all phoney plus+ 12)","/phoney-dep plus+ 12") 91 $(error phoney plus+ 12: $(deps-all phoney plus+ 12)) 92 endif 93 94 ifneq ("$(deps-all phoney trailing-slash13\)","/phoney-dep trailing-slash13\") 95 $(error phoney trailing-slash13\: $(deps-all phoney trailing-slash13\)) 96 endif 97 98 ifneq ("$(deps-all phoney trailing-slash13b\)","/phoney-dep trailing-slash13b\") 99 $(error phoney trailing-slash13b\: $(deps-all phoney trailing-slash13b\)) 100 endif 101 102 ifneq ("$(deps-all phoney trailing-slash14\)","/phoney-dep trailing-slash14\ /phoney-dep-ignore") 103 $(error phoney trailing-slash14\: $(deps-all phoney trailing-slash14\)) 104 endif 105 106 ifneq ("$(deps-all phoney 15-trailing-space )","/phoney-dep 15-trailing-space /phoney-dep-ignore") 107 $(error phoney 15-trailing-space : $(deps-all phoney 15-trailing-space )) 108 endif 109 110 ifneq ("$(deps-all phoney 16-no-trailing-space\)","/phoney-dep 16-no-trailing-space\") 111 $(error phoney 16-no-trailing-space\: $(deps-all phoney 16-no-trailing-space\)) 112 endif 113 114 ifneq ("$(deps-all phoney 17-3x-escaped-newlines becomes-single-space)","/phoney-dep 17-3x-escaped-newlines becomes-single-space") 115 $(error phoney 17-3x-escaped-newlines becomes-single-space: $(deps-all phoney 17-3x-escaped-newlines becomes-single-space)) 116 endif 117 118 ifneq ("$(deps-all phoney 18-3x-escaped-trailing-spaces-no-newline \)","/phoney-dep 18-3x-escaped-trailing-spaces-no-newline \") 119 $(error phoney 18-3x-escaped-trailing-spaces-no-newline \: $(deps-all phoney 18-3x-escaped-trailing-spaces-no-newline \)) 120 endif 121 122 ifneq ("$(deps-all phoney 19-target-trailing-space-with-padding )","/phoney-dep 19-target-trailing-space-with-padding /phoney-dep-ignore") 123 $(error phoney 19-target-trailing-space-with-padding : $(deps-all phoney 19-target-trailing-space-with-padding )) 124 endif 125 126 ifneq ("$(deps-all phoney 20-target-trailing-space-with-newline-padding )","/phoney-dep 20-target-trailing-space-with-newline-padding /phoney-dep-ignore") 127 $(error phoney 20-target-trailing-space-with-newline-padding : $(deps-all phoney 20-target-trailing-space-with-newline-padding )) 128 endif 129 130 ifneq ("$(deps-all phoney 21-target-trailing-space-with-newline-padding-and-tail my-tail-21)","/phoney-dep 21-target-trailing-space-with-newline-padding-and-tail my-tail-21") 131 $(error 21-target-trailing-space-with-newline-padding-and-tail my-tail-21: $(deps-all 21-target-trailing-space-with-newline-padding-and-tail my-tail-21)) 132 endif 133
Note:
See TracChangeset
for help on using the changeset viewer.