Что нового

Создаём свой Au3Stripper на AutoIt

Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
veretragna [?]
чтобы убирались, например, отладочные ветки кода из релиза
Можно завести директиву, типа #Au3Stripper_Debug/Remove_Start/End, и просто очищать код в её приделах.
 

asdf8

Скриптер
Сообщения
564
Репутация
152

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
CreatoR, отличная идея с отдельной директивой!

Прошу озвучить все :smile:.
Пожалуй, наилучшим вариантом можно назвать идею с запоминанием положения первого и последнего байта Func/EndFunc или объявления переменной.
Долго думал над проблемой и подумалось, что регулярные выражения нам в этом деле не подходят, поскольку, если скрипт прокручивать через StringRegExpReplace для каждой переменной/функции из длинного списка, еще и по очереди в цикле, произойдет очень много итераций, а производительность в таком случае будет нулевой.
Да и не нужны они, по большому счету. Если переменную объявили, но не используют и упоминание её в коде всего одно (когда объявляют), то какой смысл заменять фразу объявления по регулярке во всем скрипте? Достаточно переместить указатель в позицию первого байта объявления, удалить объявление и всего делов.
Даже чисто гипотетически прокрутить сферические 100 кб скрипта регуляркой через список из 500 переменных по очереди, а вторым циклом еще и функции повырезать... жутко становится.
Но если в одну итерацию пройтись по скрипту, перечислить функции и переменные, запомнить их положение, а второй итерацией вырезать их или (заполнить эти интервалы пробелами/StringStripWS в финале на весь скрипт), работать программа будет быстро.

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

Интрига в задаче есть, и когда выдастся минутка после работы, попробую нечто такое сваять. Заодно и проверю работоспособность и производительность метода. Буду держать в курсе дела.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
asdf8 сказал(а):
Прощай совместимость с Au3Check.exe.
А как это связано?

asdf8 сказал(а):
Прощай портативность.
Au3Stripper сейчас так и работает, что не позволяет использовать его разные версии. INI в этом плане решает проблему.

CreatoR, если не удасться приблизить скорость работы хотя бы к 1/3 от оригинала, то нужно что-то думать... Лучше сразу этим озаботиться. Может имеет смысл привлечь к проекту знатоков PB?
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Yashied [?]

Я так понял, что речь идет о путях поиска подключаемых файлов. Какие еще пути нужны для подобной утилиты?
Ни Au3Check.exe, ни AutoIt3.exe не будут искать дополнительные пути для подключаемых файлов ни в каких в ini-файлах, соответственно не смогут корректно работать с необработанными скриптами.


Цитата: asdf8 от Сегодня в 13:43:10
Прощай портативность.
Au3Stripper сейчас так и работает, что не позволяет использовать его разные версии.

В моей сборке SciTe Au3Stripper не видит реальный реестр и поэтому может корректно работать портативно.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
asdf8, Au3Stripper написан в стиле Jos'а, т.е. привязан к местоположению. Для нормальной работы стриппера необходим как минимум каталог Include той версии, для которой написан скрипт. Au3Stripper ищет Include так:
  • ..\..\Include
  • HKEY_CURRENT_USER\Software\AutoIt v3\AutoIt, Include
В первом случае реестр не используется, во втором путь берется из реестра. Вот именно этот костыль мы и хотим убрать.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Yashied [?]
Вот именно этот костыль мы и хотим убрать.

Против этого как раз ничего не имею против. Я имел в виду другое, хотя какая разница, если исходники будут открытыми.


[?]
если не удасться приблизить скорость работы хотя бы к 1/3 от оригинала, то нужно что-то думать.

Т.е. в 3 раза медленнее чем Au3Stripper ? По моему Au3Stripper работает черезчур медленно даже для скорости AutoIt, у меня на одном проекте он более полутора минут возится.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Yashied
Моя версия вот такой скрипт:
Код:
#include <WinAPI.au3>
#include <WinAPIFiles.au3>
ConsoleWrite(_WinAPI_GetFileTitle(@ScriptFullPath) & @LF)
MsgBox(64, @ScriptName, _WinAPI_GetClassName(WinGetHandle('')))

обрабатывает где то за 7 секунд, и это без удаления неиспользуемых переменных (ещё не прикрутил).
Использовался AutoIt 3.3.10.2 (для стрипера и скрипта).

Это можно назвать медленной работой?

Кстати, по моему Au3Stripper каким то образом кеширует то что он делает, т.к первая попытка стрипа всегда медленнее чем последующие (для того же скрипта).
 

Prog

Продвинутый
Сообщения
537
Репутация
65
CreatoR [?]
Кстати, по моему Au3Stripper каким то образом кеширует то что он делает, т.к первая попытка стрипа всегда медленнее чем последующие (для того же скрипта).
Это наверное винда кеширует файлы.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
CreatoR [?]
Моя версия вот такой скрипт:

