VirtualBox

Changeset 2744 in kBuild for trunk/src/kmk/incdep.c


Ignore:
Timestamp:
Dec 27, 2014 9:01:58 PM (10 years ago)
Author:
bird
Message:

kmk/incdep.c: Implemented support for multiple files on the left side of the colon to deal with what clang produces.

File:
1 edited

Legend:

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

    r2591 r2744  
    299299  return alloccache_calloc (cache);
    300300}
     301
     302/* duplicates the dependency list pointed to by srcdep. */
     303static struct dep *
     304incdep_dup_dep_list (struct incdep *cur, struct dep const *srcdep)
     305{
     306  struct alloccache *cache;
     307  struct dep *retdep;
     308  struct dep *dstdep;
     309
     310  if (cur->worker_tid != -1)
     311    cache = &incdep_dep_caches[cur->worker_tid];
     312  else
     313    cache = &dep_cache;
     314
     315  if (srcdep)
     316    {
     317      retdep = dstdep = alloccache_alloc (cache);
     318      for (;;)
     319        {
     320          dstdep->name = srcdep->name; /* string cached */
     321          dstdep->includedep = srcdep->includedep;
     322          srcdep = srcdep->next;
     323          if (!srcdep)
     324            {
     325              dstdep->next = NULL;
     326              break;
     327            }
     328          dstdep->next = alloccache_alloc (cache);
     329          dstdep = dstdep->next;
     330        }
     331    }
     332  else
     333    retdep = NULL;
     334  return retdep;
     335}
     336
    301337
    302338/* allocate a record. */
     
    756792          if (rc)
    757793            fatal (f, _("pthread_attr_setdetachstate failed: err=%d"), rc);
    758           rc = pthread_create(&incdep_threads[i], &attr,
     794          rc = pthread_create (&incdep_threads[i], &attr,
    759795                               incdep_worker_pthread, (void *)(size_t)i);
    760796          if (rc)
     
    846882  struct incdep_variable_def *rec_vd;
    847883  struct incdep_recorded_file *rec_f;
     884
     885  /* Display saved error. */
     886
     887  if (cur->err_msg)
     888    error(NILF, "%s(%d): %s", cur->name, cur->err_line_no, cur->err_msg);
     889
    848890
    849891  /* define_variable_in_set */
     
    13171359      else
    13181360        {
    1319           const char *colonp;
    13201361          const char *equalp;
    1321 
    1322           /* Look for a colon and an equal sign, optimize for colon.
    1323              Only one file is support and the colon / equal must be on
    1324              the same line. */
    1325           colonp = memchr (cur, ':', file_end - cur);
    1326 #ifdef HAVE_DOS_PATHS
    1327           while (   colonp
    1328                  && colonp + 1 < file_end
    1329                  && (colonp[1] == '/' || colonp[1] == '\\')
    1330                  && colonp > cur
    1331                  && isalpha ((unsigned char)colonp[-1])
    1332                  && (   colonp == cur + 1
    1333                      || strchr (" \t(", colonp[-2]) != 0))
    1334               colonp = memchr (colonp + 1, ':', file_end - (colonp + 1));
    1335 #endif
    1336           endp = NULL;
    1337           if (   !colonp
    1338               ||  (endp = memchr (cur, '\n', colonp - cur)))
    1339             {
    1340               colonp = NULL;
    1341               equalp = memchr (cur, '=', (endp ? endp : file_end) - cur);
    1342               if (   !equalp
    1343                   || (!endp && memchr (cur, '\n', equalp - cur)))
    1344                 {
    1345                   incdep_warn (curdep, line_no, "no colon.");
    1346                   break;
    1347                 }
    1348             }
    1349           else
    1350             equalp = memchr (cur, '=', (colonp + 2 <= file_end
    1351                                         ? colonp + 2 : file_end) - cur);
     1362          const char *eol;
     1363
     1364          /* Look for a colon or and equal sign.  In the assignment case, we
     1365             require it to be on the same line as the variable name to simplify
     1366             the code.  Because of clang, we cannot make the same assumptions
     1367             with file dependencies.  So, start with the equal. */
     1368
     1369          assert (*cur != '\n');
     1370          eol = memchr (cur, '\n', file_end - cur);
     1371          if (!eol)
     1372            eol = file_end;
     1373          equalp = memchr (cur, '=', eol - cur);
    13521374          if (equalp)
    13531375            {
     
    14861508          else
    14871509            {
    1488               /* file: dependencies */
     1510              /* Expecting: file: dependencies */
    14891511
    14901512              const char *filename;
     1513              const char *fnnext;
     1514              const char *fnend;
     1515              const char *colonp;
    14911516              struct dep *deps = 0;
    14921517              struct dep **nextdep = &deps;
    14931518              struct dep *dep;
    14941519
    1495               /* extract the filename, ASSUME a single one. */
    1496               endp = colonp;
    1497               while (endp > cur && isblank ((unsigned char)endp[-1]))
    1498                 --endp;
    1499               if (cur == endp)
     1520
     1521              /* Locate the next file colon.  If it's not within the bounds of
     1522                 the current line, check that all new line chars are escaped,
     1523                 and simplify them while we're at it. */
     1524
     1525              colonp = memchr (cur, ':', file_end - cur);
     1526#ifdef HAVE_DOS_PATHS
     1527              while (   colonp
     1528                     && colonp + 1 < file_end
     1529                     && (colonp[1] == '/' || colonp[1] == '\\')
     1530                     && colonp > cur
     1531                     && isalpha ((unsigned char)colonp[-1])
     1532                     && (   colonp == cur + 1
     1533                         || strchr (" \t(", colonp[-2]) != 0))
     1534                  colonp = memchr (colonp + 1, ':', file_end - (colonp + 1));
     1535#endif
     1536              if (!colonp)
     1537                {
     1538                  incdep_warn (curdep, line_no, "no colon.");
     1539                  break;
     1540                }
     1541              if ((uintptr_t)colonp >= (uintptr_t)eol)
     1542                {
     1543                  const char *sol;
     1544
     1545                  if (memchr (eol, '=', colonp - eol))
     1546                    {
     1547                      incdep_warn (curdep, line_no, "multi line assignment / dependency confusion.");
     1548                      break;
     1549                    }
     1550
     1551                  sol = cur;
     1552                  do
     1553                    {
     1554                      char *eol2 = (char *)eol - 1;
     1555                      if ((uintptr_t)eol2 >= (uintptr_t)sol && *eol2 == '\r') /* DOS line endings. */
     1556                        eol2--;
     1557                      if ((uintptr_t)eol2 < (uintptr_t)sol || *eol2 != '\\')
     1558                          incdep_warn (curdep, line_no, "no colon.");
     1559                      else if (eol2 != sol && eol2[-1] == '\\')
     1560                          incdep_warn (curdep, line_no, "fancy EOL escape. (includedep)");
     1561                      else
     1562                        {
     1563                          eol2[0] = ' ';
     1564                          eol2[1] = ' ';
     1565                          if (eol2 != eol - 1)
     1566                            eol2[2] = ' ';
     1567                          line_no++;
     1568
     1569                          sol = eol + 1;
     1570                          eol = memchr (sol, '\n', colonp - sol);
     1571                          continue;
     1572                        }
     1573                      sol = NULL;
     1574                      break;
     1575                    }
     1576                  while (eol != NULL);
     1577                  if (!sol)
     1578                    break;
     1579                }
     1580
     1581              /* Extract the first filename after trimming and basic checks. */
     1582              fnend = colonp;
     1583              while ((uintptr_t)fnend > (uintptr_t)cur && isblank ((unsigned char)fnend[-1]))
     1584                --fnend;
     1585              if (cur == fnend)
    15001586                {
    15011587                  incdep_warn (curdep, line_no, "empty filename.");
    15021588                  break;
    15031589                }
    1504               if (   memchr (cur, '$', endp - cur)
    1505                   || memchr (cur, ' ', endp - cur)
    1506                   || memchr (cur, '\t', endp - cur))
     1590              if (memchr (cur, '$', fnend - cur))
    15071591                {
    1508                   incdep_warn (curdep, line_no, "multiple / fancy file name. (includedep)");
     1592                  incdep_warn (curdep, line_no, "fancy file name. (includedep)");
    15091593                  break;
    15101594                }
    1511               filename = incdep_dep_strcache (curdep, cur, endp - cur);
     1595
     1596              fnnext = cur;
     1597              while (fnnext != fnend && !isblank ((unsigned char)*fnnext))
     1598                fnnext++;
     1599              filename = incdep_dep_strcache (curdep, cur, fnnext - cur);
    15121600
    15131601              /* parse any dependencies. */
     
    15571645              /* enter the file with its dependencies. */
    15581646              incdep_record_file (curdep, filename, deps, f);
     1647
     1648              /* More files? Record them with the same dependency list. */
     1649              if (fnnext != fnend)
     1650                for (;;)
     1651                  {
     1652                    const char *filename_prev = filename;
     1653                    const char *fnstart;
     1654                    while (fnnext != fnend && isblank ((unsigned char)*fnnext))
     1655                      fnnext++;
     1656                    if (fnnext == fnend)
     1657                      break;
     1658
     1659                    fnstart = fnnext;
     1660                    while (fnnext != fnend && !isblank ((unsigned char)*fnnext))
     1661                      fnnext++;
     1662
     1663                    filename = incdep_dep_strcache (curdep, fnstart, fnnext - fnstart);
     1664                    if (filename != filename_prev) /* clang optimization. */
     1665                      incdep_record_file (curdep, filename, incdep_dup_dep_list (curdep, deps), f);
     1666                  }
    15591667            }
    15601668        }
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