HaxeFoundation / HaxeFoundation/haxe
Writing newline to stdout produces incorrect behaviour if Sys.getChar() is running (Neko & CPP targets)
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
_OSX 10.11.6, Haxe 3.47, Neko 2.1.0, hxcpp 3.4.188_
Tested in iTerm2 3.1.7, OSX Terminal 2.6.2 and XTerm 326 running in XQuartz.
I'm writing a command line utility and have been seeing odd behaviour with newlines. I am using threads to read user input character by character (with non-echoing Sys.getChar()) and write to stdout at the same time. The call to Sys.getChar() seems to be interfering with the terminal and causing newlines to move the cursor down a line but not return it to the first column.
All of the data being sent to the terminal appears as it should (\n is sending an actual newline character), but the terminal itself is displaying the newlines incorrectly. I suppose the files of interest are `hxcpp/src/hx/lib/std/Sys.cpp:760` and `neko/libs/std/sys.c:642`, but I can't dig any more because my C/++ isn't very good.
Here is a demonstration:
`haxe -main GetCharTest --each -neko neko_test.n --next -cpp cpp_test && (./cpp_test/GetCharTest; neko neko_test.n)`
GetCharTest.hx:
```
package;
#if cpp
import cpp.vm.Thread;
#else
import neko.vm.Thread;
#end
class GetCharTest
{
static function main(){ new GetCharTest(); }
public function new()
{
Sys.stdout().writeString(#if cpp "CPP" #else "NEKO" #end + ":\n");
var testString = 'a\nb\nc\n';
Sys.stdout().writeString("without Sys.getChar()\n");
// newlines return to column 1
var thread = Thread.create(writeStdout.bind(Thread.current()));
Thread.readMessage(true);
Sys.stdout().writeString("\nwith Sys.getChar() (any key to continue)\n");
// newlines do not return to column 1
var thread = Thread.create(writeStdout.bind(Thread.current()));
getChar();
var msg = Thread.readMessage(true);
Sys.stdout().writeString("\nwith threaded Sys.getChar() (any key to continue)\n");
// a threaded getChar call doesn't help
var getCharThread = Thread.create(getChar.bind(Thread.current()));
var thread = Thread.create(writeStdout.bind(Thread.current()));
Thread.readMessage(true);
Thread.readMessage(true);
Sys.stdout().writeString('\n');
}
private function writeStdout(?main:Thread)
{
Sys.sleep(0.1);
Sys.stdout().writeString('a\nb\nc\n');
if(main != null)
main.sendMessage(true);
}
private function getChar(?main:Thread)
{
var inp:Int = Sys.getChar(false);
if(main != null)
main.sendMessage(true);
}
}
```
Hopefully it isn't something really obvious that I'm missing! In the mean time I am converting newlines to 0x85 which is just a more explicit newline anyway, and isn't affected by this issue.
Contributor guide
Assessment
This issue has not been assessed yet.