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

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

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

bob cole
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?  
    Do I save myLCprogram as an .app/.exe and run it in a shell like a cgi with a shebang (#! livecode -ui)?
    Does this only work with LiveCode Server?
I am a bit confused by it.  A simple example would help tremendously.
Thanks in advance.
Bob


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

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

Richard Gaskin
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


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

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

bob cole
In reply to this post by bob cole
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, [hidden email] wrote:

> Date: Mon, 29 Apr 2013 08:08:20 -0700
> From: Richard Gaskin <[hidden email]>
>
> 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
_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

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

Dr. Hawkins
In reply to this post by bob cole
On Sun, Apr 28, 2013 at 1:41 PM, Bob Cole <[hidden email]> 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.

I actually tried it on a linux server.

I compiled the stack on my desktop and uploaded it, and was indeed
able to have it export a pdf before attempting to hit the screen.

There is also a fairly simple X11 dummy screen driver out there for
linux, that just eats the screen commands.

Of course, I did this without knowing about this -ui business :)



--
Dr. Richard E. Hawkins, Esq.
(702) 508-8462

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode