Автор Тема: Обёртка для AutoIt-программ, имитирующая область видимости «файл»  (Прочитано 2637 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Spray [?]

  • Новичок
  • *
  • Сообщений: 7
  • Репутация: 1
    • Награды
  • Версия AutoIt: 3.3.14.0
Задача: создание и внедрение обработчика, который в каждом файле к именам функций и переменных добавляет уникальную приставку, но лишь к тем именам, которые начинаются с определённого символа (например, с подчёркивания), после чего будет затуднено использование при подключении через #include. Опционально обработчик должен уметь рекурсивно обработать все файлы, подключаемые через #include "с_кавычками" (чтобы не трогать библиотеки — они на совести собственных разработчиков).

Если не в теме, объясняю, для чего это может быть нужно. В AutoIt функции и глобальные переменные имеют глобальную область видимости, и включая библиотеку по #include вы видите все имена, которые там были объявлены, что может привести к конфликту имён и заставляет напрягаться, придумывая приставки типа «__MyLib_…».

Например, у вас есть два файла:

main.au3:
Код: AutoIt [Выделить]
#inclule "mylib.au3"

global $x

func print_x ()
    ConsoleWrite ($x)
endfunc
 


mylib.au3:
Код: AutoIt [Выделить]
#include-once

global $x

func print_x ()
    MsgBox (0, "", $x)
endfunc
 


Интерпретатор будет ругаться, так как переменная с именем x и функция с именем print_x объявлены дважды. Во избежание конфликта можно изменить имена в файле mylib.au3:

mylib.au3:
Код: AutoIt [Выделить]
#include-once

global $mylib_x

func mylib_print_x ()
    MsgBox (0, "", $mylib_x)
endfunc
 


Выглядит громоздко, особенно когда программа часто обращается к этим именам. Предложенный мною обработчик позволит избежать конфликт, всего лишь добавив в начало имени переменных и функций, которые необходимо скрыть, например, знак подчёркивания. Тогда вот такой файл

mylib.au3:
Код: AutoIt [Выделить]
#include-once

global $_bar1, $bar2

func _foo1 ()
    …
endfunc

func foo2 ()
    …
endfunc
 


автоматически превратится в такой (набор символов в конце имени для надёжности)

mylib.au3:
Код: AutoIt [Выделить]
#include-once

global $mylib_bar1__K3PDVOLEW3RV23K, $bar2

func mylib_foo1__K3PDVOLEW3RV23K ()
    …
endfunc

func foo2 ()
    …
endfunc
 


Так что если его подключить из другого файла с теми же именами _foo1 и _bar1, конфликта не произойдёт, что избавит от лишней нервотрёпки и позволит писать более лёгкий для восприятия код.

Моя реализация

Прикрепил как вложение. Как пользоваться:

FileScope.au3 filename

filename — имя файла, с которого начнётся обработка.

Обрабатываются рекурсивно все файлы, включаемые через #include "с_кавычками". Выходные файлы записываются в папку ~FileScope, которая будет создана рядом с файлом filename, независимо от того, где находится файл обработчика и какая директория является текущей. Взаимное расположение в дереве каталогов сохраняется.

При желании в алгоритм можно добавить обработку ключей, например
-p=nameprefix — будут обработаны имена с этой приставкой (по умолчанию знак подчёркивания)
-s — выключение рекурсивной обработки
-i — выводить файлы в те же папки, где находятся исходные файлы
-f=fix — имя папки, в которую будут записаны выходные файлы, или окончание, которое будет добавлено к именам выходных файлов, если активирован ключ -i (по умолчанию ~FileScope).

Пока что я запускаю сценарий через самописный Makefile перед тем, как код попадёт к компилятору. Неплохо бы прикрутить обработчик к AutoIt3Wrapper, но здесь у меня мало опыта. Может кто из вас осилит эту задачу.


Внимание: Для просмотра прикреплённых файлов необходимо Войти или Зарегистрироваться
« Последнее редактирование: Ноябрь 01, 2017, 07:25:42 от Spray »

Русское сообщество AutoIt


Оффлайн Spray [?]

  • Новичок
  • *
  • Сообщений: 7

  • Автор темы
  • Репутация: 1
    • Награды
  • Версия AutoIt: 3.3.14.0
Сейчас работаю над версией, которая будет не в виде обёртки, которую нужно прикручивать к запуску/компиляции, а будет активироваться при простом включении через #include. Как ей пользоваться:

  • скопировать файл FileScope.au3 в папку Include
  • включить его в стартовый файл вашей программы (#include <FileScope.au3>)
  • файлы проекта, которые также нужно обработать, включить через #import "MyLib.au3"
  • запускать программу в обход AutoIt3Wrapper или с отключением проверки кода

MyProg.au3
Код: AutoIt [Выделить]
#AutoIt3Wrapper_Run_AU3Check=N
#include <FileScope.au3>
#import "MyLib.au3"

global $_private = MyLib_foo () ; Ура, конфликта с повторным объявлением не будет!

ConsoleWrite ($_private) ; В SciTE произойдёт вывод в окно Output!
 


MyLib.au3
Код: AutoIt [Выделить]
global $_private = 10

func MyLib_foo ()
    return $_private
endfunc
 


Для чего всё это нужно? (3) — если включать файлы через обычный #include, то при запуске интерпретатор AutoIt сразу найдёт повторные объявления и приостановит выполнение. (4) — AutoIt3Wrapper предварительно проверяет код, поэтому будет ругаться на все функции из библиотек, «включаемых» по #import, ибо он проигнорирует директиву и просто не найдёт соответствующих объявлении.

Как это работает? Во включаемом FileScope.au3 находится код, который приводится в действие сразу же по запуску вашей программы: автоматически обрабатываются файлы, после чего запускается новый процесс AutoIt, интерпретирующий уже преобразованный код, а текущий процесс остаётся крутиться в цикле, чтобы продолжать обмен данными с новым процессом через стандартные потоки. Обработке подлежат только файлы, включаемые по #import. Обработчик комментирует строчку #include <FileScope.au3> во избежание рекурсии, а все #import заменяет на обычный #include. Обработанные файлы получают расширение .auf и помещаются в папку исходного сценария.

Следующий этап

Новая задача: имитация оператора import наподобие того, как это сделано в Python. А именно:
  • «импортированные» публичные функции (т. е. без подчёркивания в начале) должны быть тоже «зашифрованы» для сокрытия от лишних глаз, чтобы видели их только те, кто импортирует файл напрямую
first.au3:
Код: AutoIt [Выделить]
#AutoIt3Wrapper_Run_AU3Check=N
#include <import>
#import "second.au3"
 


second.au3:
Код: AutoIt [Выделить]
#import "third.au3"
#import "fourth.au3"
 

публичные из third.au3 не должны быть видны ни в first.au3, ни в fourth.au3, только в second.au3 (и для себя, конечно)
  • возможность импортировать публичные функции как есть (будут доступны по оригинальным именам) либо заданной приставкой
Код: AutoIt [Выделить]
#AutoIt3Wrapper_Run_AU3Check=N
#include <import>
#import "foo.au3" as is
#import "bar.au3" with MyPrefix

FuncFromFoo ()
MyPrefix_FuncFromBar ()
FuncFromBar () ; ошибка
 



Внимание: Для просмотра прикреплённых файлов необходимо Войти или Зарегистрироваться
« Последнее редактирование: Ноябрь 01, 2017, 08:03:11 от Spray »

Оффлайн Mute [?]

  • Новичок
  • *
  • Сообщений: 7
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Спасибо, очень пригодился скрипт

Русское сообщество AutoIt


 

Похожие темы

  Тема / Автор Ответов Последний ответ
1 Ответов
3872 Просмотров
Последний ответ Февраль 10, 2011, 21:18:33
от Viktor217
4 Ответов
2633 Просмотров
Последний ответ Ноябрь 29, 2011, 11:58:56
от neobi
8 Ответов
4726 Просмотров
Последний ответ Январь 09, 2012, 23:51:19
от rollex
6 Ответов
3185 Просмотров
Последний ответ Апрель 29, 2012, 02:48:47
от Yashied
4 Ответов
3476 Просмотров
Последний ответ Июнь 07, 2014, 02:10:25
от CreatoR
2 Ответов
1911 Просмотров
Последний ответ Апрель 30, 2013, 16:56:48
от erlik
3 Ответов
3023 Просмотров
Последний ответ Май 04, 2013, 23:22:21
от AZJIO
2 Ответов
450 Просмотров
Последний ответ Август 19, 2017, 12:02:16
от lixar21
4 Ответов
626 Просмотров
Последний ответ Ноябрь 02, 2017, 03:29:22
от dr.room
1 Ответов
354 Просмотров
Последний ответ Январь 22, 2018, 22:18:14
от ra4o