OLD | NEW |
---|---|
1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Xcode project file generator. | 5 """Xcode project file generator. |
6 | 6 |
7 This module is both an Xcode project file generator and a documentation of the | 7 This module is both an Xcode project file generator and a documentation of the |
8 Xcode project file format. Knowledge of the project file format was gained | 8 Xcode project file format. Knowledge of the project file format was gained |
9 based on extensive experience with Xcode, and by making changes to projects in | 9 based on extensive experience with Xcode, and by making changes to projects in |
10 Xcode.app and observing the resultant changes in the associated project files. | 10 Xcode.app and observing the resultant changes in the associated project files. |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 # characters listed with "+", for 1 or more occurrences: if a string is empty, | 162 # characters listed with "+", for 1 or more occurrences: if a string is empty, |
163 # it must not match this pattern, because it needs to be encoded as "". | 163 # it must not match this pattern, because it needs to be encoded as "". |
164 _unquoted = re.compile('^[A-Za-z0-9$./_]+$') | 164 _unquoted = re.compile('^[A-Za-z0-9$./_]+$') |
165 | 165 |
166 # Strings that match this pattern are quoted regardless of what _unquoted says. | 166 # Strings that match this pattern are quoted regardless of what _unquoted says. |
167 # Oddly, Xcode will quote any string with a run of three or more underscores. | 167 # Oddly, Xcode will quote any string with a run of three or more underscores. |
168 _quoted = re.compile('___') | 168 _quoted = re.compile('___') |
169 | 169 |
170 # This pattern should match any character that needs to be escaped by | 170 # This pattern should match any character that needs to be escaped by |
171 # XCObject._EncodeString. See that function. | 171 # XCObject._EncodeString. See that function. |
172 _escaped = re.compile('[\\\\"]|[^ -~]') | 172 _escaped = re.compile('[\\\\"]|[\x00-\x1f\x7f]') |
Mark Mentovai
2013/09/12 21:32:18
Why is 0x7f in here? If the input contains a DEL c
kbongort
2013/09/12 22:41:40
This was to keep the former behavior, but the comm
| |
173 | 173 |
174 | 174 |
175 # Used by SourceTreeAndPathFromPath | 175 # Used by SourceTreeAndPathFromPath |
176 _path_leading_variable = re.compile('^\$\((.*?)\)(/(.*))?$') | 176 _path_leading_variable = re.compile('^\$\((.*?)\)(/(.*))?$') |
177 | 177 |
178 def SourceTreeAndPathFromPath(input_path): | 178 def SourceTreeAndPathFromPath(input_path): |
179 """Given input_path, returns a tuple with sourceTree and path values. | 179 """Given input_path, returns a tuple with sourceTree and path values. |
180 | 180 |
181 Examples: | 181 Examples: |
182 input_path (source_tree, output_path) | 182 input_path (source_tree, output_path) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 _properties: The object's property dictionary. An object's properties are | 265 _properties: The object's property dictionary. An object's properties are |
266 described by its class' _schema variable. | 266 described by its class' _schema variable. |
267 """ | 267 """ |
268 | 268 |
269 _schema = {} | 269 _schema = {} |
270 _should_print_single_line = False | 270 _should_print_single_line = False |
271 | 271 |
272 # See _EncodeString. | 272 # See _EncodeString. |
273 _encode_transforms = [] | 273 _encode_transforms = [] |
274 i = 0 | 274 i = 0 |
275 while i < ord(' '): | 275 while i < ord(' '): |
Mark Mentovai
2013/09/12 21:32:18
…it won’t be matched by a transform in this list…
kbongort
2013/09/12 22:41:40
Done.
| |
276 _encode_transforms.append('\\U%04x' % i) | 276 _encode_transforms.append('\\U%04x' % i) |
277 i = i + 1 | 277 i = i + 1 |
278 _encode_transforms[7] = '\\a' | 278 _encode_transforms[7] = '\\a' |
279 _encode_transforms[8] = '\\b' | 279 _encode_transforms[8] = '\\b' |
280 _encode_transforms[9] = '\\t' | 280 _encode_transforms[9] = '\\t' |
281 _encode_transforms[10] = '\\n' | 281 _encode_transforms[10] = '\\n' |
282 _encode_transforms[11] = '\\v' | 282 _encode_transforms[11] = '\\v' |
283 _encode_transforms[12] = '\\f' | 283 _encode_transforms[12] = '\\f' |
284 _encode_transforms[13] = '\\n' | 284 _encode_transforms[13] = '\\n' |
285 | 285 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 # the _escaped expression. | 521 # the _escaped expression. |
522 char = match.group(0) | 522 char = match.group(0) |
523 | 523 |
524 # Backslashes (\) and quotation marks (") are always replaced with a | 524 # Backslashes (\) and quotation marks (") are always replaced with a |
525 # backslash-escaped version of the same. Everything else gets its | 525 # backslash-escaped version of the same. Everything else gets its |
526 # replacement from the class' _encode_transforms array. | 526 # replacement from the class' _encode_transforms array. |
527 if char == '\\': | 527 if char == '\\': |
528 return '\\\\' | 528 return '\\\\' |
529 if char == '"': | 529 if char == '"': |
530 return '\\"' | 530 return '\\"' |
531 return self._encode_transforms[ord(char)] | 531 return self._encode_transforms[ord(char)] |
Mark Mentovai
2013/09/12 21:32:18
…and then this will raise an exception.
kbongort
2013/09/12 22:41:40
Done.
| |
532 | 532 |
533 def _EncodeString(self, value): | 533 def _EncodeString(self, value): |
534 """Encodes a string to be placed in the project file output, mimicing | 534 """Encodes a string to be placed in the project file output, mimicing |
535 Xcode behavior. | 535 Xcode behavior. |
536 """ | 536 """ |
537 | 537 |
538 # Use quotation marks when any character outside of the range A-Z, a-z, 0-9, | 538 # Use quotation marks when any character outside of the range A-Z, a-z, 0-9, |
539 # $ (dollar sign), . (period), and _ (underscore) is present. Also use | 539 # $ (dollar sign), . (period), and _ (underscore) is present. Also use |
540 # quotation marks to represent empty strings. | 540 # quotation marks to represent empty strings. |
541 # | 541 # |
542 # Escape " (double-quote) and \ (backslash) by preceding them with a | 542 # Escape " (double-quote) and \ (backslash) by preceding them with a |
543 # backslash. | 543 # backslash. |
544 # | 544 # |
545 # Some characters below the printable ASCII range are encoded specially: | 545 # Some characters below the printable ASCII range are encoded specially: |
546 # 7 ^G BEL is encoded as "\a" | 546 # 7 ^G BEL is encoded as "\a" |
547 # 8 ^H BS is encoded as "\b" | 547 # 8 ^H BS is encoded as "\b" |
548 # 11 ^K VT is encoded as "\v" | 548 # 11 ^K VT is encoded as "\v" |
549 # 12 ^L NP is encoded as "\f" | 549 # 12 ^L NP is encoded as "\f" |
550 # 127 ^? DEL is passed through as-is without escaping | 550 # 127 ^? DEL is passed through as-is without escaping |
551 # - In PBXFileReference and PBXBuildFile objects: | 551 # - In PBXFileReference and PBXBuildFile objects: |
552 # 9 ^I HT is passed through as-is without escaping | 552 # 9 ^I HT is passed through as-is without escaping |
553 # 10 ^J NL is passed through as-is without escaping | 553 # 10 ^J NL is passed through as-is without escaping |
554 # 13 ^M CR is passed through as-is without escaping | 554 # 13 ^M CR is passed through as-is without escaping |
555 # - In other objects: | 555 # - In other objects: |
556 # 9 ^I HT is encoded as "\t" | 556 # 9 ^I HT is encoded as "\t" |
557 # 10 ^J NL is encoded as "\n" | 557 # 10 ^J NL is encoded as "\n" |
558 # 13 ^M CR is encoded as "\n" rendering it indistinguishable from | 558 # 13 ^M CR is encoded as "\n" rendering it indistinguishable from |
559 # 10 ^J NL | 559 # 10 ^J NL |
560 # All other nonprintable characters within the ASCII range (0 through 127 | 560 # All other nonprintable characters within the ASCII range (0 through 127 |
Mark Mentovai
2013/09/12 21:32:18
I just consulted with both Xcode 4.6.3 and 3.2.6 a
kbongort
2013/09/12 22:41:40
I fixed the comment.
| |
561 # inclusive) are encoded as "\U001f" referring to the Unicode code point in | 561 # inclusive) are encoded as "\U001f" referring to the Unicode code point in |
562 # hexadecimal. For example, character 14 (^N SO) is encoded as "\U000e". | 562 # hexadecimal. For example, character 14 (^N SO) is encoded as "\U000e". |
563 # Characters above the ASCII range are passed through to the output encoded | 563 # Characters above the ASCII range are passed through to the output encoded |
564 # as UTF-8 without any escaping. These mappings are contained in the | 564 # as UTF-8 without any escaping. These mappings are contained in the |
565 # class' _encode_transforms list. | 565 # class' _encode_transforms list. |
566 | 566 |
567 if _unquoted.search(value) and not _quoted.search(value): | 567 if _unquoted.search(value) and not _quoted.search(value): |
568 return value | 568 return value |
569 | 569 |
570 return '"' + _escaped.sub(self._EncodeTransform, value) + '"' | 570 return '"' + _escaped.sub(self._EncodeTransform, value) + '"' |
(...skipping 2290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2861 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') | 2861 self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') |
2862 for object in sorted(objects_by_class[class_name], | 2862 for object in sorted(objects_by_class[class_name], |
2863 cmp=lambda x, y: cmp(x.id, y.id)): | 2863 cmp=lambda x, y: cmp(x.id, y.id)): |
2864 object.Print(file) | 2864 object.Print(file) |
2865 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') | 2865 self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') |
2866 | 2866 |
2867 if self._should_print_single_line: | 2867 if self._should_print_single_line: |
2868 self._XCPrint(file, 0, '}; ') | 2868 self._XCPrint(file, 0, '}; ') |
2869 else: | 2869 else: |
2870 self._XCPrint(file, 1, '};\n') | 2870 self._XCPrint(file, 1, '};\n') |
OLD | NEW |