home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume27
/
gcom
/
part04
< prev
next >
Wrap
Text File
|
1992-01-13
|
43KB
|
1,800 lines
Newsgroups: comp.sources.misc
From: murf@oakhill.sps.mot.com (Steve Murphy)
Subject: v27i075: gcom - GEDCOM genealogical database merge utility, v1, Part04/07
Message-ID: <1992Jan13.145532.25538@sparky.imd.sterling.com>
X-Md4-Signature: 45a2e9a9c93634ed8c8f513423dda538
Date: Mon, 13 Jan 1992 14:55:32 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: murf@oakhill.sps.mot.com (Steve Murphy)
Posting-number: Volume 27, Issue 75
Archive-name: gcom/part04
Environment: SunOS
---- Cut Here and unpack ----
#!/bin/sh
# This is part 04 of gcom
if touch 2>&1 | fgrep 'amc' > /dev/null
then TOUCH=touch
else TOUCH=true
fi
# ============= keys.gperf ==============
echo "x - extracting keys.gperf (Text)"
sed 's/^X//' << 'SHAR_EOF' > keys.gperf &&
X%{
Xstatic char rcs_stuff[] = "$Id: keys.gperf,v 1.2 1992/01/03 17:49:58 murf Exp $";
X/*
X# Copyright (C) 1992 Steven Michael Murphy
X#
X#
X# This file is part of gcom, the GEDCOM file merging utility for UNIX,
X#
X#
X# gcom 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 2, or (at your option)
X# any later version.
X#
X# gcom 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 gcom; see the file COPYING. If not, write to
X# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X*/
X#include <stdio.h>
X#include "gedcom.b.tab.h"
Xextern int lineno;
Xstatic char buff[300]; /* Actually, 80 may be enough */
Xstatic char *buff_ptr = &buff[0];
X
X
XFILE *yyin;
X%}
Xstruct keyword { char *name; int val; };
X%%
XADDR, ADDR
XBAPL, BAPL
XCHAR, CHAR
XCOMM, COMM
XCONT, CONT
XDATE, DATE
XENDL, ENDL
XFILE, FILE9
XFLAG, FLAG
XDEST, DEST
XPHON, PHON
XPLAC, PLAC
XQUAL, QUAL
XREL, REL
XNOTE, NOTE
XSEX, SEX
XSOUR, SOUR
XTEMP, TEMP
XTITL, TITL
XBIC, BIC
XNUMB, NUMB
XREFN, REFN
XBIRT, BIRT
XBURI, BURI
XCHIL, CHIL
XCHR, CHR
XDEAT, DEAT
XFAM, FAM
XNAME, NAME
XFAMC, FAMC
XFAMS, FAMS
XHEAD, HEAD
XHUSB, HUSB
XINDI, INDI
XMARR, MARR
XSTAL, STAL
XTRLR, TRLR
XWIFE, WIFE
XSUBM, SUBM
XSLGC, SLGC
XSLGS, SLGS
X%%
X
X
Xyylex()
X{
X struct keyword *kw;
X char *p;
X int i;
X
X if( !(*buff_ptr) )
X {
X int lev;
X if( !fgets(buff,300,yyin) )
X {
X return 0; /* end of file */
X }
X buff[strlen(buff)-1] = 0; /* blast the newline */
X lineno++;
X buff_ptr = &buff[0]; /* get a new line */
X /* the first thing on a line is the level number, get it */
X lev = strtol(buff,&p,10);
X if( p == buff_ptr )
X {
X fprintf(stderr,"No level number at the beginning of the line on line %d\n",
X lineno);
X return LEV0;
X }
X buff_ptr = p;
X return LEV0+lev;
X }
X else
X {
X /* either a type or a reference */
X while(*buff_ptr &&
X (*buff_ptr == ' ' || *buff_ptr == '\t') )
X buff_ptr++;
X /* collect next token */
X p = buff_ptr;
X while( *buff_ptr && (*buff_ptr != ' ' && *buff_ptr != '\t' &&
X *buff_ptr != '\n' ) )
X buff_ptr++;
X if( *p == '@' )
X {
X char x,*y;
X
X x = *buff_ptr;
X *buff_ptr = 0;
X p++; /* skip the @ stuff and just pass the ref id */
X yylval.str = (char *)malloc(buff_ptr-p);
X strncpy(yylval.str,p,buff_ptr-p);
X yylval.str[buff_ptr-p-1] = 0; /* leave out the '@'s */
X *buff_ptr = x;
X return REF;
X }
X if( !strncmp(p,"DIV",3) ) /* DIV is a slightly special case ... ? */
X {
X if( *(p+4) == 'Y' ) yylval.num = 1;
X else yylval.num = 0;
X *buff_ptr = 0; /* we are done here */
X return DIV;
X }
X *buff_ptr = 0;
X /* then match on the token, and return the rest of the line as
X the value */
X /* the tokens are arranged in a ______table. */
X kw = in_word_set(p,strlen(p));
X if( kw )
X {
X *buff_ptr = ' ';
X if( *(buff_ptr+1) == '@' )
X {
X return kw->val;
X }
X setyystr(p);
X *buff_ptr = 0; /* this will reset the lexer and read in a
X new line next time.... */
X return kw->val;
X }
X else
X {
X /* else report error */
X fprintf(stderr,"HEY, '%s' is not a keyword I understand! (line %d)\n",
X p, lineno);
X }
X }
X}
X
X
Xsetyystr(txt)
Xchar *txt;
X{
X int x=strlen(txt);
X char *y = txt;
X while( *y && *y != ' ' )
X y++;
X if( *y )
X {
X /* there is a space */
X x -= (y-txt);
X y++;
X yylval.str = (char *)malloc(x);
X strcpy(yylval.str,y);
X }
X else
X yylval.str = "";
X}
X
SHAR_EOF
$TOUCH -am 0103114992 keys.gperf &&
chmod 0664 keys.gperf ||
echo "restore of keys.gperf failed"
set `wc -c keys.gperf`;Wc_c=$1
if test "$Wc_c" != "3657"; then
echo original size 3657, current size $Wc_c
fi
# ============= gedmerge.c ==============
echo "x - extracting gedmerge.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > gedmerge.c &&
Xstatic char rcs_stuff[] = "$Id: gedmerge.c,v 1.2 1992/01/03 17:49:55 murf Exp $";
X#include <stdio.h>
X#include "gedcom.h"
X#include <ctype.h>
X/*
X# Copyright (C) 1992 Steven Michael Murphy
X#
X#
X# This file is part of gcom, the GEDCOM file merging utility for UNIX,
X#
X#
X# gcom 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 2, or (at your option)
X# any later version.
X#
X# gcom 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 gcom; see the file COPYING. If not, write to
X# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X*/
X
X/* all the merges will try to take stuff in b and "add it" to a. */
X
Xvoid merge_strings(a,b,what)
Xchar **a,**b,*what;
X{
X if( *a && *b && strcmp(*a,*b) )
X fprintf(stderr,"!!!!! %ss differ.... ref=%s, addit=%s\n",
X what,*a,*b);
X else if( !(*a) && (*b) )
X {
X *a = *b;
X *b=0; /* at the same time, take away from b */
X fprintf(stderr,"added %s to ref (%s)\n", what, *a);
X }
X}
X
Xvoid merge_datplace(a,b)
Xstruct datplace **a,**b;
X{
X if( !(*a) && !(*b) ) /* neither has any */
X return;
X if( !(*b) ) /* a has something and b does not */
X return;
X if( !(*a) && *b)
X {
X /* b has some, add to a */
X *a = Calloc(struct datplace);
X }
X merge_strings(&(*a)->date,&(*b)->date,"date");
X merge_strings(&(*a)->place,&(*b)->place,"place");
X}
X
Xvoid merge_ordinance(a,b)
Xstruct ordinance **a,**b;
X{
X if( !(*a) && !(*b) ) /* neither has any */
X return;
X if( !(*b) ) /* a has something and b does not */
X return;
X if( !(*a) && *b)
X {
X /* b has some, add to a */
X *a = Calloc(struct ordinance);
X }
X merge_strings(&(*a)->date,&(*b)->date,"date");
X merge_strings(&(*a)->qual,&(*b)->qual,"qualifier");
X merge_strings(&(*a)->val,&(*b)->val,"temple ord desc");
X if( (*a)->temp[0] && (*b)->temp[0] && strcmp((*a)->temp,(*b)->temp) )
X fprintf(stderr,"!!!!! temples differ... ref=%s, addit=%s\n",
X (*a)->temp,(*b)->temp);
X}
X
Xvoid merge_notes(a,b)
Xstruct notelist **a,**b;
X{
X int i,j,k,match;
X
X if( !(*a) && !(*b) ) /* neither has any */
X return;
X if( !(*b) ) /* a has something and b does not */
X return;
X if( !(*a) && *b)
X {
X /* b has some, add to a */
X *a = Calloc(struct notelist);
X }
X /* only copy in notes not an exact duplication of previous
X notes */
X for(i=0; i < (*b)->notes; i++)
X {
X for(match=0,j=0; j < (*a)->notes; j++)
X {
X /* either every comment entry in b matches every
X comment entry in a or, the note in b can be added to a */
X if( (*a)->note[j].lines != (*b)->note[i].lines )
X {
X continue;
X }
X
X for(k=0; k < (*a)->note[j].lines; k++)
X {
X if( strcmp((*a)->note[j].line[k], (*b)->note[i].line[k]))
X {
X match = -1;
X break;
X }
X }
X if( !match )
X {
X /* I know this is confusing, but the above loop will turn
X out a -1 if it sees a non-match. if it sees no non-matches
X it will drop out without changing match. This means a
X match with match zero. Apply an inverter: */
X match = 1;
X break;
X }
X } /* j for loop */
X if ( !match )
X {
X /* no match, so add this morsel of b into a */
X if( (*a)->notes )
X (*a)->note = (struct comment *)realloc((*a)->note,
X sizeof(struct comment)*((*a)->notes+1));
X else
X (*a)->note = Calloc(struct comment);
X (*a)->note[(*a)->notes].lines = (*b)->note[i].lines;
X (*a)->note[(*a)->notes].line = (*b)->note[i].line;
X /* make the transfer of information complete */
X (*b)->note[i].lines = 0;
X fprintf(stderr,"added note to ref database, '%s.....'\n",
X (*a)->note[(*a)->notes].line[0]);
X (*a)->notes++;
X }
X }
X}
X
Xvoid merge_address(a,b)
Xstruct address **a,**b;
X{
X/* since addresses are only in the submission stuff,
Xleave it alone */
X}
X
Xvoid merge_stake(a,b)
Xstruct stake **a,**b;
X{
X/* since stake info are only in the submission stuff, leave it */
X}
X
Xvoid merge_comment(a,b)
Xstruct comment **a,**b;
X{
X int i,j,different;
X
X if( !(*a) && !(*b) ) /* neither has any */
X return;
X if( !(*b) ) /* a has something and b does not */
X return;
X if( !(*a) && *b)
X {
X /* b has some, add to a */
X *a = Calloc(struct comment);
X }
X /* all the lines of a comment match, or the comment in b is
X added to a */
X if( (*a)->lines != (*b)->lines )
X different = 1;
X else
X different = 0;
X
X}
X
Xvoid upcase(str)
Xchar *str;
X{
X char *p,toupper();
X p = str;
X while( *p )
X {
X if( islower(*p) )
X *p = toupper(*p);
X p++;
X }
X}
X
Xint my_strcmp(a,b)
Xchar *a,*b;
X{
X char buf1[300],buf2[300];
X
X strcpy(buf1,a);
X strcpy(buf2,b);
X upcase(buf1);
X upcase(buf2);
X return(strcmp(buf1,buf2));
X}
X
Xint same_individual(a,b)
Xstruct individ *a,*b;
X{
X /* this routine is trying to determine if two seperate individuals
X could be considered to be the same person. */
X /* the name MUST match -- if not, edit the input files
X and try again.........!*/
X if( a->birth && b->birth )
X {
X if(a->birth->date && b->birth->date )
X {
X if( my_strcmp(a->birth->date, b->birth->date) )
X return 0;
X }
X }
X else
X return 0;
X if( a->title && !b->title || !a->title && b->title )
X return 0;
X if( a->title && b->title && my_strcmp(a->title,b->title) )
X return 0;
X if( !my_strcmp(a->name, b->name) )
X return 1;
X else
X return 0;
X}
Xvoid merge_fams(a,b)
Xstruct family *a,*b;
X{
X fprintf(stderr,"*****Merging data for Family %s...\n", a->ref);
X merge_datplace(&a->marriage,&b->marriage);
X merge_ordinance(&a->sealspouse,&b->sealspouse);
X}
X
Xvoid merge_individ(a,b)
Xstruct individ *a,*b;
X{
X fprintf(stderr,"*****Merging data for %s...\n", a->name);
X /* it is assumed these individuals are supposed to be the same
X person. merge the data within each into "a" */
X merge_strings(&a->name,&b->name,"name");
X merge_strings(&a->title,&b->title, "title");
X merge_strings(&a->givenref, &b->givenref,"ref");
X merge_strings(&a->flag,&b->flag,"flag");
X merge_notes(&a->notes,&b->notes);
X merge_datplace(&a->birth,&b->birth);
X merge_datplace(&a->christen,&b->christen);
X merge_datplace(&a->death,&b->death);
X merge_datplace(&a->burial,&b->burial);
X merge_ordinance(&a->baptism,&b->baptism);
X merge_ordinance(&a->endow,&b->endow);
X merge_ordinance(&a->child_to_parent,&b->child_to_parent);
X if( !a->sex && b->sex )
X a->sex = b->sex;
X else if( a->sex != b->sex )
X fprintf(stderr,"!!!!! He or She? Sex mismatch! ref = %s, addit= %s\n", a->name, b->name);
X}
X
Xmerge_dbs(ged1,ged2)
Xstruct gedfile *ged1,*ged2;
X{
X int i,overlapi,overlapf,numinds,numfams;
X struct individ *ind1,*ind2;
X struct family *fam1,*fam2;
X overlapi=overlapf=numinds=numfams = 0;
X
X for(i=0; i < ged1->indlist->num; i++)
X {
X if( ged1->indlist->ind[i]->corr.match_ind )
X {
X ind1 = ged1->indlist->ind[i];
X ind2 = ged2->indlist->ind[ind1->corr.index];
X merge_individ(ind1,ind2);
X overlapi++;
X }
X numinds++;
X }
X for(i=0; i < ged1->famlist->num; i++)
X {
X if( ged1->famlist->fam[i]->corr.match_ind )
X {
X fam1 = ged1->famlist->fam[i];
X fam2 = ged2->famlist->fam[fam1->corr.index];
X merge_fams(fam1,fam2);
X overlapf++;
X }
X numfams++;
X }
X fprintf(stderr,"upon completion of data merging, the ref database\n\
Xnow holds %d individuals and %d families, with %d individs and %d fams \n\
Xoverlapping between databases\n", numinds, numfams, overlapi, overlapf);
X}
X
X
SHAR_EOF
$TOUCH -am 0103114992 gedmerge.c &&
chmod 0664 gedmerge.c ||
echo "restore of gedmerge.c failed"
set `wc -c gedmerge.c`;Wc_c=$1
if test "$Wc_c" != "7479"; then
echo original size 7479, current size $Wc_c
fi
# ============= st.c ==============
echo "x - extracting st.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > st.c &&
Xstatic char rcs_stuff[] = "$Id: st.c,v 1.1.1.1 1992/01/03 17:10:25 murf Exp $";
X/*LINTLIBRARY*/
X/*
X * String Table (Hash) Package
X *
X * Peter Moore
X * University of California, Berkeley
X * 1985
X *
X * This is a general purpose hash table package.
X */
X
X
X#ifndef OCTTOOLS_COPYRIGHT_H
X#define OCTTOOLS_COPYRIGHT_H
X/*
X * Oct Tools Distribution 3.0
X *
X * Copyright (c) 1988, 1989, Regents of the University of California.
X * All rights reserved.
X *
X * Use and copying of this software and preparation of derivative works
X * based upon this software are permitted. However, any distribution of
X * this software or derivative works must include the above copyright
X * notice.
X *
X * This software is made available AS IS, and neither the Electronics
X * Research Laboratory or the University of California make any
X * warranty about the software, its performance or its conformity to
X * any specification.
X *
X * Suggestions, comments, or improvements are welcome and should be
X * addressed to:
X *
X * octtools@eros.berkeley.edu
X * ..!ucbvax!eros!octtools
X */
X
X#if !defined(lint) && !defined(SABER)
X#ifdef MCC
Xstatic char octtools_copyright[] = "\
XCopyright (C) 1988, 1989, Regents of the University of California. All rights reserved.\n\
XCopyright (C) 1989, Microelectronics and Computer Technology Corporation. All rights reserved.";
X#else
Xstatic char octtools_copyright[] = "Copyright (c) 1988, 1989, Regents of the University of California. All rights reserved.";
X#endif /* MCC */
X#endif
X#endif
X#ifndef PORT_H
X#define PORT_H
X
X#ifdef SABER
X#define volatile
X#endif
X
X/*
X * int32 should be defined as the most economical sized integer capable of
X * holding a 32 bit quantity
X * int16 should be similarly defined
X */
X
X/* XXX hack */
X#ifndef MACHDEP_INCLUDED
X#define MACHDEP_INCLUDED
X#ifdef vax
Xtypedef int int32;
Xtypedef short int16;
X#else
X /* Ansi-C promises that these definitions should always work */
Xtypedef long int32;
Xtypedef int int16;
X#endif /* vax */
X#endif /* MACHDEP_INCLUDED */
X
X
X#ifndef __STDC__
X#ifndef __DATE__
X#ifdef CUR_DATE
X#define __DATE__ CUR_DATE
X#else
X#define __DATE__ "unknown-date"
X#endif /* CUR_DATE */
X#endif /* __DATE__ */
X
X#ifndef __TIME__
X#ifdef CUR_TIME
X#define __TIME__ CUR_TIME
X#else
X#define __TIME__ "unknown-time"
X#endif /* CUR_TIME */
X#endif /* __TIME__ */
X#endif /* __STDC__ */
X
X#ifdef sun386
X#define PORTAR
X#endif
X
X#include <stdio.h>
X#include <ctype.h>
X#ifdef macintosh
X#include <Types.h>
X#else
X#include <sys/types.h>
X#endif
X#undef HUGE
X#include <math.h>
X#include <signal.h>
X
X#if defined(ultrix) /* { */
X#if defined(_SIZE_T_) /* { */
X#define ultrix4
X#else /* } else { */
X#if defined(SIGLOST) /* { */
X#define ultrix3
X#else /* } else { */
X#define ultrix2
X#endif /* } */
X#endif /* } */
X#endif /* } */
X
X#if defined(ultrix3) && defined(mips)
Xextern double rint();
Xextern double trunc();
X#endif
X
X#if defined(sun) && defined(FD_SETSIZE)
X#define sunos4
X#else
X#define sunos3
X#endif
X
X#if defined(sequent) || defined(news800)
X#define LACK_SYS5
X#endif
X
X#if defined(ultrix3) || defined(sunos4) || defined(_IBMR2)
X#define SIGNAL_FN void
X#else
X/* sequent, ultrix2, 4.3BSD (vax, hp), sunos3 */
X#define SIGNAL_FN int
X#endif
X
X/* Some systems have 'fixed' certain functions which used to be int */
X#if defined(ultrix) || defined(SABER) || defined(hpux) || defined(aiws) || defined(apollo) || defined(__STDC__)
X#define VOID_HACK void
X#else
X#define VOID_HACK int
X#endif
X
X#ifndef NULL
X#define NULL 0
X#endif /* NULL */
X
X/*
X * CHARBITS should be defined only if the compiler lacks "unsigned char".
X * It should be a mask, e.g. 0377 for an 8-bit machine.
X */
X
X#ifndef CHARBITS
X# define UNSCHAR(c) ((unsigned char)(c))
X#else
X# define UNSCHAR(c) ((c)&CHARBITS)
X#endif
X
X#define SIZET int
X
X#ifdef __STDC__
X#define CONST const
X#define VOIDSTAR void *
X#else
X#define CONST
X#define VOIDSTAR char *
X#endif /* __STDC__ */
X
X
X/* Some machines fail to define some functions in stdio.h */
X#ifndef __STDC__
Xextern FILE *popen(), *tmpfile();
Xextern int pclose();
X#ifndef clearerr /* is a macro on many machines, but not all */
Xextern VOID_HACK clearerr();
X#endif /* clearerr */
X#ifndef rewind
X#ifndef macintosh
Xextern VOID_HACK rewind();
X#endif
X#endif /* rewind */
X#endif /* __STDC__ */
X
X
X/* most machines don't give us a header file for these */
X#ifdef __STDC__
X#include <stdlib.h>
X#else
X#ifdef hpux
Xextern int abort();
Xextern void free(), exit(), perror();
X#else
X#ifndef macintosh
Xextern VOID_HACK abort(), free(), exit(), perror();
X#endif
X#endif /* hpux */
Xextern char *getenv(), *malloc(), *realloc(), *calloc();
X#ifdef aiws
Xextern int sprintf();
X#else
X#ifndef macintosh
Xextern char *sprintf();
X#endif
X#endif
Xextern int system();
Xextern double atof();
Xextern long atol();
Xextern int sscanf();
X#endif /* __STDC__ */
X
X
X/* some call it strings.h, some call it string.h; others, also have memory.h */
X#ifdef __STDC__
X#include <string.h>
X#else
X/* ANSI C string.h -- 1/11/88 Draft Standard */
X#if defined(ultrix4)
X#include <strings.h>
X#else
Xextern char *strcpy(), *strncpy(), *strcat(), *strncat(), *strerror();
Xextern char *strpbrk(), *strtok(), *strchr(), *strrchr(), *strstr();
Xextern int strcoll(), strxfrm(), strncmp(), strlen(), strspn(), strcspn();
Xextern char *memmove(), *memccpy(), *memchr(), *memcpy(), *memset();
Xextern int memcmp(), strcmp();
X#endif /* ultrix4 */
X#endif /* __STDC__ */
X
X#ifdef lint
X#undef putc /* correct lint '_flsbuf' bug */
X#endif /* lint */
X
X/* a few extras */
Xextern VOID_HACK srandom();
Xextern long random();
X
X#if defined(ultrix3)
Xextern unsigned sleep();
X#else
Xextern VOID_HACK sleep();
X#endif
X
X/* assertion macro */
X
X#ifndef assert
X#ifdef __STDC__
X#include <assert.h>
X#else
X#ifndef NDEBUG
X#define assert(ex) {\
X if (! (ex)) {\
X (void) fprintf(stderr, "Assertion failed: file %s, line %d\n",\
X __FILE__, __LINE__);\
X (void) fflush(stdout);\
X abort();\
X }\
X}
X#else
X#define assert(ex) {;}
X#endif
X#endif
X#endif
X
X/* handle the various limits */
X#if defined(__STDC__) || defined(POSIX)
X#include <limits.h>
X#else
X#define USHRT_MAX (~ (unsigned short int) 0)
X#define UINT_MAX (~ (unsigned int) 0)
X#define ULONG_MAX (~ (unsigned long int) 0)
X#define SHRT_MAX ((short int) (USHRT_MAX >> 1))
X#define INT_MAX ((int) (UINT_MAX >> 1))
X#define LONG_MAX ((long int) (ULONG_MAX >> 1))
X#endif
X
X#endif /* PORT_H */
X
X#include "errtrap.h"
X#ifndef UTILITY_H
X#define UTILITY_H
X
X/*
X * assumes the memory manager is libmm.a
X * - allows malloc(0) or realloc(obj, 0)
X * - catches out of memory (and calls MMout_of_memory())
X * - catch free(0) and realloc(0, size) in the macros
X */
X#define NIL(type) ((type *) 0)
X#define ALLOC(type, num) \
X ((type *) malloc(sizeof(type) * (num)))
X#define REALLOC(type, obj, num) \
X (obj) ? ((type *) realloc((char *) obj, sizeof(type) * (num))) : \
X ((type *) malloc(sizeof(type) * (num)))
X#define FREE(obj) \
X if ((obj)) { (void) free((char *) (obj)); (obj) = 0; }
X
X
Xextern long util_cpu_time();
Xextern char *util_path_search
X ARGS((char *program));
Xextern char *util_file_search
X ARGS((char *file, char *path, char *mode));
Xextern int util_pipefork
X ARGS((char **argv, FILE **toCommand, FILE **fromCommand));
Xextern int util_csystem
X ARGS((char *command));
Xextern char *util_print_time
X ARGS((long t));
Xextern char *util_strsav
X ARGS((char *ptr));
Xextern char *util_tilde_expand
X ARGS((char *filename));
X
X#ifndef NIL_FN
X#define NIL_FN(type) ((type (*)()) 0)
X#endif /* NIL_FN */
X
X#ifndef MAX
X#define MAX(a,b) ((a) > (b) ? (a) : (b))
X#endif /* MAX */
X#ifndef MIN
X#define MIN(a,b) ((a) < (b) ? (a) : (b))
X#endif /* MIN */
X#ifndef ABS
X#define ABS(a) ((a) > 0 ? (a) : -(a))
X#endif /* ABS */
X
X
X#ifdef lint
X#undef ALLOC /* allow for lint -h flag */
X#undef REALLOC
X#define ALLOC(type, num) (((type *) 0) + (num))
X#define REALLOC(type, obj, num) ((obj) + (num))
X#endif /* lint */
X
X#endif
X
X#include "st.h"
X
X#define ST_NUMCMP(x,y) ((int) (x) - (int) (y))
X#define ST_NUMHASH(x,size) (ABS((int)x)%(size))
X#define ST_PTRHASH(x,size) ((int)((unsigned)(x)>>2)%size)
X#define ST_EQUAL(func, x, y) \
X ((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\
X (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))
X
X
X#define do_hash(key, table)\
X ((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\
X (table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\
X (*table->hash)((key), (table)->num_bins))
X
Xchar st_pkg_name[] = "st";
X
X/* Possible error conditions */
Xchar *st_no_mem = "out of memory";
Xchar *st_bad_ret = "bad return code from function passed to st_foreach";
Xchar *st_bad_gen = "null or zero generator";
X
X/* Forward declarations */
Xint st_numhash(), st_ptrhash(), st_numcmp(), st_ptrcmp();
Xstatic void rehash();
X
X
Xst_table *st_init_table_with_params(compare, hash, size, density, grow_factor,
X reorder_flag)
Xint (*compare)();
Xint (*hash)();
Xint size;
Xint density;
Xdouble grow_factor;
Xint reorder_flag;
X/* Detailed table allocator */
X{
X st_table *new;
X
X new = ALLOC(st_table, 1);
X if (!new) {
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);
X /* NOTREACHED */
X }
X new->compare = compare;
X new->hash = hash;
X new->num_entries = 0;
X new->max_density = density;
X new->grow_factor = grow_factor;
X new->reorder_flag = reorder_flag;
X if (size <= 0) {
X size = 1;
X }
X new->num_bins = size;
X new->bins =
X (st_table_entry **) calloc((unsigned)size, sizeof(st_table_entry *));
X if (!new->bins) {
X free((char *) new);
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);
X /* NOTREACHED */
X }
X return new;
X}
X
Xst_table *st_init_table(compare, hash)
Xint (*compare)();
Xint (*hash)();
X/* Default table allocator */
X{
X return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
X ST_DEFAULT_MAX_DENSITY,
X ST_DEFAULT_GROW_FACTOR,
X ST_DEFAULT_REORDER_FLAG);
X}
X
X
Xvoid
Xst_free_table(table)
Xst_table *table;
X/* Destroy a table */
X{
X register st_table_entry *ptr, *next;
X int i;
X
X for(i = 0; i < table->num_bins ; i++) {
X ptr = table->bins[i];
X while (ptr != NIL(st_table_entry)) {
X next = ptr->next;
X free((char *) ptr);
X ptr = next;
X }
X }
X free((char *) table->bins);
X free((char *) table);
X}
X
X
X#define ST_PTR_NOT_EQUAL(table, ptr, user_key)\
X(ptr != NIL(st_table_entry) && !ST_EQUAL(table->compare, user_key, (ptr)->key))
X
X#define FIND_ENTRY(table, hash_val, key, ptr, last) \
X (last) = &(table)->bins[hash_val];\
X (ptr) = *(last);\
X while (ST_PTR_NOT_EQUAL((table), (ptr), (key))) {\
X (last) = &(ptr)->next; (ptr) = *(last);\
X }\
X if ((ptr) != NIL(st_table_entry) && (table)->reorder_flag) {\
X *(last) = (ptr)->next;\
X (ptr)->next = (table)->bins[hash_val];\
X (table)->bins[hash_val] = (ptr);\
X }
X
Xint st_lookup(table, key, value)
Xst_table *table;
Xregister char *key;
Xchar **value;
X/* Look up item in table -- return zero if not found */
X{
X int hash_val;
X register st_table_entry *ptr, **last;
X
X hash_val = do_hash(key, table);
X
X FIND_ENTRY(table, hash_val, key, ptr, last);
X
X if (ptr == NIL(st_table_entry)) {
X return 0;
X } else {
X if (value != NIL(char *)) *value = ptr->record;
X return 1;
X }
X}
X
X#define ADD_DIRECT(table, key, value, hash_val, new)\
X{\
X if (table->num_entries/table->num_bins >= table->max_density) {\
X rehash(table);\
X hash_val = do_hash(key,table);\
X }\
X \
X new = ALLOC(st_table_entry, 1);\
X \
X if (new) {\
X new->key = key;\
X new->record = value;\
X new->next = table->bins[hash_val];\
X table->bins[hash_val] = new;\
X table->num_entries++;\
X } else {\
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);\
X /* NOTREACHED */ \
X } \
X}
X
Xint st_insert(table, key, value)
Xregister st_table *table;
Xregister char *key;
Xchar *value;
X/* Insert an item into the table - replacing if it already exists */
X{
X int hash_val;
X st_table_entry *new;
X register st_table_entry *ptr, **last;
X
X hash_val = do_hash(key, table);
X
X FIND_ENTRY(table, hash_val, key, ptr, last);
X
X if (ptr == NIL(st_table_entry)) {
X ADD_DIRECT(table,key,value,hash_val,new);
X return 0;
X } else {
X ptr->record = value;
X return 1;
X }
X}
X
Xvoid st_add_direct(table, key, value)
Xst_table *table;
Xchar *key;
Xchar *value;
X/* Add item to table without checking for existing item */
X{
X int hash_val;
X st_table_entry *new;
X
X hash_val = do_hash(key, table);
X ADD_DIRECT(table, key, value, hash_val, new);
X}
X
Xint st_find_or_add(table, key, slot)
Xst_table *table;
Xchar *key;
Xchar ***slot;
X/* Return slot for key - make one if one doesn't exist */
X{
X int hash_val;
X st_table_entry *new, *ptr, **last;
X
X hash_val = do_hash(key, table);
X
X FIND_ENTRY(table, hash_val, key, ptr, last);
X
X if (ptr == NIL(st_table_entry)) {
X ADD_DIRECT(table, key, (char *)0, hash_val, new);
X if (slot != NIL(char **)) *slot = &new->record;
X return 0;
X } else {
X if (slot != NIL(char **)) *slot = &ptr->record;
X return 1;
X }
X}
X
Xint st_find(table, key, slot)
Xst_table *table;
Xchar *key;
Xchar ***slot;
X/* Finds an entry in table */
X{
X int hash_val;
X st_table_entry *ptr, **last;
X
X hash_val = do_hash(key, table);
X
X FIND_ENTRY(table, hash_val, key, ptr, last);
X
X if (ptr == NIL(st_table_entry)) {
X return 0;
X } else {
X if (slot != NIL(char **)) *slot = &ptr->record;
X return 1;
X }
X}
X
Xstatic void rehash(table)
Xregister st_table *table;
X/* Grows table */
X{
X register st_table_entry *ptr, *next, **old_bins = table->bins;
X int i, old_num_bins = table->num_bins, hash_val;
X
X table->num_bins = table->grow_factor*old_num_bins;
X
X if (table->num_bins%2 == 0) {
X table->num_bins += 1;
X }
X
X table->bins =
X (st_table_entry **) calloc((unsigned) table->num_bins,
X sizeof(st_table_entry *));
X
X if (!table->bins) {
X /* If out of memory: don't resize */
X table->bins = old_bins;
X table->num_bins = old_num_bins;
X return;
X }
X
X table->num_entries = 0;
X
X for(i = 0; i < old_num_bins ; i++) {
X ptr = old_bins[i];
X while (ptr != NIL(st_table_entry)) {
X next = ptr->next;
X hash_val = do_hash(ptr->key, table);
X ptr->next = table->bins[hash_val];
X table->bins[hash_val] = ptr;
X table->num_entries++;
X ptr = next;
X }
X }
X free((char *) old_bins);
X}
X
Xst_table *st_copy(old_table)
Xst_table *old_table;
X{
X st_table *new_table;
X st_table_entry *ptr, *new;
X int i, num_bins = old_table->num_bins;
X
X new_table = ALLOC(st_table, 1);
X if (new_table == NIL(st_table)) {
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);
X /* NOTREACHED */
X }
X
X *new_table = *old_table;
X new_table->bins =
X (st_table_entry **) calloc((unsigned) num_bins, sizeof(st_table_entry *));
X
X if (new_table->bins == NIL(st_table_entry *)) {
X free((char *) new_table);
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);
X /* NOTREACHED */
X }
X
X for(i = 0; i < num_bins ; i++) {
X new_table->bins[i] = NIL(st_table_entry);
X ptr = old_table->bins[i];
X while (ptr != NIL(st_table_entry)) {
X new = ALLOC(st_table_entry, 1);
X if (new == NIL(st_table_entry)) {
X free((char *) new_table->bins);
X free((char *) new_table);
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);
X /* NOTREACHED */
X }
X *new = *ptr;
X new->next = new_table->bins[i];
X new_table->bins[i] = new;
X ptr = ptr->next;
X }
X }
X return new_table;
X}
X
Xint st_delete(table, keyp, value)
Xregister st_table *table;
Xregister char **keyp;
Xchar **value;
X{
X int hash_val;
X char *key = *keyp;
X register st_table_entry *ptr, **last;
X
X hash_val = do_hash(key, table);
X
X FIND_ENTRY(table, hash_val, key, ptr ,last);
X
X if (ptr == NIL(st_table_entry)) {
X return 0;
X }
X
X *last = ptr->next;
X if (value != NIL(char *)) *value = ptr->record;
X *keyp = ptr->key;
X free((char *) ptr);
X table->num_entries--;
X return 1;
X}
X
Xint st_foreach(table, func, arg)
Xst_table *table;
Xenum st_retval (*func)();
Xchar *arg;
X{
X st_table_entry *ptr, **last;
X enum st_retval retval;
X int i;
X
X for(i = 0; i < table->num_bins; i++) {
X last = &table->bins[i]; ptr = *last;
X while (ptr != NIL(st_table_entry)) {
X retval = (*func)(ptr->key, ptr->record, arg);
X switch (retval) {
X case ST_CONTINUE:
X last = &ptr->next; ptr = *last;
X break;
X case ST_STOP:
X return 0;
X case ST_DELETE:
X *last = ptr->next;
X free((char *) ptr);
X ptr = *last;
X break;
X default:
X errRaise(st_pkg_name, ST_BAD_RET, st_bad_ret);
X /* NOTREACHED */
X }
X }
X }
X return 1;
X}
X
Xint st_strhash(string, modulus)
Xregister char *string;
Xint modulus;
X{
X register int val = 0;
X register int c;
X
X while ((c = *string++) != '\0') {
X val = val*997 + c;
X }
X
X return ((val < 0) ? -val : val)%modulus;
X}
X
Xint st_numhash(x, size)
Xchar *x;
Xint size;
X{
X return ST_NUMHASH(x, size);
X}
X
Xint st_ptrhash(x, size)
Xchar *x;
Xint size;
X{
X return ST_PTRHASH(x, size);
X}
X
Xint st_numcmp(x, y)
Xchar *x;
Xchar *y;
X{
X return ST_NUMCMP(x, y);
X}
X
Xint st_ptrcmp(x, y)
Xchar *x;
Xchar *y;
X{
X return ST_NUMCMP(x, y);
X}
X
Xst_generator *
Xst_init_gen(table)
Xst_table *table;
X/* Initializes generation of items in table */
X{
X st_generator *gen;
X
X gen = ALLOC(st_generator, 1);
X if (!gen) {
X errRaise(st_pkg_name, ST_NO_MEM, st_no_mem);
X /* NOTREACHED */
X }
X gen->table = table;
X gen->entry = NIL(st_table_entry);
X gen->indx = 0;
X return gen;
X}
X
X
Xint
Xst_gen(gen, key_p, value_p)
Xst_generator *gen;
Xchar **key_p;
Xchar **value_p;
X/* Generates next item in generation sequence */
X{
X register int i;
X
X if (!gen) {
X errRaise(st_pkg_name, ST_BAD_GEN, st_bad_gen);
X /* NOTREACHED */
X }
X
X if (gen->entry == NIL(st_table_entry)) {
X /* try to find next entry */
X for(i = gen->indx; i < gen->table->num_bins; i++) {
X if (gen->table->bins[i] != NIL(st_table_entry)) {
X gen->indx = i+1;
X gen->entry = gen->table->bins[i];
X break;
X }
X }
X if (gen->entry == NIL(st_table_entry)) {
X return 0; /* that's all folks ! */
X }
X }
X *key_p = gen->entry->key;
X if (value_p != 0) *value_p = gen->entry->record;
X gen->entry = gen->entry->next;
X return 1;
X}
X
X
Xvoid
Xst_free_gen(gen)
Xst_generator *gen;
X{
X if (gen) {
X free((char *) gen);
X } else {
X errRaise(st_pkg_name, ST_BAD_GEN, st_bad_gen);
X /* NOTREACHED */
X }
X}
SHAR_EOF
$TOUCH -am 0103111092 st.c &&
chmod 0664 st.c ||
echo "restore of st.c failed"
set `wc -c st.c`;Wc_c=$1
if test "$Wc_c" != "18207"; then
echo original size 18207, current size $Wc_c
fi
# ============= st.h ==============
echo "x - extracting st.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > st.h &&
X/* $Id: st.h,v 1.1.1.1 1992/01/03 17:10:26 murf Exp $ */
X
X#ifndef ANSI_H
X#define ANSI_H
X
X/* Function prototypes */
X#ifdef __STDC__
X#define ARGS(args) args
X#else
X#define ARGS(args) ()
X#endif
X
X#endif
X#ifndef ST_INCLUDED
X#define ST_INCLUDED
X
X
Xextern char st_pkg_name[];
X
X/* Fatal error codes */
X#define ST_NO_MEM 0
X#define ST_BAD_RET 1
X#define ST_BAD_GEN 2
X
Xtypedef struct _st_table_entry st_table_entry;
Xstruct _st_table_entry {
X char *key;
X char *record;
X st_table_entry *next;
X};
X
Xtypedef struct _st_table st_table;
Xstruct _st_table {
X int (*compare)();
X int (*hash)();
X int num_bins;
X int num_entries;
X int max_density;
X int reorder_flag;
X double grow_factor;
X st_table_entry **bins;
X};
X
Xtypedef struct _st_generator st_generator;
Xstruct _st_generator {
X st_table *table;
X st_table_entry *entry;
X int indx;
X};
X
X#define st_is_member(table,key) st_lookup(table,key,(char **) 0)
X#define st_count(table) ((table)->num_entries)
X
Xenum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
X
Xextern st_table *st_init_table_with_params
X ARGS((int (*compare)(), int (*hash)(), int size, int density,
X double grow_factor, int reorder_flag));
X
Xextern st_table *st_init_table
X ARGS((int (*compare)(), int (*hash)()));
X
Xextern void st_free_table
X ARGS((st_table *table));
X
Xextern int st_lookup
X ARGS((st_table *table, char *key, char **value));
X
Xextern int st_insert
X ARGS((st_table *table, char *key, char *value));
X
Xextern void st_add_direct
X ARGS((st_table *table, char *key, char *value));
X
Xextern int st_find_or_add
X ARGS((st_table *table, char *key, char ***slot));
X
Xextern int st_find
X ARGS((st_table *table, char *key, char ***slot));
X
Xextern st_table *st_copy
X ARGS((st_table *old_table));
X
Xextern int st_delete
X ARGS((st_table *table, char **keyp, char **value));
X
Xextern int st_foreach
X ARGS((st_table *table, enum st_retval (*func)(), char *arg));
X
Xextern int st_strhash
X ARGS((char *string, int modulus));
X
Xextern int st_numhash
X ARGS((char *x, int size));
X
Xextern int st_ptrhash
X ARGS((char *x, int size));
X
Xextern int st_numcmp
X ARGS((char *x, char *y));
X
Xextern int st_ptrcmp
X ARGS((char *x, char *y));
X
Xextern st_generator *st_init_gen
X ARGS((st_table *table));
X
Xextern int st_gen
X ARGS((st_generator *gen, char **key_p, char **value_p));
X
Xextern void st_free_gen
X ARGS((st_generator *gen));
X
X#define ST_DEFAULT_MAX_DENSITY 5
X#define ST_DEFAULT_INIT_TABLE_SIZE 11
X#define ST_DEFAULT_GROW_FACTOR 2.0
X#define ST_DEFAULT_REORDER_FLAG 0
X
X#define st_foreach_item(table, gen, key_p, value_p) \
X for(gen=st_init_gen(table); st_gen(gen,key_p,value_p) || (st_free_gen(gen),0);)
X
X#endif /* ST_INCLUDED */
SHAR_EOF
$TOUCH -am 0103111092 st.h &&
chmod 0664 st.h ||
echo "restore of st.h failed"
set `wc -c st.h`;Wc_c=$1
if test "$Wc_c" != "2655"; then
echo original size 2655, current size $Wc_c
fi
# ============= errtrap.c ==============
echo "x - extracting errtrap.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > errtrap.c &&
X#ifndef OCTTOOLS_COPYRIGHT_H
X#define OCTTOOLS_COPYRIGHT_H
X/*
X * Oct Tools Distribution 3.0
X *
X * Copyright (c) 1988, 1989, Regents of the University of California.
X * All rights reserved.
X *
X * Use and copying of this software and preparation of derivative works
X * based upon this software are permitted. However, any distribution of
X * this software or derivative works must include the above copyright
X * notice.
X *
X * This software is made available AS IS, and neither the Electronics
X * Research Laboratory or the University of California make any
X * warranty about the software, its performance or its conformity to
X * any specification.
X *
X * Suggestions, comments, or improvements are welcome and should be
X * addressed to:
X *
X * octtools@eros.berkeley.edu
X * ..!ucbvax!eros!octtools
X */
X/* $Id: errtrap.c,v 1.1.1.1 1992/01/03 17:10:25 murf Exp $ */
X#if !defined(lint) && !defined(SABER)
Xstatic char octtools_copyright[] = "Copyright (c) 1988, 1989, Regents of the University of California. All rights reserved.";
X#endif
X#endif
X#ifdef macintosh
X#include <StdArg.h>
X#else
X#include <varargs.h>
X#endif
X#include "uprintf.h"
X#include "errtrap.h"
X
X/*LINTLIBRARY*/
X
X#define ERR_BUF_SIZE 4096
X
X#define STACK_SIZE 100
X
X/* error handler stack */
Xstatic void (*handlerList[STACK_SIZE])();
Xstatic int numHandlers = 0;
Xstatic int curHandlerIdx = -1;
X
X/* information given to errRaise */
Xstatic char *errPkg = (char *) 0;
Xstatic int errCode = 0;
Xstatic char errMessage[ERR_BUF_SIZE];
Xstatic char *errProgName = "\t\t*** ATTENTION ***\n\
X The writer of this program failed to register the name of the program\n\
X by calling `errProgramName'. Consequently, the name of program that\n\
X failed cannot be determined by the error handling package.\n\n<unknown>";
Xstatic int errCoreFlag = 0;
X
Xvoid errProgramName(name)
Xchar *name;
X{
X errProgName = name;
X}
X
Xvoid errCore(flag)
Xint flag;
X{
X errCoreFlag = flag;
X}
X
Xvoid errPushHandler(func)
Xvoid (*func)();
X{
X if (numHandlers >= STACK_SIZE) {
X errRaise(ERR_PKG_NAME, 0,
X "errPushHandler: can't push error handler -- stack is full");
X }
X handlerList[numHandlers++] = func;
X}
X
Xvoid errPopHandler()
X{
X if (numHandlers < 1) {
X errRaise(ERR_PKG_NAME, 0,
X "errPopHandler: can't pop error handler -- stack is empty");
X }
X numHandlers--;
X}
X
X#ifdef lint
X/*ARGSUSED*/
X/*VARARGS3*/
X
Xvoid errRaise(pkg, code, fmt, va_alist)
Xchar *pkg;
Xint code;
Xchar *fmt;
Xva_dcl
X
X#else /*LINT*/
X#ifdef macintosh
Xvoid errRaise(char *pkg, ... )
X#else
Xvoid errRaise(va_alist)
Xva_dcl
X#endif
X#endif /*LINT*/
X
X{
X va_list ap;
X char *format;
X static void defaultHandler();
X#ifdef macintosh
X va_start(ap, pkg);
X errPkg = pkg;
X#else
X va_start(ap);
X errPkg = va_arg(ap, char *);
X#endif
X errCode = va_arg(ap, int);
X format = va_arg(ap, char *);
X if (format != errMessage) {
X (void) uprintf(errMessage, format, &ap);
X }
X va_end(ap);
X
X curHandlerIdx = numHandlers;
X while (curHandlerIdx > 0) {
X (*handlerList[--curHandlerIdx])(errPkg, errCode, errMessage);
X }
X defaultHandler(errPkg, errCode, errMessage);
X}
X
Xstatic void defaultHandler(pkgName, code, mesg)
Xchar *pkgName;
Xint code;
Xchar *mesg;
X{
X (void) fprintf(stderr,
X "%s: unexpected fatal error detected by %s (code %d):\n\t%s\n",
X errProgName, pkgName, code, mesg);
X if (errCoreFlag) {
X abort();
X } else {
X exit(1);
X }
X}
X
X#ifdef lint
X/*ARGSUSED*/
X/*VARARGS1*/
X
Xvoid errPass(fmt, va_alist)
Xchar *fmt;
Xva_dcl
X
X#else /*LINT*/
X#ifdef macintosh
Xvoid errPass(char *fmt, ... )
X#else
Xvoid errPass(va_alist)
Xva_dcl
X#endif
X#endif /*LINT*/
X
X{
X va_list ap;
X char *format;
X static char tmpBuffer[ERR_BUF_SIZE];
X static void defaultHandler();
X
X#ifdef macintosh
X va_start(ap,fmt);
X format = fmt;
X#else
X va_start(ap);
X format = va_arg(ap, char *);
X#endif
X (void) uprintf(tmpBuffer, format, &ap);
X (void) strcpy(errMessage, tmpBuffer);
X va_end(ap);
X
X /* this should have been set by errRaise, but make sure it's possible */
X if (curHandlerIdx > numHandlers) curHandlerIdx = numHandlers;
X
X while (curHandlerIdx > 0) {
X (*handlerList[--curHandlerIdx])(errPkg, errCode, errMessage);
X }
X
X defaultHandler(errPkg, errCode, errMessage);
X}
X
Xjmp_buf errJmpBuf;
X
Xstatic jmp_buf jmpBufList[STACK_SIZE];
Xstatic numJmpBufs = 0;
X
Xvoid errIgnPush()
X{
X static void ignoreHandler();
X
X /* don't need to check for overflow, since errPushHandler will */
X errPushHandler(ignoreHandler);
X (void) memcpy((char *) jmpBufList[numJmpBufs++], (char *) errJmpBuf,
X sizeof(jmp_buf));
X
X /* so errStatus can tell if something trapped */
X errPkg = (char *) 0;
X}
X
Xvoid errIgnPop()
X{
X if (numJmpBufs <= 0) {
X errRaise(ERR_PKG_NAME, 0, "errIgnPop called before errIgnPush");
X }
X errPopHandler();
X numJmpBufs--;
X}
X
X/*ARGSUSED*/
Xstatic void ignoreHandler(pkgName, code, message)
Xchar *pkgName;
Xint code;
Xchar *message;
X{
X if (numJmpBufs <= 0) {
X errRaise(ERR_PKG_NAME, 0,
X "errtrap internal error: ERR_IGNORE handler called with no jmp_buf");
X }
X longjmp(jmpBufList[numJmpBufs - 1], 1);
X}
X
Xint errStatus(pkgNamePtr, codePtr, messagePtr)
Xchar **pkgNamePtr;
Xint *codePtr;
Xchar **messagePtr;
X{
X if (errPkg) {
X *pkgNamePtr = errPkg;
X *codePtr = errCode;
X *messagePtr = errMessage;
X return(1);
X }
X return(0);
X}
SHAR_EOF
$TOUCH -am 0103111092 errtrap.c &&
chmod 0664 errtrap.c ||
echo "restore of errtrap.c failed"
set `wc -c errtrap.c`;Wc_c=$1
if test "$Wc_c" != "5301"; then
echo original size 5301, current size $Wc_c
fi
# ============= errtrap.h ==============
echo "x - extracting errtrap.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > errtrap.h &&
X#ifndef ANSI_H
X#define ANSI_H
X/* $Id: errtrap.h,v 1.1.1.1 1992/01/03 17:10:25 murf Exp $ */
X
X/* Function prototypes */
X#ifdef __STDC__
X#define ARGS(args) args
X#else
X#define ARGS(args) ()
X#endif
X
X#endif
X#ifndef ERRTRAP_H
X#define ERRTRAP_H
X
X#include <setjmp.h>
X#include <stdio.h>
X
X#define ERR_PKG_NAME "errtrap"
X
Xextern void errProgramName( /* char *progName */ );
Xextern void errCore( /* int flag */ );
Xextern void errPushHandler( /* void (*handler)() */ );
Xextern void errPopHandler();
Xextern void errRaise( /* char *pkgName, int code, char *format, ... */ );
Xextern void errPass( /* char *format, ... */ );
X
X#define ERR_IGNORE(expr) \
X { \
X if ( ! setjmp(errJmpBuf)) { \
X errIgnPush(); \
X expr; \
X } \
X errIgnPop(); \
X }
Xextern jmp_buf errJmpBuf;
Xextern void errIgnPush(), errIgnPop();
Xextern int errStatus();
X
X#endif /* ERRTRAP_H */
SHAR_EOF
$TOUCH -am 0103111092 errtrap.h &&
chmod 0664 errtrap.h ||
echo "restore of errtrap.h failed"
set `wc -c errtrap.h`;Wc_c=$1
if test "$Wc_c" != "861"; then
echo original size 861, current size $Wc_c
fi
echo "End of part 4, continue with part 5"
exit 0
exit 0 # Just in case...