forked from mirrors/gecko-dev
		
	 ecb54845b0
			
		
	
	
		ecb54845b0
		
	
	
	
	
		
			
			# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D162668
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # This Source Code Form is subject to the terms of the Mozilla Public
 | |
| # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 | |
| # You can obtain one at http://mozilla.org/MPL/2.0/.
 | |
| import json
 | |
| import os
 | |
| import posixpath
 | |
| from os import PathLike
 | |
| 
 | |
| # `typing.Literal` not available until Python 3.8;
 | |
| # `typing_extensions` not generally available here
 | |
| from typing import Iterable, Set
 | |
| 
 | |
| FIRST_LINE = "// This file was generated by {}. DO NOT EDIT.".format(
 | |
|     # `posixpath` for forward slashes, for presentation purposes
 | |
|     posixpath.relpath(__file__, os.getenv("TOPSRCDIR", "/"))
 | |
| )
 | |
| 
 | |
| 
 | |
| def generate_allowed_items(
 | |
|     which: str,  # should be: Literal["files", "names"],
 | |
|     paths: Iterable[PathLike],
 | |
| ) -> str:
 | |
|     def remove_trailing_comment(s: str) -> str:
 | |
|         return s[0 : s.find("#")]
 | |
| 
 | |
|     def read_items_from_path(path: PathLike) -> Set[str]:
 | |
|         out = set()
 | |
|         with open(path) as file:
 | |
|             for line in file.readlines():
 | |
|                 line = remove_trailing_comment(line).strip()
 | |
|                 if not line:
 | |
|                     continue  # comment or empty line; discard
 | |
|                 out.add(line)
 | |
|         return out
 | |
| 
 | |
|     allowed = set().union(*(read_items_from_path(path) for path in paths))
 | |
|     # BUG: `json.dumps` may not correctly handle use of the quote character in
 | |
|     #   thread names
 | |
|     allowed_list_s = ",\n  ".join(json.dumps(elem) for elem in sorted(allowed))
 | |
| 
 | |
|     return f"""\
 | |
| static const char *allow_thread_{which}[] = {{
 | |
|   {allowed_list_s}
 | |
| }};"""
 | |
| 
 | |
| 
 | |
| def generate_allows(
 | |
|     *, allowed_names: Iterable[PathLike], allowed_files: Iterable[PathLike]
 | |
| ) -> str:
 | |
|     """
 | |
|     This function reads in the specified sets of files -- ordinarily,
 | |
|     ["ThreadAllows.txt"] and ["ThreadFileAllows.txt"] -- and generates the text
 | |
|     of a header file containing two arrays with their contents, for inclusion by
 | |
|     the thread-name checker.
 | |
| 
 | |
|     The checker will reject the creation of any thread via NS_NewNamedThread
 | |
|     unless either:
 | |
|       - the thread's name is a literal string which is found in the set of
 | |
|         allowed thread names; or
 | |
|       - the thread's creation occurs within a file which is found in the set of
 | |
|         unchecked files.
 | |
| 
 | |
|     The latter condition exists mostly for the definition of NS_NewNamedThread,
 | |
|     but there also exist a few cases where the thread name is dynamically
 | |
|     computed (and so can't be checked).
 | |
|     """
 | |
|     output_string = (
 | |
|         FIRST_LINE
 | |
|         + "\n\n"
 | |
|         + generate_allowed_items("files", allowed_files)
 | |
|         + "\n\n"
 | |
|         + generate_allowed_items("names", allowed_names)
 | |
|         + "\n"
 | |
|     )
 | |
|     return output_string
 | |
| 
 | |
| 
 | |
| # Entry point used by build/clang-plugin/moz.build (q.v.).
 | |
| def generate_file(output, allowed_names, allowed_files):
 | |
|     output.write(
 | |
|         generate_allows(allowed_names=[allowed_names], allowed_files=[allowed_files])
 | |
|     )
 |