diff options
Diffstat (limited to 'pw_emu/py/pw_emu/core.py')
-rw-r--r-- | pw_emu/py/pw_emu/core.py | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/pw_emu/py/pw_emu/core.py b/pw_emu/py/pw_emu/core.py index b563d6093..1e5c2ea9f 100644 --- a/pw_emu/py/pw_emu/core.py +++ b/pw_emu/py/pw_emu/core.py @@ -349,6 +349,34 @@ class Config: def get_targets(self) -> List[str]: return list(self.get(['targets'], entry_type=dict).keys()) + def _subst(self, string: str) -> str: + """Substitutes $pw_<subst_type>{arg} statements.""" + + match = re.search(r'\$pw_([^{]+){([^}]+)}', string) + if not match: + return string + + subst_type = match.group(1) + arg = match.group(2) + + if subst_type == 'env': + value = os.environ.get(arg) + if value is None: + msg = f'Environment variable `{arg}` not set' + raise ConfigError(self.path, msg) + return string.replace(f'$pw_{subst_type}{{{arg}}}', value) + + raise ConfigError(self.path, f'Invalid substitution type: {subst_type}') + + def _subst_list(self, items: List[Any]) -> List[Any]: + new_list = [] + for item in items: + if isinstance(item, str): + new_list.append(self._subst(item)) + else: + new_list.append(item) + return new_list + def get( self, keys: List[str], @@ -383,15 +411,22 @@ class Config: raise ConfigError(self.path, f'{keys_str}: not found') entry = entry.get(key) - if not entry: - if entry_type: - return entry_type() - return entry + if entry is None: + if optional: + if entry_type: + return entry_type() + return None + raise ConfigError(self.path, f'{keys_str}: not found') if entry_type and not isinstance(entry, entry_type): msg = f'{keys_str}: expected entry of type `{entry_type}`' raise ConfigError(self.path, msg) + if isinstance(entry, str): + entry = self._subst(entry) + elif isinstance(entry, list): + entry = self._subst_list(entry) + return entry def get_target( @@ -755,8 +790,11 @@ class Launcher(ABC): os._exit(0) try: - with open(self._path(f'{name}.pid'), 'w') as file: + # Make the pid file create and pid write operations atomic to avoid + # races with readers. + with open(self._path(f'{name}.pid.tmp'), 'w') as file: file.write(f'{os.getpid()}') + os.rename(self._path(f'{name}.pid.tmp'), self._path(f'{name}.pid')) os.execvp(cmd[0], cmd) finally: os._exit(1) |