OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 06 Август, 2020 04:51

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: Поправка в TextModels.Reader.ReadRun
СообщениеДобавлено: Вторник, 17 Декабрь, 2019 13:54 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 270
Коллеги,
в документации 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 используется всего дважды, и оба раза клиенты не анализируют текстовый диапазон, а просто пользуются полученными атрибутами. Хорошая новость: предложенные правки не поломают зависимостей. Плохая (для меня): видимо, это не очень приоритетная ошибка ). Но мне помешала в моем небольшом инструменте - поиске и замене цвета текста.

В приложении - модуль, демонстрирующий ошибку, и предлагаемая поправка.

Что скажете, коллеги?


Вложения:
ReadRunBugUnbug.txt [9.62 КБ]
Скачиваний: 128
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Поправка в TextModels.Reader.ReadRun
СообщениеДобавлено: Вторник, 17 Декабрь, 2019 17:10 

Зарегистрирован: Суббота, 04 Май, 2019 10:21
Сообщения: 18
Код:
   PROCEDURE (rd: StdReader) ReadRun (OUT attr: Attributes);
      VAR t: StdModel; a0: Attributes; u0,u, trailer: Piece; pos: INTEGER;
   BEGIN
      t := rd.base;
      IF rd.era # t.era THEN Reset(rd) END;
      a0 := rd.piece.attr; trailer := t.trailer;
      u := rd.piece;u0:=u; pos := rd.pos - rd.pieceOffset;
      WHILE (u.attr = a0) & ~(u IS ViewPiece) & (u # trailer) DO
         INC(pos, u.len); u := u.next
      END;
      IF (u = u0)&(u # trailer) THEN INC(pos, u.len); u := u.next; END;
      rd.piece := u; rd.pos := pos; rd.pieceOffset := 0;
      attr:=u.attr;
   END ReadRun;
Please check this temporary fix


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Поправка в TextModels.Reader.ReadRun
СообщениеДобавлено: Вторник, 17 Декабрь, 2019 18:20 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 270
luowy, it won't compile: StdReader doesn't have .piece (in my version on TextModels).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Поправка в TextModels.Reader.ReadRun
СообщениеДобавлено: Вторник, 17 Декабрь, 2019 18:42 

Зарегистрирован: Суббота, 04 Май, 2019 10:21
Сообщения: 18
ooo, change "piece" to "run" please, I have changed it's name


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Поправка в TextModels.Reader.ReadRun
СообщениеДобавлено: Вторник, 17 Декабрь, 2019 23:02 

Зарегистрирован: Суббота, 04 Май, 2019 10:21
Сообщения: 18
the patch
Код:
   PROCEDURE (rd: StdReader) ReadRun (OUT attr: Attributes);
      VAR t: StdModel; a0: Attributes; u, trailer: Run; pos: INTEGER;
   BEGIN
      t := rd.base;
      IF rd.era # t.era THEN Reset(rd) END;
      a0 := rd.attr; u := rd.run; pos := rd.pos - rd.off; trailer := t.trailer;
      WHILE (u.attr = a0) & ~(u IS ViewRef) & (u # trailer) DO
         INC(pos, u.len); u := u.next
      END;
      rd.run := u; rd.pos := pos; rd.off := 0;
      rd.Read;
      attr := rd.attr;
      IF (rd.view # NIL) THEN rd.attr :=NIL;END;
   END ReadRun;
use this test code
Код:
   PROCEDURE TestHere* (IN what: ARRAY OF CHAR);
      VAR a: TextModels.Attributes; s: ARRAY 16 OF CHAR; p: DevCommanders.Par; fail: BOOLEAN;
         rd, rdr: TextModels.Reader; beg, end: INTEGER; ch: CHAR;
   BEGIN p := DevCommanders.par;
      IF p # NIL THEN rdr := p.text.NewReader(rdr); rd := p.text.NewReader(NIL);
         beg := p.beg; rdr.SetPos(beg); fail := FALSE;
         REPEAT
            IF what = "BUG" THEN rdr.ReadRun(a)
            ELSIF what = "DOCU" THEN Docu(rdr, a)
            ELSIF what = "UNBUG" THEN ReadRun(rdr, a)
            ELSE fail := TRUE
            END;
            IF what = "BUG" THEN
            beg:=rdr.Pos()-1;Log.Int(beg);Log.Tab();
            END;
            end := rdr.Pos(); rd.SetPos(beg);
            IF a # NIL THEN Log.Char('"');
               WHILE beg < end DO rd.ReadChar(ch); Log.Char(ch); INC(beg) END; Log.Char('"');
               GetColName(a.color, s); Log.String(s); Log.Ln;
            END
         UNTIL (rdr.Pos() >= p.end) OR rdr.eot OR fail;
         IF fail THEN Log.String("BUG or UNBUG or DOCU expected"); Log.Ln END
      END
   END TestHere;


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2020, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB