1 module libd.console.io; 2 3 import libd.io.filesystem; 4 5 __gshared FileStream g_stdout; 6 __gshared FileStream g_stderr; 7 __gshared FileStream g_stdin; 8 9 void consoleWrite(Params...)(scope Params params) { consoleWriteImpl!g_stdout(params); } 10 void consoleWriteln(Params...)(scope Params params) { consoleWritelnImpl!g_stdout(params); } 11 bool consoleWritef(Params...)(scope bcstring spec, scope Params params) { return consoleWritefImpl!g_stdout(spec, params); } 12 bool consoleWritefln(Params...)(scope bcstring spec, scope Params params) { return consoleWriteflnImpl!g_stdout(spec, params); } 13 14 bcstring consoleRead(scope char[] buffer) 15 { 16 if(!g_stdin.isOpen) 17 return null; 18 19 const result = g_stdin.read(buffer); 20 if(!result.isValid) 21 return null; 22 23 return buffer[0..result.value]; 24 } 25 26 String consoleRead(size_t maxInput = 512)() 27 { 28 char[maxInput] buffer; 29 30 auto result = String(consoleRead(buffer[0..$])); 31 if(result.length && result[$-1] == '\n') // Remove the \n that usually comes through when the user presses ENTER 32 result.length = result.length - 1; 33 34 return result; 35 } 36 37 private void consoleWriteImpl(alias Stream, Params...)(scope Params params) 38 { 39 import libd.data.conv; 40 if(Stream.isOpen) 41 { 42 static foreach(i, param; params) 43 {{ 44 alias ParamT = typeof(param); 45 static if(is(ParamT : bcstring)) 46 Stream.write(param); 47 else static if(is(ParamT : const String)) 48 Stream.write(params[i][0..$]); 49 else static if(is(ParamT == bool)) 50 Stream.write(param ? "true" : "false"); 51 else static if(is(ParamT : const char)) 52 Stream.write((¶ms[i])[0..1]); 53 else 54 Stream.write(params[i].to!String[0..$]); 55 }} 56 } 57 } 58 59 private void consoleWritelnImpl(alias Stream, Params...)(scope Params params) 60 { 61 consoleWriteImpl!Stream(params); 62 Stream.write("\n"); 63 } 64 65 private bool consoleWritefImpl(alias Stream, Params...)(scope bcstring spec, scope Params params) 66 { 67 import libd.data.format; 68 69 auto result = format(spec, params); 70 if(!result.isValid) 71 { 72 consoleWritelnImpl!Stream("Failed to format string."); 73 displayError(result.error); 74 return false; 75 } 76 77 consoleWriteImpl!Stream(result.value[0..$]); 78 return true; 79 } 80 81 private bool consoleWriteflnImpl(alias Stream, Params...)(scope bcstring spec, scope Params params) 82 { 83 const result = consoleWritefImpl!Stream(spec, params); 84 if(!result) 85 return false; 86 87 Stream.write("\n"); 88 return true; 89 } 90 91 @("not for public use") 92 void _d_console_io_init() 93 { 94 version(Windows) 95 { 96 import runtime.system.windows; 97 void createStream(ref FileStream file, DWORD stdType, FileUsage usage) 98 { 99 const result = GetStdHandle(stdType); 100 if(result == INVALID_HANDLE_VALUE || !result) 101 return; 102 file = FileStream(cast(HANDLE)result, usage); 103 } 104 105 createStream(g_stdout, STD_OUTPUT_HANDLE, FileUsage.write); 106 createStream(g_stderr, STD_ERROR_HANDLE, FileUsage.write); 107 createStream(g_stdin, STD_INPUT_HANDLE, FileUsage.read); 108 109 HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE); 110 DWORD mode = 0; 111 GetConsoleMode(stdOut, &mode); 112 mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; 113 SetConsoleMode(stdOut, mode); 114 } 115 }