vixie@wrl.dec.com (Paul Vixie) (05/03/90)
Submitted-by: vixie@wrl.dec.com (Paul Vixie) Posting-number: Volume 7, Issue 15 Archive-name: awl/part01 Awl is a relatively simple layout language for defining widget hierarchies and (to some extent) behaviour. I had it in mind to write something like this for a long time, but kept putting it off until being recently re-inspired by the "layout" program posted by Dwight Cooper (thanks Dwight!). Anyway, this should be generally useful to anyone desiring a less complicated interface to the Athena, Motif or Xw widgets (depending on what you're actually licensed for, of course. We won't, ahem, mention the OSF's licensing policies here..) I am releasing awl at this stage because I am swamped with other work and desperately need a little feedback on whether I'm even on the right track with this (a little help in testing and enhancing it would also be greatly appreciated). I think that most of the pathological bugs have been worked out and that it should be reasonably useful for more elementary tasks. I'm hoping that some real motivated types will be willing to look past the inadequate documentation and half-baked Motif mapping and see if there's something of value underneath. Enough chat, have fun. Jordan Hubbard #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 17)." # Contents: Imakefile MANIFEST README etc/xmu.h examples/arith.awl # examples/array.awl examples/browse.awl examples/case.awl # examples/clocks.awl examples/fact.awl examples/fact2.awl # examples/file.awl examples/files.awl examples/flags.awl # examples/form.awl examples/gcd.awl examples/hello.awl # examples/ilayout.awl examples/list.awl examples/list2.awl # examples/main.awl examples/pipe.awl examples/range.awl # examples/set.awl examples/stat.awl examples/stringops.awl # examples/view.awl examples/winfo.awl extract.perl hash.h # patchlevel.h shar_files strrtns.c # Wrapped by vixie@jove.pa.dec.com on Mon Apr 30 01:25:19 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Imakefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Imakefile'\" else echo shar: Extracting \"'Imakefile'\" \(3207 characters\) sed "s/^X//" >'Imakefile' <<'END_OF_FILE' X# X# Here lies the Imakefile for AWL. X# MOTIFINCS and XWINCS should be set to the top of the Motif and Xw include X# trees, respectively, if either the Motif or HP Widget sets are used. X# WIDGETSET should be ONE of ATHENA, MOTIF or XW depending on whether the X# Athena, Motif or HP Widget set is desired. X# WIDGETLIB should point to the libraries necessary to link an Athena, Motif X# or Xw application. X# AWLDIR should point to where you want to install awl's auxilliary files. X# X# Three other GNU utilities are used: bison, flex and gperf. If you don't X# have bison or flex, you can uncomment the appropriate lines below to use X# yacc and lex. If you don't have gperf you can use the pre-created [*]_gp.c X# hash tables, you just won't be able to modify awl's gperf files. X# X MOTIFINCS = /usr/include/Motif/Xm X XWINCS = $(INCDIR)/Xw X AWLDIR = /usr/src/local/awl/etc X WIDGETSET = ATHENA X WIDGETLIB = $(DEPXAWLIB) X DEFINES = -D$(WIDGETSET) -DESCAPED_STRING -DGeneric="void *" \ X -DAWLDIR=\"$(AWLDIR)\" X LOCAL_LIBRARIES = libawl.a $(WIDGETLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) X CDEBUGFLAGS = -g X GPERF = gperf -t -p -o -g X# YACC = yacc -dtv X# LEX = lex X YACC = bison -dty X LEX = flex -cef X CC = gcc X PROGRAMS = awl X SRCS1 = awl_driver.c OBJS1 = awl_driver.o X SRCS2 = y.tab.c lex.yy.c util.c eval.c evalutils.c symbols.c layout.c \ X builtins.c mathrtns.c strrtns.c sysrtns.c xtkrtns.c dasm.c \ X Awl.c widgets_gp.c resw_gp.c regex.c hash.c stat.c \ X convert.c strftime.c X OBJS2 = y.tab.o lex.yy.o util.o eval.o evalutils.o symbols.o layout.o \ X builtins.o mathrtns.o strrtns.o sysrtns.o xtkrtns.o dasm.o \ X Awl.o widgets_gp.o resw_gp.o regex.o strsed.o hash.o stat.o \ X convert.o strftime.o X X HDRS = Awl.h AwlP.h regex.h hash.h ltypes.h macros.h patchlevel.h X X# Enable one or both of the EXTENDEDINCS if you have Motif or Xw. X#EXTENDEDINCS = $(AWLDIR)/xw.h $(AWLDIR)/xm.h XEXTENDEDINCS = X BASICINCS = $(AWLDIR)/xt.h $(AWLDIR)/xmu.h $(AWLDIR)/xaw.h X AUXINCS = $(BASICINCS) $(EXTENDEDINCS) X NormalLibraryTarget(awl,$(OBJS2)) ComplexProgramTarget_1(awl,,$(LOCAL_LIBRARIES) $(SYS_LIBRARIES)) X depend:: $(SRCS1) $(SRCS2) $(HDRS) X resw_gp.c:: $(HDRS) resw.gperf X $(GPERF) -G -N is_resword resw.gperf > $@ X y.tab.c:: awl.y X $(YACC) awl.y X lex.yy.c:: awl.lex X $(LEX) awl.lex X widgets_gp.c:: $(HDRS) ${WIDGETSET}.gperf X $(GPERF) -G -N is_generic ${WIDGETSET}.gperf > $@ X strsed.o: strsed.c X $(CC) $(CFLAGS) -DGNU_REGEX -DFWRD_STATIC=static -c strsed.c X install:: $(AUXINCS) X $(INSTALL) $(AUXINCS) $(AWLDIR) X all-incs: $(AUXINCS) X @echo Made all include files.. X X$(AWLDIR)/xt.h: X ./extract.perl Xt $(INCDIR) | sort | uniq > $@ X X$(AWLDIR)/xmu.h: X ./extract.perl 'X[t\|mu]' $(INCDIR)/Xmu | sort | uniq > $@ X X$(AWLDIR)/xaw.h: X ./extract.perl Xt $(INCDIR)/Xaw | sort | uniq > $@ X X$(AWLDIR)/xm.h: X ./extract.perl Xm $(MOTIFINCS) | sort | uniq > $@ X X$(AWLDIR)/xw.h: X ./extract.perl 'X[tw]' $(XWINCS) | sort | uniq > $@ X allclean:: clean X $(RM) -f awl.toc awl.aux awl.cp awl.fn awl.vr awl.tp awl.ky awl.pg \ X resw_gp.c widgets_gp.c lex.yy.c y.tab.c y.tab.h awl.dvi awl.log awl.PS END_OF_FILE if test 3207 -ne `wc -c <'Imakefile'`; then echo shar: \"'Imakefile'\" unpacked with wrong size! fi # end of 'Imakefile' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(2413 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X This shar comes with the following files... X ATHENA.gperf.............8116 Awl.c....................13050 Awl.h....................3700 AwlP.h...................7711 COPYING..................12488 Imakefile................3203 MOTIF.gperf..............9038 Makefile.................12163 README...................3031 TODO.....................4835 awl.1....................4143 awl.lex..................6140 awl.texinfo..............85434 awl.y....................26311 awl_driver.c.............3617 builtins.c...............8086 cftime.c.................1361 convert.c................16995 dasm.c...................7436 etc/strsed.3c............14113 etc/xaw.h................8195 etc/xm.h.................32204 etc/xmu.h................1022 etc/xt.h.................38962 etc/xw.h.................17768 eval.c...................41981 evalutils.c..............15387 examples/arith.awl.......710 examples/array.awl.......638 examples/awlculator.awl..7204 examples/browse.awl......1216 examples/case.awl........2269 examples/clocks.awl......2227 examples/fact.awl........445 examples/fact2.awl.......836 examples/file.awl........757 examples/files.awl.......1883 examples/flags.awl.......1530 examples/form.awl........1384 examples/gcd.awl.........475 examples/hackpict.awl....5412 examples/hello.awl.......363 examples/ilayout.awl.....1162 examples/list.awl........965 examples/list2.awl.......2172 examples/main.awl........432 examples/pipe.awl........482 examples/porsche.awl.....5562 examples/range.awl.......830 examples/sample.awl......7830 examples/set.awl.........1161 examples/set2.awl........5795 examples/stat.awl........1335 examples/stringops.awl...2652 examples/view.awl........525 examples/winfo.awl.......638 extract.perl.............2560 hash.c...................9072 hash.h...................1644 layout.c.................5102 ltypes.h.................4426 macros.h.................15211 mathrtns.c...............5236 patchlevel.h.............21 regex.c..................47364 regex.h..................12869 resw.gperf...............3579 resw_gp.c................6221 shar_files...............1015 stat.c...................8163 strrtns.c................3303 strsed.c.................41443 symbols.c................8228 sysrtns.c................35683 texinfo.tex..............69537 util.c...................12340 widgets_gp.c.............10175 xtkrtns.c................12805 X And this MANIFEST. X END_OF_FILE if test 2413 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(2569 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X# X# $Header: README,v 2.2 90/04/30 01:13:35 vixie Exp $ X# X# $Log: README,v $ X# Revision 2.2 90/04/30 01:13:35 vixie X# vixie X# X# Revision 2.1 90/04/19 20:04:10 jkh X# Alpha checkin. X# X# Revision 2.0 90/03/26 01:51:37 jkh X# pre-beta check-in X# X ALPHA notes: X This is a double-secret pre-alpha prototype release of AWL. It is mainly functional, though the following features remain unimplemented: X X1. The Motif mapping is half-baked. The Xw mapping is unimplemented (all X mechanisms for doing such a mapping exist, however.. Hint hint). X X2. The documentation is incomplete, to say the least. Those wishing to X know more about the system / utility calls provided are encouraged to X read the comments in strrtns.c, sysrtns.c, mathrtns.c & xtkrtns.c X X3. The C application -> AWL interface is somewhat untested, though everything X should work in theory. X I am releasing awl at this stage because I am swamped with other work and desperately need a little feedback on whether I'm even on the right track with this (a little help in testing and enhancing it would also be greatly appreciated). I think that most of the pathological bugs have been worked out and that it should be reasonably useful for more elementary tasks. I'm hoping that some real motivated types will be willing to look past the inadequate documentation and half-baked Motif mapping and see if there's something of value underneath. Enough chat, have fun. X X Jordan Hubbard X X---------------------------------------------- X Awl is a relatively simple layout language for defining widget hierarchies and (to some extent) behaviour. I had it in mind to write something like this for a long time, but kept putting it off until being recently re-inspired by the "layout" program posted by Dwight Cooper (thanks Dwight!). Anyway, this should be generally useful to anyone desiring a less complicated interface to the Athena, Motif or Xw widgets (depending on what you're actually licensed for, of course. We won't, ahem, mention the OSF's licensing policies here..) X There a number of examples programs in the examples/ directory. Those that don't like to RTFM can simply build the awl driver `awl' (hopefully) and try it out on some of them. Those that like more documentation can read the awl.texinfo file. X Any questions, comments, suggestions, etc. should be directed to: X X X Jordan Hubbard X SMAIL: PCS Computer Systeme, GmbH. X Pfaelzer-Wald-Str. 36 X D-8000 Muenchen, 90. X West Germany X X USENET: jkh@meepmeep.pcs.com or pyramid!pcsbst!jkh X ARPA: jkh@violet.berkeley.edu END_OF_FILE if test 2569 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'etc/xmu.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'etc/xmu.h'\" else echo shar: Extracting \"'etc/xmu.h'\" \(1022 characters\) sed "s/^X//" >'etc/xmu.h' <<'END_OF_FILE' X#define XctAcceptC0Extensions 0 X#define XctAcceptC1Extensions 0 X#define XctFreeString 0 X#define XctHideDirection 0 X#define XctLeftToRight 1 X#define XctProvideExtensions 0 X#define XctRightToLeft 2 X#define XctSegment 0 X#define XctShiftMultiGRToGL 0 X#define XctSingleSetSegments 0 X#define XctUnspecified 0 X#define XctVersion 1 X#define XmuShapeEllipse 3 X#define XmuShapeOval 2 X#define XmuShapeRectangle 1 X#define XmuShapeRoundedRectangle 4 X#define XtCBackingStore "BackingStore" X#define XtEEllipse "Ellipse" X#define XtEOval "Oval" X#define XtERectangle "Rectangle" X#define XtERoundedRectangle "RoundedRectangle" X#define XtEalways "always" X#define XtEcenter "center" X#define XtEdefault "default" X#define XtEleft "left" X#define XtEnotUseful "notUseful" X#define XtEright "right" X#define XtEwhenMapped "whenMapped" X#define XtJustifyLeft 0 X#define XtNbackingStore "backingStore" X#define XtRBackingStore "BackingStore" X#define XtRLong "Long" X#define XtRShapeStyle "ShapeStyle" X#define XtorientHorizontal 0 X#define XtorientVertical 1 END_OF_FILE if test 1022 -ne `wc -c <'etc/xmu.h'`; then echo shar: \"'etc/xmu.h'\" unpacked with wrong size! fi # end of 'etc/xmu.h' fi if test -f 'examples/arith.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/arith.awl'\" else echo shar: Extracting \"'examples/arith.awl'\" \(710 characters\) sed "s/^X//" >'examples/arith.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This example tests simple aritmetic operators. X */ main() X{ X /* integer */ X a = 15; X b = 20; X println("Integer:"); X do_ops(a, b); X X /* float */ X a = 15.0; X b = 20.0; X println("Float:"); X do_ops(a, b); X exit(0); X} X do_ops(a, b) X{ X println("a = ", a, ", b = ", b); X X /* bit operations */ X println("a & b = ", a & b); X println("a | b = ", a | b); X println("a ^ b = ", a ^ b); X println("~b = ", ~b); X X /* arithmetic */ X println("a * b = ", a * b); X println("a / b = ", a / b); X println("a % b = ", a % b); X println("a - b = ", a - b); X println("a + b = ", a + b); X println("-b = ", -b); X} END_OF_FILE if test 710 -ne `wc -c <'examples/arith.awl'`; then echo shar: \"'examples/arith.awl'\" unpacked with wrong size! fi # end of 'examples/arith.awl' fi if test -f 'examples/array.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/array.awl'\" else echo shar: Extracting \"'examples/array.awl'\" \(638 characters\) sed "s/^X//" >'examples/array.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This example shows off simple array usage. If user types "val = val" X * an array element will be created. If the user simply types "val" then X * the corresponding element will be shown. X */ main() X{ X frobbing = TRUE; X while(frobbing) { X cmd = input("foo> ", STRING); X if (cmd == "quit") X frobbing = FALSE; X else if ('=' ?? cmd) { X value = cmd - ".*="; X idx = cmd - "=.*"; X stuff[idx] = value; X } X else if ("!!" ?? cmd) { X idx = cmd - "!![ \t]*"; X !!stuff[idx]; X } X else X println("stuff[", cmd, "] = ", stuff[cmd]); X } X exit(0); X} END_OF_FILE if test 638 -ne `wc -c <'examples/array.awl'`; then echo shar: \"'examples/array.awl'\" unpacked with wrong size! fi # end of 'examples/array.awl' fi if test -f 'examples/browse.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/browse.awl'\" else echo shar: Extracting \"'examples/browse.awl'\" \(1216 characters\) sed "s/^X//" >'examples/browse.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X#include <xaw.h> X X#define MAX_COMMAND 2048 X global commandText[MAX_COMMAND]; X clear_text() X{ X println("clear.."); X} X execute() X{ X if (system(commandText)) X XBell(); X else X println("Ok"); X} X change_directory() X{ X if ((item = XgListGetItem(xxx)) != -1) X status = chdir(xxx.fred.view.files[XgListItems][item]); X} X create_browser_panel() X{ X local bp; X X bp = Shell "browser" { X Form fred { X Viewport view { X XgViewportScrollVert TRUE; X List files; X } X Box joe { X XgFormVertWidget (WIDGET)fred.view; X Button Clear { XgCallback (CALLBACK)clear_text; } X Button Doit { XgCallback (CALLBACK)execute; } X Button cd { XgCallback (CALLBACK)change_directory; } X Button + { XgCallback (CALLBACK)add_entry; } X Button - { XgCallback (CALLBACK)remove_entry; } X AsciiText command { X XgWidth 200; X XgAllowResize TRUE; X XgResize TRUE; X XgBorderWidth 2; X XtNstring commandText; X XtNuseStringInPlace TRUE; X XtNlength MAX_COMMAND; X XtNeditType XawtextEdit; X } X } X } X }; X return(bp); X} X main() X{ X top = create_browser_panel(); X X END_OF_FILE if test 1216 -ne `wc -c <'examples/browse.awl'`; then echo shar: \"'examples/browse.awl'\" unpacked with wrong size! fi # end of 'examples/browse.awl' fi if test -f 'examples/case.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/case.awl'\" else echo shar: Extracting \"'examples/case.awl'\" \(2269 characters\) sed "s/^X//" >'examples/case.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * Show off several ways of using the switch statement. This could, of course, X * be done much nicer using associative arrays but then we wouldn't be X * demonstrating switch, would we? X */ X main() X{ X do { X /* get lower case name */ X x = strsed(input("Enter the name of a fabled character or 'quit': ", X STRING), "/.*/{A-Z}{a-z}/"); X switch (x) { X case "mary": X println("Had a juvinal herbivore or was quite contrary"); X break; X X case "peter": X println("Ate pumpkins or picked peppers"); X break; X X case "jack": X print("Climbed a beanstalk or "); X /* no break means fall-through, as in C */ X X case "jill": X println("tumbled down a hill with ", X (x == "jack" ? "jill" : "jack")); X break; X X case "alladin": X println("Owned a lamp"); X break; X X case "tom": X println("Was a pipers son"); X break; X X case "miss muffet": X println("Sat on a tuffet"); X break; X X case "simon": X println("Was a pieman of low intelligence"); X break; X X case "hansel": X case "gretel": X println("Got busted for B&E"); X break; X X case "terry": X println("Was a clueless Aussie hacker with wanderlust"); X break; X X case "quit": X break; X X default: X println("Sorry, don't know anything about a '", x, "'."); X } X } until (x == "quit"); X X /* X * case expressions in switches can actually be any valid expression. X * Sorry, but I couldn't think of an example that was actually useful X * for anything. This should at least illustrate the point, however. X */ X print("Enter two integers: "); X limit = get(INT); X value = get(INT); X X switch (value) { X case limit: X println("The first equals the second"); X break; X X case limit/2: X println("The second is one-half of the first"); X break; X X case limit/3: X println("The second is one-third of the first"); X break; X X case limit/4: X println("The second is one-fourth of the first"); X break; X X case limit*2: X println("The second is twice that of the first"); X break; X X default: X println("Nothing too interesting about them."); X } X exit(0); X} X END_OF_FILE if test 2269 -ne `wc -c <'examples/case.awl'`; then echo shar: \"'examples/case.awl'\" unpacked with wrong size! fi # end of 'examples/case.awl' fi if test -f 'examples/clocks.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/clocks.awl'\" else echo shar: Extracting \"'examples/clocks.awl'\" \(2227 characters\) sed "s/^X//" >'examples/clocks.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This demo shows three things: X * 1. How layouts can be arbitrarily nested. X * 2. Simple translation table handling. X * 3. How to be really really silly after 3 AM when you've had way too much X * Expresso and you're punchy as hell. X */ X#include <xt.h> X#include <xaw.h> X stop() X{ X println("Catch ya later, man.."); X exit(0); X} X help() X{ X println("You want help? Here, eat this, man, serious colors.."); X} X yelp(type) X{ X if (type == CASUAL) X println("Hey man, like, mellow out. Put it back!"); X else if (type == HEAVY) { X println("Negative vibes, man, why are you so uptite?"); X println("Something must have, like, put your head in a bad"); X println("space.. Just mellow out and go with the flow, dig?"); X } X else X println("Something really uncool is goin' down here."); X} X activate(w, type) X{ X if (type == CHECKIN) X println("Hey man! Welcome to the party!"); X else if (type == BOOKOUT) X println("Later days, man, take it easy.."); X else /* should never happen */ X println("Whoa! Bummer! I can't handle this, man."); X} X clock(analogp, fore, back) X{ X return(Clock fred { X XtNanalog analogp; X XtNbackground back; X XtNforeground fore; X }); X} X clocks() X{ X local x, black, white; X X black = (XtRPixel)"Black"; X white = (XtRPixel)"White"; X x = Pane "clocks" { X XtNtranslations (TRANSLATION)"<FocusIn>:activate(CHECKIN) X <FocusOut>:activate(BOOKOUT) X <Btn1Up>:do_show(ONE, TWO, THREE) X None<Key>q:stop() X None<Key>Help:help() X None<Key>h:help()"; X clock(FALSE, white, black); X clock(TRUE, black, white); X }; X return(x); X} X X/* this shows off more complicated argument handling */ do_show(w) X{ X /* since we don't know (technically) how many args we got */ X x = _argc(); X X println(x, " arguments to do_show for widget ", w); X while (x) { X println("arg[",x,"] = ", _argv(x)); X --x; X } X} X main() X{ X println("A couple of clocks.."); X XtCreateManaged(clocks()); X XtRealize(SELF); X} END_OF_FILE if test 2227 -ne `wc -c <'examples/clocks.awl'`; then echo shar: \"'examples/clocks.awl'\" unpacked with wrong size! fi # end of 'examples/clocks.awl' fi if test -f 'examples/fact.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/fact.awl'\" else echo shar: Extracting \"'examples/fact.awl'\" \(445 characters\) sed "s/^X//" >'examples/fact.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* Compute factorial using recursion (see fact2.wl for iterative version) */ fact(n) X{ X if (n == 1) X return 1; X else X return(n * fact(n - 1)); X} X main() X{ X while (x = input("Enter a number: ", ANY)) { X if (typeof(x) != INT && typeof(x) != FLOAT) X println("'", x, "' is not a number."); X else { X n = fact(x); X println("The factorial of ", x, " is ", n); X } X } X exit(0); X} END_OF_FILE if test 445 -ne `wc -c <'examples/fact.awl'`; then echo shar: \"'examples/fact.awl'\" unpacked with wrong size! fi # end of 'examples/fact.awl' fi if test -f 'examples/fact2.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/fact2.awl'\" else echo shar: Extracting \"'examples/fact2.awl'\" \(836 characters\) sed "s/^X//" >'examples/fact2.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* Compute factorial using iteration and local variables prod and cnt */ fact(n) X{ X local prod, cnt; X X /* X * Notice here how we cast the literal "1" to the type of "n" (FLOAT or X * INT) before assigning it. This is necessary or the automatic typing X * rules would take over in the (cnt <= n) expression and convert X * n to the type of "1". fact() would then only work for integer X * (or float, if we made it "1.0") values, but not both. X */ X prod = cnt = (typeof(n))1; X while (cnt < n) X prod *= cnt++; X return prod; X} X main() X{ X while (x = input("Enter a number: ", ANY)) { X if (typeof(x) != FLOAT && typeof(x) != INT) X println("'", x, "' is not a number."); X else X println("The factorial of ", x, " is ", fact(x)); X } X exit(0); X} END_OF_FILE if test 836 -ne `wc -c <'examples/fact2.awl'`; then echo shar: \"'examples/fact2.awl'\" unpacked with wrong size! fi # end of 'examples/fact2.awl' fi if test -f 'examples/file.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/file.awl'\" else echo shar: Extracting \"'examples/file.awl'\" \(757 characters\) sed "s/^X//" >'examples/file.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This demonstrates some elementary file handling. X */ main() X{ X print("Enter a file: "); X name = get(STRING); X if (length(name)) { X if (file = open(name, "r")) { X local len; X X len = length(file); X data = malloc(len + 1); X printf("Loading %d bytes from %s... ", len, name); X assign(file, stdin); X read(data, len); X assign(STDIN, stdin); X printf("Done.\n"); X close(file); X lv = (LIST)data; X free(data); X printf("lv = %x, lv[0] = %s\n", lv, lv[0]); X for (i = 0; lv[i]; i++) X printf("lv[%d] = %s\n", i, lv[i]); X } X else X perror("Can't open '" + name + "'"); X } X else X print("Ciao.."); X exit(0); X} END_OF_FILE if test 757 -ne `wc -c <'examples/file.awl'`; then echo shar: \"'examples/file.awl'\" unpacked with wrong size! fi # end of 'examples/file.awl' fi if test -f 'examples/files.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/files.awl'\" else echo shar: Extracting \"'examples/files.awl'\" \(1883 characters\) sed "s/^X//" >'examples/files.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This example demonstrates several ways of accessing directories and X * their contents. X */ X X/* X * Here's a slow, sorta klunky way of doing it that might, nonetheless, X * be preferable depending on how you'd like to see the files. Doing X * an ls -1F would, for instance, also get you little "*" and "/" indicators X * tacked onto each filename. Hmm. Still klunky. X */ grabdir_slow(dir) X{ X local f, retval; X X if (f = open("ls -a1" + dir, "rp")) { X assign(f, stdin); /* make it stdin */ X oldsep = $SEP; /* save the old line separator */ X $SEP = EOF; /* make a "string" the whole file */ X stuff = get(STRING); /* slurp it in */ X assign(STDIN, stdin); /* put stdin back where we found it */ X $SEP = oldsep; /* restore the line separator */ X close(f); /* be tidy */ X retval = (LIST)stuff; /* convert string to list */ X } X else X retval = NULL; X return(retval); X} X X/* X * Here's the preferred method (unless you want your filenames to X * have extra "ls" frobs attached or something). X */ grabdir_quick(dir) X{ X /* Much simpler */ X return(readdir(dir)); X} X main() X{ KLUNKY_GOTO: X print("What directory would you like listed, sir? "); X foo = get(STRING); X if (foo != quit) { X print("Would you like to do it the hard way? "); X ans = get(STRING); X if ("[Yy]" ?? ans) { X println("As you wish.."); X grabber = grabdir_slow; X } X else { X println("Very good, sir."); X grabber = grabdir_quick; X } X if (contents = grabber(foo)) { X l = length(contents); X printf("\nThere are %d files in the directory %s\n", l, foo); X for (i = 0; i < l; i++) X printf("%d: %s\n", i, contents[i]); X } X else X printf("I'm sorry, sir, I cannot seem to find a '%s'..\n", dir); X } X else { X println("Of course.."); X exit(0); X } X goto KLUNKY_GOTO; X} END_OF_FILE if test 1883 -ne `wc -c <'examples/files.awl'`; then echo shar: \"'examples/files.awl'\" unpacked with wrong size! fi # end of 'examples/files.awl' fi if test -f 'examples/flags.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/flags.awl'\" else echo shar: Extracting \"'examples/flags.awl'\" \(1530 characters\) sed "s/^X//" >'examples/flags.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * Make your own three striped national flag. For example: X * black/orange/gold = West Germany X * red/white/red = Austria X * X * Note, however, that this example is *very* inefficient since we're X * representing 3 simple rectanges as (10,000!) points. The pixmap X * conversion mechanism was designed more for dealing with arbitrary X * pixmap "picture" images than this kind of work. A far better approach X * would be to allocate the colors in awl and pass them (and the window of X * the box widget) to a C routine that creates the pixmap accordingly. That, X * while simple enough to do, is beyond the scope of this example. X */ X X#define WIDTH 200 X#define STRIPE 50 main() X{ X /* Make a simple 3 striped flag image (see above comment) */ X flag = { "A" * 200 } * STRIPE + { "B" * 200 } * STRIPE + { "C" * 200 } * X STRIPE; X X /* Ask for the colors */ X top = input("Top color? ", STRING); X middle = input("Middle color? ", STRING); X bottom = input("Bottom color? ", STRING); X X /* X * Make a color table with our choices (forcing list coercion) and X * install the puppy. X */ X x = { "A" } + top + "B" + middle + "C" + bottom; X XgInstallColorTable(x); X X /* Construct the pixmap */ X picture = (PIXMAP)flag; X X /* Make a simple view for it */ X x = Box "flag" { X XgWidth 200; X XgHeight STRIPE * 3; X XgBackgroundPixmap picture; X XgTranslations (TRANSLATION)"#augment <Key>Q: exit(0)"; X }; X XtCreateManaged(x); X XtRealize(SELF); X} END_OF_FILE if test 1530 -ne `wc -c <'examples/flags.awl'`; then echo shar: \"'examples/flags.awl'\" unpacked with wrong size! fi # end of 'examples/flags.awl' fi if test -f 'examples/form.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/form.awl'\" else echo shar: Extracting \"'examples/form.awl'\" \(1384 characters\) sed "s/^X//" >'examples/form.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X#include <xt.h> X X/* X * This is pure whimsy. Actually, I wrote this to test some of the resource X * setting code and then never threw it away. Most of the code in this X * examples directory is like that. X */ X global swapit(), names = { "swap", "this", "junk", "around" }, rolls = 0; X X/* Create Joe Widget */ joe_widget(name, cb, i) X{ X local type = (cb ? Button : Label); X X /* The callback will be simply ignored for labels */ X return(type name {XgLabel names[i]; XgWidth 80; XgCallback cb;}); X} X main() X{ X /* Show clever (sort of) use of mid-layout function calls to save work */ X X = Form fore { X XgTranslations (TRANSLATION)"#augment <Key>q: exit(0)"; X joe_widget("a", (CALLBACK)swapit, 0); X joe_widget("b", 0, 1); X joe_widget("c", 0, 2); X joe_widget("d", 0, 3); X }; X X.b[XgFormHorizWidget] = X.c[XgFormVertWidget] = X.d[XgFormVertWidget] = X (WIDGET)X.a; X X.d[XgFormHorizWidget] = (WIDGET)X.c; X XtCreateManaged(X); X XtRealize(SELF); X} X swapit() X{ X if (!initted) { X initted = TRUE; X for (i = 0; i < 3; i++) X rolls[i] = i + 1; X rolls[3] = 0; X } X else { X for (i = 0; i < 4; i++) X if (++rolls[i] > 3) X rolls[i] = 0; X } X X.a[XgLabel] = names[rolls[0]]; X X.b[XgLabel] = names[rolls[1]]; X X.c[XgLabel] = names[rolls[2]]; X X.d[XgLabel] = names[rolls[3]]; X} END_OF_FILE if test 1384 -ne `wc -c <'examples/form.awl'`; then echo shar: \"'examples/form.awl'\" unpacked with wrong size! fi # end of 'examples/form.awl' fi if test -f 'examples/gcd.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/gcd.awl'\" else echo shar: Extracting \"'examples/gcd.awl'\" \(475 characters\) sed "s/^X//" >'examples/gcd.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * Recursive example of Euclid's algorithm for calculating the greatest X * common denominator of 2 numbers. X */ main() X{ X a = b = 1; X while (a) { X print("Input two numbers: "); X a = get(INT); b = get(INT); X if (a && b) X printf("The gcd of %d and %d is %d\n", a, b, gcd(a,b)); X } X exit(0); X} X gcd(x, y) X{ X if (x == y) X return x; X else if (x > y) X return gcd(x - y, y); X else X return gcd(x, y - x); X} END_OF_FILE if test 475 -ne `wc -c <'examples/gcd.awl'`; then echo shar: \"'examples/gcd.awl'\" unpacked with wrong size! fi # end of 'examples/gcd.awl' fi if test -f 'examples/hello.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/hello.awl'\" else echo shar: Extracting \"'examples/hello.awl'\" \(363 characters\) sed "s/^X//" >'examples/hello.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X#include <xt.h> X X/* X * This is the standard, unavoidable, "hello world" demo. X */ X main() X{ X /* Allow the user to exit by clicking on it or typing "q" */ X hi = Button "Hello, world!" { X XgTranslations (TRANSLATION)"#augment <Key>Q: exit(0)"; X XgCallback (CALLBACK)exit; X }; X XtCreateManaged(hi); X XtRealize(SELF); X} END_OF_FILE if test 363 -ne `wc -c <'examples/hello.awl'`; then echo shar: \"'examples/hello.awl'\" unpacked with wrong size! fi # end of 'examples/hello.awl' fi if test -f 'examples/ilayout.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/ilayout.awl'\" else echo shar: Extracting \"'examples/ilayout.awl'\" \(1162 characters\) sed "s/^X//" >'examples/ilayout.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This is the top level view for the interactive widget placement X * editor. X */ X#include "enum-to-def.h" Layout top Pane { X Form "Top" { X height 60; X Box "Menubar" { X height 20; X Button "File"; X Button "Font"; X Button "Color"; X Button "Pixmap"; X } X Box "Types" { X fromVert "Menubar" : W_ID; X height 20; X left XtChainLeft; X right XtChainRight; X Button "Box"; X Button "Button"; X Button "Clock"; X Button "Dialog"; X Button "Form"; X Button "Grip"; X Button "Label"; X Button "List"; X Button "Load"; X Button "Logo"; X Button "Mailbox"; X Button "Pane"; X Button "Popup"; X Button "Scrollbar"; X Button "Shell"; X Button "Text"; X Button "Toggle"; X Button "Viewport"; X } X Box "Misc" { X fromVert "Types" : W_ID; X Button "Edit"; X Button "Copy"; X Button "Group"; X Button "Break"; X } X } X Viewport "fred" { X allowHoriz convert(TRUE, VALUE); X allowVert convert(TRUE, VALUE); X Box "Canvas"; X } X} END_OF_FILE if test 1162 -ne `wc -c <'examples/ilayout.awl'`; then echo shar: \"'examples/ilayout.awl'\" unpacked with wrong size! fi # end of 'examples/ilayout.awl' fi if test -f 'examples/list.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/list.awl'\" else echo shar: Extracting \"'examples/list.awl'\" \(965 characters\) sed "s/^X//" >'examples/list.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X#include <xt.h> X yip() X{ X printf("Yow!\n"); X} X forp(name) X{ X LW = Shell name { X XgAllowShellResize TRUE; X XgCallback (CALLBACK)yip; X Viewport "view" { X XgTranslations (TRANSLATION)"#augment <Key>Q: exit(0)"; X XgViewportScrollVert TRUE; X XgViewportScrollHoriz TRUE; X List foo { X XgCallback (CALLBACK)yip; X } X } X }; X XtPopup(XtCreateManaged(LW), XtGrabNone); X} X main() X{ X print("File: "); X file = open(name = get(STRING), "r"); X assign(file, stdin); X $SEP = EOF; X contents = get(STRING); X $SEP = "\n"; X list = (LIST)contents; X assign(STDIN, stdin); X close(file); X contents = 0; X forp(name); X X longest = 0; X len = length(list); X for (i = 0; i < len; i++) { X s = list[i]; X if (length(s) > longest) X longest = length(s); X } X printf("file contains %d items, longest is %d. Setting list widget.\n", X len, longest); X XgListChange(LW.view.foo, list); X} END_OF_FILE if test 965 -ne `wc -c <'examples/list.awl'`; then echo shar: \"'examples/list.awl'\" unpacked with wrong size! fi # end of 'examples/list.awl' fi if test -f 'examples/list2.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/list2.awl'\" else echo shar: Extracting \"'examples/list2.awl'\" \(2172 characters\) sed "s/^X//" >'examples/list2.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X#include <xt.h> X#include <xaw.h> X X/* THIS DOESN'T WORK YET. I DON'T KNOW HOW TO CONFIGURE THE TEXT WIDGET PROPERLY */ X X/* X * These are necessary since we ref these symbols as functions before X * they're declared. X */ global grabdir(), swap_1_to_2(), swap_2_to_1(); X global dirname[128]; /* Better to have this "static" */ global List1 = 0, List2 = 0; /* save a check later */ X make_list(name, cb) X{ X local ret; X X ret = Viewport name { X XgViewportScrollVert TRUE; X List ll { X XgCallback (CALLBACK)cb; X } X }; X return ret; X} X main() X{ X Top = Pane flip_demo { X XgTranslations (TRANSLATION)"<Key>Q: exit(0)"; X Box b { X XgPaneMinHeight 30; X Button Read { X XgCallback (CALLBACK)grabdir; X } X AsciiText dir { X XgTextString dirname; X/* XgTextUseStringInPlace TRUE; */ X XtNeditType XttextEdit; X XgWidth 200; X } X } X Viewport port1 { X XgViewportScrollVert TRUE; X List ll { X XgCallback (CALLBACK)swap_1_to_2; X } X } X Viewport port2 { X XgViewportScrollVert TRUE; X List ll { X XgCallback (CALLBACK)swap_2_to_1; X } X } X }; X XtCreateManaged(Top); X XtRealize(SELF); X} X X/* grab dir contents */ grabdir() X{ X /* has user entered anything? */ X if (length(dirname)) { X if ((List1 = readdir(dirname)) != NULL) X XgListChange(Top.port1.ll, List1); X else X XgListChange(Top.port1.ll, { "Empty" }); X } X else X XBell(); /* let the user know we're unhappy */ X} X X/* swap item from list 1 to list 2 */ swap_1_to_2() X{ X selected = XgListGetItem(Top.port1.ll); X s = List1[selected]; X List1 -= s; /* remove item from list */ X XgListChange(Top.port1.ll, List1); X List2 += s; /* add it to the other list */ X XgListChnage(Top.port2.ll, List2); X} X X/* swap item from list 2 to list 1 */ swap_2_to_1() X{ X selected = XgListGetItem(top.port2.ll); X s = List2[selected]; X List2 -= s; /* remove item from list */ X XgListChange(top.port2.ll, List2); X List1 += s; /* add it to the other list */ X XgListChnage(top.port1.ll, List1); X} END_OF_FILE if test 2172 -ne `wc -c <'examples/list2.awl'`; then echo shar: \"'examples/list2.awl'\" unpacked with wrong size! fi # end of 'examples/list2.awl' fi if test -f 'examples/main.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/main.awl'\" else echo shar: Extracting \"'examples/main.awl'\" \(432 characters\) sed "s/^X//" >'examples/main.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This demonstrates passing arguments to main() with the awl driver. X * Invoke this demo with something like: "awl examples/mail.awl one two three" X */ X main(argc, argv) X{ X if (argc > 1) { X println("argc = ", argc, " argv = ", argv); X for (i = 0; i < argc; i++) X printf("argv[%d] = %s\n", i, argv[i]); X } X else X printf("No arguments were passed, read the code.\n", X argv[0]); X} END_OF_FILE if test 432 -ne `wc -c <'examples/main.awl'`; then echo shar: \"'examples/main.awl'\" unpacked with wrong size! fi # end of 'examples/main.awl' fi if test -f 'examples/pipe.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/pipe.awl'\" else echo shar: Extracting \"'examples/pipe.awl'\" \(482 characters\) sed "s/^X//" >'examples/pipe.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This shows off two-way process file descriptors X */ bc_doit(fd, cmd) X{ X local ret; X X assign(fd, stdin); X assign(fd, stdout); X println(cmd); X ret = get(STRING); X assign(STDIN, stdin); X assign(STDOUT, stdout); X return ret; X} X main() X{ X x = open("bc", "+p"); X setbuf(x, NULL, NULL); X while (line = input("Line to bc: ", STRING)) { X res = bc_doit(x, line); X println("result is ", res); X } X exit(0); X} END_OF_FILE if test 482 -ne `wc -c <'examples/pipe.awl'`; then echo shar: \"'examples/pipe.awl'\" unpacked with wrong size! fi # end of 'examples/pipe.awl' fi if test -f 'examples/range.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/range.awl'\" else echo shar: Extracting \"'examples/range.awl'\" \(830 characters\) sed "s/^X//" >'examples/range.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This is a very simple demonstration of ranges. I used a label/goto X * pair here just to show it can be done, I don't expect anyone to actually X * ever use gotos, but just in case.. X */ main() X{ X WOO: X ch = input("Enter a character: ", CHAR); X while ((junk = get(CHAR)) != '\n'); X if (ch == EOF) { X println("Bye.."); X exit(0); X } X else if (ch ?? 'a'..'z') X println("It's lower case."); X else if (ch ?? 'A'..'Z') X println("It's upper case."); X else if (ch ?? '0'..'9') X println("It's numeric."); X else if (ch ?? "\t\n\r\013") /* we cheat and use a string here */ X println("It's white space."); X else if (ch <= 27) /* here we just cheat */ X println("It's a control character."); X else X println("It's punctuation or something."); X goto WOO; X} END_OF_FILE if test 830 -ne `wc -c <'examples/range.awl'`; then echo shar: \"'examples/range.awl'\" unpacked with wrong size! fi # end of 'examples/range.awl' fi if test -f 'examples/set.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/set.awl'\" else echo shar: Extracting \"'examples/set.awl'\" \(1161 characters\) sed "s/^X//" >'examples/set.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * This is a simplistic example of ?? operator usage. X * We also show off some string manipulations. X */ X init_grocery() X{ X /* disambiguate [] */ X fruit = vegetables = 0; X X /* X * Since array elements are created the first time they're seen, just X * saying "var[element]" is enough for our purposes; we don't have to X * assign them to anything. X */ X fruit["apple"]; fruit["pear"]; fruit["orange"]; fruit["mango"]; X fruit["banana"]; fruit["papaya"]; fruit["grape"]; fruit["lemon"]; X X vegetables["carrot"]; vegetables["celery"]; vegetables["tomato"]; X vegetables["onion"]; vegetables["lettuce"]; vegetables["cucumber"]; X} X main() X{ X init_grocery(); X do { X q = input("Enter the name of a fruit or vegetable: ", STRING); X q -= "s$"; /* de-pluralize if necessary */ X art = q[0] ?? "aeio" ? "an " : "a "; X if (q ?? fruit) X println(art, q, " is a fruit"); X else if (q ?? vegetables) X println(art, q, " is a vegetable"); X else if (q != "quit") X printf("Huh? Is %s\"%s\" a fruit or vegetable?\n", art, q); X } until (q == "quit"); X exit(0); X} END_OF_FILE if test 1161 -ne `wc -c <'examples/set.awl'`; then echo shar: \"'examples/set.awl'\" unpacked with wrong size! fi # end of 'examples/set.awl' fi if test -f 'examples/stat.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/stat.awl'\" else echo shar: Extracting \"'examples/stat.awl'\" \(1336 characters\) sed "s/^X//" >'examples/stat.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X/* X * This demo shows how to use the stat and fmt_time builtins. They're X * demonstrated together since they both use the similar methods for X * specifying date format strings. This is explained below. X */ X main() X{ X /* X * Create a format string that will display: X * %P - protection bits in ascii format. X * %U - username of owner. X * %G - groupname of owner. X * %s - file size in bytes. X * %m - modification time with trailing time specifier: X * %b - abbreviated month name. X * %d - day of month. X * %X - time as HH:MM. X * %n - file name. X * X * This should end up looking similar to ls -l (though not sorted). X */ X statfmt = "%P\t%U\t%G\t%s\t%m(%h %d %R) %n\n"; X X /* X * Now construct a time string that looks like X * that printed by "date". X */ X datefmt = "%A %B, %d. %Y, %X %Z"; X X dirname = input("Directory to list: ", STRING); X if (contents = readdir(dirname)) { X printf("%s\n", fmt_time(datefmt, time())); X nfiles = length(contents); X for (i = 0; i < nfiles; i++) { X if (desc = stat(statfmt, dirname + "/" + contents[i])) X printf(desc); X else X printf("Can't stat %s!\n", contents[i]); X } X } X else X printf("Can't open directory %s\n", dirname); X} END_OF_FILE if test 1336 -ne `wc -c <'examples/stat.awl'`; then echo shar: \"'examples/stat.awl'\" unpacked with wrong size! fi # end of 'examples/stat.awl' fi if test -f 'examples/stringops.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/stringops.awl'\" else echo shar: Extracting \"'examples/stringops.awl'\" \(2652 characters\) sed "s/^X//" >'examples/stringops.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X X/* X * Here we show off some of the string and list manipulations X * possible with awl. X */ X global a_list = {"this is", "a test", "of the emergency", "broadcast system"}; global small = {"over", "and" }; X global a_string = "Hi there, I am a string; a kludgy hack"; global shorty = "on and "; X main() X{ X /* simple string addition */ X Fred = a_string + " with hairy features.\n"; X print("S#1: ", Fred); X X /* simple string substitution (insert "and arcane") */ X Fred = strsed(Fred, "s/features/and arcane \\0/"); X print("S#2: ", Fred); X X /* Change a single character directly ("Hi" -> "Ho") */ X Fred[1] = 'o'; X print("S#3: ", Fred); X X /* grab a section of string by position */ X Joe = substr(Fred, 0, 8); X println("S#4: ", Joe); X X /* grab a section of string by pattern ("hairy and arcane features.") */ X Joe = "hair.*$" ?? Fred; X println("S#5: ", Joe); X X /* Simple string subtraction (remove "hairy and arcane features.") */ X Bob = Fred - "hair.*$"; X print("S#6: ", Bob); X X /* String multiplication */ X Irving = shorty * 10; X println("S#7: ", Irving); X X /* Other interesting string hacks: */ X X /* Upcase string */ X Joe = strsed(Fred, "/.*/{a-z}{A-Z}/"); X print("S#8: ", Joe); X X /* Lowercase string */ X Joe = strsed(Fred, "/.*/{A-Z}{a-z}/"); X print("S#9: ", Joe); X X /* Upcase only the first letter of each word, preserving whitespace */ X Munge = "g/\\([\t\s]*\\)\\(.\\)\\([^\t\s]*\\)/\\1\\2{a-z}{A-Z}\\3/"; X Joe = strsed(Fred, Munge); X print("S#10: ", Joe); X X X /* All is possible with lists too */ X X /* X * First change separator character from \n to '-' to better illustrate X * what is happening to the list. X */ X $SEP = '-'; X X /* List addition */ X Fred = a_list + {"this is only", "a test"}; X println("L#1: ", Fred); X X /* List subtraction */ X Joe = Fred - "a test"; X println("L#2: ", Joe); X X /* List multiplication */ X Bob = small * 8; X println("L#3: ", Bob); X X /* X * The more advanced and searching features can be done on lists X * by converting the list to a string, performing the op, then X * converting it back to a list. To wit: X */ X /* Upcase the first character of each word in the list X * Set $SEP to nl to get temporary "line" behaviour. X */ X $SEP = "\n"; X Munge = "g/\\([^\n]?\\)\\([^\n]*\\)\\(\n?\\)/\\1{a-z}{A-Z}\\2\\3/"; X Fred = (LIST)strsed((STRING)Fred, Munge); X /* put the $SEP back to '-' for printing */ X $SEP = "-"; X println("L#4: ", Fred); X exit(0); X} X END_OF_FILE if test 2652 -ne `wc -c <'examples/stringops.awl'`; then echo shar: \"'examples/stringops.awl'\" unpacked with wrong size! fi # end of 'examples/stringops.awl' fi if test -f 'examples/view.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/view.awl'\" else echo shar: Extracting \"'examples/view.awl'\" \(525 characters\) sed "s/^X//" >'examples/view.awl' <<'END_OF_FILE' X/* short test of file "browser" */ X X#include <xt.h> X nukit(w) X{ X XtDestroy((WIDGET)w); X} X main() X{ X top = Viewport bar { X XgTranslations (TRANSLATION)"<Key>Q: exit(0)"; X XgViewportScrollVert TRUE; X Box foo; X }; X XtCreateManaged(top); X printf("Which directory: "); X dir = get(STRING); X files = readdir(dir); X action = (CALLBACK)XtDestroy; X for (i = 0; files[i]; i++) X XtCreateManaged(files[i], Button, top.foo, X XtNcallback, action, XtNborderWidth, 0); X XtRealize(SELF); X} END_OF_FILE if test 525 -ne `wc -c <'examples/view.awl'`; then echo shar: \"'examples/view.awl'\" unpacked with wrong size! fi # end of 'examples/view.awl' fi if test -f 'examples/winfo.awl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'examples/winfo.awl'\" else echo shar: Extracting \"'examples/winfo.awl'\" \(638 characters\) sed "s/^X//" >'examples/winfo.awl' <<'END_OF_FILE' X/* -*-Mode: C; -*- */ X main() X{ X x = Shell $? { X Box b { X XgTranslations (TRANSLATION)"#augment <Key>Q: exit(0)"; X Button c { X "font" ("FontStruct")"9x15"; X } X Button d; X } X }; X XtCreateManaged(x); X XtPopup(x, 0); X println("x is class ", (STRING)XtClass(x), " name ", XtName(x)); X println("b is class ", (STRING)XtClass(x.b), " name ", XtName(x.b)); X println("c[font] = ", x.b.c["font"]); X println("c[fore] = ", x.b.c["foreground"], " back = ", X x.b.c["background"]); X} END_OF_FILE if test 638 -ne `wc -c <'examples/winfo.awl'`; then echo shar: \"'examples/winfo.awl'\" unpacked with wrong size! fi # end of 'examples/winfo.awl' fi if test -f 'extract.perl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'extract.perl'\" else echo shar: Extracting \"'extract.perl'\" \(2560 characters\) sed "s/^X//" >'extract.perl' <<'END_OF_FILE' X#!/usr/local/bin/perl X# X# $Header: /usr/src/local/awl/RCS/extract.perl,v 2.1 90/04/19 20:05:09 jkh Exp $ X# X# This perl script is used to extract all important CPP macros from a set of X# Toolkit or widget header files. It also converts enums to macro definitions X# so that they can be used as ordinary numeric constants. X# X# Perl (Practical Extraction and Report Language) is Copyright (c) 1989 by X# Larry Wall and may be obtained from him or your favorite local PD source X# archive. X# X# Thanks go to Michael Elbel of PCS Computer Systeme, GmbH for writing the X# initial version of this script. X# X# $Log: extract.perl,v $ X# Revision 2.1 90/04/19 20:05:09 jkh X# Alpha checkin. X# X# Revision 2.0 90/03/26 01:44:23 jkh X# pre-beta check-in X# X# Revision 1.2 90/03/11 05:34:39 jkh X# Changed format of outer loop to allow whole directories to be specified X# rather than individual files. This makes the Imakefile rules easier to X# specify (imake doesn't deal well with rules containing wildcards). Changed X# some comments around, re-indented, added RCS log and comment initiator. X# X# X$pattern = @ARGV[0]; shift; X$dir = @ARGV[0]; shift; open(list, "ls -1 $dir/*.h|"); print STDERR "Directory is ", $dir, ":\n"; while (<list>) { X print STDERR "\tSearching ", $_; X open(ARGV, $_); X while (<>) { X ;# first choice gets textual defines X if (/^\s*#define\s+($pattern[A-Z]\w*)\s+(\"\w*\")/) { X print "#define $1 $2\n"; X X ;# second choice gets numeric defines X } elsif (/^\s*#define\s+(X\w*)\s+([0-9]+)/) { X print "#define $1 $2\n"; X X ;# third choice splits up enums X } elsif (/^\s*typedef\s+enum/) { X $_ = "$'"; # look only at the rest of the line X if (!(/\}/)) { # if the enum is not on one line X $/ = "\}"; # change line delimiter to { X $_ .= <>; # get the whole enum on one line X $/ = "\n"; # restore delimiter X $_ .= <>; # get rest of line that ends enum X s/\n/ /g; # kill newlines X } X s/\/\*.*\*\///; # get rid of comments X /\}/; X $_ = "$`"; # throw away everything after } X # check for initialization of the enum X if(/\{\s*(\w+)\s*=\s*([0-9]+)/) { X $counter = $2; # initialize counter X # print first item X printf ("#define $1 $counter\n"); X $_ = "$'"; X $counter++; X } else { X $counter = 0; # initialize counter X /\{\s*/; X $_ = "$'"; X } X while (/\w+/) { #print all the items X printf ("#define $& $counter\n"); X $counter++; X $_ = "$'"; X } X } X } X} END_OF_FILE if test 2560 -ne `wc -c <'extract.perl'`; then echo shar: \"'extract.perl'\" unpacked with wrong size! fi chmod +x 'extract.perl' # end of 'extract.perl' fi if test -f 'hash.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'hash.h'\" else echo shar: Extracting \"'hash.h'\" \(1644 characters\) sed "s/^X//" >'hash.h' <<'END_OF_FILE' X#ifndef _HASH_H_INCLUDE X#define _HASH_H_INCLUDE X X/* $Header: /usr/src/local/awl/RCS/hash.h,v 2.0 90/03/26 01:44:28 jkh Exp $ */ X X/* X * X * Copyright 1990 X * Terry Jones & Jordan Hubbard X * X * PCS Computer Systeme, GmbH. X * Munich, West Germany X * X * X * All rights reserved. X * X * This is unsupported software and is subject to change without notice. X * the author makes no representations about the suitability of this software X * for any purpose. It is supplied "as is" without express or implied X * warranty. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, provided X * that the above copyright notice appear in all copies and that both that X * copyright notice and this permission notice appear in supporting X * documentation, and that the name of the author not be used in X * advertising or publicity pertaining to distribution of the software X * without specific, written prior permission. X * X */ X X/* X * This is the definition file for hash.c. The plunderer from down-under X * did the code, I just helped define the spec. That's why his name gets X * to go first. X */ X X#define HASH_SZ 97 X typedef struct _node { X caddr_t key; X void *data; X struct _node *next; X} hash_node; X typedef struct { X int size; X hash_node **buckets; X} hash_table; X extern hash_table *hash_create(); extern void hash_destroy(); extern void *hash_search(); extern void hash_traverse(); extern void hash_purge(); X X#ifdef HASH_STATS extern void hash_stats(); X#endif X X#endif /* _HASH_H_INCLUDE */ END_OF_FILE if test 1644 -ne `wc -c <'hash.h'`; then echo shar: \"'hash.h'\" unpacked with wrong size! fi # end of 'hash.h' fi if test -f 'patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel.h'\" else echo shar: Extracting \"'patchlevel.h'\" \(21 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' X#define PATCHLEVEL 1 END_OF_FILE if test 21 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi if test -f 'shar_files' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'shar_files'\" else echo shar: Extracting \"'shar_files'\" \(1015 characters\) sed "s/^X//" >'shar_files' <<'END_OF_FILE' ATHENA.gperf Awl.c Awl.h AwlP.h COPYING Imakefile MOTIF.gperf Makefile README TODO awl.1 awl.lex awl.texinfo awl.y awl_driver.c builtins.c cftime.c convert.c dasm.c eval.c evalutils.c extract.perl hash.c hash.h layout.c ltypes.h macros.h mathrtns.c patchlevel.h regex.c regex.h resw.gperf resw_gp.c shar_files stat.c strrtns.c strsed.c symbols.c sysrtns.c texinfo.tex util.c widgets_gp.c xtkrtns.c etc/strsed.3c etc/xaw.h etc/xm.h etc/xmu.h etc/xt.h etc/xw.h examples/arith.awl examples/array.awl examples/awlculator.awl examples/browse.awl examples/case.awl examples/clocks.awl examples/fact.awl examples/fact2.awl examples/file.awl examples/files.awl examples/flags.awl examples/form.awl examples/gcd.awl examples/hackpict.awl examples/hello.awl examples/ilayout.awl examples/list.awl examples/list2.awl examples/main.awl examples/pipe.awl examples/porsche.awl examples/range.awl examples/sample.awl examples/set.awl examples/set2.awl examples/stat.awl examples/stringops.awl examples/view.awl examples/winfo.awl END_OF_FILE if test 1015 -ne `wc -c <'shar_files'`; then echo shar: \"'shar_files'\" unpacked with wrong size! fi # end of 'shar_files' fi if test -f 'strrtns.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'strrtns.c'\" else echo shar: Extracting \"'strrtns.c'\" \(3303 characters\) sed "s/^X//" >'strrtns.c' <<'END_OF_FILE' X#ifndef lint static char *rcsid = "$Header: /usr/src/local/awl/RCS/strrtns.c,v 2.1 90/04/19 20:05:49 jkh Exp $"; X#endif X X/* X * X * Copyright 1989 X * Jordan K. Hubbard X * X * PCS Computer Systeme, GmbH. X * Munich, West Germany X * X * X * This file is part of AWL. X * X * AWL is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 1, or (at your option) X * any later version. X * X * AWL is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with AWL; see the file COPYING. If not, write to X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. X * X * X */ X X/* X * This file contains all string manipulation built-ins. X * X * $Log: strrtns.c,v $ X * Revision 2.1 90/04/19 20:05:49 jkh X * Alpha checkin. X * X * Revision 2.0 90/03/26 01:44:40 jkh X * pre-beta check-in X * X */ X X#include "AwlP.h" X#include "y.tab.h" X Local Value arg, arg2, arg3; X X/* X * strsed(STRING1, STRING2 [, start, end ]): X * Do a strsed() on STRING1 with pattern STRING2, optionally returning X * starting and ending positions. X * I know that this looks a little grotty with everything about to fall X * off the right, but that's the price I have to pay to prevent cascading X * errors. X * X */ DEFUN(strsed) X{ X int range[2], nargs = awl_nparms(aw); X String cp = NULL; X Value arg4; X X if (nargs == 2 || nargs == 4) { X arg = get_arg(aw, 1, STRING, TRUE); X if (value_type(arg)) { X arg2 = get_arg(aw, 2, STRING, TRUE); X if (value_type(arg2)) { X if (nargs == 4) { X arg3 = get_arg(aw, 3, IADDR, TRUE); X if (value_type(arg3)) { X arg4 = get_arg(aw, 4, IADDR, TRUE); X if (value_type(arg4)) { X cp = strsed(value_string(arg), X value_string(arg2), X range); X if (cp) { X *((int *)value_any(arg3)) = range[0]; X *((int *)value_any(arg4)) = range[1]; X } X } X } X } X else { X cp = strsed(value_string(arg), value_string(arg2), 0); X } X } X } X } X else X exec_warn("strsed: Expected either 2 or 4 args, got %d", nargs); X value_set(arg, DATA, STRING, aobj, new_aobj(cp)); X return(arg); X} X X/* X * substr(STRING, start, len): X * Returns a "len" character long substring from STRING beginning at "start". X */ DEFUN(substr) X{ X String tmp = NULL; X X arg = get_arg(aw, 1, STRING, TRUE); /* str */ X arg2 = get_arg(aw, 2, INT, FALSE); /* start */ X arg3 = get_arg(aw, 3, INT, FALSE); /* len */ X if (value_type(arg)) { X int len = strlen(value_string(arg)); X X if (value_int(arg2) + value_int(arg3) > len) X value_int(arg3) = len - value_int(arg2); X if (value_int(arg2) < len) { X tmp = XtMalloc(value_int(arg3) + 1); X strncpy(tmp, value_string(arg) + value_int(arg2), X value_int(arg3)); X tmp[value_int(arg3)] = '\0'; X } X } X value_set(arg, DATA, STRING, aobj, new_aobj(tmp)); X return(arg); X} END_OF_FILE if test 3303 -ne `wc -c <'strrtns.c'`; then echo shar: \"'strrtns.c'\" unpacked with wrong size! fi # end of 'strrtns.c' fi echo shar: End of archive 1 \(of 17\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 17 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.