Как сделать вывод Facebook/Warp в строку?

Хорошо, так что это в основном то, что мне нужно:

  • Я пытаюсь интегрировать Warp (https://github.com/facebook/warp) в свой D проект
  • Мне нужно получить вывод (предварительной обработки) в строку, а не в файл (как сейчас)

Я внимательно изучил исходники, но, не будучи гуру D, я подумал, что могу упустить что-то очевидное.

Ключ, вероятно, находится в main.d :

            auto foutr = fout.lockingTextWriter();      // has destructor

            context.localStart(sf, &foutr);
            context.preprocess();
            context.localFinish();

С context.localStart() ожидается alias typeof(File.lockingTextWriter()) R; в качестве второго параметра (выходной поток?).

Однако я просто не могу найти это нигде в документации.

Любые идеи?


ОБНОВЛЕНИЕ

Я думаю, что очень близко; Я опубликую полное решение, как только буду уверен на 100%. Но это то, что я заметил в context.d (наверняка юнит-тесты — отличное место для поиска полезного кода! лол)

version (unittest)
{
    void testPreprocess(const Params params, string src, string result)
    {

        uchar[100] tmpbuf = void;
        auto outbuf = Textbuf!uchar(tmpbuf);

        auto context = Context!(Textbuf!uchar)(params);

        // Create a fake source file with contents
        auto sf = SrcFile.lookup("test.c");
        sf.contents = cast(ustring)src;

        context.localStart(sf, &outbuf);

        context.preprocess();

        context.expanded.finish();
        if (outbuf[] != result)
            writefln("output = |%s|", outbuf[]);
        assert(outbuf[] == result);
    }
}

version (all)
{
unittest
{
    const Params params;
    testPreprocess(params,
"asdf\r
asd\\\r
ff\r
",

`# 2 "test.c"
asdf
# 3 "test.c"
asdff
`);
}

d dmd
person Dr.Kameleon    schedule 06.05.2014    source источник
comment
Textbuf, вероятно, является выходным диапазоном, аналогичным тому, который я описал в своей статье. Похоже, он использует opSplice вместо .result, чтобы получить строку ответа.   -  person Adam D. Ruppe    schedule 06.05.2014


Ответы (1)


На самом деле я не смотрел на этот код, но lockingTextWriter — это то, что D называет выходным диапазоном.

Это просто структура с методом put, который принимает строку в качестве аргумента. Таким образом, вы можете получить информацию в виде строки, выполнив следующие действия:

struct StringSink {
    string result;
    void put(in char[] s) { result ~= s; }
}


StringSink sink;
context.localStart(sf, &sink);
.....

string result = sink.result;

Или что-то вдоль этих линий.

person Adam D. Ruppe    schedule 06.05.2014
comment
С char[1000] tmpbuf = void; auto outbuf = Textbuf!char(tmpbuf); и контекстом, объявленным как Context!(Textbuf!char), мне удалось заставить его работать. Чтобы получить вывод в виде строки, ваша идея хороша, но простой to!string(outbuf[]) все еще работает! ;-) - person Dr.Kameleon; 06.05.2014
comment
Да, теперь я помню Textbuf, Уолтер хотел что-то очень быстрое, поэтому он сделал крошечную вещь, которая не выделяет памяти (у меня это простая строка GC!). Но в любом случае круто. - person Adam D. Ruppe; 07.05.2014