OberonCore
https://forum.oberoncore.ru/

Название импортирующего модуля
https://forum.oberoncore.ru/viewtopic.php?f=29&t=6857
Страница 1 из 1

Автор:  Александр К [ Пятница, 17 Июнь, 2022 15:59 ]
Заголовок сообщения:  Название импортирующего модуля

Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру?

Автор:  Иван Денисов [ Пятница, 17 Июнь, 2022 17:26 ]
Заголовок сообщения:  Re: Название импортирующего модуля

Александр К писал(а):
Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру?

Теоретически может. Есть в StdDebug процедура ShowStack, которая из адреса раскручивает порядок вызова модулей, когда происходит аварийная остановка. Думаю, что аналогично возможно узнать, кто вызвал процедуру.

Автор:  Comdiv [ Пятница, 17 Июнь, 2022 17:45 ]
Заголовок сообщения:  Re: Название импортирующего модуля

При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?".

Автор:  Artyemov [ Суббота, 18 Июнь, 2022 01:12 ]
Заголовок сообщения:  Re: Название импортирующего модуля

Comdiv писал(а):
При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?".

Один из моих знакомых в подобных случаях отвечает:"Спросят, а у меня - есть..."

Автор:  Иван Денисов [ Суббота, 18 Июнь, 2022 06:53 ]
Заголовок сообщения:  Re: Название импортирующего модуля

В целом это может быть какая-то разновизность параметризации вместо кастования типа, если спрашивает один модуль, то вычисляем одним образом, если другой ­— другим. Еще полезно может быть для отладки на лету, вместо ассерта, пишется в журнал, кто вызывал процедуру. Потом можно посчитать статитстику и т.п.

Автор:  Илья Ермаков [ Суббота, 18 Июнь, 2022 14:48 ]
Заголовок сообщения:  Re: Название импортирующего модуля

Код:
   PROCEDURE ModOfCodeAddr (adr: Mem.AddrInt (* = INTEGER в стандартном ББ *)): Kernel.Module;
      VAR m: Kernel.Module;
   BEGIN
      (* TODO: Кэшировать *)
      m := Kernel.modList;
      WHILE (m # NIL) & ~ ((m.code <= adr) & (adr < m.code + m.csize)) DO
         m := m.next
      END;
   RETURN m
   END ModOfCodeAddr;

   PROCEDURE GetCallMod* (level: INTEGER; OUT mod: Kernel.Module);
      VAR ebp, ret: INTEGER;
   BEGIN
      S.GETREG(5, ebp);
      S.GET(ebp + 4, ret);
      WHILE level > 0 DO
         S.GET(ebp, ebp);
         S.GET(ebp + 4, ret);
         DEC(level)
      END;
      mod := ModOfCodeAddr(ret);
   END GetCallMod;

   PROCEDURE NameOfProcAddr (adr: Mem.AddrInt; OUT m: Kernel.Module; OUT name: ARRAY OF CHAR);
      VAR ref, radr: Mem.AddrInt; s: Kernel.Name;
   BEGIN
      m := NIL; name := "";
      Kernel.SearchProcVar(adr, m, adr);
      IF m # NIL THEN
         IF m.refcnt < 0 THEN
            m := NIL
         ELSE
            ref := m.refs;
            REPEAT
               Kernel.GetRefProc(ref, radr, s)
            UNTIL (radr = 0) OR (adr < radr);
            IF adr < radr THEN
               name := s$
            ELSE
               m := NIL
            END
         END
      END
   END NameOfProcAddr;

   PROCEDURE GetCallProc* (level: INTEGER; OUT mod, proc: ARRAY OF CHAR);
      VAR ebp, ret: INTEGER;
         m: Kernel.Module;
   BEGIN
      S.GETREG(5, ebp);
      S.GET(ebp + 4, ret);
      WHILE level > 0 DO
         S.GET(ebp, ebp);
         S.GET(ebp + 4, ret);
         DEC(level)
      END;
      NameOfProcAddr(ret, m, proc);
      IF m # NIL THEN
         mod := m.name$
      ELSE
         mod := ""
      END
   END GetCallProc;



Чисто имя модуля - GetCallMod.
С точностью до имени процедуры - GetCallProc.

level = 1 - непосредственно вызывающий уровень, 2 - ещё на уровень выше по стеку и т. д. (лучше было бы, наверное, в минус нумеровать).

Код вырезан из двух модулей, чтобы опубликовать здесь, мелочи могут быть некомпилируемы, но разберётесь.

Автор:  Александр К [ Суббота, 18 Июнь, 2022 14:56 ]
Заголовок сообщения:  Re: Название импортирующего модуля

Цитата:
При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?".

Я хочу сделать свой "Рабочий журнал". Все сообщения в нём будут делиться по важности на маловажные, важные и большой важности (степень важности будет указываться программистом при отправке сообщений). При этом пользователь будет иметь возможность настраивать внешний вид сообщений для каждой степени важности и выбирать какие по степени важности сообщения конкретных модулей или всех модулей показывать. Будет так же опция показа какое сообщение вывел какой модуль.

Такое я видел в космической игре "Цивилизация". Там можно было выбрать, какие сообщения показывать (что-то вроде фильтра).

Автор:  Илья Ермаков [ Суббота, 18 Июнь, 2022 15:19 ]
Заголовок сообщения:  Re: Название импортирующего модуля

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

Если делаете именно под конкретное понимание - то хорошо.

Если делаете "в общем" - то, в принципе, неплохая тренировка/пример. Который, опять же, можно будет взять за основу, если для какой-то конкретной системы что-то подобное потребуется.

Автор:  Александр Ильин [ Суббота, 18 Июнь, 2022 17:38 ]
Заголовок сообщения:  Re: Название импортирующего модуля

Александр К писал(а):
Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру?
Конечно! Достаточно в список параметров процедуры добавить параметр "ИмяВызывающегоМодуля". Все будут должны его предоставить при вызове.

Автор:  Иван Денисов [ Четверг, 01 Декабрь, 2022 05:31 ]
Заголовок сообщения:  Re: Название импортирующего модуля

Илья Ермаков писал(а):
Чисто имя модуля - GetCallMod.
С точностью до имени процедуры - GetCallProc.

level = 1 - непосредственно вызывающий уровень, 2 - ещё на уровень выше по стеку и т. д. (лучше было бы, наверное, в минус нумеровать).

Код вырезан из двух модулей, чтобы опубликовать здесь, мелочи могут быть некомпилируемы, но разберётесь.


Илья, очень благодарен, что делишься кодом. Меня сильно выручил этот пример!

Александр, а вам спасибо, что задаёте вопросы, которые пополняют базу знаний на форуме!

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/