ITworld.com
  Search  
ITworld Home Page ITworld Webcasts ITworld White Papers ITworld Newsletters ITworld News ITworld Topics Careers ITworld Voices ITwhirled Changing the way you view IT

Scripted wrappers for legacy applications

Unix Insider 12/18/00

Cameron Laird and Kathryn Soraiz, Unix Insider

unixinsiderhome
Let's start with an easy example, the kind you'll want to do on your own: create a C source file, test1.c:


        #include  
        #include  
        main() 
        { 
            struct timeval timevalue; 
            struct timezone timezone; 
 
            gettimeofday(&timevalue, &timezone); 
            printf("The current time is %s", 
                     ctime((time_t *) &timevalue.tv_sec)); 
        } 
and make an executable program from it. Under Unix, you'd generally do that with a command-line invocation:

        cc -o test1 test1.c 
Now create the Perl/Tk source file, test1.pl:

       use Tk; 
 
       $mw = MainWindow->new; 
       $label = $mw->Label(); 
       $label->pack; 
       $mw->Button(-text => "Show the time", 
            -command => sub{ 
                $label->configure(-text => `./test1`) 
             })->pack; 
       MainLoop; 
There! If you execute:

        perl test1.pl 
you'll see a small GUI panel with a button. Pushing the button launches the C-coded program, retrieves output, and displays it. The problem's solved, for both Unix and Windows.
On this topic
>

swol-1218-regex_fig1

There's more to the story
For many programmers, though, that is only the beginning. Let's look at the example in more detail.

To run the example, we launch a Perl program, which itself controls the legacy test1 as a separate process. With all the examples in this article, it doesn't matter that test1 is compiled from C source; it could be a Fortran, C++, Java, or even another Perl program. All that matters in that architecture is that it can be launched as a command-line application, which puts its results to standard output.

Most modern languages available for Unix and Win* have at least one way of invoking an external process and retrieving its result in that way. The gluing languages we discuss in this column are particularly rich in those facilities. Most accessible to beginners are the backtick operator or function used in test1.pl above, which is also available in much the same form in Ruby, Tcl, Bourne shell, and several other languages.

A simple control panel of that sort is a great way to wrap a legacy application with complex command-line arguments or inputs. A high-level scripting language validates all the flags, ensures that they're properly consistent, then invokes the legacy application correctly. That is particularly valuable because it means that the legacy application need not change. There's no need to relink it, port it, or do anything else that might introduce delays or errors. Scripting languages just translate between a more modern GUI appearance and the older command-line interface.

Both the legacy application and the scripting wrapper can be in nearly any language. The final element of this solution's universality is the choice of GUI toolkit. Most languages bind to at least a couple of GUI toolkits, and deciding between them is independent of process invocation -- it's a free choice. The architecture works the same whether you're using Perl with Tk to run a C application or Python with Qt to control a Pascal process.

Predictable sequence
Questioners are happy to see for themselves that test1.pl and its equivalents in other languages are easy to use. They usually come back the next day, though, complaining, "The GUI locks up until the subprocess returns! I can't have that; I need for it to stay responsive, so my users can do other things. In fact, it ought to show a progress bar while the subprocess is running, and..."

Most scripting languages have a good answer to that, too, and we'll look at an example in a moment. First, though, let's clarify a couple of new concepts.

When we want the GUI wrapper to be alive at the same time the legacy application is grinding through to a result, we're asking for concurrency or multitasking. Modern operating systems know about concurrency; in fact, many support more than one programming construct for concurrency.

Java and Microsoft development kits emphasize threading for multitasked operations. More suitable for the high-level wrapping of this column, though, is event-based programming. Last year, we wrote a couple of times about how different scripting languages support threads and events. Now let's look at an example that uses events to keep a GUI responsive, while managing a long-lasting subprocess.

Create a small, long-running command-line application such as:

long.tcl:


       for {set i 0} {$i < 10} {incr i} { 
            puts $i 
            flush stdout 
                # This says, "pause 1000 milliseconds". 
            after 1000 
       } 
Wrap it with test2.tcl:

       proc launch {} { 
            global fp 
 
           set subprocess "tclsh long.tcl" 
            set fp [open "|open $subprocess"] 
            fileevent $fp readable read_one_line 
       } 
 
       proc read_one_line {} { 
            global fp 
 
            if [eof $fp] { 
                close $fp 
                .t insert end Done 
                return 
            } 
            .t insert end [gets $fp]\n 
       } 
 
       pack [button .b -text "Push me" -command launch] 
       pack [text .t] 
swol-1218-regex_fig2

Notice that when you run that, the textbox methodically fills up as it counts from zero to nine, and the GUI remains responsive. If we'd done that with the commands of test1, the GUI would have frozen for 10 seconds, then shown all of its results at once.

That is the second major architecture for combining a legacy application with a GUI or other scripting wrapper. Again, the high-level language is in charge, and it runs the legacy application as a subprocess. The legacy application needs no changes and can be written in any language, plus you're free to choose any GUI toolkit you find convenient.

What makes that architecture different is its finer control over the subprocess. Perl and Tcl batch subprocesses with the backtick operator and the exec command, respectively. For concurrent operations, both languages use open. Our second example is often called opening a pipe to a subprocess (the | sign in the test2.tcl is called a pipe). Many languages can also open pipes.

Next month, we'll look at variations of the second architecture and introduce the third and final major architecture for combining legacy applications with scripted wrappers.

In the news
Important news about scripting languages breaks faster than we can write about it. Our particular congratulations, though, go to the Lua team for its recent release of version 4.0. This update is faster, improves error handling, is fully re-entrant, and includes several other important advances.

Cameron Laird and Kathryn Soraiz manage Phaseit, a software consultancy just outside Houston.




Sponsored Links

Improving the View with IP Videoconferencing
New videoconferencing technologies are poised to benefit the enterprise.
Great Deals On FUJITSU Notebooks @ Synnex!
SYNNEX RESELLERS - Check Out The Savings On Lifebook Notebooks, Tablet PCs, And Ultra-Mobile PCs!
FREE SECURITY AUDIT RESOURCES
Take a Risk Assessment, get White Papers on the Latest Threats, listen to Malware Expert Webcasts.
IMPROVE YOUR SUPPORT EFFICIENCY
WebEx lets you remotely control, configure and install applications and updates more efficiently.
Metadata Management Software
MetaCenter: Plug & play metadata management software for enterprise systems. Features: data dictionary, process documentation, impact analysis, search across multiple systems, web-based interface, reports, dashboards, import, export and more!
» Buy a link now

Advertisements
Sponsored links
Locate Hidden Software on business PCs with this free tool
KODAK i1400 Series Scanners stand up to the challenge
Bring harmony to your mix of UNIX-Linux-Windows computing environments
Top 5 Reasons to Combine App Performance and Security
 Home   Application Development  Programming tools  Programming languages  Server Scripting
www.itworld.com    open.itworld.com     security.itworld.com     smallbusiness.itworld.com
storage.itworld.com     utilitycomputing.itworld.com     wireless.itworld.com

 
Contact Us   About Us   Privacy Policy    Terms of Service   Reprints  

CIO   Computerworld   CSO   GamePro   Games.net   IDG Connect   IDG World Expo   Industry Standard   Infoworld   ITworld   JavaWorld   LinuxWorld  MacUser   Macworld   Network World   PC World   Playlist  

Copyright © Computerworld, Inc. All rights reserved

Reproduction in whole or in part in any form or medium without express written permission of Computerworld Inc. is prohibited. Computerworld and Computerworld.com and the respective logos are trademarks of International Data Group Inc.