ERights Home elang / intro 
Back to: Example: Finding Text x On to: A 15 Minute Introduction to E

Standalone
E Programs


Putting an E Program Into a File

Now that we have our directory-tree-walking findall function, we'd like to be able to call it from our operating system's shell (or command line interpreter).

Using a plain-text editor (such as Notepad) save the following text into a file named "findall.e":

#!/usr/bin/env rune

/**
 * The find function from the E Tutorial, modified to show the
 * pathname.
 * Prints all lines of a given file that contains a given substring.
 */
def find(file, substring) {
    for num => line in file {
        if (line.indexOf(substring) != -1) {
            print(file.getPath() + ":" + num + ":" + line)
        }
    }
}

/**
 * The findall function from the E Tutorial, modified to take an
 * extension parameter.
 * Recursively walks a directory tree, and prints all lines in .txt
 * files that contain the given substring.
 */
def findall(dirfile, ext, substring) {
    if (dirfile.isDirectory()) {
        for file in dirfile {
            findall(file, ext, substring)
        }
    } else if (dirfile.getName().endsWith(ext)) {
        find(dirfile, substring)
    }
}

def args := interp.getArgs()
if (args.size() != 3) {
    throw("usage: findall.e rootname extension substring")
}
def root := <file: (args[0])>
findall(root, args[1], args[2])

The find function in this file is our earlier find function enhanced to show the full file pathname as well. The findall function is our earlier findall function generalized from only looking at ".txt" files to accepting the file-extension string as a parameter. Now let's run this as a standalone program.

Running an E Program from the MS-DOS Shell

At the beginning of this chapter we saw how to start rune from an MS-DOS prompt:

MS-DOS Prompt
C:\WINDOWS> rune
? pragma.syntax("0.8")

? 2 + 3
# value: 5

? #Control-z
C:\WINDOWS> _
 

If, instead, we run "rune" with arguments, the first argument will be used as the name of the file from which rune should read and interpret commands.

C:\WINDOWS> rune findall.e
# problem: usage: findall.e rootname extension substring
#
# ...

C:\WINDOWS> _
 

This error came from these lines in our findall.e program:

def args := interp.getArgs()
if (args.size() != 3) {
    throw("usage: findall.e rootname extension substring")
}

findall.e knows it needs three arguments, and notices that these haven't been provided. We use the built-in function throw to indicate that an exception has occurred, and to prevent the program from continuing past this point as if everything were fine. The value we provide to throw should be a description of the problem -- in this case, an explanation of how findall.e should be invoked. (This usage string does not include the leading "e" as this is only necessary under some operating systems.) All the junk after the usage message is a stack traceback. Later we will learn how to use or suppress these, but let's ignore it for now.

Let's obey the suggested usage and see what happens:

C:\WINDOWS> rune findall.e c:/test .txt and
c:\test\jabberwocky.txt:1:'Twas brillig and the slithy toves
c:\test\jabberwocky.txt:2:Did gyre and gimble in the wabe:
c:\test\jabberwocky.txt:8:Beware the Jubjub bird and shun
c:\test\jabberwocky.txt:9:The frumious Bandersnatch."

C:\WINDOWS> _
 

To see the full syntax of the rune command line, type "rune --help".

Running an E Program from the Bash Shell

Unless you are required to work with the MS-DOS shell for some ungodly compatibility reason, we recommend bash, already pre-installed on all Unixes, and available for Windows from Cygnus Support.

Everything you can do with E using the MS-DOS shell you can also do in the bash shell. In addition, if there is an rune command on your path (which the E installer does by default), and if you copy Cygwin's env command to /usr/bin,

BASH.EXE-2.02$ mkdir -p /usr/bin
BASH.EXE-2.02$ cp `command -v env` /usr/bin/env

then you can run E programs directly without having to say rune first.

BASH.EXE-2.02$ cp `command -v env` /usr/bin/env
BASH.EXE-2.02$ findall.e c:/test .txt and
c:\test\jabberwocky.txt:1:'Twas brillig and the slithy toves
c:\test\jabberwocky.txt:2:Did gyre and gimble in the wabe:
c:\test\jabberwocky.txt:8:Beware the Jubjub bird and shun
c:\test\jabberwocky.txt:9:The frumious Bandersnatch."
BASH.EXE-2.02$ _
 

An E program can be invoked from within shell scripts(such as bash scripts) in this manner. In addition, a shell script can contain an E program which it invokes directly. Here's how you can demonstrate the principles involved interactively:

BASH.EXE-2.02$ rune - << FOO
> println(2 + 3)
> FOO
5
BASH.EXE-2.02$ _
 

The "-" tells rune to interpret its standard input as if it were an E program in a file (rather than interactively). The "<< FOO" and matching "FOO" is bash-speak for "Take all the text between the FOOs and feed it to the command on the left as its standard input.". Like E, bash prompts you with "> " when you are in the midst of entering a single multi-line command. The "> " prompts above came from bash rather than E.

Making findall.e Launchable as a GUI Application

*** to be written

 
Unless stated otherwise, all text on this page which is either unattributed or by Mark S. Miller is hereby placed in the public domain.
ERights Home elang / intro 
Back to: Example: Finding Text x On to: A 15 Minute Introduction to E
Download    FAQ    API    Mail Archive    Donate

report bug (including invalid html)

Golden Key Campaign Blue Ribbon Campaign