[comp.sources.unix] v22i102: GNU AWK, version 2.11, Part16/16

rsalz@bbn.com (Rich Salz) (06/08/90)

Submitted-by: "Arnold D. Robbins" <arnold@unix.cc.emory.edu>
Posting-number: Volume 22, Issue 102
Archive-name: gawk2.11/part16

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  ./README ./alloca.c ./array.c ./missing.d/strcase.c
# Wrapped by rsalz@litchi.bbn.com on Wed Jun  6 12:25:02 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 16 (of 16)."'
if test -f './README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./README'\"
else
  echo shar: Extracting \"'./README'\" \(4506 characters\)
  sed "s/^X//" >'./README' <<'END_OF_FILE'
XREADME:
X
XThis is GNU Awk 2.11. It should be upwardly compatible with the
XSystem V Release 4 awk.
X
XThis release is essentially a bug fix release.  The files have been
Xrenamed and code moved around to organize things by function.  Gawk should
Xalso be somewhat faster now.  More care has been given towards portability
Xacross different Unix systems.  See the installation instructions, below.
X
XKnown problems are given in the PROBLEMS file.  Work to be done is
Xdescribed briefly in the FUTURES file.
X
XThe gawk.texinfo included in this release has been revised; it should
Xbe in sync with what the code does.  The man page should also be accurate,
Xbut no promises there.
X
XCHANGES FROM 2.10
X
XUser visible changes:
X	Compatibility mode is now obtained via new -c option.
X	The new ANSI C \a and \x escapes are now a standard part of gawk
X		as Unix nawk has picked them up.
X	The new tolower() and toupper() functions are also standard.
X	A new undocumented option, -nostalgia, has been added.
X	Command line options have changed somewhat from 2.10.
X		-v	is now	-V
X		-V	is now	-C
X		new -v for doing variable assignments before the BEGIN block.
X		new -c for compatibility mode.
X		new -a for awk style regexps (default)
X		new -e for egrep style regexps, per the POSIX draft spec.
X	Some more formats have been added to printf, ala nawk and ANSI C.
X
XOther changes (the hard stuff):
X	All known bugs fixed.
X	Still more memory leaks plugged.
X	Lots of changes to improve performance and portability.
X
XPC users, you've been saved!
X	As of patchlevel 1, we are now supplying MS-DOS "support."  Said
X	support was generously provided by Kent Williams, who is now
X	the contact person for it.  See below for his address.
X
XINSTALLATION:
X
XThe Makefile will need some tailoring.  Currently it is set up for
Xa Sun running SunOS 4.x and gcc.  The changes to make in the Makefile are
Xcommented and should be obvious.  Starting with 2.11, our intent has been
Xto make the code conform to standards (ANSI, POSIX, SVID, in that order)
Xwhenever possible, and to not penalize standard conforming systems.
XWe have included substitute versions of routines not universally available.
XSimply add the appropriate define for the missing feature(s) on your system.
X
XIf you have 4.2 or 4.3 BSD, you should add -DTMPNAM_MISSING since the
Xversion of tmpnam on these systems won't accept a NULL pointer.
XThis does not apply to 4.3-tahoe or the S5R[23] systems I have access to.
XYou need this if gawk core dumps on something simple like 'BEGIN {print "hi"}'.
X
XIf you have neither bison nor yacc, use the awk.tab.c file here.  It was
Xgenerated with bison, and should have no AT&T code in it.  (Note that
Xmodifying awk.y without bison or yacc will be difficult, at best.  You might
Xwant to get a copy of bison from the FSF too.)
X
XIf you have an MS-DOS system, use the stuff in pc.d.
X
XPRINTING THE MANUAL
X
XThe 'support' directory contains texinfo.tex 2.1, which will be necessary
Xfor printing the manual, and the texindex.c program from the emacs distribution
Xwhich is also necessary.  See the makefile for the steps needed to get a
XDVI file from the manual.
X
XCAVEATS
X
XThe existence of a patchlevel.h file does *N*O*T* imply a commitment on
Xour part to issue bug fixes or patches.  It is there in case we should
Xdecide to do so.
X
XBUG REPORTS AND FIXES:
X
XPlease coordinate changes through David Trueman and/or Arnold Robbins.
X
XDavid Trueman
XDepartment of Mathematics, Statistics and Computing Science,
XDalhousie University, Halifax, Nova Scotia, Canada
X
XUUCP		{uunet utai watmath}!dalcs!david
XINTERNET	david@cs.dal.ca
X
XArnold Robbins
X1315 Kittredge Court, N.E.
XAtlanta, GA, 30329-3539, USA
X
XINTERNET:	arnold@skeeve.atl.ga.us
XUUCP:		{ gatech, emory, emoryu1 }!skeeve!arnold
X
XIf you can't contact either of us, try Jay Fenlason, hack@prep.ai.mit.edu
XAKA mit-eddie!prep!hack.  During odd hours he can sometimes be reached at
X(617) 253-8975, which is an MIT phone in the middle of the corridor, so don't
Xbe suprised if someone wierd answers, or if the person on the other end has
Xnever heard of him.  (Direct them to the microvax about 10 feet to their left.)
X
XMS-DOS SUPPORT
X
XSupport for MSC 5.1 was supplied for 2.11 by Kent Williams, who can be
Xreached at williams@umaxc.weeg.uiowa.edu.  It relies heavily on the
Xearlier work done for 2.10 by Conrad Kwok and Scott Garfinkle.  Bug
Xreports on the MS-DOS version should go to Kent.  Of course, if it's
Xa generic bug, we want to hear about it too, but if it isn't reproducible
Xunder Unix, we won't be as interested.
END_OF_FILE
  if test 4506 -ne `wc -c <'./README'`; then
    echo shar: \"'./README'\" unpacked with wrong size!
  fi
  # end of './README'