#include <WinAPI.au3>
#include <WinAPIFiles.au3>
ConsoleWrite(_WinAPI_GetFileTitle(@ScriptFullPath) & @LF)
MsgBox(64, @ScriptName, _WinAPI_GetClassName(WinGetHandle('')))

обрабатывает где то за 7 секунд, и это без удаления неиспользуемых переменных

...

Это можно назвать медленной работой?

Это только склейка скрипта и подключаемых файлов в один файл? Если да - то это совсем не быстро.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
veretragna [?]
Пожалуй, наилучшим вариантом можно назвать идею с запоминанием положения первого и последнего байта Func/EndFunc или объявления переменной.
Не всё так просто.
Для функции, достаточно пройтись по именам функции полученных с RegExp и проверять лишь код с которого можно заранее вырезать все функции, а по завершению прохода вырезать не найденные, это оптимальный способ.
Но для переменных всё гораздо сложнее, нужно учитывать что объявление глобальных переменных может выполняться и внутри функции, поэтому проходить нужно весь код.
Мне кажется без регулярок тут не обойтись.

В общем прикладываю версию где очищаются неиспользуемые функции (#OnAutoItStartRegister не учитывается), до переменных пока не дошёл.
 

Вложения

  • A3S.zip
    4.8 КБ · Просмотры: 8
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
asdf8 [?]
Это только склейка скрипта и подключаемых файлов в один файл?
Нет, это включая очистку неиспользуемых функции.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Затрудняюсь понять, как в строке отличить переменные которым присваиваются значения, от переменных, которые проверяются в условии? :scratch:

Например:
Код:
If $iAsk = 6 Then $iVar = 1

Как тут получить именно присваиваемую переменную ($iVar), вместо проверяемой ($iAsk)?

Из моих наблюдении, Au3Stripper не трогает подобные переменные, он вырезает лишь те переменные, которые не имеют условия или вызовы функции.
Даже больше скажу, он не вырезает весь набор переменных, если одна из этих переменных используется:

Код:
Global $test = 0, $test2, $test3 = 1
If $test2 Then  MsgBox(36, '', 'Ok?')

Он тут ничего не вырежет, хотя должен вырезать $test и $test3...
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Вроде нашёл багу в Au3Stripper:

Код:
test()
ConsoleWrite($test & @LF)

Func test()
	Global $test = 1
EndFunc


Global $test = 1 будет удалена, хотя и используется.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
CreatoR [?]
Затрудняюсь понять, как в строке отличить переменные которым присваиваются значения, от переменных, которые проверяются в условии?

Думаю встроенные функции AutoIt нужно проверять по отдельному списку правил, чтобы точно знать где искать объявления, присваивание или проверку условия.

ps: Не пойму зачем выносить этот список правил в ini-файл - это же практически константа.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
asdf8
Я пришёл к тому же мнению что и разработчик Au3Stripper - не нужно трогать условные переменные, только "чистое" объявление.

[?]
зачем выносить этот список правил в ini-файл
Чтобы добавлять другие функции, например у меня там ещё и эти:

Код:
_timer_settimer,3,0
_mousesetonevent,2,0
_winapi_registerwindowmessage,1,0
 

asdf8

Скриптер
Сообщения
564
Репутация
152
CreatoR [?]
Чтобы добавлять другие функции, например у меня там ещё и эти:

Имхо - правильнее, для поддержки совместимости, в UDF заносить такие функции в исключения (#Au3Stripper_Ignore_Funcs, #Au3Stripper_Ignore_Variables и т.п.)
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
asdf8 [?]
Имхо - правильнее, для поддержки совместимости, в UDF заносить такие функции в исключения (#Au3Stripper_Ignore_Funcs, #Au3Stripper_Ignore_Variables и т.п.)
Это не исключение, а использование функции/переменных.

Код:
_UDF_Wrapper('test') ;UDF заранее не знает имени функции

Func test()
	MsgBox(64, @ScriptName, 'test')
EndFunc

;UDF
Func _UDF_Wrapper($sFunc)
	Call($sFunc)
EndFunc


Этот список облегчает работу разработчику (как UDF, так и пользователю UDF).
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Короче вроде всё получилось сделать (хотя результат немного отличается от Au3Stripper, но у него свой алгоритм, а у меня свой :smile:)...
Вот такой скрипт очищает за ~6 секунд (это включая удаление неиспользуемых функции и переменных, без этого намного быстрее):

Код:
#include <WinAPI.au3>
#include <WinAPIFiles.au3>
ConsoleWrite(_WinAPI_GetFileTitle(@ScriptFullPath) & @LF)
MsgBox(64, @ScriptName, _WinAPI_GetClassName(WinGetHandle('')))


Это медленно?
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
CreatoR, а ручками это дело пощупать можно? =)
Мой недо-стриппер работает значительно медленнее и не совсем стабильно, сказывается отсутствие опыта.
 
Верх