[comp.sources.x] v07i015: AWL -- layout language for widget hierarchies, Part01/17

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.