1 //===-- MICmnStreamStdin.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Third Party Headers
18 #include "MICmnResources.h"
19 #include "MICmnStreamStdin.h"
20 #include "MICmnStreamStdout.h"
22 #include "MIUtilSingletonHelper.h"
25 //------------------------------------------------------------------------------------
26 // Details: CMICmnStreamStdin constructor.
32 CMICmnStreamStdin::CMICmnStreamStdin()
33 : m_strPromptCurrent("(gdb)"), m_bShowPrompt(true), m_pCmdBuffer(nullptr) {}
36 //------------------------------------------------------------------------------------
37 // Details: CMICmnStreamStdin destructor.
43 CMICmnStreamStdin::~CMICmnStreamStdin() { Shutdown(); }
46 //------------------------------------------------------------------------------------
47 // Details: Initialize resources for *this Stdin stream.
50 // Return: MIstatus::success - Functional succeeded.
51 // MIstatus::failure - Functional failed.
54 bool CMICmnStreamStdin::Initialize() {
55 m_clientUsageRefCnt++;
58 return MIstatus::success;
60 bool bOk = MIstatus::success;
63 // Note initialisation order is important here as some resources depend on
65 MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
66 MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
69 m_pCmdBuffer = new char[m_constBufferSize];
71 CMIUtilString strInitError(CMIUtilString::Format(
72 MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
73 SetErrorDescription(strInitError);
75 return MIstatus::failure;
79 return MIstatus::success;
83 //------------------------------------------------------------------------------------
84 // Details: Release resources for *this Stdin stream.
87 // Return: MIstatus::success - Functional succeeded.
88 // MIstatus::failure - Functional failed.
91 bool CMICmnStreamStdin::Shutdown() {
92 if (--m_clientUsageRefCnt > 0)
93 return MIstatus::success;
96 return MIstatus::success;
98 m_bInitialized = false;
100 ClrErrorDescription();
102 if (m_pCmdBuffer != nullptr) {
103 delete[] m_pCmdBuffer;
104 m_pCmdBuffer = nullptr;
107 bool bOk = MIstatus::success;
108 CMIUtilString errMsg;
110 MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
111 MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
114 SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
117 return MIstatus::success;
121 //------------------------------------------------------------------------------------
122 // Details: Validate and set the text that forms the prompt on the command line.
124 // Args: vNewPrompt - (R) Text description.
125 // Return: MIstatus::success - Functional succeeded.
126 // MIstatus::failure - Functional failed.
129 bool CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt) {
130 if (vNewPrompt.empty()) {
131 const CMIUtilString msg(CMIUtilString::Format(
132 MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
133 CMICmnStreamStdout::Instance().Write(msg);
134 return MIstatus::failure;
137 m_strPromptCurrent = vNewPrompt;
139 return MIstatus::success;
143 //------------------------------------------------------------------------------------
144 // Details: Retrieve the command line prompt text currently being used.
147 // Return: const CMIUtilString & - Functional failed.
150 const CMIUtilString &CMICmnStreamStdin::GetPrompt() const {
151 return m_strPromptCurrent;
155 //------------------------------------------------------------------------------------
156 // Details: Set whether to display optional command line prompt. The prompt is
158 // stdout. Disable it when this may interfere with the client reading
160 // input and it tries to interpret the prompt text to.
162 // Args: vbYes - (R) True = Yes prompt is shown/output to the user
163 // (stdout), false = no prompt.
164 // Return: MIstatus::success - Functional succeeded.
165 // MIstatus::failure - Functional failed.
168 void CMICmnStreamStdin::SetEnablePrompt(const bool vbYes) {
169 m_bShowPrompt = vbYes;
173 //------------------------------------------------------------------------------------
174 // Details: Get whether to display optional command line prompt. The prompt is
176 // stdout. Disable it when this may interfere with the client reading
178 // input and it tries to interpret the prompt text to.
181 // Return: bool - True = Yes prompt is shown/output to the user (stdout), false
185 bool CMICmnStreamStdin::GetEnablePrompt() const { return m_bShowPrompt; }
188 //------------------------------------------------------------------------------------
189 // Details: Wait on new line of data from stdin stream (completed by '\n' or
192 // Args: vwErrMsg - (W) Empty string ok or error description.
193 // Return: char * - text buffer pointer or NULL on failure.
196 const char *CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg) {
200 const char *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
201 if (pText == nullptr) {
204 // On Windows, Ctrl-C gives an ERROR_OPERATION_ABORTED as error on the
206 // The end-of-file indicator is also set, so without this check we will exit
207 // next if statement.
208 if (::GetLastError() == ERROR_OPERATION_ABORTED)
212 const bool bForceExit = true;
213 CMIDriver::Instance().SetExitApplicationFlag(bForceExit);
214 } else if (::ferror(stdin) != 0)
215 vwErrMsg = ::strerror(errno);
219 // Strip off new line characters
220 for (char *pI = m_pCmdBuffer; *pI != '\0'; pI++) {
221 if ((*pI == '\n') || (*pI == '\r')) {