This is README.rtf in view mode; [Download] [Up]
Eval Glen Diener Center for Computer Research in Music and Acoustics (CCRMA) Dept. of Music Stanford University grd@ccrma.stanford.edu Eval is a service provider for any app that writes ascii to the pasteboard. It can do two things: compile, load, and execute the selection as ObjC code, or interpret the selection as postScript. Eval manages a window, called the "Transcript", with both a text view and a graphics view. ObjC output or postscrip output can be directed to these windows. Installing Eval runs as a "service". To install it, copy the Eval executable into ~/Apps or /LocalApps (you must be be root to install in /LocalApps). Then logout and log back in again. The "Eval" option should now appear in the services menus of Edit, Terminal, Librarian, WriteNow, and many other Apps. Any application which can print ascii text to the pasteboard should show the "Eval" . If Eval does not appear, try deleting the files ".applit" and ".cache" in ~/NeXT/services, then log back out and log back in. This will regenerate these files automatically. The readme for MailHelper1.1 also suggests the following... There is a report of applications not recognized if installed in /LocalApps with 2.0 release OS. This is apparently a bug in Release 2.0. It should work fine with 2.1. To make it work with release 2.0, do in Terminal: dwrite Workspace ApplicationPaths "~/Apps:/LocalApps:/NextApps:/NextDeveloper/Apps: /NextAdmin:/NextDeveloper/Demos" (This should be all on one line.) Special note: If you remake the binary, DO NOT STRIP the executable! It NEEDS those symbol tables! It should be possible, using strip, to remove just those needed symbols, but I've not worked this out yet, sigh. Running Eval Eval is run by selecting text in your application, then selecting either the "ObjC" or the "PostScript" options in Eval's services menu. Assuming you have installed Eval, then try working through the following examples. In might be useful to "tear off" the Eval services menu to make things more convenient. Select the following line of ObjC code, then execute the menu item "ObjC" [Eval printf: "Hello world\n"] ; You should see Eval's transcript window pop up, with the phrase "Hello World" written into the lower view. Let's examine the above code."Eval" , the message receiver, is the name of a "prelinked" class which understands a number of useful class messages. One of these, printf:, works exactly like good old printf(), except that it always writes to the transcript's text view, concatenating its output to the contents of that view. You can clear the text in Eval's text view by pressing the "Clear Text" button. Clear it now, then evaluate the following ObjC code to see how printf: accepts a variable number of arguments, just as printf() does... int i, j = 0 ; for(i = 1 ; i <= 100 ; i++) j += i ; [Eval printf: "%s %d\n","The answer is ", j] ; If you need to #import anything into the code, no problem. Just be sure you leave at least one blank line between the #import (#define, whatever), and the rest of your code (more on this later). Evaluate the following ObjC.... #import <sys/dir.h> // Print a listing of the root directory. // Note: 1 or more blank lines seperate #defines from code int i,fileCount ; struct direct **filesList ; char *aPath = "/" ; fileCount = scandir(aPath,&filesList,NULL,NULL) ; for(i = 0 ; i < fileCount ; i++) [Eval printf: "%s\n", (*filesList[i]).d_name] ; Eval's upper view is used for displaying postscript graphics output. Select the following, then choose Eval's PostScript menu item... /Times-Roman findfont 20 scalefont setfont 10 10 moveto (Hello world) show You can see how Eval functions like a ready-to-use version of Yap. Unlike Yap, however, Eval let's you generate postscript via ObjC, using Eval's ps: class message. Clear the graphics (using the Clear Graphics button), then evaluate the following as ObjC... [Eval ps: "/Helvetica findfont " "50 scalefont setfont " "10 10 moveto " "(c'est quoi ca?) show " ] ; As shown in the following example, Eval's ps: method can accept arguments, just like its printf: method. The example also shows Eval's clearGraphics class method, which accomplishes programmatically what hitting the Clear Graphics button accomplushes manually. int i ; for(i = 1 ; i < 10 ; i++) { [Eval clearGraphics] ; [Eval ps: "/Helvetica findfont " "%d scalefont setfont " "%d %d moveto " "(Hello world) show ", i * 10, i * 5, i * 10 ] ; NXPing() ; usleep(500000) ; // sleep for half a second } If "Hello world" has become too big and is no longer completely visible in the Graphics view, use the scrollers to view it all (or resize the window!). The safest way to do postscript is to use either Eval's ps: method or to just evaluate straight postscript using the Services/Eval/PostScript item. In both cases, the postscript sent to the window server is wrapped in error-handling code to catch errors, which will be reported in the text view. Both of these methods also wrap the postscript in a gsave/grestore pair, so if you want to build up state between calls to these methods, you can't use these methods. The alternative is to braket ObjC code within [Eval startPS] and [Eval stopPS] messages. startPS takes care of "locking focus" on the graphics view's underlying NXImage. stopPS unlocks it composites the image to the graphics view, and flushes the window. The following example illustrates this technique... #import <math.h> #import <dpsclient/psops.h> float x ; #define PI 3.14159 [Eval clearGraphics] ; [Eval ps: "0 100 moveto 250 100 lineto stroke"] ; [Eval startPS] ; PSmoveto(0.0,100.0) ; for(x = 0.0 ; x <= 4.0 * PI ; x += 0.05) PSlineto(x * 20.0, sin(x) * 100.0 + 100.0) ; PSstroke() ; [Eval stopPS] ; How it works When you select code and evaluate it using the ObjC button, the Eval app sandwiches your code with both a header and a footer. It creates a complete objC class definition with exactly one class method, called "doit". It then saves the definition in a temporary file in /tmp, invokes the objC compiler, then uses the objc_loadmodules call to dynamically link the result into the Eval app itself. Finally, the newly linked class is sent the "doit" message, and your code is executed. When the message returns, all the temporary files are removed. Actually, Eval attempts to cut your code into two sections, a "header" section, and a body section. The "header" section is placed at the beginning of the file Eval creates, and is not tectually part of the "doit" method. For more prescise details about how this works, see the file "Eval.m", and, in particular, the method - evalObjC:(id) pboard userData: (const char *) uBuf error: (char **) msg ; You can customize the compiler options using Eval's Preferences Panel. The panel also lets you add or remove link libraries searched during the dynamic linking. The transcript's text view's font and font size can be saved, and the size of the graphics view, in pixels, can also me specified here. Eval Class Methods Definitions of the following class methods are already present in the file which Eval creates, so the code you use can simply call them directly without having to #import any headers. + clearGraphics ; Clears the transcript's graphics view. + clearText ; Clears the transcript's text view. + printf: (char *) format, ... ; Formats and prints text to the transcript. + ps: (char *) format, ... ; "Locks focus" on the transcript's graphic's view's NXImage object, formats and prints text to the postscript window server, wrapped inside a NXHandler and bracketed by a gsave/grestore pair., then unlocks focus, composites the NXImage to the graphics view, and flushes the offscreen window. + startPS ; "Locks focus" on the transcript's graphic's view's NXImage object. Must be followed, eventually, by a stopPS message. Any PostScript rendered after startPS will show up in the graphics view after stopPS is sent. + stopPS ; "Unlocks focus" on the transcript's graphic's view's NXImage object, then composites the image to the graphics view and flushes the window. Stanford Univ., Tuesday, Jan. 28, 1:03 P.M., 1992
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.