How to run an AutoIt script and call a function from it? - function

CONVERTER.au3 converts webp to png using dwebp:
Convert()
Func Convert()
$hSearch = FileFindFirstFile(#ScriptDir & "\*.webp")
$sFileName = FileFindNextFile($hSearch)
$Split = StringSplit($sFileName, ".")
;~ MsgBox(0,'',$Split[1])
Run("dwebp.exe " & $sFilename & " -o " & $Split[1] & ".png")
EndFunc
Func Troubleshoot()
Convert()
Local $hSearch
If $hSearch = -1 Then
$desktopCON = "supported"
Else
$desktopCON = "unsupported"
EndIf
FileClose($hSearch)
Exit
EndFunc
I need to run CONVERTER.au3 and call a specific function from it. I tried this but doesn't seem to work:
Run("D:\SCRIPT\NEW\CONVERTER.au3 Call(Convert)")

Parameters are referenced with the $CmdLine array. The first element ($CmdLine[0] is the number of parameters, $CmdLine[1] is the first parameter, etc.).
If $CmdLine[0] = 0 Then ; standard behavour for no params
Convert()
Exit
EndIf
If $CmdLine[1] = "convert" Then ; param is "convert"
Convert()
Exit
EndIf
If $CmdLine[1] = "troubleshoot" Then ; param is "troubleshoot"
Troubleshoot()
Exit
EndIf
MsgBox(0, "ERRROR", "undefined function: " & $CmdLine[1])
Func Convert()
MsgBox(0, "", "your converting code here")
EndFunc ;==>Convert
Func Troubleshoot()
MsgBox(0, "", "your troubleshooting code here")
EndFunc ;==>Troubleshoot
Execute it from AutoIt with Run('"Converter.au3" foobar')
or from the Windows Command line with just converter.au3 troubleshoot
If no parameter is given, it executes a default function (or whatever you want it to do).

Related

lua function attempt to call global (a nil value)

I am new to lua and i am trying to make a function that receives documents and outputs a table but I am getting the above error. Why??
io.write("How many documents are we evaluating? \nInput: ")
local total_documents=io.read("*n")
io.read()
local docTable = {}
inputDocument()
function inputDocument()
local input
local file
local inputFile = {filename = nil, contents = nil, wordcount = nil}
repeat
io.write("Please enter document (filename.extension): ")
input = io.read()
file =io.open(input)
if file == nil then
print("File does not exist try again")
end
until(file ~=nil)
inputFile.filename = input
return inputFile
end
You need to define inputDocument before using it:
function inputDocument()
...
end
io.write("How many documents are we evaluating? \nInput: ")
...
inputDocument()

Functions don't operate correctly (AutoIt)

So i am trying to make a function out of many functions (i believe it is called recursion, read a post about it earlier on this forum)
When i try to make a number of things into 1 big function so i can call upon it later it doesn't seem to be working but when i take away the "func _hello()" and the "endfunc" from the end, everything seems to be working fine. Can someone please explain this to me. I know the problem is occurring because of the the "Conversion" function but i can't seem to understand why this is happening. Please help, language used here is AutoIt
;;;****Program adds spaces *****
;;;***** the input variable here is $New*****
Global $final
Global $Hexadec
Func _hello()
$DataToBeDecrypted = "55fdaf fdafd"
$2space = $DataToBeDecrypted
$New = $2space
$AddingSpace = StringSplit($New, "")
$Final = ""
If Conversion($AddingSpace[0]) Then
For $Spacing = 1 to $AddingSpace[0] Step 2
$Final = $Final & $AddingSpace[$Spacing] & $AddingSpace[$Spacing+1] & " "
Next
MsgBox(0, "Adding space to the message so it can be converted back to Hex", $Final)
Else
MsgBox(0, "Result", "String does not contain an even number of characters.")
EndIf
Func Conversion($Hexadec)
Return Mod($Hexadec, 2) = 0
EndFunc
;;;***The final value is stored in the $final variable****
;***** Hexadecimals to ASCII*****
;;***Input variable is $HexadecimaltoASCII2******
$HexadecimalToASCII2 =$final
$HexadecimalsToASCII = ChrH($HexadecimalToASCII2)
$Ascii2Hex = Sub($HexadecimalsToASCII)
$v5ar = Chr($HexadecimalsToASCII);char
MsgBox(0,"Hex to ASCII",$HexadecimalsToASCII)
Func ChrH($v8)
Local $v5=""
$A1 = StringSplit($v8, " ")
For $count = 1 To $A1[0]
$v5 &= Chr(Dec($A1[$count]))
Next
Return $v5
endFunc
Func Sub($v8)
Local $v9=""
For $count = 1 To StringLen($v8)
If StringLen(Hex(Asc(StringMid($v8, $count, 1)),2)) = 1 Then
$v9 &= "0" & Hex(Asc(StringMid($v8, $count, 1)))
Else
$v9 &= Hex(Asc(StringMid($v8, $count, 1)),2)
EndIf
If $count <> StringLen($v8) Then $v9 &= " "
Next
Return $v9
endFunc
;*****HEXADECIMAL to ASCII*****
EndFunc
It seems like you never call your Hello() function. To execute a function you have to call it.
Try adding Hello() at the top of the file and it should work.

New to autoit, what is wrong with this variable?

so today I just started learning this language, and I'm trying to make my script with parts of example scripts from https://www.autoitscript.com/autoit3/docs/functions.
I'm trying to run a mysql query and I'm getting "Variable Undeclared" error even if it declared as a Global one (atleast i think i declared it as one..)
Basically what my script should do is make an ID for every machine in my LAN store it into a txt file in AppData and then insert it into a db.
#include <MsgBoxConstants.au3>
#include <FileConstants.au3>
#include "EzMySql.au3"
#include <Array.au3>
Example()
Func Example()
$id = Random(1, 1000, 1);Numar random de la 1 la 100
Local Const $sFilePath = #AppDataDir & "\id.txt" ; Selectare %appdata% si id.txt
Local $iFileExists = FileExists($sFilePath)
If $iFileExists Then
Else
; Create a temporary file to write data to.
If Not FileCreate($sFilePath, $ID & #CRLF) Then Return MsgBox($MB_SYSTEMMODAL, "", "O eroare s-a produs in timp ce se scria fila temporara")
; Open the file for writing (append to the end of a file) and store the handle to a variable.
Global $hFileOpen = FileOpen($sFilePath, $FO_APPEND)
If $hFileOpen = -1 Then
MsgBox($MB_SYSTEMMODAL, "", "O eroare s-a produs in timp ce se citea fila.")
Return False
EndIf
; Read the contents of the file using the handle returned by FileOpen.
Global $sFileRead = FileRead($hFileOpen)
; Close the handle returned by FileOpen.
FileClose($hFileOpen)
EndIf
EndFunc
; Create a file.
Func FileCreate($sFilePath, $sString)
Local $bReturn = True ; Create a variable to store a boolean value.
If FileExists($sFilePath) = 0 Then $bReturn = FileWrite($sFilePath, $sString) = 1 ; If FileWrite returned 1 this will be True otherwise False.
Return $bReturn ; Return the boolean value of either True of False, depending on the return value of FileWrite.
EndFunc ;==>FileCreate
$name=#ComputerName
If Not _EzMySql_Startup() Then
MsgBox(0, "Error Starting MySql", "Error: "& #error & #CR & "Error string: " & _EzMySql_ErrMsg())
Exit
EndIf
If Not _EzMySql_Open("127.0.0.1", "root", "", "vrgaming", "3306") Then
MsgBox(0, "Error opening Database", "Error: "& #error & #CR & "Error string: " & _EzMySql_ErrMsg())
Exit
EndIf
If Not _EzMySql_Exec("INSERT INTO `lan` (id, nume) VALUES ('"& $sFileRead &"', '"& $name &"')") Then
MsgBox(0, "Error opening Database", "Error: "& #error & #CR & "Error string: " & _EzMySql_ErrMsg())
Exit
EndIf
_EzMySql_Close()
_EzMySql_ShutDown()
Exit
There are a number of logic issues with the code, that makes it a little tricky to follow.
The error in this case is almost certainly caused because "id.txt" exists, and so $iFileExists evaluates to true, and the global variable is never created.
Then you are creating a new "id.txt", for writing, before reading all the data, so $sFileRead will always be blank and FileRead will set #error as you are trying to read from a file opened for writing.
Now, I think you want the $sFileRead to be whatever the contents of id.txt is, and id.txt should be created with a new random id if it doesn't exist. If so then you need to move the code that opens and reads the file outside of the Else...Endif block (in addition to changing FileOpen to use $FO_READ).
This answer doesn't address the questionable programming practice and code structure.

Vim: Show current json path

I'm editing a very large, nested JSON doc (rightscale api incase you're interested) in vim and would love to know the current json-path (like xpath for json) Something like:
Given the JSON:
{
"leve1": {
"level2": {
"level3": {
"name": "goes here"
}
}
}
}
With my cursor between "name": and "goes here" i'd like a command (or status line) that shows me:
level1/level2/level3/name
or similar.
Does anything like this exist?
I recently wrote a plugin for this called vim-jsonpath. It currently provides the following commands (that of course can be mapped):
:JsonPath: Echoes the path to the identifier under the cursor.
:JsonPath path.to.prop: Searches the active buffer for the given path, placing the cursor on it if found.
I've written two mappings that use the fold information (so they should work with any structure, not just JSON). For your example, they output
{ / "leve1": { / "level2": { / "level3": {
and (long version):
1 {
2 "leve1": {
3 "level2": {
4 "level3": {
Here is the scriptlet. It depends on my ingo-library plugin.
" [count]z? Print all lines (with numbers) that start a fold where
" the current line is contained in (for [count] upper
" levels). When a line consists of just a symbol like "{",
" the preceding non-empty line is printed, too.
" [count]z/ Like z?, but use a short output format with all line
" contents concatenated, and without line numbers and
" symbols.
if ! exists('g:PrintFoldHierarchySymbolLinePattern')
let g:PrintFoldHierarchySymbolLinePattern = '^\s*{\s*$'
endif
function! s:PrintFoldHierarchy( count, isJoin )
if foldclosed('.') != -1
return 0
endif
let l:save_view = winsaveview()
let l:levels = []
let l:lnum = line('.')
while (a:count ? len(l:levels) < a:count : 1)
silent! normal! [z
if line('.') == l:lnum
break
endif
let l:lnum = line('.')
call insert(l:levels, l:lnum)
if getline(l:lnum) =~# g:PrintFoldHierarchySymbolLinePattern
let l:precedingLnum = prevnonblank(l:lnum - 1)
if l:precedingLnum > 0
if a:isJoin
let l:levels[0] = l:precedingLnum
else
call insert(l:levels, l:precedingLnum)
endif
endif
endif
endwhile
call winrestview(l:save_view)
if a:isJoin
echo
let l:isFirst = 1
for l:lnum in l:levels
if l:isFirst
let l:isFirst = 0
else
echohl SpecialKey
echon ' / '
echohl None
endif
echon ingo#str#Trim(getline(l:lnum))
endfor
else
for l:lnum in l:levels
echohl LineNr
echo printf('%' . (ingo#window#dimensions#GetNumberWidth(1) - 1) . 'd ', l:lnum)
echohl None
echon getline(l:lnum)
endfor
endif
return 1
endfunction
nnoremap <silent> z? :<C-u>if ! <SID>PrintFoldHierarchy(v:count, 0)<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>
nnoremap <silent> z/ :<C-u>if ! <SID>PrintFoldHierarchy(v:count, 1)<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>
You can put that into your ~/.vimrc (or a separate ~/.vim/plugin/PrintFoldHierarchy.vim), and invoke the mappings from normal mode via z? and z/.

Vim vmap, send selected text as parameter to function

In brief, having written some functions to save typing I'm trying to set up a vmap[ping] that will allow me to select something I typed, and pass this selection to a function (since typing the function call on the command line, typing the parameters (with quotes), and escaping backslashes etc... counteracts most of the time saved by calling functions)
For (a simple) example, supposing I had the following function
func Test(iStr)
if a:iStr[0] =~ [a-zA-z]
echo "hello"
else
echo "hello world"
endif
endfunc
I'd like to be able to visual select some text and then with some key mapping, F2 say, it will call Test(iStr) with the selection serving as the parameter iStr
I believe, that with more work (i.e. some way to specify that what I've selected should be inside Test()), the following
vmap <F2> :call Test()
is what I'm after. Thing is I've tried a number of variants (guesswork plus a little bit of dodgy inference from :help map) and I'm not getting anything useful. Update, I've tried using a helper function Test2() with just
call Test(<C-W>)
as its body...somehow I think I need to grab hold of the word under my cursor (somehow) and then I'm done - since I can pass that to Test(...) from within Test2
As for an actual example of a function I want to call, the following (incomplete yet) function (and helper functions) would allow me to convert an expression of the form, say,
f_k^{(j)}g
to
f_1^{(j)}g, f_2^{(j)}g, \dots, f_{n-1}^{(j)}g, f_n^{(j)}g
In terms of a procedure I want to
a) type the repeated term in vim
b) visually select it
c) hit some mapping key that will call SumOrSequence(iExpression, iIndex)
d) provide "k" as a parameter
e) press enter
f) see the change made by SumOrSequence(...)
The code for SumOrSequence(...) is as follows:
func SumOrSequence(iExpression, iIndex)
"need to check validity of these - maybe set a default
let default = Interrogate("do with defaults? yes [y] (2,1,n,0,\",\"), yes but specify last term [d[a-Z]], no [n]")
if default == "y"
let leftTerms = 2
let rightTerms = 1
let lastTermIndex = "n"
let firstTermIndex = 0
let operator = ","
let dotType = "\\dots"
elseif default =~ 'd[a-zA-Z]'
let leftTerms = 2
let rightTerms = 1
let lastTermIndex = default[1]
let firstTermIndex = 0
let operator = Interrogate("what separates terms? add [+], subtract [-], times [*], comma [,], ampersand [&]?")
let dotType = "\\cdots"
else "so n or anything else
let leftTerms = InterrogateNumber("how many terms before dots? ")
let rightTerms = InterrogateNumber("how many terms after dots? ")
let lastTermIndex = Interrogate("what is last term index?")
let firstTermIndex = Interrogate("what is first term index?")
let operator = Interrogate("what separates terms? add [+], subtract [-], times [*], comma [,], ampersand [&]?") "need to check only any of these provided
let dotType = "\\cdots"
endif
if operator == ","
let dotType = "\\dots"
endif
if operator == "*"
let operator = "\\times"
endif
let leftCount = 0
let oExpression = ""
while leftCount < leftTerms
if leftCount > 0
let oExpression .= operator . " "
endif
let oExpression .= ReplaceIndex(a:iExpression, a:iIndex, leftCount,1)
let leftCount += 1
endwhile
let oExpression .= operator . " " . dotType . " "
let rightCount = rightTerms-1
while rightCount > 0
"here we are going to be counting backwards from some number denoting number of terms - may need to know if we actually have a number!
echo "decrement: " . HandleDecrement(lastTermIndex, rightCount)
let oExpression .= operator . " " . ReplaceIndex(a:iExpression, a:iIndex, HandleDecrement(lastTermIndex, rightCount),1)
let rightCount -= 1
endwhile
let oExpression .= operator . " " . ReplaceIndex(a:iExpression, a:iIndex, lastTermIndex,0)
echo oExpression
endfunc
func ReplaceIndex(iExpression, iIndex, iReplacement, iInsertBraces)
"the game we play here is to search for iIndex in such form that it is not part of any other string
"We should expect this to be the case if the character to the left or right of the index is not in [A-z] (or just to the right if a greek char)
let oExpression = ""
let strEndPosition = strlen(a:iExpression) - 1
let currPosition = 0
let indexLen = strlen(a:iIndex)
while currPosition <= strEndPosition
let indexCounter = 0
let foundIndex = 1
while indexCounter < indexLen
if a:iExpression[currPosition + indexCounter] == a:iIndex[indexCounter]
if a:iExpression[currPosition + indexLen] =~ '[a-zA-Z]'
let foundIndex = 0
let indexCounter = indexLen
elseif a:iExpression[currPosition -1] =~ '[a-zA-Z]' && a:iExpression[currPosition] != "\\"
let foundIndex = 0
let indexCounter = indexLen
else
let indexCounter+=1
endif
else
let indexCounter = indexLen
let foundIndex = 0
endif
endwhile
if foundIndex == 0
let oExpression .= a:iExpression[currPosition]
let currPosition+=1
else
if a:iInsertBraces == 1
let oExpression .= "{" . a:iReplacement . "}"
else
let oExpression .= a:iReplacement
endif
let currPosition+=indexLen
endif
endwhile
echo "oExpression: " . oExpression
return oExpression
endfunc
func HandleIncrement(iExpression, iIncrement)
"and what about negative numbers for iExpression!??? not handling these yet :[
let oExpression = ""
if !(a:iExpression[0] =~ '[0-9]') || a:iExpression < 10 && strlen(a:iExpression) > 1
let oExpression = a:iExpression . " + " . a:iIncrement
else
let oExpression = a:iExpression + a:iIncrement
endif
echo oExpression
return oExpression
endfunc
func HandleDecrement(iExpression, iIncrement)
"TODO and what about negative numbers for iExpression!??? not handling these yet :[
let oExpression = ""
if !(a:iExpression[0] =~ '[0-9]') || a:iExpression < 10 && strlen(a:iExpression) > 1
let oExpression = a:iExpression . " - " . a:iIncrement
else
let oExpression = a:iExpression - a:iIncrement
endif
echo oExpression
return oExpression
endfunc
func Interrogate(iQuestion)
call inputsave()
let answer = input(a:iQuestion)
call inputrestore()
return answer
endfunc
func InterrogateNumber(iQuestion)
call inputsave()
let answer = input(a:iQuestion)
call inputrestore()
"TODO what if negative number??
if !(answer[0] =~ '[0-9]')
let answer = InterrogateNumber(a:iQuestion . " you didn't enter a numerical value ")
endif
return answer
endfunc
As regards the mapping bit, I know it looks like I haven't done too much work but assuming I have lots more digging ahead of me to find the answer myself, can anyone help?
Update. Ok, I have something that works in a clumsy sort of way, i.e. if I define the following helperfunction:
func SumOrSequenceHelper()
let oIndex = Interrogate("index variable? ")
"go to last thing visually selected (I think!), yank it (putting it in the " register), then fetch it via oParam. Then pass this off to SumOrSequence
execute "normal! gvy"
let oExpression = getreg('"')
call SumOrSequence(oExpression, oIndex)
endfunc
vnoremap <F6> :call SumOrSequenceHelper()
then all is well, and I can just do an execute command to replace what I selected with what I got from SumOrSequence(...)
Would be grateful for any improvements but for all intents and purposes this one is solved :]
You could use a helper function like this:
func! GetSelectedText()
normal gv"xy
let result = getreg("x")
normal gv
return result
endfunc
vnoremap <F6> :call MyFunc(GetSelectedText())<cr>
There is also :com -range, which can register a custom command that operates on a selection, but the interface is line oriented.
Use the selection register to call the function with whatever you have visually selected.
vnoremap <F6> :call Test(#*)<CR>
If you just want to grab hold of the word under the cursor in Normal mode you can use this, which yanks to the selection register then uses the value. (You could yank to any named register instead , e.g. the a register with "ay and #a.)
noremap <S-F6> "*yaw:call Test(#*)<CR>
By the way these don't work with your Test function, but just calling it doesn't seem to work either?
:call Test("fred")
Error detected while processing function Test:
line 1:
E121: Undefined variable: a
E15: Invalid expression: a:iStr[0] =~ [a-zA-z]
They work with this test function:
function Test(iStr)
echo a:iStr
endfunction