VirtualBox

Changeset 3318 in kBuild for trunk/src


Ignore:
Timestamp:
Apr 1, 2020 7:05:32 AM (5 years ago)
Author:
bird
Message:

kmk/incdep.c: Unescaping.

Location:
trunk/src/kmk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/incdep.c

    r3316 r3318  
    13031303   */
    13041304static 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;
     1305incdep_unescape_and_cache_filename(struct incdep *curdep, char *start, const char *end,
     1306                                   int const is_dep, const char **nextp, unsigned int *linenop)
     1307{
    13091308  unsigned const esc_mask = MAP_BLANK        /*  ' ' + '\t' */
    13101309                          | MAP_COLON        /* ':' */
     
    13161315                             : MAP_PERCENT); /* '%' */
    13171316  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;
    13191318  char volatile *src;
    13201319  char volatile *dst;
     
    13871386      else
    13881387        {
    1389           const 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 " :". */
    13901389          if (ch == '$')
    13911390            {
     
    13961395          else
    13971396            {
    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];
    13991412              if (ch2_map & all_esc_mask)
    14001413                {
    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 
    14071414                  /* Non-whitespace is simple: Slash slashes, output or stop. */
    14081415                  if (!(ch2_map & (MAP_BLANK | MAP_NEWLINE)))
    14091416                    {
    14101417                      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))
    14131424                        *dst++ = ch2;
    14141425                      else
     
    14401451                          if (ch3 == '\\' && src[1] == '\n')
    14411452                            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')
    14431454                            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                            }
    14441461                          else
    14451462                            {
    14461463                              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)
    14491470                                {
    14501471                                  *dst++ = ch2;
    14511472                                  continue;
    14521473                                }
    1453                               assert(nextp);
     1474                              assert (nextp || (uintptr_t)src >= (uintptr_t)end);
    14541475                              break;
    14551476                            }
     
    14641485                      else
    14651486                        {
    1466                           assert(ch2_map & MAP_NEWLINE);
     1487                          assert (ch2_map & MAP_NEWLINE);
    14671488                          if (ch2 == '\r' && *src == '\n')
    14681489                            src++;
     
    14721493                      for (;;)
    14731494                        {
     1495                          if (linenop)
     1496                            *linenop += 1;
    14741497                          while ((uintptr_t)src < (uintptr_t)end && ISBLANK(*src))
    14751498                            src++;
     
    14851508                          if (ch3 == '\n')
    14861509                            src += 2;
    1487                           else if (ch3 == '\r' && src[1] == '\n')
     1510                          else if (ch3 == '\r' && src[2] == '\n')
    14881511                            src += 3;
    14891512                          else
     
    14911514                        }
    14921515
    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)
    14971528                        *dst++ = ' ';
    14981529                      else
    14991530                        {
    1500                           assert(nextp);
     1531                          assert (nextp || (uintptr_t)src >= (uintptr_t)end);
    15011532                          break;
    15021533                        }
     
    15071538                {
    15081539                  src--;
     1540                  while (slashes-- > 0)
     1541                    *dst++ = '\\';
    15091542                  *dst++ = ch;
    15101543                }
     
    18541887
    18551888              /* 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. */
    18581890
    18591891              colonp = memchr (cur, ':', file_end - cur);
     
    18781910                  break;
    18791911                }
    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))
    18811917                {
    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;
    18911924                  do
    18921925                    {
     
    19001933                      else
    19011934                        {
    1902                           eol2[0] = ' ';
    1903                           eol2[1] = ' ';
    1904                           if (eol2 != eol - 1)
    1905                             eol2[2] = ' ';
    19061935                          line_no++;
    1907 
    19081936                          sol = eol + 1;
    19091937                          eol = memchr (sol, '\n', colonp - sol);
     
    19161944                  if (!sol)
    19171945                    break;
     1946                  unescape_filename = 1;
    19181947                }
    19191948
     
    19281957                }
    19291958              fnnext = cur;
    1930               if (   !memchr (cur, '\\', fnend - cur)
    1931                   && !memchr (cur, '$', fnend - cur))
     1959              if (!unescape_filename)
    19321960                {
    19331961                  while (fnnext != fnend && !ISBLANK (*fnnext))
     
    19361964                }
    19371965              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);
    19421967
    19431968              /* parse any dependencies. */
     
    19451970              while ((uintptr_t)cur < (uintptr_t)file_end)
    19461971                {
     1972                  const char *dep_file;
     1973
    19471974                  /* 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')
    19491977                    ++cur;
    19501978                  if ((uintptr_t)cur >= (uintptr_t)file_end)
    19511979                    break;
    1952                   if (*cur == '\n')
     1980                  if (ch == '\n')
    19531981                    {
    19541982                      cur++;
     
    19581986
    19591987                  /* continuation + eol? */
    1960                   if (*cur == '\\')
     1988                  if (ch == '\\')
    19611989                    {
    19621990                      unsigned eol_len = (file_end - cur > 1 && cur[1] == '\n') ? 2
     
    19711999                    }
    19722000
    1973                   /* find the end of the filename */
     2001                  /* find the end of the filename and cache it */
     2002                  dep_file = NULL;
    19742003                  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                      }
    19792030
    19802031                  /* add it to the list. */
    19812032                  *nextdep = dep = incdep_alloc_dep (curdep);
    19822033                  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;
    19882035                  nextdep = &dep->next;
    19892036
     
    20032050                    if (fnnext == fnend)
    20042051                      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                      }
    20052067
    20062068                    if (!unescape_filename)
     
    20122074                      }
    20132075                    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);
    20152077                    if (filename != filename_prev) /* clang optimization. */
    20162078                      incdep_record_file (curdep, filename, incdep_dup_dep_list (curdep, deps), f);
  • trunk/src/kmk/testcase-includedep-esc-sub.kmk

    r3316 r3318  
    3131                /phoney/header-file-with-two-spaces\ \ .h
    3232
     33
     34#
     35# From example-spaces.kmk
     36#
     37/phoney-dep-ignore:
     38
     39phoney\ space\ \ 1: /phoney-dep\ space\ \ 1
     40
     41phoney\ colon\:\ 2: /phoney-dep\ colon\:\ 2 \
     42
     43phoney\ hash\#\ 3 : /phoney-dep\ hash\#\ 3
     44
     45phoney\ dollar$$\ 4 : /phoney-dep\ dollar$$\ 4 \
     46
     47phoney\ slash-space\\\ 5: /phoney-dep\ slash-space\\\ 5
     48
     49phoney\ slash-hash\\\#\ 6: /phoney-dep\ slash-hash\\\#\ 6 \
     50
     51phoney\ slash-slash-hash\\\\\#\ 7:  /phoney-dep\ slash-slash-hash\\\\\#\ 7
     52
     53phoney\ equal\=\ 8: /phoney-dep\ equal\=\ 8
     54
     55phoney\ semI\;\ 9: /phoney-dep\ semi\;\ 9
     56
     57# Note! The percent is only escaped on the target side!
     58phoney\ percent\%\ 10:  /phoney-dep\ percent%\ 10 \
     59
     60# Note! The pipe is only escaped on the dependency list side!
     61phoney\ pipe|\ 11: /phoney-dep\ pipe\|\ 11   
     62
     63phoney\ plus+\ 12: \
     64        /phoney-dep\ plus+\ 12
     65
     66phoney\ trailing-slash13\\: /phoney-dep\ trailing-slash13\ \
     67
     68phoney\ trailing-slash13b\\: /phoney-dep\ trailing-slash13b\ \
     69        \
     70        \
     71        \
     72
     73phoney\ trailing-slash14\\: \
     74        /phoney-dep\ trailing-slash14\\ \
     75        /phoney-dep-ignore
     76
     77phoney\ 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.
     80phoney\ 16-no-trailing-space\\: /phoney-dep\ 16-no-trailing-space\
     81
     82phoney\ 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.
     88phoney\ 18-3x-escaped-trailing-spaces-no-newline\ \ \\: \
     89        /phoney-dep\ 18-3x-escaped-trailing-spaces-no-newline\ \ \
     90
     91phoney\ 19-target-trailing-space-with-padding\   : /phoney-dep\ 19-target-trailing-space-with-padding\  /phoney-dep-ignore
     92
     93phoney\ 20-target-trailing-space-with-newline-padding\   \
     94\
     95: /phoney-dep\ 20-target-trailing-space-with-newline-padding\  /phoney-dep-ignore
     96
     97phoney\ 21-target-trailing-space-with-newline-padding-and-tail\ \
     98\
     99 \
     100                \
     101my-tail-21: /phoney-dep\ 21-target-trailing-space-with-newline-padding-and-tail\ \
     102\
     103\
     104my-tail-21
     105
     106
     107all-trailing-slashes1: /phoney-dep\ trailing-slash13\ \
     108
     109all-trailing-slashes2: /phoney-dep\ trailing-slash13b\ \
     110        \
     111        \
     112        \
     113
  • trunk/src/kmk/testcase-includedep-esc.kmk

    r3316 r3318  
    2424#
    2525
     26all_recursive:
     27        $(ECHO) "includedep works fine"
     28
     29# Include before header to avoid secondary expansion in the noraml
     30# include scenario.
     31ifndef USE_NORMAL_INCLUDE
     32includedep testcase-includedep-esc-sub.kmk
     33else
     34include testcase-includedep-esc-sub.kmk
     35endif
     36
     37# We need the header for variables for special characters.
    2638DEPTH = ../..
    2739include $(PATH_KBUILD)/header.kmk
    2840
    29 includedep testcase-includedep-esc-sub.kmk
    3041
     42ifneq ("$(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))
     44endif
    3145
    32 all_recursive:
    33         $(ECHO) "includedep works fine $(deps-all /phoney/file-with-two-spaces  .c)"
     46ifneq ("$(deps-all phoney space  1)","/phoney-dep space  1")
     47$(error phoney space  1: $(deps-all phoney space  1))
     48endif
    3449
     50ifneq ("$(deps-all phoney colon: 2)","/phoney-dep colon: 2")
     51$(error phoney colon: 2: $(deps-all phoney colon: 2))
     52endif
     53
     54ifneq ("$(deps-all phoney hash$(HASH) 3)","/phoney-dep hash$(HASH) 3")
     55$(error phoney hash$(HASH) 3: $(deps-all phoney hash$(HASH) 3))
     56endif
     57
     58ifeq ("$(deps-all phoney dollar$$ 4)","$/phoney-dep dollar$(DOLLAR) 4")
     59$(error phoney dollar$$ 4: $(deps-all phoney dollar$$ 4))
     60endif
     61
     62ifneq ("$(deps-all phoney slash-space\ 5)","/phoney-dep slash-space\ 5")
     63$(error phoney slash-space\ 5: $(deps-all phoney slash-space\ 5))
     64endif
     65
     66ifneq ("$(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))
     68endif
     69
     70ifneq ("$(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))
     72endif
     73
     74ifneq ("$(deps-all phoney equal= 8)","/phoney-dep equal= 8")
     75$(error phoney equal= 8: $(deps-all phoney equal= 8))
     76endif
     77
     78ifneq ("$(deps-all phoney semI; 9)","/phoney-dep semi; 9")
     79$(error phoney semI; 9: $(deps-all phoney semI; 9))
     80endif
     81
     82ifneq ("$(deps-all phoney percent% 10)","/phoney-dep percent% 10")
     83$(error phoney percent% 10: $(deps-all phoney percent% 10))
     84endif
     85
     86ifneq ("$(deps-all phoney pipe| 11)","/phoney-dep pipe| 11")
     87$(error phoney pipe| 11: $(deps-all phoney pipe| 11))
     88endif
     89
     90ifneq ("$(deps-all phoney plus+ 12)","/phoney-dep plus+ 12")
     91$(error phoney plus+ 12: $(deps-all phoney plus+ 12))
     92endif
     93
     94ifneq ("$(deps-all phoney trailing-slash13\)","/phoney-dep trailing-slash13\")
     95$(error phoney trailing-slash13\: $(deps-all phoney trailing-slash13\))
     96endif
     97
     98ifneq ("$(deps-all phoney trailing-slash13b\)","/phoney-dep trailing-slash13b\")
     99$(error phoney trailing-slash13b\: $(deps-all phoney trailing-slash13b\))
     100endif
     101
     102ifneq ("$(deps-all phoney trailing-slash14\)","/phoney-dep trailing-slash14\ /phoney-dep-ignore")
     103$(error phoney trailing-slash14\: $(deps-all phoney trailing-slash14\))
     104endif
     105
     106ifneq ("$(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 ))
     108endif
     109
     110ifneq ("$(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\))
     112endif
     113
     114ifneq ("$(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))
     116endif
     117
     118ifneq ("$(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  \))
     120endif
     121
     122ifneq ("$(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 ))
     124endif
     125
     126ifneq ("$(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 ))
     128endif
     129
     130ifneq ("$(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))
     132endif
     133
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette