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.