fi
if test -f './alloca.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./alloca.c'\"
else
  echo shar: Extracting \"'./alloca.c'\" \(5456 characters\)
  sed "s/^X//" >'./alloca.c' <<'END_OF_FILE'
X/*
X	alloca -- (mostly) portable public-domain implementation -- D A Gwyn
X
X	last edit:	86/05/30	rms
X	   include config.h, since on VMS it renames some symbols.
X	   Use xmalloc instead of malloc.
X
X	This implementation of the PWB library alloca() function,
X	which is used to allocate space off the run-time stack so
X	that it is automatically reclaimed upon procedure exit, 
X	was inspired by discussions with J. Q. Johnson of Cornell.
X
X	It should work under any C implementation that uses an
X	actual procedure stack (as opposed to a linked list of
X	frames).  There are some preprocessor constants that can
X	be defined when compiling for your specific system, for
X	improved efficiency; however, the defaults should be okay.
X
X	The general concept of this implementation is to keep
X	track of all alloca()-allocated blocks, and reclaim any
X	that are found to be deeper in the stack than the current
X	invocation.  This heuristic does not reclaim storage as
X	soon as it becomes invalid, but it will do so eventually.
X
X	As a special case, alloca(0) reclaims storage without
X	allocating any.  It is a good idea to use alloca(0) in
X	your main control loop, etc. to force garbage collection.
X*/
X#ifndef lint
Xstatic char	SCCSid[] = "@(#)alloca.c	1.1";	/* for the "what" utility */
X#endif
X
X#ifdef emacs
X#include "config.h"
X#ifdef static
X/* actually, only want this if static is defined as ""
X   -- this is for usg, in which emacs must undefine static
X   in order to make unexec workable
X   */
X#ifndef STACK_DIRECTION
Xyou
Xlose
X-- must know STACK_DIRECTION at compile-time
X#endif /* STACK_DIRECTION undefined */
X#endif /* static */
X#endif /* emacs */
X
X#ifdef X3J11
Xtypedef void	*pointer;		/* generic pointer type */
X#else
Xtypedef char	*pointer;		/* generic pointer type */
X#endif
X
X#define	NULL	0			/* null pointer constant */
X
Xextern void	free();
Xextern pointer	xmalloc();
X
X/*
X	Define STACK_DIRECTION if you know the direction of stack
X	growth for your system; otherwise it will be automatically
X	deduced at run-time.
X
X	STACK_DIRECTION > 0 => grows toward higher addresses
X	STACK_DIRECTION < 0 => grows toward lower addresses
X	STACK_DIRECTION = 0 => direction of growth unknown
X*/
X
X#ifndef STACK_DIRECTION
X#define	STACK_DIRECTION	0		/* direction unknown */
X#endif
X
X#if STACK_DIRECTION != 0
X
X#define	STACK_DIR	STACK_DIRECTION	/* known at compile-time */
X
X#else	/* STACK_DIRECTION == 0; need run-time code */
X
Xstatic int	stack_dir;		/* 1 or -1 once known */
X#define	STACK_DIR	stack_dir
X
Xstatic void
Xfind_stack_direction (/* void */)
X{
X  static char	*addr = NULL;	/* address of first
X				   `dummy', once known */
X  auto char	dummy;		/* to get stack address */
X
X  if (addr == NULL)
X    {				/* initial entry */
X      addr = &dummy;
X
X      find_stack_direction ();	/* recurse once */
X    }
X  else				/* second entry */
X    if (&dummy > addr)
X      stack_dir = 1;		/* stack grew upward */
X    else
X      stack_dir = -1;		/* stack grew downward */
X}
X
X#endif	/* STACK_DIRECTION == 0 */
X
X/*
X	An "alloca header" is used to:
X	(a) chain together all alloca()ed blocks;
X	(b) keep track of stack depth.
X
X	It is very important that sizeof(header) agree with malloc()
X	alignment chunk size.  The following default should work okay.
X*/
X
X#ifndef	ALIGN_SIZE
X#define	ALIGN_SIZE	sizeof(double)
X#endif
X
Xtypedef union hdr
X{
X  char	align[ALIGN_SIZE];	/* to force sizeof(header) */
X  struct
X    {
X      union hdr *next;		/* for chaining headers */
X      char *deep;		/* for stack depth measure */
X    } h;
X} header;
X
X/*
X	alloca( size ) returns a pointer to at least `size' bytes of
X	storage which will be automatically reclaimed upon exit from
X	the procedure that called alloca().  Originally, this space
X	was supposed to be taken from the current stack frame of the
X	caller, but that method cannot be made to work for some
X	implementations of C, for example under Gould's UTX/32.
X*/
X
Xstatic header *last_alloca_header = NULL; /* -> last alloca header */
X
Xpointer
Xalloca (size)			/* returns pointer to storage */
X     unsigned	size;		/* # bytes to allocate */
X{
X  auto char	probe;		/* probes stack depth: */
X  register char	*depth = &probe;
X
X#if STACK_DIRECTION == 0
X  if (STACK_DIR == 0)		/* unknown growth direction */
X    find_stack_direction ();
X#endif
X
X				/* Reclaim garbage, defined as all alloca()ed storage that
X				   was allocated from deeper in the stack than currently. */
X
X  {
X    register header	*hp;	/* traverses linked list */
X
X    for (hp = last_alloca_header; hp != NULL;)
X      if (STACK_DIR > 0 && hp->h.deep > depth
X	  || STACK_DIR < 0 && hp->h.deep < depth)
X	{
X	  register header	*np = hp->h.next;
X
X	  free ((pointer) hp);	/* collect garbage */
X
X	  hp = np;		/* -> next header */
X	}
X      else
X	break;			/* rest are not deeper */
X
X    last_alloca_header = hp;	/* -> last valid storage */
X  }
X
X  if (size == 0)
X    return NULL;		/* no allocation required */
X
X  /* Allocate combined header + user data storage. */
X
X  {
X    register pointer	new = xmalloc (sizeof (header) + size);
X    /* address of header */
X
X    ((header *)new)->h.next = last_alloca_header;
X    ((header *)new)->h.deep = depth;
X
X    last_alloca_header = (header *)new;
X
X    /* User storage begins just after header. */
X
X    return (pointer)((char *)new + sizeof(header));
X  }
X}
X
Xpointer xmalloc(n)
Xunsigned int n;
X{
X  extern pointer malloc();
X  pointer cp;
X  static char mesg[] = "xmalloc: no memory!\n";
X
X  cp = malloc(n);
X  if (! cp) {
X    write (2, mesg, sizeof(mesg) - 1);
X    exit(1);
X  }
X  return cp;
X}
END_OF_FILE
  if test 5456 -ne `wc -c <'./alloca.c'`; then
    echo shar: \"'./alloca.c'\" unpacked with wrong size!
  fi
  # end of './alloca.c'
