Faceless LiveCode App for CLI on Mac OS X and Windows 7
Richard Gaskin
ambassador at fourthworld.com
Mon Apr 29 11:08:20 EDT 2013
Bob Cole wrote:
> I am looking for an example of how to create a utility program in LC
> to process a text file on Mac OS X and Windows 7.
> I want to put it in a faceless processing stream perhaps with pipes
> or redirection or options. Such as:
> ...
> cat textfile1 | myLCprogram | more
> ...
> or
> ...
> myLCprogram < textfile1 > textfile2
> ...
> or
> ...
> myLCprogram -f textfile1 -o textfile2
> ...
>
> I have read the dictionary about open process and open file but I
> don't know how to save the LC program without triggering the ui.
> What I need is an example of how myLCprogram is structured or wrapped
> in a shell script that can be used as cli command.
> Do I need to use -ui somewhere?
Yes. Add -ui, and avoid flags the engine currently expects, and you'll
be fine.
The latter is the harder part of this, since the engine still reserves a
great many flags it no longer uses - these are listed here in this
request to remove the ones that are no longer relevant (perhaps this
will be one of the first pull requests submitted, since I can't imagine
it'll take long to fix):
<http://quality.runrev.com/show_bug.cgi?id=1644>
[-f[iles] (disable access to files and processes)
[-g[eometry] ={+-}<xoffset>{+-}<yoffset>]
[-i[nput] fd] read commands from fd (0 is stdin) or named pipe
[-m[map]] (don't memory map files)
[-n[opixmaps]] (draw direct to screen)
[-p[ointerfocus]] (use active focus)
[-s[haredoff]] (don't use shared memory server extension)
[+s[haredon]] (use shared memory server extension)
[-u[i]] (don't create graphical user interface)
[-v[isualid] n] (use visual id n as listed from xdpyinfo)
[-w[indowid] n] (watch window id n for commands)
[stackname(s) | argument(s)]
One challenge for apps that support both GUI and CLI is to determine
whether the app has been called with "-ui", and it turns out if so the
windowID will be "1", so you can use:
on startup
if the windowID of this stack = 1 then
HandleCommandLineInterface
end if
end startup
My HandleCommandLineInterface handler does a lot of app-specific things
not relevant here, but one of the first things it calls is a handler to
parse the arguments which may be useful, using "$#" to obtain the number
of args passed in:
on CLIInit
-- Parse args:
put $# into sCLINumArgs
repeat with i = 1 to sCLINumArgs
do ("put $"& i &" into sCLIArgsA[i]")
end repeat
-- Get App Name:
put $0 into tmp
if the platform is "Win32" then
replace "\" with "/" in tmp
end if
set the itemdel to "/"
put last item of tmp into sCLIAppName
-- Get log file:
put CLIArg("-l") into sCLIErrLogFile
end CLIInit
That uses a function named CLIArg, defined as:
-- CLIArg
-- Returns the data in the argument following the one
-- matching the data supplied in pFlag. If pRequired
-- is not empty and no matching arg is found, logs
-- an error:
function CLIArg pFlag, pRequired
repeat with i = 1 to sCLINumArgs
if sCLIArgsA[i] = pFlag then
return sCLIArgsA[i+1]
end if
end repeat
-- If we got here, then no arg was supplied:
if pRequired is empty then
return empty
else
CLIErr "Couldn't find required argument for flag "& pFlag
end if
end CLIArg
Some other supporting handlers I use:
function CLIFlag pFlag
repeat with i = 1 to sCLINumArgs
if sCLIArgsA[i] = pFlag then
return true
end if
end repeat
return empty
end CLIFlag
-- CLILog
-- Outputs s only if log file provided:
on CLILog s
if sCLIErrLogFile is not empty then
CLIOut s
end if
end CLILog
-- CLIErr
-- Checks if s is empty, and if not it logs the string
-- in p; if p is empty s is logged instead
on CLIErr s, p
if s is not empty then
if p is empty then put s into p
CLIOut p
quit
end if
end CLIErr
-- CLIOut
-- Writes s to stdout, also write s to log file
-- if path provided in arg after -l
on CLIOut s
if sCLIErrLogFile is not empty then
open file sCLIErrLogFile for append
CLIErr the result, "Couldn't open log file: "& sCLIErrLogFile
write s&cr to file sCLIErrLogFile
close file sCLIErrLogFile
end if
write sCLIAppName &">: "&s &cr to stdout
end CLIOut
The vars preceded with "s" (e.g., sCLINumArgs) are script-local vars
declared outside the handlers at the top of the script so they can be
used in any subsequent handlers.
Hope that helps. Keep us posted with how it goes. It may be a bit
geeky, but I find making CLI apps in LiveCode very rewarding. :)
--
Richard Gaskin
Fourth World
LiveCode training and consulting: http://www.fourthworld.com
Webzine for LiveCode developers: http://www.LiveCodeJournal.com
Follow me on Twitter: http://twitter.com/FourthWorldSys
More information about the use-livecode
mailing list