Escapes command line arguments for MSVS. The VCProj format stores string lists in a single string using commas and semi-colons as separators, which must be quoted if they are to be interpreted literally. However, command-line arguments may already have quotes, and the VCProj parser
(s)
| 791 | |
| 792 | |
| 793 | def _EscapeVCProjCommandLineArgListItem(s): |
| 794 | """Escapes command line arguments for MSVS. |
| 795 | |
| 796 | The VCProj format stores string lists in a single string using commas and |
| 797 | semi-colons as separators, which must be quoted if they are to be |
| 798 | interpreted literally. However, command-line arguments may already have |
| 799 | quotes, and the VCProj parser is ignorant of the backslash escaping |
| 800 | convention used by CommandLineToArgv, so the command-line quotes and the |
| 801 | VCProj quotes may not be the same quotes. So to store a general |
| 802 | command-line argument in a VCProj list, we need to parse the existing |
| 803 | quoting according to VCProj's convention and quote any delimiters that are |
| 804 | not already quoted by that convention. The quotes that we add will also be |
| 805 | seen by CommandLineToArgv, so if backslashes precede them then we also have |
| 806 | to escape those backslashes according to the CommandLineToArgv |
| 807 | convention. |
| 808 | |
| 809 | Args: |
| 810 | s: the string to be escaped. |
| 811 | Returns: |
| 812 | the escaped string. |
| 813 | """ |
| 814 | |
| 815 | def _Replace(match): |
| 816 | # For a non-literal quote, CommandLineToArgv requires an even number of |
| 817 | # backslashes preceding it, and it produces half as many literal |
| 818 | # backslashes. So we need to produce 2n backslashes. |
| 819 | return 2 * match.group(1) + '"' + match.group(2) + '"' |
| 820 | |
| 821 | segments = s.split('"') |
| 822 | # The unquoted segments are at the even-numbered indices. |
| 823 | for i in range(0, len(segments), 2): |
| 824 | segments[i] = delimiters_replacer_regex.sub(_Replace, segments[i]) |
| 825 | # Concatenate back into a single string |
| 826 | s = '"'.join(segments) |
| 827 | if len(segments) % 2 == 0: |
| 828 | # String ends while still quoted according to VCProj's convention. This |
| 829 | # means the delimiter and the next list item that follow this one in the |
| 830 | # .vcproj file will be misinterpreted as part of this item. There is nothing |
| 831 | # we can do about this. Adding an extra quote would correct the problem in |
| 832 | # the VCProj but cause the same problem on the final command-line. Moving |
| 833 | # the item to the end of the list does works, but that's only possible if |
| 834 | # there's only one such item. Let's just warn the user. |
| 835 | print( |
| 836 | "Warning: MSVS may misinterpret the odd number of " + "quotes in " + s, |
| 837 | file=sys.stderr, |
| 838 | ) |
| 839 | return s |
| 840 | |
| 841 | |
| 842 | def _EscapeCppDefineForMSVS(s): |
no test coverage detected