1 //===-- MICmnStreamStdin.cpp ------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
17 #include "MICmnResources.h"
18 #include "MICmnStreamStdin.h"
19 #include "MICmnStreamStdout.h"
21 #include "MIUtilSingletonHelper.h"
24 // Details: CMICmnStreamStdin constructor.
30 CMICmnStreamStdin::CMICmnStreamStdin()
31 : m_strPromptCurrent("(gdb)"), m_bShowPrompt(true), m_pCmdBuffer(nullptr) {}
34 // Details: CMICmnStreamStdin destructor.
40 CMICmnStreamStdin::~CMICmnStreamStdin() { Shutdown(); }
43 // Details: Initialize resources for *this Stdin stream.
46 // Return: MIstatus::success - Functional succeeded.
47 // MIstatus::failure - Functional failed.
50 bool CMICmnStreamStdin::Initialize() {
51 m_clientUsageRefCnt++;
54 return MIstatus::success;
56 bool bOk = MIstatus::success;
59 // Note initialisation order is important here as some resources depend on
61 MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
62 MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
65 m_pCmdBuffer = new char[m_constBufferSize];
67 CMIUtilString strInitError(CMIUtilString::Format(
68 MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
69 SetErrorDescription(strInitError);
71 return MIstatus::failure;
75 return MIstatus::success;
79 // Details: Release resources for *this Stdin stream.
82 // Return: MIstatus::success - Functional succeeded.
83 // MIstatus::failure - Functional failed.
86 bool CMICmnStreamStdin::Shutdown() {
87 if (--m_clientUsageRefCnt > 0)
88 return MIstatus::success;
91 return MIstatus::success;
93 m_bInitialized = false;
95 ClrErrorDescription();
97 if (m_pCmdBuffer != nullptr) {
98 delete[] m_pCmdBuffer;
99 m_pCmdBuffer = nullptr;
102 bool bOk = MIstatus::success;
103 CMIUtilString errMsg;
105 MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
106 MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
109 SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
112 return MIstatus::success;
116 // Details: Validate and set the text that forms the prompt on the command line.
118 // Args: vNewPrompt - (R) Text description.
119 // Return: MIstatus::success - Functional succeeded.
120 // MIstatus::failure - Functional failed.
123 bool CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt) {
124 if (vNewPrompt.empty()) {
125 const CMIUtilString msg(CMIUtilString::Format(
126 MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
127 CMICmnStreamStdout::Instance().Write(msg);
128 return MIstatus::failure;
131 m_strPromptCurrent = vNewPrompt;
133 return MIstatus::success;
137 // Details: Retrieve the command line prompt text currently being used.
140 // Return: const CMIUtilString & - Functional failed.
143 const CMIUtilString &CMICmnStreamStdin::GetPrompt() const {
144 return m_strPromptCurrent;
148 // Details: Set whether to display optional command line prompt. The prompt is
150 // stdout. Disable it when this may interfere with the client reading
152 // input and it tries to interpret the prompt text to.
154 // Args: vbYes - (R) True = Yes prompt is shown/output to the user
155 // (stdout), false = no prompt.
156 // Return: MIstatus::success - Functional succeeded.
157 // MIstatus::failure - Functional failed.
160 void CMICmnStreamStdin::SetEnablePrompt(const bool vbYes) {
161 m_bShowPrompt = vbYes;
165 // Details: Get whether to display optional command line prompt. The prompt is
167 // stdout. Disable it when this may interfere with the client reading
169 // input and it tries to interpret the prompt text to.
172 // Return: bool - True = Yes prompt is shown/output to the user (stdout), false
176 bool CMICmnStreamStdin::GetEnablePrompt() const { return m_bShowPrompt; }
179 // Details: Wait on new line of data from stdin stream (completed by '\n' or
182 // Args: vwErrMsg - (W) Empty string ok or error description.
183 // Return: char * - text buffer pointer or NULL on failure.
186 const char *CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg) {
190 const char *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
191 if (pText == nullptr) {
194 // On Windows, Ctrl-C gives an ERROR_OPERATION_ABORTED as error on the
196 // The end-of-file indicator is also set, so without this check we will exit
197 // next if statement.
198 if (::GetLastError() == ERROR_OPERATION_ABORTED)
202 const bool bForceExit = true;
203 CMIDriver::Instance().SetExitApplicationFlag(bForceExit);
204 } else if (::ferror(stdin) != 0)
205 vwErrMsg = ::strerror(errno);
209 // Strip off new line characters
210 for (char *pI = m_pCmdBuffer; *pI != '\0'; pI++) {
211 if ((*pI == '\n') || (*pI == '\r')) {