fi
if test -f './array.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./array.c'\"
else
  echo shar: Extracting \"'./array.c'\" \(6106 characters\)
  sed "s/^X//" >'./array.c' <<'END_OF_FILE'
X/*
X * array.c - routines for associative arrays.
X */
X
X/* 
X * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
X * 
X * This file is part of GAWK, the GNU implementation of the
X * AWK Progamming Language.
X * 
X * GAWK 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 * GAWK 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 GAWK; see the file COPYING.  If not, write to
X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X */
X
X#include "awk.h"
X
X#ifdef DONTDEF
Xint primes[] = {31, 61, 127, 257, 509, 1021, 2053, 4099, 8191, 16381};
X#endif
X
X#define ASSOC_HASHSIZE 127
X#define STIR_BITS(n) ((n) << 5 | (((n) >> 27) & 0x1f))
X#define HASHSTEP(old, c) ((old << 1) + c)
X#define MAKE_POS(v) (v & ~0x80000000)	/* make number positive */
X
XNODE *
Xconcat_exp(tree)
XNODE *tree;
X{
X	NODE *r;
X	char *str;
X	char *s;
X	unsigned len;
X	int offset;
X	int subseplen;
X	char *subsep;
X
X	if (tree->type != Node_expression_list)
X		return force_string(tree_eval(tree));
X	r = force_string(tree_eval(tree->lnode));
X	if (tree->rnode == NULL)
X		return r;
X	subseplen = SUBSEP_node->lnode->stlen;
X	subsep = SUBSEP_node->lnode->stptr;
X	len = r->stlen + subseplen + 1;
X	emalloc(str, char *, len, "concat_exp");
X	memcpy(str, r->stptr, r->stlen+1);
X	s = str + r->stlen;
X	free_temp(r);
X	tree = tree->rnode;
X	while (tree) {
X		if (subseplen == 1)
X			*s++ = *subsep;
X		else {
X			memcpy(s, subsep, subseplen+1);
X			s += subseplen;
X		}
X		r = force_string(tree_eval(tree->lnode));
X		len += r->stlen + subseplen;
X		offset = s - str;
X		erealloc(str, char *, len, "concat_exp");
X		s = str + offset;
X		memcpy(s, r->stptr, r->stlen+1);
X		s += r->stlen;
X		free_temp(r);
X		tree = tree->rnode;
X	}
X	r = tmp_string(str, s - str);
X	free(str);
X	return r;
X}
X
X/* Flush all the values in symbol[] before doing a split() */
Xvoid
Xassoc_clear(symbol)
XNODE *symbol;
X{
X	int i;
X	NODE *bucket, *next;
X
X	if (symbol->var_array == 0)
X		return;
X	for (i = 0; i < ASSOC_HASHSIZE; i++) {
X		for (bucket = symbol->var_array[i]; bucket; bucket = next) {
X			next = bucket->ahnext;
X			deref = bucket->ahname;
X			do_deref();
X			deref = bucket->ahvalue;
X			do_deref();
X			freenode(bucket);
X		}
X		symbol->var_array[i] = 0;
X	}
X}
X
X/*
X * calculate the hash function of the string subs, also returning in *typtr
X * the type (string or number) 
X */
Xstatic int
Xhash_calc(subs)
XNODE *subs;
X{
X	register int hash1 = 0, i;
X
X	subs = force_string(subs);
X	for (i = 0; i < subs->stlen; i++)
X		hash1 = HASHSTEP(hash1, subs->stptr[i]);
X
X	hash1 = MAKE_POS(STIR_BITS((int) hash1)) % ASSOC_HASHSIZE;
X	return (hash1);
X}
X
X/*
X * locate symbol[subs], given hash of subs and type 
X */
Xstatic NODE *				/* NULL if not found */
Xassoc_find(symbol, subs, hash1)
XNODE *symbol, *subs;
Xint hash1;
X{
X	register NODE *bucket;
X
X	for (bucket = symbol->var_array[hash1]; bucket; bucket = bucket->ahnext) {
X		if (cmp_nodes(bucket->ahname, subs))
X			continue;
X		return bucket;
X	}
X	return NULL;
X}
X
X/*
X * test whether the array element symbol[subs] exists or not 
X */
Xint
Xin_array(symbol, subs)
XNODE *symbol, *subs;
X{
X	register int hash1;
X
X	if (symbol->type == Node_param_list)
X		symbol = stack_ptr[symbol->param_cnt];
X	if (symbol->var_array == 0)
X		return 0;
X	subs = concat_exp(subs);
X	hash1 = hash_calc(subs);
X	if (assoc_find(symbol, subs, hash1) == NULL) {
X		free_temp(subs);
X		return 0;
X	} else {
X		free_temp(subs);
X		return 1;
X	}
X}
X
X/*
X * SYMBOL is the address of the node (or other pointer) being dereferenced.
X * SUBS is a number or string used as the subscript. 
X *
X * Find SYMBOL[SUBS] in the assoc array.  Install it with value "" if it
X * isn't there. Returns a pointer ala get_lhs to where its value is stored 
X */
XNODE **
Xassoc_lookup(symbol, subs)
XNODE *symbol, *subs;
X{
X	register int hash1, i;
X	register NODE *bucket;
X
X	hash1 = hash_calc(subs);
X
X	if (symbol->var_array == 0) {	/* this table really should grow
X					 * dynamically */
X		emalloc(symbol->var_array, NODE **, (sizeof(NODE *) *
X			ASSOC_HASHSIZE), "assoc_lookup");
X		for (i = 0; i < ASSOC_HASHSIZE; i++)
X			symbol->var_array[i] = 0;
X		symbol->type = Node_var_array;
X	} else {
X		bucket = assoc_find(symbol, subs, hash1);
X		if (bucket != NULL) {
X			free_temp(subs);
X			return &(bucket->ahvalue);
X		}
X	}
X	bucket = newnode(Node_ahash);
X	bucket->ahname = dupnode(subs);
X	bucket->ahvalue = Nnull_string;
X	bucket->ahnext = symbol->var_array[hash1];
X	symbol->var_array[hash1] = bucket;
X	return &(bucket->ahvalue);
X}
X
Xvoid
Xdo_delete(symbol, tree)
XNODE *symbol, *tree;
X{
X	register int hash1;
X	register NODE *bucket, *last;
X	NODE *subs;
X
X	if (symbol->var_array == 0)
X		return;
X	subs = concat_exp(tree);
X	hash1 = hash_calc(subs);
X
X	last = NULL;
X	for (bucket = symbol->var_array[hash1]; bucket; last = bucket, bucket = bucket->ahnext)
X		if (cmp_nodes(bucket->ahname, subs) == 0)
X			break;
X	free_temp(subs);
X	if (bucket == NULL)
X		return;
X	if (last)
X		last->ahnext = bucket->ahnext;
X	else
X		symbol->var_array[hash1] = bucket->ahnext;
X	deref = bucket->ahname;
X	do_deref();
X	deref = bucket->ahvalue;
X	do_deref();
X	freenode(bucket);
X}
X
Xstruct search *
Xassoc_scan(symbol)
XNODE *symbol;
X{
X	struct search *lookat;
X
X	if (!symbol->var_array)
X		return 0;
X	emalloc(lookat, struct search *, sizeof(struct search), "assoc_scan");
X	lookat->numleft = ASSOC_HASHSIZE;
X	lookat->arr_ptr = symbol->var_array;
X	lookat->bucket = symbol->var_array[0];
X	return assoc_next(lookat);
X}
X
Xstruct search *
Xassoc_next(lookat)
Xstruct search *lookat;
X{
X	for (; lookat->numleft; lookat->numleft--) {
X		while (lookat->bucket != 0) {
X			lookat->retval = lookat->bucket->ahname;
X			lookat->bucket = lookat->bucket->ahnext;
X			return lookat;
X		}
X		lookat->bucket = *++(lookat->arr_ptr);
X	}
X	free((char *) lookat);
X	return 0;
X}
END_OF_FILE
  if test 6106 -ne `wc -c <'./array.c'`; then
    echo shar: \"'./array.c'\" unpacked with wrong size!
  fi
  # end of './array.c'
