A lot of comments in LLDB are surrounded by an ASCII line to delimit the begging and end of the comment. Its use is not really consistent across the code base, sometimes the lines are longer, sometimes they are shorter and sometimes they are omitted. Furthermore, it looks kind of weird with the 80 column limit, where the comment actually extends past the line, but not by much. Furthermore, when /// is used for Doxygen comments, it looks particularly odd. And when // is used, it incorrectly gives the impression that it's actually a Doxygen comment. I assume these lines were added to improve distinguishing between comments and code. However, given that todays editors and IDEs do a great job at highlighting comments, I think it's worth to drop this for the sake of consistency. The alternative is fixing all the inconsistencies, which would create a lot more churn. Differential revision: https://reviews.llvm.org/D60508 llvm-svn: 358135
219 lines
6.0 KiB
C++
219 lines
6.0 KiB
C++
//===-- MICmnStreamStdin.cpp ------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Third Party Headers
|
|
#ifdef _MSC_VER
|
|
#include <windows.h>
|
|
#endif
|
|
#include <string.h>
|
|
|
|
// In-house headers:
|
|
#include "MICmnLog.h"
|
|
#include "MICmnResources.h"
|
|
#include "MICmnStreamStdin.h"
|
|
#include "MICmnStreamStdout.h"
|
|
#include "MIDriver.h"
|
|
#include "MIUtilSingletonHelper.h"
|
|
|
|
//++
|
|
// Details: CMICmnStreamStdin constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmnStreamStdin::CMICmnStreamStdin()
|
|
: m_strPromptCurrent("(gdb)"), m_bShowPrompt(true), m_pCmdBuffer(nullptr) {}
|
|
|
|
//++
|
|
// Details: CMICmnStreamStdin destructor.
|
|
// Type: Overridable.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmnStreamStdin::~CMICmnStreamStdin() { Shutdown(); }
|
|
|
|
//++
|
|
// Details: Initialize resources for *this Stdin stream.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmnStreamStdin::Initialize() {
|
|
m_clientUsageRefCnt++;
|
|
|
|
if (m_bInitialized)
|
|
return MIstatus::success;
|
|
|
|
bool bOk = MIstatus::success;
|
|
CMIUtilString errMsg;
|
|
|
|
// Note initialisation order is important here as some resources depend on
|
|
// previous
|
|
MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
|
|
MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
|
|
|
|
if (bOk) {
|
|
m_pCmdBuffer = new char[m_constBufferSize];
|
|
} else {
|
|
CMIUtilString strInitError(CMIUtilString::Format(
|
|
MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
|
|
SetErrorDescription(strInitError);
|
|
|
|
return MIstatus::failure;
|
|
}
|
|
m_bInitialized = bOk;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++
|
|
// Details: Release resources for *this Stdin stream.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmnStreamStdin::Shutdown() {
|
|
if (--m_clientUsageRefCnt > 0)
|
|
return MIstatus::success;
|
|
|
|
if (!m_bInitialized)
|
|
return MIstatus::success;
|
|
|
|
m_bInitialized = false;
|
|
|
|
ClrErrorDescription();
|
|
|
|
if (m_pCmdBuffer != nullptr) {
|
|
delete[] m_pCmdBuffer;
|
|
m_pCmdBuffer = nullptr;
|
|
}
|
|
|
|
bool bOk = MIstatus::success;
|
|
CMIUtilString errMsg;
|
|
|
|
MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
|
|
MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
|
|
|
|
if (!bOk) {
|
|
SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
|
|
}
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++
|
|
// Details: Validate and set the text that forms the prompt on the command line.
|
|
// Type: Method.
|
|
// Args: vNewPrompt - (R) Text description.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt) {
|
|
if (vNewPrompt.empty()) {
|
|
const CMIUtilString msg(CMIUtilString::Format(
|
|
MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
|
|
CMICmnStreamStdout::Instance().Write(msg);
|
|
return MIstatus::failure;
|
|
}
|
|
|
|
m_strPromptCurrent = vNewPrompt;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++
|
|
// Details: Retrieve the command line prompt text currently being used.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: const CMIUtilString & - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
const CMIUtilString &CMICmnStreamStdin::GetPrompt() const {
|
|
return m_strPromptCurrent;
|
|
}
|
|
|
|
//++
|
|
// Details: Set whether to display optional command line prompt. The prompt is
|
|
// output to
|
|
// stdout. Disable it when this may interfere with the client reading
|
|
// stdout as
|
|
// input and it tries to interpret the prompt text to.
|
|
// Type: Method.
|
|
// Args: vbYes - (R) True = Yes prompt is shown/output to the user
|
|
// (stdout), false = no prompt.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
void CMICmnStreamStdin::SetEnablePrompt(const bool vbYes) {
|
|
m_bShowPrompt = vbYes;
|
|
}
|
|
|
|
//++
|
|
// Details: Get whether to display optional command line prompt. The prompt is
|
|
// output to
|
|
// stdout. Disable it when this may interfere with the client reading
|
|
// stdout as
|
|
// input and it tries to interpret the prompt text to.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: bool - True = Yes prompt is shown/output to the user (stdout), false
|
|
// = no prompt.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmnStreamStdin::GetEnablePrompt() const { return m_bShowPrompt; }
|
|
|
|
//++
|
|
// Details: Wait on new line of data from stdin stream (completed by '\n' or
|
|
// '\r').
|
|
// Type: Method.
|
|
// Args: vwErrMsg - (W) Empty string ok or error description.
|
|
// Return: char * - text buffer pointer or NULL on failure.
|
|
// Throws: None.
|
|
//--
|
|
const char *CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg) {
|
|
vwErrMsg.clear();
|
|
|
|
// Read user input
|
|
const char *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
|
|
if (pText == nullptr) {
|
|
#ifdef _MSC_VER
|
|
// Was Ctrl-C hit?
|
|
// On Windows, Ctrl-C gives an ERROR_OPERATION_ABORTED as error on the
|
|
// command-line.
|
|
// The end-of-file indicator is also set, so without this check we will exit
|
|
// next if statement.
|
|
if (::GetLastError() == ERROR_OPERATION_ABORTED)
|
|
return nullptr;
|
|
#endif
|
|
if (::feof(stdin)) {
|
|
const bool bForceExit = true;
|
|
CMIDriver::Instance().SetExitApplicationFlag(bForceExit);
|
|
} else if (::ferror(stdin) != 0)
|
|
vwErrMsg = ::strerror(errno);
|
|
return nullptr;
|
|
}
|
|
|
|
// Strip off new line characters
|
|
for (char *pI = m_pCmdBuffer; *pI != '\0'; pI++) {
|
|
if ((*pI == '\n') || (*pI == '\r')) {
|
|
*pI = '\0';
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pText;
|
|
}
|