OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 17:44

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




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

Зарегистрирован: Воскресенье, 06 Август, 2017 19:33
Сообщения: 79
Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 17 Июнь, 2022 17:26 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Александр К писал(а):
Может ли импортируемый модуль узнать имя импортирующего модуля, который вызывает его процедуру?

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 17 Июнь, 2022 17:45 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 18 Июнь, 2022 01:12 

Зарегистрирован: Пятница, 13 Март, 2015 16:40
Сообщения: 597
Comdiv писал(а):
При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?".

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 18 Июнь, 2022 06:53 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
В целом это может быть какая-то разновизность параметризации вместо кастования типа, если спрашивает один модуль, то вычисляем одним образом, если другой ­— другим. Еще полезно может быть для отладки на лету, вместо ассерта, пишется в журнал, кто вызывал процедуру. Потом можно посчитать статитстику и т.п.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 18 Июнь, 2022 14:48 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Код:
   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 

Зарегистрирован: Воскресенье, 06 Август, 2017 19:33
Сообщения: 79
Цитата:
При таких вопросах больше всего интересует не основной ответ, а ответ на вопрос "зачем?".

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 18 Июнь, 2022 15:19 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Если пытаетесь сделать общее решение - то вряд ли получится, такую штуку нужно проектировать и дотачивать под конкретный тип применений.

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 18 Июнь, 2022 17:38 
Аватара пользователя

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 01 Декабрь, 2022 05:31 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Илья Ермаков писал(а):
Чисто имя модуля - GetCallMod.
С точностью до имени процедуры - GetCallProc.

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

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


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

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


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

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


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

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


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

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