Tools For Using the SAL Library

Compiling

There is an example makefile in the clients directory. It specifies all the flags you need to correctly compile and link a SAL application. You must have environment variable SALLIB set to the root SAL library directory (for example, /afs/ir/class/cs329/sal-1.1/lib). Note that the SAL library is compiled with garbage-collection support; see the conventions page for more detail.

Geomview

Geomview is free software provided by the University of Minnesota Geometry Center for interactively viewing 3D graphics. A SAL inspector can produce output in the form of files that can be read by Geomview. Alternatively, a SAL program can be run interactively as a Geomview module, feeding updates to Geomview and handling user events from the Geomview window.

Geomview is installed locally at .../Geomview (executable is geomview); more documentation is available in its on-line manual.

To use a SAL program as a Geomview module, go to the Geomview commands window and enter (emodule-define "identifier" "command-line-to-run-program"). Start the program in the main Geomview window by clicking on the identifier. Your program will run as a sub-process of Geomview, with stdin coming from Geomview and stdout going to Geomview, so don't count on them for anything else!

Ops

The ops Perl script in the SAL bin directory preprocesses specially-formatted functions into classes whose instances can be passed around as ops. Call it with the name of the input file and the output C++ file.

Declare operations to be passed as follows:

    #Op
    return-type name(args)
    {
      body
    }
or
    #Op [ parameters ]
    return-type name(args)
    {
      body
    }

In the second case, the parameters (declared like an argument list) are visible within the body. The script sets up a class called "Op_name". If there are no parameters, it goes ahead and creates an instance named "name". Otherwise, when you create one, provide actuals for the parameters to the constructor.

Example:

    // No parameters
    #Op
    int add_one_to(int i)
    { 
      return i+1; 
    }

    // One parameter: how much to add to the argument
    #Op [int x]
    int add_x_to(int i)
    { 
      return i+x; 
    }

    // Three containers created elsewhere
    Container *is1, *is2, *is3;

    // Add 1 to each element of is1
    transform(is1, add_one_to, is2);

    // Create an op that will add 2 to its argument
    Op_1 *add_two_to = new Op_add_x_to(2);

    // Add 2 to each element of is1
    transform(is1, add_two_to, is3);