Overview
Comment: | Improve path handling on Windows/DOS |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
ec17b9225ae59684bb413b638d66cd5a |
User & Date: | js on 2019-04-06 20:35:03 |
Other Links: | manifest | tags |
Context
2019-04-07
| ||
19:30 | Improve -[OFURL pathComponents] check-in: b1d795b650 user: js tags: trunk | |
2019-04-06
| ||
20:35 | Improve path handling on Windows/DOS check-in: ec17b9225a user: js tags: trunk | |
2019-04-02
| ||
21:55 | OFURLHandler_file: Fix leaked find handle on Win32 check-in: 103d934719 user: js tags: trunk | |
Changes
Modified src/OFString+PathAdditions_DOS.m from [40a93ee30e] to [e7d86c2c3e].
︙ | ︙ | |||
31 32 33 34 35 36 37 | void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; | > | | > < < < | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if (!first && ![ret hasSuffix: @":"] && ([component isEqual: @"\\"] || [component isEqual: @"/"])) continue; if (!first && ![ret hasSuffix: @"\\"] && ![ret hasSuffix: @"/"] && ![ret hasSuffix: @":"]) [ret appendString: @"\\"]; [ret appendString: component]; first = false; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } |
︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } if ([self hasPrefix: @"\\\\"]) { [ret addObject: @"\\\\"]; cString += 2; cStringLength -= 2; } for (i = 0; i < cStringLength; i++) { if (cString[i] == '\\' || cString[i] == '/') { | > > > > > > | > > > > > > > > > > < < < < < | < < | < < < < | < < | < > | < < | < < < | < < | < < < < < < < < < < < < < < < < < < | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; bool isUNC = false; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } if ([self hasPrefix: @"\\\\"]) { isUNC = true; [ret addObject: @"\\\\"]; cString += 2; cStringLength -= 2; } for (i = 0; i < cStringLength; i++) { if (cString[i] == '\\' || cString[i] == '/') { if (i == 0) [ret addObject: [OFString stringWithUTF8String: cString length: 1]]; else if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; last = i + 1; } else if (!isUNC && cString[i] == ':') { if (i + 1 < cStringLength && (cString[i + 1] == '\\' || cString[i + 1] == '/')) i++; [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last + 1]]; last = i + 1; } } if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (OFString *)lastPathComponent { /* * Windows/DOS need the full parsing to determine the last path * component. This could be optimized by not creating the temporary * objects, though. */ void *pool = objc_autoreleasePoolPush(); OFString *ret = self.pathComponents.lastObject; if (ret == nil) { objc_autoreleasePoolPop(pool); return @""; } [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; |
︙ | ︙ | |||
184 185 186 187 188 189 190 191 | [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { void *pool = objc_autoreleasePoolPush(); | > > > > | | < < < < < | < < < < < < < < < < < < | | < | | > > > > | < < < | < | < < < < < < < < < < < < | < | | | > > > > < < < < | < | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { /* * Windows/DOS need the full parsing to delete the last path component. * This could be optimized, though. */ void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components = self.pathComponents; size_t count = components.count; OFString *ret; if (count == 0) { objc_autoreleasePoolPop(pool); return @""; } if (count == 1) { OFString *firstComponent = components.firstObject; if ([firstComponent hasSuffix: @":"] || [firstComponent hasSuffix: @":\\"] || [firstComponent hasSuffix: @":/"] || [firstComponent hasPrefix: @"\\"]) { ret = [firstComponent retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } objc_autoreleasePoolPop(pool); return @"."; } components = [components objectsInRange: of_range(0, components.count - 1)]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; |
︙ | ︙ | |||
289 290 291 292 293 294 295 | - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; | < < < < < < < < < < | | > > > > < < < < < < < < < < | < < < < | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."] && ![parent hasSuffix: @":"] && ![parent hasSuffix: @":\\"] && ![parent hasSuffix: @"://"] && (![parent hasPrefix: @"\\"] || i != 1)) { [array removeObjectsInRange: of_range(i - 1, 2)]; done = false; break; } } } ret = [[OFString pathWithComponents: array] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByAppendingPathComponent: (OFString *)component |
︙ | ︙ |
Modified tests/OFStringTests.m from [a63c11f262] to [c166811b76].
︙ | ︙ | |||
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | a.count == i) #ifdef OF_HAVE_FILES # if defined(OF_WINDOWS) TEST(@"+[pathWithComponents:]", [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]] isEqual: @"foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"foo", @"bar", @"baz", nil]] isEqual: @"c:\\foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo/", @"bar\\", @"", @"baz", @"\\", nil]] isEqual: @"foo/bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", nil]] isEqual: @"foo"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"c:"]] | > > > > > > > > > | > > > > > > > > > > > > > > > | > > > > > > | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 | a.count == i) #ifdef OF_HAVE_FILES # if defined(OF_WINDOWS) TEST(@"+[pathWithComponents:]", [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]] isEqual: @"foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:\\", @"foo", @"bar", @"baz", nil]] isEqual: @"c:\\foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"foo", @"bar", @"baz", nil]] isEqual: @"c:foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"\\", @"foo", @"bar", @"baz", nil]] isEqual: @"c:\\foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"/", @"foo", @"bar", @"baz", nil]] isEqual: @"c:/foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo/", @"bar\\", @"", @"baz", @"\\", nil]] isEqual: @"foo/bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", nil]] isEqual: @"foo"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"c:"]] isEqual: @"c:"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"c:\\"]] isEqual: @"c:\\"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"\\"]] isEqual: @"\\"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"/"]] isEqual: @"/"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"\\\\", @"foo", @"bar", nil]] isEqual: @"\\\\foo\\bar"]) # elif defined(OF_MSDOS) TEST(@"+[pathWithComponents:]", [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]] isEqual: @"foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:\\", @"foo", @"bar", @"baz", nil]] isEqual: @"c:\\foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"foo", @"bar", @"baz", nil]] isEqual: @"c:foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"\\", @"foo", @"bar", @"baz", nil]] isEqual: @"c:\\foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"c:", @"/", @"foo", @"bar", @"baz", nil]] isEqual: @"c:/foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo/", @"bar\\", @"", @"baz", @"\\", nil]] isEqual: @"foo/bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", nil]] isEqual: @"foo"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"c:"]] isEqual: @"c:"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"c:\\"]] isEqual: @"c:\\"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"\\"]] isEqual: @"\\"] && [[stringClass pathWithComponents: [OFArray arrayWithObject: @"/"]] isEqual: @"/"]) # elif defined(OF_AMIGAOS) TEST(@"+[pathWithComponents:]", [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"dh0:", @"foo", @"bar", @"baz", nil]] isEqual: @"dh0:foo/bar/baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]] isEqual: @"foo/bar/baz"] && |
︙ | ︙ | |||
710 711 712 713 714 715 716 | @"foo", nil]] isEqual: @"foo"]) # endif # if defined(OF_WINDOWS) TEST(@"-[pathComponents]", /* c:/tmp */ (a = C(@"c:/tmp").pathComponents) && a.count == 2 && | | | > > > > > > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 | @"foo", nil]] isEqual: @"foo"]) # endif # if defined(OF_WINDOWS) TEST(@"-[pathComponents]", /* c:/tmp */ (a = C(@"c:/tmp").pathComponents) && a.count == 2 && [[a objectAtIndex: 0] isEqual: @"c:/"] && [[a objectAtIndex: 1] isEqual: @"tmp"] && /* c:\tmp\ */ (a = C(@"c:\\tmp\\").pathComponents) && a.count == 2 && [[a objectAtIndex: 0] isEqual: @"c:\\"] && [[a objectAtIndex: 1] isEqual: @"tmp"] && /* c:\ */ (a = C(@"c:\\").pathComponents) && a.count == 1 && [[a objectAtIndex: 0] isEqual: @"c:\\"] && /* c:/ */ (a = C(@"c:/").pathComponents) && a.count == 1 && [[a objectAtIndex: 0] isEqual: @"c:/"] && /* c: */ (a = C(@"c:").pathComponents) && a.count == 1 && [[a objectAtIndex: 0] isEqual: @"c:"] && /* foo\bar */ (a = C(@"foo\\bar").pathComponents) && a.count == 2 && [[a objectAtIndex: 0] isEqual: @"foo"] && [[a objectAtIndex: 1] isEqual: @"bar"] && /* foo\bar/baz/ */ (a = C(@"foo\\bar/baz/").pathComponents) && a.count == 3 && |
︙ | ︙ | |||
741 742 743 744 745 746 747 | [[a objectAtIndex: 1] isEqual: @"foo"] && [[a objectAtIndex: 2] isEqual: @"bar"] && C(@"").pathComponents.count == 0) # elif defined(OF_MSDOS) TEST(@"-[pathComponents]", /* c:/tmp */ (a = C(@"c:/tmp").pathComponents) && a.count == 2 && | | | > > > > > > | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | [[a objectAtIndex: 1] isEqual: @"foo"] && [[a objectAtIndex: 2] isEqual: @"bar"] && C(@"").pathComponents.count == 0) # elif defined(OF_MSDOS) TEST(@"-[pathComponents]", /* c:/tmp */ (a = C(@"c:/tmp").pathComponents) && a.count == 2 && [[a objectAtIndex: 0] isEqual: @"c:/"] && [[a objectAtIndex: 1] isEqual: @"tmp"] && /* c:\tmp\ */ (a = C(@"c:\\tmp\\").pathComponents) && a.count == 2 && [[a objectAtIndex: 0] isEqual: @"c:\\"] && [[a objectAtIndex: 1] isEqual: @"tmp"] && /* c:\ */ (a = C(@"c:\\").pathComponents) && a.count == 1 && [[a objectAtIndex: 0] isEqual: @"c:\\"] && /* c:/ */ (a = C(@"c:/").pathComponents) && a.count == 1 && [[a objectAtIndex: 0] isEqual: @"c:/"] && /* c: */ (a = C(@"c:").pathComponents) && a.count == 1 && [[a objectAtIndex: 0] isEqual: @"c:"] && /* foo\bar */ (a = C(@"foo\\bar").pathComponents) && a.count == 2 && [[a objectAtIndex: 0] isEqual: @"foo"] && [[a objectAtIndex: 1] isEqual: @"bar"] && /* foo\bar/baz/ */ (a = C(@"foo\\bar/baz/").pathComponents) && a.count == 3 && |
︙ | ︙ | |||
847 848 849 850 851 852 853 | # if defined(OF_WINDOWS) TEST(@"-[lastPathComponent]", [C(@"c:/tmp").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\tmp\\").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\").lastPathComponent isEqual: @"c:\\"] && [C(@"c:/").lastPathComponent isEqual: @"c:/"] && | | | | 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 | # if defined(OF_WINDOWS) TEST(@"-[lastPathComponent]", [C(@"c:/tmp").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\tmp\\").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\").lastPathComponent isEqual: @"c:\\"] && [C(@"c:/").lastPathComponent isEqual: @"c:/"] && [C(@"\\").lastPathComponent isEqual: @"\\"] && [C(@"foo").lastPathComponent isEqual: @"foo"] && [C(@"foo\\bar").lastPathComponent isEqual: @"bar"] && [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"] && [C(@"\\\\foo\\bar").lastPathComponent isEqual: @"bar"] && [C(@"\\\\").lastPathComponent isEqual: @"\\\\"]) # elif defined(OF_MSDOS) TEST(@"-[lastPathComponent]", [C(@"c:/tmp").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\tmp\\").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\").lastPathComponent isEqual: @"c:\\"] && [C(@"c:/").lastPathComponent isEqual: @"c:/"] && [C(@"\\").lastPathComponent isEqual: @"\\"] && [C(@"foo").lastPathComponent isEqual: @"foo"] && [C(@"foo\\bar").lastPathComponent isEqual: @"bar"] && [C(@"foo/bar/baz/").lastPathComponent isEqual: @"baz"]) # elif defined(OF_AMIGAOS) TEST(@"-[lastPathComponent]", [C(@"dh0:tmp").lastPathComponent isEqual: @"tmp"] && [C(@"dh0:tmp/").lastPathComponent isEqual: @"tmp"] && |
︙ | ︙ | |||
899 900 901 902 903 904 905 | [C(@"foo.bar").pathExtension isEqual: @"bar"] && [C(@"foo/.bar").pathExtension isEqual: @""] && [C(@"foo/.bar.baz").pathExtension isEqual: @"baz"] && [C(@"foo/bar.baz/").pathExtension isEqual: @"baz"]) # if defined(OF_WINDOWS) TEST(@"-[stringByDeletingLastPathComponent]", | | | | | | | | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 | [C(@"foo.bar").pathExtension isEqual: @"bar"] && [C(@"foo/.bar").pathExtension isEqual: @""] && [C(@"foo/.bar.baz").pathExtension isEqual: @"baz"] && [C(@"foo/bar.baz/").pathExtension isEqual: @"baz"]) # if defined(OF_WINDOWS) TEST(@"-[stringByDeletingLastPathComponent]", [C(@"\\tmp").stringByDeletingLastPathComponent isEqual: @"\\"] && [C(@"/tmp/").stringByDeletingLastPathComponent isEqual: @"/"] && [C(@"c:\\").stringByDeletingLastPathComponent isEqual: @"c:\\"] && [C(@"c:/").stringByDeletingLastPathComponent isEqual: @"c:/"] && [C(@"c:\\tmp/foo/").stringByDeletingLastPathComponent isEqual: @"c:\\tmp"] && [C(@"foo\\bar").stringByDeletingLastPathComponent isEqual: @"foo"] && [C(@"\\").stringByDeletingLastPathComponent isEqual: @"\\"] && [C(@"foo").stringByDeletingLastPathComponent isEqual: @"."] && [C(@"\\\\foo\\bar").stringByDeletingLastPathComponent isEqual: @"\\\\foo"] && [C(@"\\\\foo").stringByDeletingLastPathComponent isEqual: @"\\\\"] && [C(@"\\\\").stringByDeletingLastPathComponent isEqual: @"\\\\"]) # elif defined(OF_MSDOS) TEST(@"-[stringByDeletingLastPathComponent]", [C(@"\\tmp").stringByDeletingLastPathComponent isEqual: @"\\"] && [C(@"/tmp/").stringByDeletingLastPathComponent isEqual: @"/"] && [C(@"c:\\").stringByDeletingLastPathComponent isEqual: @"c:\\"] && [C(@"c:/").stringByDeletingLastPathComponent isEqual: @"c:/"] && [C(@"c:\\tmp/foo/").stringByDeletingLastPathComponent isEqual: @"c:\\tmp"] && [C(@"foo\\bar").stringByDeletingLastPathComponent isEqual: @"foo"] && [C(@"\\").stringByDeletingLastPathComponent isEqual: @"\\"] && [C(@"foo").stringByDeletingLastPathComponent isEqual: @"."]) # elif defined(OF_AMIGAOS) TEST(@"-[stringByDeletingLastPathComponent]", [C(@"dh0:").stringByDeletingLastPathComponent isEqual: @"dh0:"] && [C(@"dh0:tmp").stringByDeletingLastPathComponent isEqual: @"dh0:"] && [C(@"dh0:tmp/").stringByDeletingLastPathComponent |
︙ | ︙ | |||
1015 1016 1017 1018 1019 1020 1021 | [C(@".foo.bar").stringByDeletingPathExtension isEqual: @".foo"]) # endif # ifdef OF_WINDOWS /* TODO: Add more tests */ TEST(@"-[stringByStandardizingPath]", [C(@"\\\\foo\\..\\bar\\qux").stringByStandardizingPath | | > > | 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 | [C(@".foo.bar").stringByDeletingPathExtension isEqual: @".foo"]) # endif # ifdef OF_WINDOWS /* TODO: Add more tests */ TEST(@"-[stringByStandardizingPath]", [C(@"\\\\foo\\..\\bar\\qux").stringByStandardizingPath isEqual: @"\\\\bar\\qux"] && [C(@"c:\\..\\asd").stringByStandardizingPath isEqual: @"c:\\..\\asd"]) # endif #endif TEST(@"-[decimalValue]", C(@"1234").decimalValue == 1234 && C(@"\r\n+123 ").decimalValue == 123 && C(@"-500\t").decimalValue == -500 && |
︙ | ︙ |