Коллеги,
в документации TextModels.Reader.ReadRun говорится:
Цитата:
Read next attribute run, stops at next view. (*1*)
Я истолковываю "read next attribute run" так:
Код:
Post:
(attr = AttributeOf(rd.Pos() - 1)) & (rd.eot OR (attr # AttributeOf(rd.Pos())) (*2*)
Мой пример (в приложении) демонстрирует, что TextModels.StdReader.ReadRun не удовлетворяет такому толкованию: она НЕ останавливает ридер сразу же после окончания диапазона, который имеет атрибуты attr. Такая ReadRun бесполезна, если нужно перебирать диапазоны текста по атрибутам. Хотя это не ошибка - поскольку ReadRun не удовлетворяет моему истолкованию, а не явно прописанным постусловиям, - все же я предлагаю внести изменения в документацию и включить туда мое истолкование (*2*). Я полагаю, что оно здраво и соответствует тексту (*1*) и логике использования ридеров.
Все за?
Если все за, то теперь - в ReadRun ошибка! Шучу.
Далее, в документации сказано:
Цитата:
Except for performance, equivalent to:
Код:
VAR a: Attributes;
a := rd.attr;
REPEAT rd.Read UNTIL (rd.attr # a) OR (rd.view # NIL) OR rd.eot;
IF rd.eot THEN attr := NIL ELSE attr := rd.attr END
И это тоже не соответствует (*2*).
Предлагаю универсальную поправку на уровне TextModels.Reader.ReadRun, а не .StdReader.ReadRun (поскольку я не разбираюсь в тонкостях организации StdReader/StdModel):
ЗАМЕНИТЬ в TextModels всю процедуру PROCEDURE (rd: Reader) ReadRun* (OUT attr: Attributes), NEW, ABSTRACT;
СЛЕДУЮЩИМ:
Код:
PROCEDURE (rd: Reader) ReadRun* (OUT attr: TextModels.Attributes), NEW, EXTENSIBLE;
(** post: rd.eot OR a # NIL, rd.view = ViewAt(rd.Pos() - 1) **)
BEGIN
rd.Read; attr := rd.attr;
IF rd.view = NIL THEN
WHILE (rd.attr = attr) & (rd.view = NIL) & ~rd.eot DO rd.Read END;
IF ~rd.eot OR (rd.view # NIL) THEN rd.ReadPrev END
END
END ReadRun;
А имеющуюся реализацию PROCEDURE (rd: StdReader) ReadRun - закомментировать: возможно, кто-нибудь когда-нибудь захочет вникнут и поправить там.
Поиск по исходникам в стандартной сборке показал, что ReadRun используется всего дважды, и оба раза клиенты не анализируют текстовый диапазон, а просто пользуются полученными атрибутами. Хорошая новость: предложенные правки не поломают зависимостей. Плохая (для меня): видимо, это не очень приоритетная ошибка ). Но мне помешала в моем небольшом инструменте - поиске и замене цвета текста.
В приложении - модуль, демонстрирующий ошибку, и предлагаемая поправка.
Что скажете, коллеги?