| 73 | """ |
| 74 | |
| 75 | def __init__( |
| 76 | self, |
| 77 | s, |
| 78 | store, |
| 79 | distro: str | None = None, |
| 80 | release: str | None = None, |
| 81 | distro_preference: list[tuple[str, str]] | None = None, |
| 82 | ): |
| 83 | self.s = s |
| 84 | self.store = store |
| 85 | self.distro = distro |
| 86 | self.release = release |
| 87 | self._distro_preference = distro_preference or [] |
| 88 | self._anchored = False |
| 89 | self._prev_option = self._current_option = None |
| 90 | self.groups = [MatchGroup("shell")] |
| 91 | |
| 92 | # a list of `match_word_exp` where expansions happened during word |
| 93 | # expansion |
| 94 | self.expansions = [] |
| 95 | |
| 96 | # a stack to manage nested command groups: whenever a new simple |
| 97 | # command is started, we push a tuple with: |
| 98 | # - the node that started this group. this is used to find it when |
| 99 | # a command ends (see visitnodeend) |
| 100 | # - its `MatchGroup`. new `MatchResult`s will be added to it. |
| 101 | # - a word used to end the top-most command. this is used when a flag |
| 102 | # starts a new command, e.g. find -exec. |
| 103 | self.group_stack = [(None, self.groups[-1], None)] |
| 104 | |
| 105 | # keep a stack of the currently visited compound command (if/for..) |
| 106 | # to provide context when matching reserved words, since for example |
| 107 | # the keyword 'done' can appear in a for, while.. |
| 108 | self.compound_stack = [] |
| 109 | |
| 110 | # a set of functions defined in the current input, we will try to match |
| 111 | # commands against them so if one refers to defined function, it won't |
| 112 | # show up as unknown or be taken from the db |
| 113 | self.functions = set() |
| 114 | |
| 115 | def _generate_cmd_group_name(self): |
| 116 | existing = len([g for g in self.groups if g.name.startswith("command")]) |