v07i019: AWL -- layout language for widget hierarchies, Part05/17
Paul Vixie
vixie at wrl.dec.com
Wed May 2 18:10:53 AEST 1990
Submitted-by: vixie at 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 at 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 - at 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 - at 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 at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list