fi
if test -f './missing.d/strcase.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./missing.d/strcase.c'\"
else
  echo shar: Extracting \"'./missing.d/strcase.c'\" \(3821 characters\)
  sed "s/^X//" >'./missing.d/strcase.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1987 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)strcasecmp.c	5.6 (Berkeley) 6/27/88";
X#endif /* LIBC_SCCS and not lint */
X
X#ifndef USG
X#include <sys/types.h>
X#else
X#define u_char unsigned char
X#endif
X
X/*
X * This array is designed for mapping upper and lower case letter
X * together for a case independent comparison.  The mappings are
X * based upon ascii character sequences.
X */
Xstatic u_char charmap[] = {
X	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
X	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
X	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
X	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
X	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
X	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
X	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
X	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
X	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
X	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
X	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
X	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
X	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
X	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
X	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
X	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
X	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
X	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
X	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
X	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
X	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
X	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
X	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
X	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
X	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
X	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
X	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
X	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
X	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
X	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
X	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
X	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
X};
X
Xstrcasecmp(s1, s2)
X	char *s1, *s2;
X{
X	register u_char	*cm = charmap,
X			*us1 = (u_char *)s1,
X			*us2 = (u_char *)s2;
X
X	while (cm[*us1] == cm[*us2++])
X		if (*us1++ == '\0')
X			return(0);
X	return(cm[*us1] - cm[*--us2]);
X}
X
Xstrncasecmp(s1, s2, n)
X	char *s1, *s2;
X	register int n;
X{
X	register u_char	*cm = charmap,
X			*us1 = (u_char *)s1,
X			*us2 = (u_char *)s2;
X
X	while (--n >= 0 && cm[*us1] == cm[*us2++])
X		if (*us1++ == '\0')
X			return(0);
X	return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
X}
END_OF_FILE
  if test 3821 -ne `wc -c <'./missing.d/strcase.c'`; then
    echo shar: \"'./missing.d/strcase.c'\" unpacked with wrong size!
  fi
  # end of './missing.d/strcase.c'
fi
echo shar: End of archive 16 \(of 16\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.