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

vixie@wrl.dec.com (Paul Vixie) (05/02/90)

Submitted-by: vixie@wrl.dec.com (Paul Vixie)
Posting-number: Volume 7, Issue 19
Archive-name: awl/part05

#! /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 5 (of 17)."
# Contents:  Makefile hash.c util.c widgets_gp.c
# Wrapped by vixie@jove.pa.dec.com on Mon Apr 30 01:25:21 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(12167 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space.  Imake tries to compensate
X# for this, but is not always successful.
X#
X
X###########################################################################
X# Makefile generated from "Imake.tmpl" and </tmp/IIf.a04638>
X# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
X#
X# Platform-specific parameters may be set in the appropriate .cf
X# configuration files.  Site-wide parameters may be set in the file
X# site.def.  Full rebuilds are recommended if any parameters are changed.
X#
X# If your C preprocessor doesn't define any unique symbols, you'll need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make Makefile", "make Makefiles", or "make World").
X#
X# If you absolutely can't get imake to work, you'll need to set the
X# variables at the top of each Makefile as well as the dependencies at the
X# bottom (makedepend will do this automatically).
X#
X
X###########################################################################
X# platform-specific configuration parameters - edit cadmus_m68.cf to change
X
X###########################################################################
X# site-specific configuration parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
X
X            SHELL = /bin/sh
X
X              TOP = .
X      CURRENT_DIR = .
X
X               AR = gar cq
X  BOOTSTRAPCFLAGS = -DSYSV -DPCS
X               CC = gcc
X
X         COMPRESS = compress
X              CPP = /usr/gnu/lib/gcc/gcc-cpp $(STD_CPP_DEFINES)
X    PREPROCESSCMD = gcc -E $(STD_CPP_DEFINES)
X          INSTALL = /usr/ucb/install
X               LD = gld
X             LINT = lint
X      LINTLIBFLAG = -o
X         LINTOPTS = -ax
X               LN = ln -s
X             MAKE = make
X               MV = mv
X               CP = cp
X           RANLIB = ranlib
X  RANLIBINSTFLAGS =
X               RM = rm -f
X     STD_INCLUDES = -I/usr/gnu/lib/gcc/gcc-include/bsd -I/usr/gnu/lib/gcc/gcc-include -I/usr/include/bsd
X  STD_CPP_DEFINES = -DSYSV
X      STD_DEFINES = -DSYSV -DPCS
X EXTRA_LOAD_FLAGS = -z -lbsd -lPW -lm
X  EXTRA_LIBRARIES =
X             TAGS = ctags
X
X           MFLAGS = -$(MAKEFLAGS)
X
X    PROTO_DEFINES =
X
X     INSTPGMFLAGS =
X
X     INSTBINFLAGS = -m 0755 -o bin -g bin
X     INSTUIDFLAGS = -m 2755 -o bin -g sys
X     INSTLIBFLAGS = -m 0444 -o bin -g bin
X     INSTINCFLAGS = -m 0444 -o bin -g bin
X     INSTMANFLAGS = -m 0444 -o bin -g bin
X     INSTDATFLAGS = -m 0444 -o bin -g bin
X    INSTKMEMFLAGS = -m 2755 -o bin -g sys
X
X          DESTDIR =
X
X     TOP_INCLUDES = -I$(INCROOT)
X
X      CDEBUGFLAGS = -O
X        CCOPTIONS = -DNOSTDHDRS -fstrength-reduce -fwritable-strings -pipe -fforce-addr -fforce-mem -fcombine-regs
X      COMPATFLAGS =
X
X      ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
X       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
X           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
X        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
X           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
X   LDCOMBINEFLAGS = -X -r
X
X        MACROFILE = cadmus_m68.cf
X           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
X
X    IMAKE_DEFINES =
X
X         IRULESRC = $(CONFIGDIR)
X        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
X
X     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
X			$(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
X			$(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
X
X###########################################################################
X# X Window System Build Parameters
X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
X
X###########################################################################
X# X Window System make variables; this need to be coordinated with rules
X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
X
X          PATHSEP = /
X        USRLIBDIR = $(DESTDIR)/usr/lib
X           BINDIR = $(DESTDIR)/usr/bin/X11
X          INCROOT = $(DESTDIR)/usr/include
X     BUILDINCROOT = $(TOP)
X      BUILDINCDIR = $(BUILDINCROOT)/X11
X      BUILDINCTOP = ..
X           INCDIR = $(INCROOT)/X11
X           ADMDIR = $(DESTDIR)/usr/adm
X           LIBDIR = $(USRLIBDIR)/X11
X        CONFIGDIR = $(LIBDIR)/config
X       LINTLIBDIR = $(USRLIBDIR)/lint
X
X          FONTDIR = $(LIBDIR)/fonts
X         XINITDIR = $(LIBDIR)/xinit
X           XDMDIR = $(LIBDIR)/xdm
X           AWMDIR = $(LIBDIR)/awm
X           TWMDIR = $(LIBDIR)/twm
X           GWMDIR = $(LIBDIR)/gwm
X          MANPATH = $(DESTDIR)/usr/man
X    MANSOURCEPATH = $(MANPATH)/man
X           MANDIR = $(MANSOURCEPATH)1
X        LIBMANDIR = $(MANSOURCEPATH)3
X      XAPPLOADDIR = $(LIBDIR)/app-defaults
X
X       FONTCFLAGS = -t
X
X     INSTAPPFLAGS = $(INSTDATFLAGS)
X
X            IMAKE = imake
X           DEPEND = makedepend
X              RGB = rgb
X            FONTC = bdftosnf
X        MKFONTDIR = mkfontdir
X        MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier.sh
X
X        CONFIGSRC = $(TOP)/config
X        CLIENTSRC = $(TOP)/clients
X          DEMOSRC = $(TOP)/demos
X           LIBSRC = $(TOP)/lib
X          FONTSRC = $(TOP)/fonts
X       INCLUDESRC = $(TOP)/X11
X        SERVERSRC = $(TOP)/server
X          UTILSRC = $(TOP)/util
X        SCRIPTSRC = $(UTILSRC)/scripts
X       EXAMPLESRC = $(TOP)/examples
X       CONTRIBSRC = $(TOP)/../contrib
X           DOCSRC = $(TOP)/doc
X           RGBSRC = $(TOP)/rgb
X        DEPENDSRC = $(UTILSRC)/makedepend
X         IMAKESRC = $(CONFIGSRC)
X         XAUTHSRC = $(LIBSRC)/Xau
X          XLIBSRC = $(LIBSRC)/X
X           XMUSRC = $(LIBSRC)/Xmu
X       TOOLKITSRC = $(LIBSRC)/Xt
X       AWIDGETSRC = $(LIBSRC)/Xaw
X       OLDXLIBSRC = $(LIBSRC)/oldX
X      XDMCPLIBSRC = $(LIBSRC)/Xdmcp
X      BDFTOSNFSRC = $(FONTSRC)/bdftosnf
X     MKFONTDIRSRC = $(FONTSRC)/mkfontdir
X     EXTENSIONSRC = $(TOP)/extensions
X
X  DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a
X     EXTENSIONLIB =  -lXext
X
X          DEPXLIB = $(DEPEXTENSIONLIB) $(USRLIBDIR)/libX11.a
X             XLIB = $(EXTENSIONLIB)  -lX11
X
X      DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
X         XAUTHLIB =  -lXau
X
X        DEPXMULIB = $(USRLIBDIR)/libXmu.a
X           XMULIB =  -lXmu
X
X       DEPOLDXLIB = $(USRLIBDIR)/liboldX.a
X          OLDXLIB =  -loldX
X
X      DEPXTOOLLIB = $(USRLIBDIR)/libXt.a
X         XTOOLLIB =  -lXt
X
X        DEPXAWLIB = $(USRLIBDIR)/libXaw.a
X           XAWLIB =  -lXaw
X
X LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln
X         LINTXLIB = $(USRLIBDIR)/llib-lX11.ln
X          LINTXMU = $(USRLIBDIR)/llib-lXmu.ln
X        LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln
X          LINTXAW = $(USRLIBDIR)/llib-lXaw.ln
X
X          DEPLIBS = $(LOCAL_LIBRARIES)
X
X         DEPLIBS1 = $(DEPLIBS)
X         DEPLIBS2 = $(DEPLIBS)
X         DEPLIBS3 = $(DEPLIBS)
X
X###########################################################################
X# Imake rules for building libraries, programs, scripts, and data files
X# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
X
X###########################################################################
X# start of Imakefile
X
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
all:: libawl.a
X
libawl.a: $(OBJS2)
X	$(RM) $@
X	$(AR) $@ $(OBJS2)
X	$(RANLIB) $@
X
X OBJS = $(OBJS1) $(OBJS2) $(OBJS3)
X SRCS = $(SRCS1) $(SRCS2) $(SRCS3)
X
all:: $(PROGRAMS)
X
awl: $(OBJS1) $(DEPLIBS1)
X	$(RM) $@
X	$(CC) -o $@ $(LDOPTIONS) $(OBJS1)  $(LDLIBS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LOAD_FLAGS)
X
install:: awl
X	$(INSTALL) -c $(INSTPGMFLAGS)   awl $(BINDIR)
X
install.man:: awl.man
X	$(INSTALL) -c $(INSTMANFLAGS) awl.man $(MANDIR)/awl.1
X
depend::
X	$(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
lint:
X	$(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
lint1:
X	$(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
X
clean::
X	$(RM) $(PROGRAMS)
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
X
X###########################################################################
X# common rules for all Makefiles - do not edit
X
emptyrule::
X
clean::
X	$(RM_CMD) \#*
X
Makefile:: Imakefile $(ICONFIGFILES)
X	-@if [ -f Makefile ]; then \
X	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
forceMakefile::
X	-@if [ -f Makefile ]; then \
X	echo "$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
tags::
X	$(TAGS) -w *.[ch]
X	$(TAGS) -xw *.[ch] > TAGS
X
X###########################################################################
X# empty rules for directories that do not have SUBDIRS - do not edit
X
install::
X	@echo "install in $(CURRENT_DIR) done"
X
install.man::
X	@echo "install.man in $(CURRENT_DIR) done"
X
Makefiles::
X
includes::
X
X###########################################################################
X# dependencies generated by makedepend
X
END_OF_FILE
if test 12167 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'hash.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hash.c'\"
else
echo shar: Extracting \"'hash.c'\" \(9072 characters\)
sed "s/^X//" >'hash.c' <<'END_OF_FILE'
X#ifndef lint
static char *rcsid = "$Header: /usr/src/local/awl/RCS/hash.c,v 2.0 90/03/26 01:44:26 jkh Exp $";
X#endif
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 a fairly simple open addressing hash scheme.
X * Terry did all the code, I just did the spec.
X * Thanks again, you crazy Aussie..
X * 
X */
X
X/*
X * $Log:	hash.c,v $
X * Revision 2.0  90/03/26  01:44:26  jkh
X * pre-beta check-in
X * 
X * Revision 1.8  90/03/09  19:22:35  jkh
X * Fixed bogus comment.
X * 
X * Revision 1.7  90/03/09  19:01:08  jkh
X * Added comments, GPL.
X * 
X * Revision 1.6  90/03/08  17:55:58  terry
X * Rearranged hash_purge to be a tiny bit more efficient.
X * Added verbose option to hash_stats.
X * 
X * Revision 1.5  90/03/08  17:19:54  terry
X * Added hash_purge. Added arg to hash_traverse. Changed all
X * void * to Generic.
X * 
X * Revision 1.4  90/03/08  12:02:35  terry
X * Fixed problems with allocation that I screwed up last night.
X * Changed bucket lists to be singly linked. Thanks to JKH, my hero.
X * 
X * Revision 1.3  90/03/07  21:33:33  terry
X * Cleaned up a few decls to keep gcc -Wall quiet.
X * 
X * Revision 1.2  90/03/07  21:14:53  terry
X * Comments. Added HASH_STATS define. Removed hash_find()
X * and new_node().
X * 
X * Revision 1.1  90/03/07  20:49:45  terry
X * Initial revision
X * 
X *
X */
X
X
X#include <string.h>
X#include <malloc.h>
X#include <sys/types.h>
X#include "hash.h"
X
X#define HASH_NULL    (hash_table *)0
X#define NODE_NULL    (hash_node *)0
X#define GENERIC_NULL (Generic)0
X
X#define HASH_SZ 97
X
X
static int hash();
static hash_node *list_find();
X
X
X/*
X * hash_create()
X *
X * Malloc room for a new hash table and then room for its
X * bucket pointers. Then set all the buckets to
X * point to 0. Return the address of the new table.
X */
hash_table *
hash_create(size)
int size;
X{
X    register int i;  
X    hash_table *new = (hash_table *)malloc(sizeof(hash_table));
X
X    if (!new || size < 0){
X	return HASH_NULL;
X    }
X    
X    if (size == 0){
X	size = HASH_SZ;
X    }
X    
X    if (!(new->buckets = (hash_node **)malloc(size * sizeof(hash_node *)))){
X	return HASH_NULL;
X    }
X
X    for (i = 0; i < size; i++){
X	new->buckets[i] = NODE_NULL;
X    } 
X    new->size = size;
X    
X    return new;
X}
X
X
X/*
X * list_find()
X *
X * Find the key in the linked list pointed to by head.
X */
static hash_node *
list_find(key, head)
caddr_t key;
hash_node *head;
X{
X    while (head){
X	if (!strcmp(head->key, key)){
X	    return head;
X	}
X	head = head->next;
X    }
X    return NODE_NULL;
X}
X
X
X/*
X * hash()
X *
X * Compute the hash value for the given key.
X */
static int
hash(size, key)
int size;
register char *key;
X{
X    register int h = 0x0;
X
X    while (*key){
X	h = (h << 1) ^ (h ^ *key++);
X    }	
X
X    h %= size;
X    return h;
X}
X
X/*
X * hash_destroy()
X *
X * Find the key and (if it's there) remove it entirely.
X * The function (*nukefunc)() is in charge of disposing
X * of the storage help by the data associated with the node.
X */
void 
hash_destroy(table, key, nukefunc)
hash_table *table;
char *key;
void (*nukefunc)();
X{
X    extern void free();
X    
X    int bucket = hash(table->size, key);
X    hash_node *found = table->buckets[bucket];
X    hash_node *to_free = NODE_NULL;
X    
X    if (!found){
X	return;
X    }
X    
X    if (!strcmp(found->key, key)){
X	/*
X	 * It was the head of the list.
X	 */
X	table->buckets[bucket] = found->next;
X	to_free = found;
X    }
X    else{
X	/*
X	 * Walk the list, looking one ahead.
X	 */
X	while (found->next){
X	    if (!strcmp(found->next->key, key)){
X		to_free = found->next;
X		found->next = found->next->next;
X		break;
X	    }
X	    found = found->next;
X	}
X	
X	if (!to_free){
X	    return;
X	}
X    }
X    
X    if (nukefunc){
X	(*nukefunc)(to_free->data);
X    }
X    free(to_free);
X    return;
X}
X
X
X/*
X * hash_search()
X *
X * Search the table for the given key. Then:
X *
X * 1) If you find it and there is no replacement function, just 
X *    return what you found. (This is a simple search). 
X * 2) If you find it and there is a replacement function, run
X *    the function on the data you found, and replace the old
X *    data with whatever is passed in datum. Return 0.
X * 3) If you don't find it and there is some datum, insert a
X *    new item into the table. Insertions go at the front of
X *    the bucket. Return 0.
X * 4) Otherwise just return 0.
X *
X */
Generic
hash_search(table, key, datum, replace_func)
hash_table *table;
caddr_t key;
Generic datum;
void (*replace_func)(); 
X{
X    int bucket = hash(table->size, key);
X    hash_node *found = list_find(key, table->buckets[bucket]);
X
X    if (found){
X	if (!replace_func){
X	    return found->data;
X	}
X	else{
X	    (*replace_func)(found->data);
X	    found->data = datum;
X	}
X    }
X    else{
X	if (datum){
X	    
X	    static int assign_key();
X	    
X	    hash_node *new = (hash_node *)malloc(sizeof(hash_node));
X	    
X	    if (!new || !assign_key(key, new)){
X		return GENERIC_NULL;
X	    }
X	    new->data = datum;
X	    new->next = table->buckets[bucket];
X	    table->buckets[bucket] = new;
X	}
X    }
X    return GENERIC_NULL;
X}
X
X
X/*
X * assign_key()
X *
X * Set the key value of a node to be 'key'. Get some space from 
X * malloc and copy it in etc. Return 1 if all is well, 0 otherwise.
X */
static int
assign_key(key, node)
caddr_t key;
hash_node *node;
X{
X    if (!node || !key){
X	return 0;
X    }
X    
X    if (!(node->key = malloc(strlen(key) + 1))){
X	return 0;
X    }
X    
X    node->key[0] = '\0';
X    strcat(node->key, key);
X    return 1;
X}
X
X/*
X * hash_traverse()
X *
X * Traverse the hash table and run the function func on the
X * data found at each node and the argument we're passed for it.
X */
void
hash_traverse(table, func, arg)
hash_table *table;
int (*func)();
Generic arg;
X{
X    register int i; 
X    register int size = table->size;
X
X    if (!func){
X	return;
X    }
X    
X    for (i = 0; i < size; i++){
X	hash_node *n = table->buckets[i];
X	while (n){
X	    if ((*func)(n->data, arg) == 0){
X		return;
X	    }
X	    n = n->next;
X	}
X    } 
X    
X    return;
X}
X
X/*
X * hash_purge()
X *
X * Run through the entire hash table. Call purge_func
X * on the data found at each node, and then free the node.
X * Set all the bucket pointers to 0.
X */
void
hash_purge(table, purge_func)
hash_table *table;
void (*purge_func)();
X{
X    register int i; 
X    register int size = table->size;
X    
X    for (i = 0; i < size; i++){
X	hash_node *n = table->buckets[i];
X	if (n){
X	    do {
X		hash_node *to_free = n;
X		if (purge_func){
X		    (*purge_func)(n->data);
X		}
X		n = n->next;
X		free(to_free);
X	    } while (n);
X	    
X	    table->buckets[i] = NODE_NULL;
X	}
X    } 
X}
X
X#ifdef HASH_STATS
X#include <stdio.h>
X#define min(a, b) (a) < (b) ? (a) : (b)
X
X/*
X * hash_stats()
X *
X * Print statistics about the current table allocation to stdout.
X */
void
hash_stats(table, verbose)
hash_table *table;
int verbose;
X{
X    register int i; 
X    int total_elements = 0;
X    int non_empty_buckets = 0;
X    int max_count = 0;
X    int max_repeats = 0;
X    int *counts;
X    int size = table->size;
X    
X    if (!(counts = (int *)malloc(size * sizeof(int)))){
X	fprintf(stderr, "malloc returns 0\n");
X	exit(1); 
X    }
X    
X    for (i = 0; i < size; i++){
X	int x = 0;
X	hash_node *n = table->buckets[i];
X	counts[i] = 0;
X	while (n){
X	    if (!x){
X		x = 1;
X		non_empty_buckets++;
X		if (verbose){
X		    printf("bucket %2d: ", i);
X		}
X	    }
X	    if (verbose){
X		printf(" %s", n->key);
X	    }
X	    counts[i]++;
X	    n = n->next;
X	}
X	
X	total_elements += counts[i];
X	if (counts[i] > max_count){
X	    max_count = counts[i];
X	    max_repeats = 1;
X	}
X	else if (counts[i] == max_count){
X	    max_repeats++;
X	}
X	
X	if (counts[i] && verbose){
X	    printf(" (%d)\n", counts[i]);
X	}
X    } 
X    
X    printf("\n");
X    printf("%d element%s in storage.\n", total_elements, total_elements == 1 ? "" : "s");
X    
X    if (total_elements){
X	printf("%d of %d (%.2f%%) buckets are in use\n", non_empty_buckets, size, 
X	       (double)100 * (double)non_empty_buckets / (double)(size));
X	printf("the maximum number of elements in a bucket is %d (%d times)\n", max_count, max_repeats);
X	printf("average per bucket is %f\n", (double)total_elements / (double)non_empty_buckets);
X	printf("optimal would be %f\n", (double)total_elements / (double)(min(size, total_elements)));
X    }
X    return;
X}
X#endif /* HASH_STATS */
END_OF_FILE
if test 9072 -ne `wc -c <'hash.c'`; then
    echo shar: \"'hash.c'\" unpacked with wrong size!
fi
# end of 'hash.c'
fi
if test -f 'util.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util.c'\"
else
echo shar: Extracting \"'util.c'\" \(12444 characters\)
sed "s/^X//" >'util.c' <<'END_OF_FILE'
X#ifndef lint
static char *rcsid = "$Header: util.c,v 2.3 90/04/30 01:13:28 vixie Exp $";
X#endif
X
X/*
X *
X *                   Copyright 1989, 1990
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 * Various string/numeric/allocation utilities that don't fit anywhere
X * else.
X *
X * $Log:	util.c,v $
X * Revision 2.3  90/04/30  01:13:28  vixie
X * vixie
X * 
X * Revision 2.2  90/04/19  20:05:59  jkh
X * rcvd
X * 
X * Revision 2.2  90/04/19  20:05:59  jkh
X * Alpha checkin.
X * 
X * Revision 2.1  90/03/29  18:29:05  jkh
X * Various bits of munging around.
X * 
X * Revision 2.0  90/03/26  01:43:57  jkh
X * pre-beta check-in
X * 
X */
X
X#include <sys/time.h>
X#include "AwlP.h"
X#include "y.tab.h"
X
XExport Inline String skip_whitespace(s)
register String s;
X{
X     while (*s && isspace(*s))
X	  s++;
X     return(s);
X}
X
X/* Returns the ascii print value for a Datum union, given its type. */
XExport String datum_string_value(aw, type, d)
AwlWidget aw;
int type;
Datum d;
X{
X     Local char chr[2], aval[20];
X
X     switch(type) {
X     case CHAR:
X	  chr[0] = datum_char(d);
X	  chr[1] = '\0';
X	  return(chr);
X
X     case INT:
X	  return(numtoa(aw, datum_int(d), 0));
X
X     case FLOAT:
X	  return(ftoa(datum_float(d)));
X
X     case STRING:
X	  return(datum_string(d));
X
X     case RANGE:
X	  sprintf(aval, "%d..%d", range_min(datum_range(d)),
X		  range_max(datum_range(d)));
X	  return(aval);
X
X     default:
X	  sprintf(aval, "%#08x", datum_any(d));
X	  return(aval);
X     }
X}
X
X/* Same as above but for values (shorthand) */
XExport String value_string_value(aw, val)
AwlWidget aw;
Value val;
X{
X     return(datum_string_value(aw, value_type(val), value_data(val)));
X}
X
X/* format a time specifier and return it */
XExport String format_time(fmt, t)
String fmt;
time_t t;
X{
X     char buffer[512];
X
X     if (strftime(buffer, 512, fmt, localtime(&t)))
X	  return(XtNewString(buffer));
X     else
X	  return(NULL);
X}
X
X/*
X * "Safe" strcmp. Handles NULL pointer value for either string.
X */
XExport int strcomp(s1, s2)
register String s1, s2;
X{
X     if (s1 && s2)
X	  return(strcmp(s1, s2));
X     else if (!s1 && !s2)
X	  return(0);
X     else if (!s1 && s2)
X	  return(-1);
X     else
X	  return(1);
X}
X
X/*
X * Another "safe" strcmp that ignores case.
X */
XExport int stricomp(s1, s2)
register String s1, s2;
X{
X#ifndef tolower
X     Import char tolower();
X#endif
X
X     if (s1 && s2) {
X          if (strlen(s1) != strlen(s2))
X              return(-1);
X
X          while (*s1 && *s2 && (tolower(*s1) == tolower(*s2)))
X               s1++, s2++;
X          if (!*s1 && !*s2)
X               return(0);
X          else if (*s1 < *s2)
X               return (-1);
X          else
X               return(1);
X     }
X     else if (!s1 && !s2)
X          return(0);
X     else if (!s1 && s2)
X          return(-1);
X     else
X          return(1);
X}
X
X/* list manipulation routines */
X
X/* free all elements of a list */
XExport void list_free(l)
register String *l;
X{
X     if (l)
X	  while (*l)
X	       XtFree(*(l++));
X}
X
X/* return the number of elements in a list */
XExport int list_len(l)
register String *l;
X{
X     register int i = 0;
X
X     if (l)
X	  while (*(l++))
X	       ++i;
X     return(i);
X}
X
X/* indicate whether or not all elements of a list are the same length */
XExport int list_is_rect(l)
register String *l;
X{
X     register int i, comp, len = list_len(l);
X
X     if (len) {
X	  comp = strlen(l[0]);
X	  for (i = 1; i < len; i++)
X	       if (strlen(l[i]) != comp)
X		    return 0;
X	  return 1;
X     }
X     return 0;
X}
X  
XExport String *list_dup(aw, l)
AwlWidget aw;
register String *l;
X{
X     register int i, j;
X     register String *m = NULL;
X
X     if (i = list_len(l)) {
X	  m = (String *)XtMalloc((i + 1) * sizeof(String *));
X	  for (j = 0; j < i; j++) {
X	       String tmp;
X	       int len = strlen(l[j]);
X
X	       m[j] = XtMalloc(len + 1);
X	       strncpy(m[j], l[j], len);
X	       m[j][len] = '\0';
X	  }
X	  m[j] = NULL;
X     }
X     return(m);
X}
X
X#define BINGO '\377'
X
XExport String *list_from_string(aw, s)
AwlWidget aw;
register String s;
X{
X     String *ret;
X
X     if (!s)
X	 ret = NULL;
X     else {
X	 register int zap_char;
X	 register int len = strlen(s);
X	 register int count;
X	 register int i;
X	 register String tmp, strsed_cmd;
X	 int sep_len = strlen(awl_sep(aw));
X	 
X	 switch (sep_len){
X	     case 0:
X		 /*
X		  * Make a list with an element for each char in s.
X		  */
X		 tmp = (String)XtMalloc(len * 2);
X		 ret = (String *)XtMalloc((len + 1) * sizeof(String));
X		 for (i = 0; i < len; i++){
X		     tmp[2 * i] = s[i];
X		     tmp[2 * i + 1] = '\0';
X		     ret[i] = tmp + 2 * i;
X		 } 
X		 ret[len] = NULL;
X		 return ret;
X		 break;
X	     
X	     case 1:
X		 /*
X		  * Do it the fast way - no strsed here.
X		  */
X		 tmp = (String)XtMalloc(len + 1);
X		 zap_char = awl_sep(aw)[0];
X		 tmp[0] = '\0';
X		 strcat(tmp, s);
X		 break;
X	     
X	     default:
X		 /*
X		  * Use strsed to zap the regex into an "unlikely"
X		  * char. Then proceed as though that char (BINGO) 
X		  * were the actual separator.
X		  */
X		 strsed_cmd = (String)XtMalloc(6 + sep_len);
X		 sprintf(strsed_cmd, "g/%s/%c/", awl_sep(aw), BINGO);
X		 if (!(tmp = strsed(s, strsed_cmd))){
X		     XtFree(strsed_cmd);
X		     return NULL;
X		 }
X		 XtFree(strsed_cmd);
X		 len = strlen(tmp);
X		 zap_char = BINGO;
X		 break;
X	     
X	 }
X	 
X	 if (tmp[len - 1] == zap_char)
X	     len--;
X	 
X	 count = 1;
X	 for (i = 0; i < len; i++)
X	     if (tmp[i] == zap_char){
X		 tmp[i] = '\0';
X		 count++;
X	     }
X	 
X	 tmp[len] = '\0';
X	 
X	 ret = (String *)XtMalloc((count + 1) * sizeof(String));
X	 
X	 for (i = 0; i < count; i++){
X	     ret[i] = tmp;
X	     while (*tmp++)
X		 ;
X	 }
X	 ret[count] = NULL;
X     }
X     return(ret);
X}
X
X#undef BINGO
X
X
XExport String list_to_string(aw, l)
AwlWidget aw;
register String *l;
X{
X     register String ret = NULL;
X
X     if (l) {
X	 register int items, i, len, sep_len;
X	 register String sep = awl_sep(aw);
X	 
X	 items = i = len = 0;
X	 while (l[items]) {
X	     len += strlen(l[items]);
X	     items++;
X	 }
X	 sep_len = strlen(sep);
X	 ret = (String)XtMalloc(len + (items * sep_len) + 1);
X	 i = len = 0;
X	 
X	 /*
X	  * Copy the first items - 1 of them, each followed by a separator.
X	  */
X	 for (i = 0; i < items; i++) {
X	     strcpy(ret + len, l[i]);
X	     len += strlen(l[i]);
X	     strcpy(ret + len, sep);
X	     len += sep_len;
X	 }
X	 ret[len] = '\0';
X     }
X     return(ret);
X}
X
X#define LIST_INCR	10
X
struct _linfo {
X     String *l;
X     int max, idx;
X};
X
Local int build_list(sym, ll)
Symbol sym;
register struct _linfo *ll;
X{
X     if (ll->idx == (ll->max - 1)) {
X	  ll->max += LIST_INCR;
X	  ll->l = (String *)XtRealloc(ll->l, ll->max * sizeof(String *));
X     }
X     else
X	  ll->l[ll->idx++] = XtNewString(symbol_name(sym));
X     return(TRUE);
X}
X
XExport String *list_from_alist(aw, t)
AwlWidget aw;
Table t;
X{
X     struct _linfo li;
X
X     li.idx = 0;
X     li.max = LIST_INCR;
X     li.l = (String *)XtMalloc(li.max * sizeof(String *));
X     hash_traverse(t, build_list, &li);
X     li.l[li.idx] = NULL;
X     return(li.l);
X}
X
X/*
X * Do a "search only" strsed, returning only the portion of string
X * that matched.
X */
XExport String s_strsed(s1, s2)
String s1, s2;
X{
X     register String tmp, tmp1;
X     int r[2];
X     Boolean noslash = FALSE;
X
X     if (!s1 || !s2)
X	  return(NULL);
X     else if (s2[0] != '/') {
X	  tmp1 = XtMalloc(strlen(s2) + 3);
X	  tmp1[0] = '/'; tmp1[1] = '\0';
X	  strcat(tmp1, s2);
X	  strcat(tmp1, "/");
X	  noslash = TRUE;
X     }
X     else
X	  tmp1 = s2;
X     if ((tmp = strsed(s1, tmp1, r)) != NULL) {
X	  register int i = 0;
X	  register String s = NULL;
X
X	  if (r[1] > 0) {
X	       s = XtMalloc((r[1] - r[0]) + 1);
X	       
X	       while (r[0] < r[1])
X		    s[i++] = tmp[r[0]++];
X	       s[i] = '\0';
X	  }
X	  XtFree(tmp);
X	  tmp = s;
X     }
X     if (noslash)
X	  XtFree(tmp1);
X     return(tmp);
X}
X
X/* Append a character to a string, lengthening it if necessary. */
XExport void append_string(sp, lp, idx, ch)
String *sp;
int *lp, idx;
char ch;
X{
X     if (!*lp) {
X	  *lp = ALLOC_INCR;
X	  *sp = XtMalloc(ALLOC_INCR);
X     }
X     else if (idx >= *lp) {
X	  *lp += ALLOC_INCR;
X	  *sp = XtRealloc(*sp, *lp);
X     }
X     (*sp)[idx] = ch;
X}
X
X/* Append a string to another string, lengthening target if necessary. */
XExport int sappend_string(sp, lp, idx, s)
String *sp;
int *lp, idx;
String s;
X{
X     int len;
X
X     len = strlen(s);
X     if (!*lp) {
X	  *lp = ALLOC_INCR;
X	  *sp = XtMalloc(ALLOC_INCR);
X     }
X     else if (idx + len >= *lp) {
X	  if (len < ALLOC_INCR)
X	       *lp += ALLOC_INCR;
X	  else /* round up */
X	       *lp += len + (len % ALLOC_INCR);
X	  *sp = XtRealloc(*sp, *lp);
X     }
X     strcpy(*sp + idx, s);
X     return(len);
X}
X
X/* Create a string that's a multiple of itself */
XExport String string_multiply(str, m)
register String str;
register int m;
X{
X     register String ret;
X     register int i, o, l = strlen(str);
X
X     ret = XtMalloc((l * m) + 1);
X     o = 0;
X     for (i = 0; i < m; i++) {
X	  strcpy(ret + o, str);
X	  o += l;
X     }
X     ret[o] = '\0';
X     return(ret);
X}
X
Local void zombie_time()
X{
X     signal(SIGALRM, SIG_DFL);
X}
X
X/* process file descriptor routines */
XExport Process p_popen(aw, s, mode)
AwlWidget aw;
String s, mode;
X{
X     Process ret = NULL;
X     int in[2], out[2], pid;
X
X     if (pipe(in) < 0 || pipe(out) < 0)
X	  exec_warn(aw, "p_popen: Couldn't open input or output pipe");
X     else {
X	  ret = (Process)XtMalloc(process_size);
X	  if (proc_pid(ret) = fork()) {	/* der Vati */
X	       if (*mode == 'r' || *mode == '+')
X		    proc_in(ret) = fdopen(in[0], "r");
X	       else {
X		    proc_in(ret) = NULL;
X		    close(in[0]);
X	       }
X	       if (*mode == 'w' || *mode == '+')
X		    proc_out(ret) = fdopen(out[1], "w");
X	       else {
X		    proc_out(ret) = NULL;
X		    close(out[1]);
X	       }
X	       close(in[1]);
X	       close(out[0]);
X	  }
X	  else {			/* das Kind */
X	       int fl;
X
X	       if (*mode == 'w' || *mode == '+')
X		    dup2(out[0], 0);
X	       else
X		    close(out[0]);
X	       if (*mode == 'r' || *mode == '+') {
X		    dup2(in[1], 1);
X		    dup2(in[1], 2);
X	       }
X	       else
X		    close(in[1]);
X
X	       for (fl = 3; fl < NFILES; fl++)
X		    close(fl);
X
X	       setpgrp(0, getpid());
X	       execl("/bin/sh", "sh", "-c", s, 0);
X	       exec_warn(aw, "Couldn't exec shell on '%s'", s);
X	  }
X     }
X     return(ret);
X}
X
XExport int p_pclose(aw, p)
AwlWidget aw;
Process p;
X{
X     int ret, pid, status;
X
X     pid = proc_pid(p);
X     if (proc_in(p))
X	  fclose(proc_in(p));
X     if (proc_out(p))
X	  fclose(proc_out(p));
X     XtFree(p);
X
X     /*
X      * Set an ALARM to prevent really bad process states from wedging the
X      * whole show.
X      */
X     signal(SIGALRM, zombie_time);
X     alarm(20);
X     while ((ret = wait(&status)) != pid && ret > 0);
X     if (ret < 0) { /* alarm went off */
X          exec_warn(aw, "p_pclose: Abandoned wait() for wedged process.");
X	  /* Try nuking it as a parting shot */
X	  kill(pid, SIGKILL);
X	  status = -1;
X     }
X     else {
X	  alarm(0);
X	  signal(SIGALRM, SIG_DFL);
X     }
X     return(status);
X}
X
X/* Allocation routines */
X
XExport Inline AllocObj new_aobj(ptr)
Generic ptr;
X{
X     AllocObj ret;
X
X     ret = (AllocObj)XtMalloc(aobj_size);
X     aobj_cnt(ret) = 0;
X     aobj_ptr(ret) = ptr;
X     return(ret);
X}
X
XExport Layout new_wl(type)
WidgetClass type;
X{
X     Layout tmp;
X
X     tmp = (Layout)XtMalloc(wl_size);
X     bzero(tmp, wl_size);
X     wl_wclass(tmp) = type;
X     return(tmp);
X}
X
XExport Resource new_res(p)
Layout p;
X{
X     Resource tmp;
X
X     tmp = (Resource)XtMalloc(res_size);
X     bzero(tmp, res_size);
X     res_parent(tmp) = p;
X     return(tmp);
X}
X
XExport Breakpoint new_bkpt(addr)
int addr;
X{
X     Breakpoint tmp;
X
X     tmp = (Breakpoint)XtMalloc(bkpt_size);
X     bzero(tmp, bkpt_size);
X     bkpt_addr(tmp) = addr;
X     return(tmp);
X}
END_OF_FILE
if test 12444 -ne `wc -c <'util.c'`; then
    echo shar: \"'util.c'\" unpacked with wrong size!
fi
# end of 'util.c'
fi
if test -f 'widgets_gp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'widgets_gp.c'\"
else
echo shar: Extracting \"'widgets_gp.c'\" \(10175 characters\)
sed "s/^X//" >'widgets_gp.c' <<'END_OF_FILE'
X/* C code produced by gperf version 1.9.1 (K&R C version) */
X/* Command-line: gperf -t -p -o -g -G -N is_generic ATHENA.gperf  */
X
X
X#ifndef lint
static char *rcsid = "$Header: /usr/src/local/awl/RCS/widgets_gp.c,v 1.1 90/04/19 20:06:02 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 is the gperf hash table for using the Athena implementation
X * of the awl generic widget set.
X *
X * $Log:	widgets_gp.c,v $
X * Revision 1.1  90/04/19  20:06:02  jkh
X * Initial revision
X * 
X * Revision 2.0  90/03/26  01:41:58  jkh
X * pre-beta check-in
X * 
X */
X
X#include "AwlP.h"
X#include "y.tab.h"
X
X#include	<X11/Xaw/AsciiText.h>
X#include	<X11/Xaw/Box.h>
X#include	<X11/Xaw/Clock.h>
X#include	<X11/Xaw/Command.h>
X#include	<X11/Xaw/Dialog.h>
X#include	<X11/Xaw/Form.h>
X#include	<X11/Xaw/Grip.h>
X#include	<X11/Xaw/Label.h>
X#include	<X11/Xaw/List.h>
X#include	<X11/Xaw/Logo.h>
X#include	<X11/Xaw/Mailbox.h>
X#include	<X11/Xaw/MenuButton.h>
X#include	<X11/Xaw/Paned.h>
X#include	<X11/Xaw/Scrollbar.h>
X#include	<X11/Xaw/SimpleMenu.h>
X#include	<X11/Xaw/Sme.h>
X#include	<X11/Xaw/SmeBSB.h>
X#include	<X11/Xaw/SmeLine.h>
X#include	<X11/Xaw/StripChart.h>
X#include	<X11/Xaw/Text.h>
X#include	<X11/Xaw/Toggle.h>
X#include	<X11/Xaw/Viewport.h>
X
DEFRMAP(mapBoxSpacing)
X{
X     XtSetArg(args[*idx], XtNhSpace, value_int(res_value(res))); (*idx)++;
X     XtSetArg(args[*idx], XtNvSpace, value_int(res_value(res))); (*idx)++;
X}
X
XExport RMap ResMap[] = {
X     { "XgAccelerators",	XtNaccelerators		},
X     { "XgAllowResize",		XtNallowResize		},
X     { "XgAllowShellResize",	XtNallowShellResize	},
X     { "XgAncestorSensitive",	XtNancestorSensitive	},
X     { "XgBitmap",		XtNbitmap		},
X     { "XgBackground",		XtNbackground		},
X     { "XgBackgroundPixmap",	XtNbackgroundPixmap	},
X     { "XgBorderColor",		XtNborderColor		},
X     { "XgBorderPixmap",	XtNborderPixmap		},
X     { "XgBorderWidth",		XtNborderWidth		},
X     { "XgBoxSpacing",		"mapBoxSpacing"		},
X     { "XgCallback",		XtNcallback		},
X     { "XgColormap",		XtNcolormap		},
X     { "XgCursor",		XtNcursor		},
X     { "XgDepth",		XtNdepth		},
X     { "XgDestroyCallback",	XtNdestroyCallback	},
X     { "XgFont",		XtNfont			},
X     { "XgForeground",		XtNforeground		},
X     { "XgFormBottom",		XtNbottom		},
X     { "XgFormHorizDist",	XtNhorizDistance	},
X     { "XgFormHorizWidget",	XtNfromHoriz		},
X     { "XgFormLeft",		XtNleft			},
X     { "XgFormResizable",	XtNresizable		},
X     { "XgFormRight",		XtNright		},
X     { "XgFormTop",		XtNtop			},
X     { "XgFormVertDist",	XtNvertDistance		},
X     { "XgFormVertWidget",	XtNfromVert		},
X     { "XgHighlightThickness",	XtNhighlightThickness	},
X     { "XgHeight",		XtNheight		},
X     { "XgIconic",		XtNiconic		},
X     { "XgLabel",		XtNlabel		},
X     { "XgListItems",		XtNlist			},
X     { "XgListNitems",		XtNnumberStrings	},
X     { "XgMappedWhenManaged",	XtNmappedWhenManaged	},
X     { "XgMarginHeight",	XtNinternalHeight	},
X     { "XgMarginWidth",		XtNinternalWidth	},
X     { "XgPaneAllowResize",	XtNallowResize		},
X     { "XgPaneMaxHeight",	XtNmax			},
X     { "XgPaneMinHeight",	XtNmin			},
X     { "XgPaneSkipAdjust",	XtNskipAdjust		},
X     { "XgSaveUnder",		XtNsaveUnder		},
X     { "XgScreen",		XtNscreen		},
X     { "XgSensitive",		XtNsensitive		},
X     { "XgTextInsertPosition",	XtNinsertPosition	},
X     { "XgTextJustify",		XtNjustify		},
X     { "XgTextString",		XtNstring		},
X     { "XgTranslations",	XtNtranslations		},
X     { "XgViewportScrollHoriz",	XtNallowHoriz		},
X     { "XgViewportScrollVert",	XtNallowVert		},
X     { "XgWidth",		XtNwidth		},
X     { "XgX",			XtNx			},
X     { "XgY",			XtNy			},
X     { NULL,			NULL			},
X};
X
struct WMap { char *name; WidgetClass *type; long flags; };
X
X#define MIN_WORD_LENGTH 3
X#define MAX_WORD_LENGTH 14
X#define MIN_HASH_VALUE 4
X#define MAX_HASH_VALUE 39
X/*
X   28 keywords
X   36 is the maximum key range
X*/
X
X#ifdef __GNUC__
inline
X#endif
static int
hash (str, len)
X     register char *str;
X     register unsigned int  len;
X{
X  static unsigned char hash_table[] =
X    {
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X     39, 39, 39, 39, 39,  0, 30,  0,  5, 39,
X      8,  0, 39, 39, 39, 39, 15, 15, 39, 15,
X     30, 39, 39,  0, 10, 39, 10, 39, 39, 39,
X     39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
X      0,  0, 39,  0, 39, 39, 39, 25,  0,  0,
X      0, 20,  0, 39, 20, 39,  0,  5, 39, 39,
X      0, 39, 39, 39, 39, 39, 39, 39,
X    };
X  return len + hash_table[str[len - 1]] + hash_table[str[0]];
X}
X
X
static struct WMap  wordlist[] =
X{
X      {"",}, {"",}, {"",}, {"",}, 
X      {"Grip", 		&gripWidgetClass,		W_NONE},
X      {"Shell", 		&topLevelShellWidgetClass,	W_MANAGER | W_POPUP},
X      {"Simple", 		&simpleWidgetClass,		W_EXTENDED},
X      {"Command", 	&commandWidgetClass,		W_EXTENDED},
X      {"AppShell", 	&applicationShellWidgetClass,	W_MANAGER | W_POPUP},
X      {"AsciiText", 	&asciiTextWidgetClass,		W_EXTENDED},
X      {"StripChart", 	&stripChartWidgetClass,		W_EXTENDED},
X      {"Dialog", 		&dialogWidgetClass,		W_NONE},
X      {"Form", 		&formWidgetClass,		W_MANAGER},
X      {"mapBoxSpacing", 	MAP(mapBoxSpacing),		W_RESPROC},
X      {"Text", 		&textWidgetClass,		W_NONE},
X      {"SimpleMenu", 	&simpleMenuWidgetClass,		W_NONE},
X      {"Toggle", 		&toggleWidgetClass,		W_NONE},
X      {"",}, 
X      {"Viewport", 	&viewportWidgetClass,		W_EXTENDED | W_MANAGER},
X      {"List", 		&listWidgetClass,		W_NONE},
X      {"Label", 		&labelWidgetClass,		W_NONE},
X      {"",}, 
X      {"Mailbox", 	&mailboxWidgetClass,		W_EXTENDED},
X      {"ToplevelShell", 	&topLevelShellWidgetClass,	W_MANAGER | W_POPUP},
X      {"TransientShell", 	&transientShellWidgetClass,	W_MANAGER | W_POPUP},
X      {"MenuButton", 	&menuButtonWidgetClass,		W_NONE},
X      {"",}, {"",}, 
X      {"OverrideShell", 	&overrideShellWidgetClass,	W_POPUP | W_MANAGER},
X      {"Scrollbar", 	&scrollbarWidgetClass,		W_NONE},
X      {"Clock", 		&clockWidgetClass,		W_EXTENDED},
X      {"",}, {"",}, 
X      {"Box", 		&boxWidgetClass,		W_MANAGER},
X      {"Pane", 		&panedWidgetClass,		W_MANAGER},
X      {"Popup", 		&transientShellWidgetClass,	W_POPUP | W_MANAGER},
X      {"Button", 		&commandWidgetClass,		W_NONE},
X      {"",}, {"",}, 
X      {"Logo", 		&logoWidgetClass,		W_EXTENDED},
X};
X
X#ifdef __GNUC__
inline
X#endif
struct WMap *
is_generic (str, len)
X     register char *str;
X     register unsigned int len;
X{
X  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
X    {
X      register int key = hash (str, len);
X
X      if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
X        {
X          register char *s = wordlist[key].name;
X
X          if (*s == *str && !strcmp (str + 1, s + 1))
X            return &wordlist[key];
X        }
X    }
X  return 0;
X}
X
X/*
X * Given a widget name, return its class.
X */
XExport WidgetClass map_wname_to_wclass(name)
String name;
X{
X     struct WMap *wm;
X
X     if ((wm = is_generic(name, strlen(name))) != NULL
X	 && !(wm->flags & W_RESPROC))
X	  return(*(wm->type));
X     else
X	  return((WidgetClass)0);
X}
X
X/*
X * Given a resource name, see if it maps to something else
X */
XExport String map_rname(name, flags)
String name;
int *flags;
X{
X     struct WMap *wm;
X     String ret = NULL;
X
X     if ((wm = is_generic(name, strlen(name))) != NULL
X	 && (wm->flags & W_RESPROC)) {
X	  if (flags)
X	       *flags = wm->flags;
X	  ret = (String)wm->type;
X     }
X     return(ret);
X}
X
X/*
X * These next two actually grub around in the wordlist array directly and
X * that's kludge. I wish there was a way I could make gperf generate multiple
X * hash tables for different members of the same struct, but that would
X * probably be kludge too. I don't think gperf does hash tables for
X * non-string values anyway. In any case, we don't lose a whole lot
X * doing linear searches on the class member since it's not done very
X * often. We're in trouble if gperf ever changes the name of the wordlist
X * array, but given the existence of gperf's -G flag), I doubt that this will
X * ever happen.
X */
X 
X/*
X * Given a widget class, return its name.
X */
XExport String map_wclass_to_wname(type)
WidgetClass type;
X{
X     register int i, limit = (sizeof(wordlist) / sizeof(struct WMap));
X
X     for (i = 0; i < limit; i++)
X	  if (!(wordlist[i].flags & W_RESPROC) && wordlist[i].type
X	      && *(wordlist[i].type) == type)
X	       return(wordlist[i].name);
X     return((String)0);
X}
X
X/*
X * Given a widget class, return its mask.
X */
XExport long map_wclass_to_flags(type)
WidgetClass type;
X{
X     register int i, limit = (sizeof(wordlist) / sizeof(struct WMap));
X
X     for (i = 0; i < limit; i++)
X	  if (!(wordlist[i].flags & W_RESPROC) && wordlist[i].type
X	      && *(wordlist[i].type) == type)
X	       return(wordlist[i].flags);
X     return((long)0);
X}
X
X
X/*******************************************************
X * Here lie the generic widget manipulation functions. *
X *******************************************************/
X
XExport void XgListSelectItem(list, item)
Widget list;
int item;
X{
X     XawListHighlight(list, item);
X}
X
XExport void XgListUnselectItem(list, item)
Widget list;
int item;
X{
X     XawListUnhighlight(list, item);
X}
X
XExport void XgListChange(list, data)
Widget list;
String *data;
X{
X     XawListChange(list, data, 0, 0, TRUE);
X}
END_OF_FILE
if test 10175 -ne `wc -c <'widgets_gp.c'`; then
    echo shar: \"'widgets_gp.c'\" unpacked with wrong size!
fi
# end of 'widgets_gp.c'
fi
echo shar: End of archive 5 \(of 17\).
cp /dev/null ark5isdone
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.