-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-102255: Improve build support on xbox #102256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
58ab04a
66a68bd
26f5a44
68a1f67
492bac0
26b4b24
467bf40
e734492
fad23bc
b6b28ec
cdbb1f2
e7622cc
7812891
3b005f4
fa526b6
36887bc
6fe3018
8499940
69f0a2c
f43ce54
43cf0a5
8f717ea
29d5b65
8a73500
92ae5ef
f27fe95
f15d9e2
d816baa
2ba0a87
ed17e03
c360b4a
3b5b119
975191a
91a95f2
3be5fa7
6bd1207
ca98366
fac3431
c1bf0e2
ace99f6
e83d398
76ea310
2f1d19c
559199f
b119bf5
1dd69e8
a1e6dba
7a45988
846f8eb
a56f215
191cab2
144280e
ca9f7d9
30c0818
6ebb05b
fc5c642
5f286a7
3be5e3c
d9e1663
2a2a8fd
165286d
1413849
6465d73
3f0c6f0
8f3a262
6b8074e
99b6a1d
d0e548d
c569a18
3e86c9e
d5cb524
63267d8
79f2bfe
fc6b942
05e9859
9769662
8f12bf8
509d0f5
f20fea8
e33a42f
556a8e1
aa8964b
74258ca
686da59
b151f7f
39d2d13
2895563
8e3d3c5
659d1a3
e9ff60e
32c4886
2f1fe40
5854e91
d3d2e1c
b1ffce9
0b4d407
d9976dc
427de79
603cea7
6db80a3
4d78066
65cdd56
35217ab
331b1f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -2117,17 +2117,107 @@ _Py_abspath(const wchar_t *path, wchar_t **abspath_p) | |||
#endif | ||||
} | ||||
|
||||
#ifdef MS_WINDOWS_GAMES | ||||
static wchar_t* | ||||
win32_games_skip_root(wchar_t* path) | ||||
{ | ||||
if (path[0] == '\\') { | ||||
/* relative path with root e.g. \Windows */ | ||||
if (path[1] != '\\') { | ||||
return path + 1; | ||||
} | ||||
|
||||
/* UNC drives e.g. \\server\share or \\?\UNC\server\share */ | ||||
wchar_t *end = path + 2; | ||||
if (!wcsnicmp(end, L"?\\UNC\\", 6)) { | ||||
end += 6; | ||||
} | ||||
|
||||
end = wcschr(end, '\\'); | ||||
if (!end) { | ||||
return path + wcslen(path); | ||||
} | ||||
end = wcschr(end + 1, '\\'); | ||||
return (!end) ? path + wcslen(path) : end + 1; | ||||
} | ||||
/* absolute / relative path with drive, e.g. C: or C:\ */ | ||||
else if (isalpha(path[0]) && path[1] == ':') { | ||||
return (path[2] == '\\') ? path + 3 : path + 2; | ||||
} | ||||
|
||||
/* relative path */ | ||||
return NULL; | ||||
} | ||||
|
||||
// The Windows Games API partition does not provide PathCchCombineEx | ||||
// so we need our own implementation | ||||
static int | ||||
win32_games_join_relfile(wchar_t *buffer, size_t bufsize, | ||||
const wchar_t *dirname, const wchar_t *relfile) | ||||
{ | ||||
if ((isalpha(relfile[0]) && relfile[1] == ':') || | ||||
(relfile[0] == '\\' && relfile[1] == '\\')) | ||||
{ | ||||
dirname = relfile; | ||||
relfile = NULL; | ||||
} | ||||
|
||||
size_t dir_len = wcslen(dirname); | ||||
size_t file_len = relfile ? wcslen(relfile) : 0; | ||||
/* path is at max dirname + filename + backslash + \0 */ | ||||
size_t new_len = dir_len + file_len + 2; | ||||
if (bufsize >= MAXPATHLEN || new_len > bufsize) { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The value of Else if
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yeah, we shouldn't have references to MAXPATHLEN in here. I'm not so concerned about error codes. They're only going to be reported to users, and really we ought to be getting the buffer right ourselves before calling. I think it's fine for this implementation to assume There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I agree, if getting the correct behavior is excessively complicated with no tangible benefit. What about my other comment on this function? The way There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Firstly, the suggested change is good. I'm not particularly worried about the case where Maybe just add a comment like The only reasonable alternative (without complicating everything) would involve modifying the result buffer before potentially returning an error, which I think is worse. I'm pretty sure the original API uses temporary buffers internally, but there's no real need to go there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I would assume the implementation to use something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we really wanted to I could come up with an implementation that behaves closer to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It would calculate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hold off on any more changes on this function for a day or two - I'm having some interesting conversations with colleagues right now. Might have a more suitable approach (or at least more information about it). |
||||
return -1; | ||||
} | ||||
|
||||
size_t combined_length = dir_len; | ||||
wcscpy(buffer, dirname); | ||||
if (!relfile || !relfile[0]) { | ||||
if(wcsncmp(buffer, L"\\\\?\\", 4)) { | ||||
buffer += 4; | ||||
} | ||||
if (isalpha(buffer[0]) && buffer[1] == ':') { | ||||
if (!buffer[2]) { | ||||
buffer[2] = '\\'; | ||||
buffer[3] = '\0'; | ||||
} | ||||
} | ||||
} | ||||
else { | ||||
if (relfile[0] == '\\' && relfile[1] != '\\') | ||||
{ | ||||
wchar_t* root_end = win32_games_skip_root(buffer); | ||||
if (root_end) { | ||||
*root_end = '\0'; | ||||
} | ||||
combined_length = root_end - buffer; | ||||
relfile++; | ||||
} | ||||
if (combined_length && buffer[combined_length - 1] != '\\') { | ||||
buffer[combined_length++] = '\\'; | ||||
buffer[combined_length] = '\0'; | ||||
} | ||||
wcscat(buffer, relfile); | ||||
} | ||||
return 0; | ||||
} | ||||
#endif /* MS_WINDOWS_GAMES */ | ||||
|
||||
// The caller must ensure "buffer" is big enough. | ||||
static int | ||||
join_relfile(wchar_t *buffer, size_t bufsize, | ||||
const wchar_t *dirname, const wchar_t *relfile) | ||||
{ | ||||
#if defined(MS_WINDOWS) && !defined(MS_WINDOWS_GAMES) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mostly selected this implementation for it's simplicity. On the xbox you should probably simply work with absolute paths, so I considered it as good enough for now. That said a better implementation would certainly not hurt. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On all platforms you should work with absolute paths :) You're likely in control of your development process well enough to ensure it, but we need to account for broader expectations than that when it comes into core. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm I guess on Windows/Linux we do use paths relative to the binary we ship. On Xbox basically every application has their "own" filesystem, so you really use absolute paths everywhere. I guess that might be the reason why they do not provide the API there. Anyway I know to little about WIndows file path concatenation to come up with a better implementation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The POSIX code is okay as long as it's always a simple relative path such as "eggs\foo.py". One minor annoyance is if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added an implementation which should be able to handle more of these cases on the xbox. |
||||
#ifdef MS_WINDOWS_GAMES | ||||
return win32_games_join_relfile(buffer, bufsize, dirname, relfile) | ||||
#else | ||||
if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, | ||||
PATHCCH_ALLOW_LONG_PATHS))) { | ||||
return -1; | ||||
} | ||||
return 0; | ||||
#endif | ||||
#else | ||||
assert(!_Py_isabs(relfile)); | ||||
size_t dirlen = wcslen(dirname); | ||||
|
@@ -2151,8 +2241,8 @@ join_relfile(wchar_t *buffer, size_t bufsize, | |||
} | ||||
wcscpy(&buffer[relstart], relfile); | ||||
} | ||||
#endif | ||||
return 0; | ||||
#endif | ||||
} | ||||
|
||||
/* Join the two paths together, like os.path.join(). Return NULL | ||||
|
Uh oh!
There was an error while loading. Please reload this page.