You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测特定字符时关闭STDIN并获取llvm::MemoryBuffer内容?

Got it, let's tackle this problem. The issue here is that llvm::MemoryBuffer::getFileOrSTDIN("-") is designed to read all of stdin until it hits EOF (like when you press Ctrl+D on Unix or Ctrl+Z on Windows), but you want to stop reading as soon as a specific <END_CHAR> is encountered.

The fix is to handle the stdin case manually instead of relying on getFileOrSTDIN, since that function doesn't support custom termination characters. Here's how to do it properly within the LLVM ecosystem:

First, create a helper function that checks if we're reading from stdin, then reads characters until your end marker is found, and wraps the result in a MemoryBuffer:

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Error.h"

llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> getSourceBuffer(const std::string& File, char EndChar) {
    if (File == "-") {
        std::string inputContent;
        char currentChar;
        std::error_code readErr;

        // Read from stdin one character at a time until we hit EndChar or an error
        while ((readErr = llvm::sys::fs::readSTDIN(&currentChar, 1)) == 0 && currentChar != EndChar) {
            inputContent += currentChar;
        }

        // Handle any unexpected errors (ignore EOF if we didn't hit EndChar? Adjust as needed)
        if (readErr && readErr != llvm::errc::no_such_file_or_directory) { // EOF returns this code in LLVM's readSTDIN
            return llvm::make_error<llvm::StringError>(readErr.message(), readErr);
        }

        // Create a MemoryBuffer from our collected content; "<stdin>" is the buffer name for diagnostics
        return llvm::MemoryBuffer::getMemBufferCopy(inputContent, "<stdin>");
    } else {
        // Use the original function for regular files
        return llvm::MemoryBuffer::getFileOrSTDIN(File);
    }
}

Then replace your original getSource line with a call to this helper:

auto Source = getSourceBuffer(File, '<END_CHAR>'); // Replace '<END_CHAR>' with your actual termination character
if (std::error_code err = Source.getError()) {
    llvm::errs() << err.message();
} else {
    someFunction(std::move(*Source), File, makeOutputWriter(Format, llvm::outs()), IdentifiersOnly, DumpAST);
}

Why this works:

  • We bypass getFileOrSTDIN for stdin, since it's hardcoded to wait for EOF.
  • Using llvm::sys::fs::readSTDIN keeps us within LLVM's I/O utilities (avoiding potential issues with C++ standard streams interacting with LLVM's own handling).
  • Once we hit your <END_CHAR>, we stop reading immediately, package the collected content into a MemoryBuffer, and proceed to someFunction without blocking.

You can adjust the error handling logic to match your needs—for example, if hitting EOF before <END_CHAR> should be considered an error, you can add a check for that and return an appropriate error message.

内容的提问来源于stack exchange,提问作者Mathieu Nls

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:39:13