Faceless LiveCode App for CLI on Mac OS X and Windows 7

Bob Cole bobcole at earthlink.net
Mon Apr 29 21:52:25 EDT 2013


Richard:
This is a wonderful response with great detail and advice; just what I need.  
I continue to be impressed with the responsiveness and thoughtfulness of the members on this LiveCode list.  With genuinely useful help like this, LiveCode becomes even more valuable. 
I also received knowledgeable advice and a working example from another person off-list.  I did not know if I should use his name so I refrain but, if he wishes, he could provide the guidance he provided me, too.
I have lots to study and use as a base for my development.  
I offer sincere thanks,
Bob

On Apr 29, 2013, at 12:00 PM, use-livecode-request at lists.runrev.com wrote:
> Date: Mon, 29 Apr 2013 08:08:20 -0700
> From: Richard Gaskin <ambassador at fourthworld.com>
> 
> 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



More information about the use-livecode mailing list