Closed CatEricka closed 2 years ago
Having the same issue here. The error occurs when first pressing REPL: Load file in REPL
on the menu bar. However, pressing it a second time seems to work fine.
Upon further investigation, it seems that running racket --repl --eval '(enter! (file "c:/Users/.../file.rkt"))'
directly in PowerShell also has this issue, while running (enter! (file "c:/Users/.../file.rkt"))
once in the REPL seems to work fine. Maybe it's a racket REPL problem instead of the extension?
fixed by #65
The problem seems to be caused by racket
's weird escaping rules for parsing command line arguments on windows.
Actually, this problem is caused by weird Powershell behaviour. It just strips double-quotes from command line parameters for whatever reason. i.e. in Powershell racket --eval '(displayln "123")'
is exactly the same as racket --eval '(displayln 123)'
. The solution is to additionally escape the quotes (racket --eval '(displayln \"123\")'
)
Actually, this problem is caused by weird Powershell behaviour. It just strips double-quotes from command line parameters for whatever reason. i.e. in Powershell
racket --eval '(displayln "123")'
is exactly the same asracket --eval '(displayln 123)'
. The solution is to additionally escape the quotes (racket --eval '(displayln \"123\")'
)
The parsing of double quotes on the command line under Windows is more complicated than I thought. But I don't think it's caused by weird PowerShell behavior: PowerShell doesn't escape double quotes inside single quotes:
...it's not racket's fault either.
In fact, the command line string is processed twice by the PowerShell and c/c++ program:
https://daviddeley.com/autohotkey/parameters/parameters.htm
How this parameter gets parsed:
parameter string: ^"(enter! (file \^"file_path\^"))^"
-> cmd.exe
=> "(enter! (file \"file_path\"))"
-> msvcrt/msvcpprt processed
=> (enter! (file "file_path"))
-> racket get the parameter.
Same as cmd.exe, just PowerShell call CreateProcess().
How this parameter gets parsed:
parameter string: '(enter! (file \"file_path\"))'
-> PowerShell magic
=> "(enter! (file \"file_path\"))"
(I guess)
-> msvcrt/msvcpprt processed
=> (enter! (file "file_path"))
-> racket get the parameter.
If I understand correctly,
the argument that racket gets are actually (enter! (file "file/path))
, and I think it's pure coincidence that it works
cmd.exe:
C:\Users\Ericka\test>argv_echo.exe racket --repl --eval "(enter! (file ""c:/Users/Ericka/Untitled-1.rkt""))"
argv 0: argv_echo.exe
argv 1: racket
argv 2: --repl
argv 3: --eval
argv 4: (enter! (file "c:/Users/Ericka/Untitled-1.rkt))
C:\Users\Ericka\test>argv_echo.exe racket --repl --eval ^"(enter! (file \^"c:/Users/Ericka/Untitled-1.rkt\^"))^"
argv 0: argv_echo.exe
argv 1: racket
argv 2: --repl
argv 3: --eval
argv 4: (enter! (file "c:/Users/Ericka/Untitled-1.rkt"))
code of argv_echo.exe:
#include <iostream>
using namespace std;
int main(int argc, char*argv[])
{
for (int i = 0; i < argc; i++)
{
cout << "argv " << i << ": " << argv[i] << endl;
}
return 0;
}
Interesting! I agree with you that this should be changed just to be safe. But here is the thing:
1) If racket actually gets (enter! (file "file/path))
then why doesn't it show an error? Because when I try explicitly import file in REPL it throws one at me (I use Git Bash in this example)
2) I wrote a similar "program" in Python and ran it from cmd.exe
import sys
print("\n".join(sys.argv))
And here what I got. The quote is present Although it probably depends on how various programs treat (parse?) cmd params individually. Both Python's and Racket's runtimes do it right
If racket actually gets (enter! (file "file/path)) then why doesn't it show an error?
It occurred to me that how the main function gets arguments is up to the compiler.
Same code, different compiler:
Code:
#include <stdio.h>
int main(int argc, char*argv[])
{
for (int i = 0; i < argc; i++)
{
printf("argv %d: %s\n", i, argv[i]);
}
return 0;
}
cmd > args.exe "(enter! (file ""c:/test/test.rkt""))"
argv 0: args.exe
argv 1: (enter! (file "c:/test/test.rkt))
cmd > args.exe "(enter! (file ""c:/test/test.rkt""))"
0: Project1.exe
1: (enter! (file "c:/test/test.rkt"))
So, it seems that different c runtimes have different understanding of command line argument escaping.
In any case, programs should not rely on the behavior of the c runtime, I think using \"
escaping is the correct thing to do.
I checked the header of Racket.exe
using dumpbin.exe
:
OPTIONAL HEADER VALUES
...
2.35 linker version
...
... it doesn't seem to be compiled by visual studio, and then I searched for the keyword mingw
000000000040CF80: 4D 69 6E 67 77 2D 77 36 34 20 72 75 6E 74 69 6D Mingw-w64 runtim
000000000040CF90: 65 20 66 61 69 6C 75 72 65 3A 0A 00 00 00 00 00 e failure:......
000000000040CFA0: 41 64 64 72 65 73 73 20 25 70 20 68 61 73 20 6E Address %p has n
000000000040CFB0: 6F 20 69 6D 61 67 65 2D 73 65 63 74 69 6F 6E 00 o image-section.
I can only think there’s some magic in it.
Thanks for investing the issue guys. Wish I could help--I just started taking a course in racket last week and wanted to report issues so that people more competent than me could take a shot fixing them! cheers
Should be fixed in 0.6.3. Made sure to package the correct code this time. Please, test this and then close the issue if everything is ok.
Version 0.6.3 still packs the wrong files, same as 0.6.2.
$ diff evzen-wybitul.magic-racket-0.6.2 evzen-wybitul.magic-racket-0.6.3
diff evzen-wybitul.magic-racket-0.6.2/extension.vsixmanifest evzen-wybitul.magic-racket-0.6.3/extension.vsixmanifest
4c4
< <Identity Language="en-US" Id="magic-racket" Version="0.6.2" Publisher="evzen-wybitul" />
---
> <Identity Language="en-US" Id="magic-racket" Version="0.6.3" Publisher="evzen-wybitul" />
evzen-wybitul.magic-racket-0.6.3.vsix/extension/out/repl.js#L23-L38
exports.executeSelectionInRepl = executeSelectionInRepl;
function runFileInTerminal(command, filePath, terminal) {
terminal.show();
terminal.sendText(`clear`);
terminal.sendText((0, shell_quote_1.quote)([...command, filePath]));
// Leaving this here if we ever need to fix cmd.exe again
// const shell: string | undefined = vscode.workspace
// .getConfiguration("terminal.integrated.shell")
// .get("windows");
// if (process.platform === "win32" && shell && /cmd\.exe$/.test(shell)) {
// // cmd.exe doesn't recognize single quotes
// terminal.sendText(`${racket} "${filePath}"`);
// } else {
// terminal.sendText(`${racket} '${filePath}'`);
// }
}
current master
branch
Should be fixed. I manually downloaded the 0.6.4 from the marketplace and checked that the repl.js
file is the correct one. Sorry everyone for the mishaps!
This is also an issue with powershell on linux.
Still not fixed.
Please create a new issue to track whatever remains, rather than reviving this old closed one. Include more info in the new issue with your system details and versions along what you tried, and then we'll take a look.
Environment
Error message
code
Untitled-1.rkt
:REPL message:
Additional context
run
(enter! (file "c:/Users/Ericka/sources/racket/Untitled-1.rkt"))
in REPL: