tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ar.star (2532B)


      1 # -*- bazel-starlark -*-
      2 # Copyright 2024 The Chromium Authors
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 """Siso configuration for ar."""
      6 
      7 load("@builtin//path.star", "path")
      8 load("@builtin//struct.star", "module")
      9 
     10 # https://en.wikipedia.org/wiki/Ar_(Unix)
     11 
     12 def __file_header(fname, size):
     13     fid = fname + " " * 16
     14     header = fid[:16]
     15     if fname == "//":
     16         header += " " * 12  # file modification timestamp
     17         header += " " * 6  # owner id
     18         header += " " * 6  # group id
     19         header += " " * 8  # file mode
     20     else:
     21         header += "0" + " " * 11  # file modification timestamp
     22         header += "0" + " " * 5  # owner id
     23         header += "0" + " " * 5  # group id
     24         header += "644" + " " * 5  # file mode
     25     s = ("%d" % size) + " " * 10
     26     header += s[:10]  # file size
     27     header += "\x60\n"  # header trailer string
     28     return header
     29 
     30 def __ref_fname(offset, fname):
     31     i = offset[fname]
     32     return "/%d" % i
     33 
     34 def __padding(data):
     35     if len(data) % 2 == 0:
     36         return data
     37     return data + "\n"
     38 
     39 def __ar_create(ctx, wd, ins):
     40     """Creates a thin archive without a symbol table."""
     41     data = "!<thin>\n"
     42     offset = {}
     43     content = ""
     44     for fname in ins:
     45         offset[fname] = len(content)
     46         content += path.rel(wd, fname) + "/\n"
     47     content = __padding(content)
     48     data += __file_header("//", len(content))
     49     data += content
     50     for fname in ins:
     51         size = ctx.fs.size(fname)
     52         if size:
     53             data += __file_header(__ref_fname(offset, fname), size)
     54     return bytes(data)
     55 
     56 def __ar_entries(ctx, fname, build_dir):
     57     """Read entries from a thin archive. """
     58 
     59     # TODO: It may take long time to read an entire archive.
     60     # Is it better to read only the first X bytes?
     61     lines = str(ctx.fs.read(fname)).splitlines()
     62     lib_dir = path.rel(build_dir, path.dir(fname))
     63     ents = []
     64     if not len(lines):
     65         print("warning: empty archive. `%s`" % fname)
     66         return []
     67     if not lines[0].startswith("!<thin>"):
     68         print("not thin archive. `%s`" % fname)
     69         return []
     70     for l in lines:
     71         l.strip()
     72         if l.endswith(".obj/") or l.endswith(".o/"):
     73             ents.append(path.join(lib_dir, l.removesuffix("/")))
     74         if l.endswith(".lib/") or l.endswith(".a/"):
     75             fail("nested archive is not supported, yet. found `%s` in `%s`" % (l, fname))
     76     return ents
     77 
     78 ar = module(
     79     "ar",
     80     create = __ar_create,
     81     entries = __ar_entries,
     82 )