yea, the Tests are an extremely important part of this project, make sure to keep adding them in as you test them. even if they seem like basic and trivial tests
v1 -> v2 Script Converter
Re: v1 -> v2 Script Converter
Re: v1 -> v2 Script Converter
Almost completed adding tests of all v1 ahk doc examples of the Window section!!!
Hard work, but the only way to detect the errors...
I have included the old tests from test.ahk into my test system. I find it easier to manage them this way.
Re: v1 -> v2 Script Converter
ok, i like yunit because sometimes it can give you information about where the test failed, like what line number. i wonder if they can be somehow combined. but whatever works for you. i leave those decisions to you, since you are the active developer right now.
Re: v1 -> v2 Script Converter
That is indeed usefull information, but it took to much time to add tests to tests.ahk, this should not be asking that much time, currently I just check if the converted code is equal to the expected code. If some code fails, I run it manually. I have added the line numbers in the statusbar (similar to our beloved Notepad)
Re: v1 -> v2 Script Converter
Registry convertion added, all examples of the registry documentation are working now
Re: v1 -> v2 Script Converter
user Frankie started this converter many years ago on the old forum. i built on top of his foundation. and now AHK_user is doing amazing work building on what i did. community effort
Re: v1 -> v2 Script Converter
I just ran the converter on my scripts, and I have a few observations. Overall, the percentage of the code that did convert is amazing. I have code from 2009-ish (pre-1.1!!!!), so . I will probably have to re-write some of my modules due to some of the breaking changes, and the fact that it was written before Objects.
- Loop statements frequently had the opening brace quoted when input uses One True Brace style.
Spoiler
- Gosub Hotstring, which is invalid in v2, not handled.Spoiler
- A old-array to new in local statement ... not smart enough.Spoiler
- Conversion of old assign operator is inconsistent. An example...Spoiler
- Pause is not converted like Suspend.
- SendRaw not converted.
- Comment lines confuse the block enclosing logic. I moved and/or added a bunch of closing braces.
Re: v1 -> v2 Script Converter
Thanks for the compliment. It is indeed a huge job.Lorien wrote: ↑22 Sep 2021, 08:36I just ran the converter on my scripts, and I have a few observations. Overall, the percentage of the code that did convert is amazing. I have code from 2009-ish (pre-1.1!!!!), so . I will probably have to re-write some of my modules due to some of the breaking changes, and the fact that it was written before Objects.
- Loop statements frequently had the opening brace quoted when input uses One True Brace style.
Spoiler- Gosub Hotstring, which is invalid in v2, not handled.
Spoiler- A old-array to new in local statement ... not smart enough.
Spoiler- Conversion of old assign operator is inconsistent. An example...
Spoiler- Pause is not converted like Suspend.
- SendRaw not converted.
- Comment lines confuse the block enclosing logic. I moved and/or added a bunch of closing braces.
And thanks for detecting some error conversions . Some of them are simple to solve, others are harder to figure out...
If it is possible, could you please provide me a simple short examples of fully working V1 script that demonstrates the error and a short description what it should do, this facilitates my work. A suggestion of the correct V2 conversion is also of course welcome. Not all conversions are easy or even possible, but I am starting to collect small examples that result wrong errors.
1. Loop = DONE
I'm little suprized that I did not encountered this error, should be fixed now.
2. Gosub Hotstring
It indeed does not work, any idea what the correct conversion should be like? The current convertor tries to changing the label into a fuction.
? Can you provide me a short example?
3. A old-array to new in local statement ... not smart enough.
I disabled at the array conversion at the moment for lines with local, static and global better to do no conversion than an fault one.
? Can you provide me a short example? I should think how to handle this, there is a danger that in large scripts where same name of variables is used, other problems will occur.
4. Conversion of old assign operator is inconsistent.
? Is this v1 code
? Can you provide me a short working v1 example?
5. Pause is now added into the conversion =DONE
The second parameter OperateOnUnderlyingThread is currently ignored
Two questions: How should this be converted and does somebody uses this?
6. SendRaw DONE
7. Comment lines confuse the bloc enclosing logic
=> Can you provide me a short example?
Re: v1 -> v2 Script Converter
Short answer: I think you will probably need to generate a warning or error message. The Gosub and the hotstring it is trying to call are not in the same file.
Long answer: This is one of the things that will probably cause me to start writing my scripts anew. I'm not sure how I'm going to do it, yet. I run a single instance of AHK. On startup, it scans all of the included files for hotkeys and hotstrings, and builds pair of menus as both "help" and quick access. This line of code is in the menu handler for the hotstrings menu. I will have to wrap ALL of my hotstrings in functions in order for make this work. Do-able, but...
As for the example for the rest... I may have to sanitize the code, then send you a zip. It's kind of a mess that slowly grew over 12 years (another reason to re-write).
-
- Posts: 941
- Joined: 30 Sep 2017, 03:59
- Location: Romania
- Contact:
Re: v1 -> v2 Script Converter
I'm happy to hear this
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
Re: v1 -> v2 Script Converter
Found this and was blown away. did a video on this
https://www.youtube.com/watch?v=QB-gBg8JCBM&t=251s
https://www.youtube.com/watch?v=QB-gBg8JCBM&t=251s
Re: v1 -> v2 Script Converter
Nice that you like it.tadamm wrote: ↑26 Feb 2022, 16:39Found this and was blown away. did a video on this
https://www.youtube.com/watch?v=QB-gBg8JCBM&t=251s
The comment in the statusbar is fixed.
Testmode is used for the development of the tool itself. If testmode is activated, the tree and expected code can become visible. This is meant to save and evaluate tests so it it easy to see if some saved conversion test have changed.
Re: v1 -> v2 Script Converter
thank you
i use this to convert
but some I DO not know how to convert .
v2 say has wrong but ???why??
and
how to change it to v2??
i use this to convert
but some I DO not know how to convert .
Code: Select all
BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall
and
Code: Select all
if !p:=RegExMatch(j,"(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|" . "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p)
Re: v1 -> v2 Script Converter
Code: Select all
BytesRead_ += NumGet(BytesRead, A_Index-1, 'UChar') << 8*(A_Index-1) ;Bytes read in this very DllCall
if !p:=RegExMatch(j,"(?<!\\)(`"`"|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|" . "(?<!\\)(`"`"|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", &x, p)
Re: v1 -> v2 Script Converter
We should fix the dereference in the future, for the regexMatch, I understand that it fails after that many characters... that is just asking for it to break. Just replace the complex string with a simple string and see what the convertor does.joomb wrote: ↑14 Mar 2022, 08:51thank you
i use this to convert
but some I DO not know how to convert .v2 say has wrong but ???why??Code: Select all
BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall
andhow to change it to v2??Code: Select all
if !p:=RegExMatch(j,"(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|" . "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p)
Unfortunately, I do not have a lot of experience with the deref.
to make the conversion simple, maybe it is possible to replace
*( to DereferenceV1(
if before this, ( ignoring the spaces) is one of the following characters:
( , = {
afterwards we can change DereferenceV1 to NumGet, but I need more examples of conversions, as my experience with deref and NumGet is limited
Last edited by AHK_user on 15 Mar 2022, 06:14, edited 2 times in total.
Re: v1 -> v2 Script Converter
thanks very much but it still can not work .swagfag wrote: ↑14 Mar 2022, 12:13Code: Select all
BytesRead_ += NumGet(BytesRead, A_Index-1, 'UChar') << 8*(A_Index-1) ;Bytes read in this very DllCall if !p:=RegExMatch(j,"(?<!\\)(`"`"|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|" . "(?<!\\)(`"`"|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", &x, p)
I will post the all codes v1 here for help
Code: Select all
json(Byref js, s, v:="") { ;v2版本需要将Byref替换为&
j := js
Loop Parse, s, % chr(46) ;V2版本将%去掉
{
p := "2"
RegExMatch(A_LoopField, "([+\-]?)([^[]+)((?:\[\d+\])*)", q)
Loop {
If (!p := RegExMatch(j, "(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|" "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p))
Return
Else If (x2 == q2 or q2 == "*") {
j := x3
z += p + StrLen(x2) - 2
If (q3 != "" and InStr(j, "[") == 1) {
q3 := SubStr(q3, 1, -1)
Loop Parse, q3, "]", "["
{
z += 1 + RegExMatch(SubStr(j, 2, -1), "^(?:\s*((\[(?:[^[\]]++|(?-1))*\])|(\{(?:[^{\}]++|(?-1))*\})|[^,]*?)\s*(?:,|$)){" . SubStr(A_LoopField, 1) + 1 . "}", x)
j := x1
}
}
Break
}
Else p += StrLen(x)
}
}
if (v != "")
{
vs := chr(34)
If (RegExMatch(v, "^\s*(?:""|')*\s*([+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:""|')*\s*$", vx)
and (vx1 + 0 or vx1 == 0 or vx1 == "true" or vx1 == "false" or vx1 == "null" or vx1 == "nul"))
vs := "", v := vx1
v := StrReplace(v, CHR(34), "\" . CHR(34))
js := SubStr(js, 1, z := RegExMatch(js, ":\s*", zx, z) + StrLen(zx) - 1) . vs . v . vs . SubStr(js, z + StrLen(x3) + 1)
}
Return j == "false" ? 0 : j == "true" ? 1 : j == "null" or j == "nul"
? "" : SubStr(j, 1, 1) == """" ? SubStr(j, 2, -1) : j
}
Code: Select all
UrlDownloadToVar(URL,encode := "CP0", UserAgent := "", Proxy := "", ProxyBypass := "") {
; Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0,
; Windows Me, Windows 98, or Windows 95.
; Requires Internet Explorer 3.0 or later.
pFix:=a_isunicode ? "W" : "A"
hModule := DllCall("LoadLibrary", "Str", "wininet.dll")
AccessType := Proxy != "" ? 3 : 1
;INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT 1 // direct to net
;INTERNET_OPEN_TYPE_PROXY 3 // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
io := DllCall("wininet\InternetOpen" . pFix
, "Str", UserAgent ;lpszAgent
, "UInt", AccessType
, "Str", Proxy
, "Str", ProxyBypass
, "UInt", 0) ;dwFlags
iou := DllCall("wininet\InternetOpenUrl" . pFix
, "UInt", io
, "Str", url
, "Str", "" ;lpszHeaders
, "UInt", 0 ;dwHeadersLength
, "UInt", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "UInt", 0) ;dwContext
If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "UInt", hModule)
return 0
}
VarSetCapacity(buffer, 1024, 0)
VarSetCapacity(BytesRead, 4, 0)
Loop
{
;http://msdn.microsoft.com/library/en-us/wininet/wininet/internetreadfile.asp
irf := DllCall("wininet\InternetReadFile", "UInt", iou, "UInt", &buffer, "UInt", 1024, "UInt", &BytesRead)
VarSetCapacity(buffer, -1) ;to update the variable's internally-stored length
BytesRead_ := 0 ; reset
Loop 4 ; Build the integer by adding up its bytes. (From ExtractInteger-function)
BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall
; To ensure all data is retrieved, an application must continue to call the
; InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.
If (irf == 1 and BytesRead_ == 0)
break
Else ; append the buffer's contents
{
a_isunicode ? buffer:=StrGet(&buffer, encode)
Result .= SubStr(buffer, 1, BytesRead_ * (a_isunicode ? 2 : 1))
}
/* optional: retrieve only a part of the file
BytesReadTotal += BytesRead_
If (BytesReadTotal >= 30000) ; only read the first x bytes
break ; (will be a multiple of the buffer size, if the file is not smaller; trim if neccessary)
*/
}
DllCall("wininet\InternetCloseHandle", "UInt", iou)
DllCall("wininet\InternetCloseHandle", "UInt", io)
DllCall("FreeLibrary", "UInt", hModule)
return Result
}
Re: v1 -> v2 Script Converter
Code: Select all
UrlDownloadToVar(URL,encode := "CP0", UserAgent := "", Proxy := "", ProxyBypass := "") {
; Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0,
; Windows Me, Windows 98, or Windows 95.
; Requires Internet Explorer 3.0 or later.
pFix:=a_isunicode ? "W" : "A"
hModule := DllCall("LoadLibrary", "Str", "wininet.dll")
AccessType := Proxy != "" ? 3 : 1
;INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT 1 // direct to net
;INTERNET_OPEN_TYPE_PROXY 3 // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
io := DllCall("wininet\InternetOpen" . pFix
, "Str", UserAgent ;lpszAgent
, "UInt", AccessType
, "Str", Proxy
, "Str", ProxyBypass
, "UInt", 0) ;dwFlags
iou := DllCall("wininet\InternetOpenUrl" . pFix
, "UInt", io
, "Str", url
, "Str", "" ;lpszHeaders
, "UInt", 0 ;dwHeadersLength
, "UInt", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "UInt", 0) ;dwContext
If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "UInt", hModule)
return 0
}
VarSetCapacity(buffer, 1024, 0)
VarSetCapacity(BytesRead, 4, 0)
Loop
{
;http://msdn.microsoft.com/library/en-us/wininet/wininet/internetreadfile.asp
irf := DllCall("wininet\InternetReadFile", "UInt", iou, "UInt", &buffer, "UInt", 1024, "UInt", &BytesRead)
VarSetCapacity(buffer, -1) ;to update the variable's internally-stored length
BytesRead_ := 0 ; reset
Loop 4 ; Build the integer by adding up its bytes. (From ExtractInteger-function)
BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall
; To ensure all data is retrieved, an application must continue to call the
; InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.
If (irf == 1 and BytesRead_ == 0)
break
Else ; append the buffer's contents
{
a_isunicode ? buffer:=StrGet(&buffer, encode)
Result .= SubStr(buffer, 1, BytesRead_ * (a_isunicode ? 2 : 1))
}
/* optional: retrieve only a part of the file
BytesReadTotal += BytesRead_
If (BytesReadTotal >= 30000) ; only read the first x bytes
break ; (will be a multiple of the buffer size, if the file is not smaller; trim if neccessary)
*/
}
DllCall("wininet\InternetCloseHandle", "UInt", iou)
DllCall("wininet\InternetCloseHandle", "UInt", io)
DllCall("FreeLibrary", "UInt", hModule)
return Result
}
Code: Select all
json(Byref js, s, v:="") { ;v2版本需要将Byref替换为&
j := js
Loop Parse, s, % chr(46) ;V2版本将%去掉
{
p := "2"
RegExMatch(A_LoopField, "([+\-]?)([^[]+)((?:\[\d+\])*)", q)
Loop {
If (!p := RegExMatch(j, "(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|" "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p))
Return
Else If (x2 == q2 or q2 == "*") {
j := x3
z += p + StrLen(x2) - 2
If (q3 != "" and InStr(j, "[") == 1) {
q3 := SubStr(q3, 1, -1)
Loop Parse, q3, "]", "["
{
z += 1 + RegExMatch(SubStr(j, 2, -1), "^(?:\s*((\[(?:[^[\]]++|(?-1))*\])|(\{(?:[^{\}]++|(?-1))*\})|[^,]*?)\s*(?:,|$)){" . SubStr(A_LoopField, 1) + 1 . "}", x)
j := x1
}
}
Break
}
Else p += StrLen(x)
}
}
if (v != "")
{
vs := chr(34)
If (RegExMatch(v, "^\s*(?:""|')*\s*([+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:""|')*\s*$", vx)
and (vx1 + 0 or vx1 == 0 or vx1 == "true" or vx1 == "false" or vx1 == "null" or vx1 == "nul"))
vs := "", v := vx1
v := StrReplace(v, CHR(34), "\" . CHR(34))
js := SubStr(js, 1, z := RegExMatch(js, ":\s*", zx, z) + StrLen(zx) - 1) . vs . v . vs . SubStr(js, z + StrLen(x3) + 1)
}
Return j == "false" ? 0 : j == "true" ? 1 : j == "null" or j == "nul"
? "" : SubStr(j, 1, 1) == """" ? SubStr(j, 2, -1) : j
}
Re: v1 -> v2 Script Converter
My excuses for the confusion, I meant that we should fix the dereference conversion in the future, not that it is done. If I have enough conversion examples we can implement it.