Further splits tokens from a command line using punctuation characters. Punctuation characters are treated as word breaks when they are in unquoted strings. Each run of punctuation characters is treated as a single token. :param tokens: the tokens as parsed by shlex
(self, tokens: list[str])
| 696 | return command, args |
| 697 | |
| 698 | def split_on_punctuation(self, tokens: list[str]) -> list[str]: |
| 699 | """Further splits tokens from a command line using punctuation characters. |
| 700 | |
| 701 | Punctuation characters are treated as word breaks when they are in |
| 702 | unquoted strings. Each run of punctuation characters is treated as a |
| 703 | single token. |
| 704 | |
| 705 | :param tokens: the tokens as parsed by shlex |
| 706 | :return: a new list of tokens, further split using punctuation |
| 707 | """ |
| 708 | # Using a set for faster lookups |
| 709 | punctuation = {*self.terminators, *constants.REDIRECTION_CHARS} |
| 710 | |
| 711 | punctuated_tokens = [] |
| 712 | |
| 713 | for cur_initial_token in tokens: |
| 714 | # Save tokens up to 1 character in length or quoted tokens. No need to parse these. |
| 715 | if len(cur_initial_token) <= 1 or cur_initial_token[0] in constants.QUOTES: |
| 716 | punctuated_tokens.append(cur_initial_token) |
| 717 | continue |
| 718 | |
| 719 | # Iterate over each character in this token |
| 720 | cur_index = 0 |
| 721 | cur_char = cur_initial_token[cur_index] |
| 722 | |
| 723 | # Keep track of the token we are building |
| 724 | new_token = "" |
| 725 | |
| 726 | while True: |
| 727 | if cur_char not in punctuation: |
| 728 | # Keep appending to new_token until we hit a punctuation char |
| 729 | while cur_char not in punctuation: |
| 730 | new_token += cur_char |
| 731 | cur_index += 1 |
| 732 | if cur_index < len(cur_initial_token): |
| 733 | cur_char = cur_initial_token[cur_index] |
| 734 | else: |
| 735 | break |
| 736 | |
| 737 | else: |
| 738 | cur_punc = cur_char |
| 739 | |
| 740 | # Keep appending to new_token until we hit something other than cur_punc |
| 741 | while cur_char == cur_punc: |
| 742 | new_token += cur_char |
| 743 | cur_index += 1 |
| 744 | if cur_index < len(cur_initial_token): |
| 745 | cur_char = cur_initial_token[cur_index] |
| 746 | else: |
| 747 | break |
| 748 | |
| 749 | # Save the new token |
| 750 | punctuated_tokens.append(new_token) |
| 751 | new_token = "" |
| 752 | |
| 753 | # Check if we've viewed all characters |
| 754 | if cur_index >= len(cur_initial_token): |
| 755 | break |
no test coverage detected