v19i028: dmake - dmake version 3.7, Part07/37
Dennis Vadura
dvadura at watdragon.waterloo.edu
Sat May 11 04:55:24 AEST 1991
Submitted-by: Dennis Vadura <dvadura at watdragon.waterloo.edu>
Posting-number: Volume 19, Issue 28
Archive-name: dmake/part07
Supersedes: dmake-3.6: Volume 15, Issue 52-77
---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is dmake.shar.07 (part 7 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file dmake/dbug/malloc/testmem.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 7; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test -f _shar_wnt_.tmp; then
sed 's/^X//' << 'SHAR_EOF' >> 'dmake/dbug/malloc/testmem.c' &&
X (void) strncat(one, "cdef", 2);
X equal(one, "abcd", 10); /* Count-limited. */
X
X (void) strncat(one, "gh", 0);
X equal(one, "abcd", 11); /* Zero count. */
X
X (void) strncat(one, "gh", 2);
X equal(one, "abcdgh", 12); /* Count and length equal. */
X
X /*
X * strncmp - first test as strcmp with big counts, then test
X * count code.
X */
X it = "strncmp";
X check(strncmp("", "", 99) == 0, 1); /* Trivial case. */
X check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
X check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */
X check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */
X check(strncmp("abcd", "abc", 99) > 0, 5);
X check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
X check(strncmp("abce", "abcd", 99) > 0, 7);
X check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
X if (charsigned) /* Sign-bit comparison. */
X check(strncmp("a\203", "a\003", 2) < 0, 9);
X else
X check(strncmp("a\203", "a\003", 2) > 0, 9);
X check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */
X check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */
X check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
X check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */
X
X /*
X * strncpy - testing is a bit different because of odd semantics
X */
X it = "strncpy";
X check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
X equal(one, "abc", 2); /* Did the copy go right? */
X
X (void) strcpy(one, "abcdefgh");
X (void) strncpy(one, "xyz", 2);
X equal(one, "xycdefgh", 3); /* Copy cut by count. */
X
X (void) strcpy(one, "abcdefgh");
X (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
X equal(one, "xyzdefgh", 4);
X
X (void) strcpy(one, "abcdefgh");
X (void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */
X equal(one, "xyz", 5);
X equal(one+4, "efgh", 6); /* Wrote too much? */
X
X (void) strcpy(one, "abcdefgh");
X (void) strncpy(one, "xyz", 5); /* Copy includes padding. */
X equal(one, "xyz", 7);
X equal(one+4, "", 8);
X equal(one+5, "fgh", 9);
X
X (void) strcpy(one, "abc");
X (void) strncpy(one, "xyz", 0); /* Zero-length copy. */
X equal(one, "abc", 10);
X
X (void) strncpy(one, "", 2); /* Zero-length source. */
X equal(one, "", 11);
X equal(one+1, "", 12);
X equal(one+2, "c", 13);
X
X (void) strcpy(one, "hi there");
X (void) strncpy(two, one, 9);
X equal(two, "hi there", 14); /* Just paranoia. */
X equal(one, "hi there", 15); /* Stomped on source? */
X
X /*
X * strlen
X */
X it = "strlen";
X check(strlen("") == 0, 1); /* Empty. */
X check(strlen("a") == 1, 2); /* Single char. */
X check(strlen("abcd") == 4, 3); /* Multiple chars. */
X
X /*
X * strchr
X */
X it = "strchr";
X check(strchr("abcd", 'z') == NULL, 1); /* Not found. */
X (void) strcpy(one, "abcd");
X check(strchr(one, 'c') == one+2, 2); /* Basic test. */
X check(strchr(one, 'd') == one+3, 3); /* End of string. */
X check(strchr(one, 'a') == one, 4); /* Beginning. */
X check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */
X (void) strcpy(one, "ababa");
X check(strchr(one, 'b') == one+1, 6); /* Finding first. */
X (void) strcpy(one, "");
X check(strchr(one, 'b') == NULL, 7); /* Empty string. */
X check(strchr(one, '\0') == one, 8); /* NUL in empty string. */
X
X /*
X * index - just like strchr
X */
X it = "index";
X check(index("abcd", 'z') == NULL, 1); /* Not found. */
X (void) strcpy(one, "abcd");
X check(index(one, 'c') == one+2, 2); /* Basic test. */
X check(index(one, 'd') == one+3, 3); /* End of string. */
X check(index(one, 'a') == one, 4); /* Beginning. */
X check(index(one, '\0') == one+4, 5); /* Finding NUL. */
X (void) strcpy(one, "ababa");
X check(index(one, 'b') == one+1, 6); /* Finding first. */
X (void) strcpy(one, "");
X check(index(one, 'b') == NULL, 7); /* Empty string. */
X check(index(one, '\0') == one, 8); /* NUL in empty string. */
X
X /*
X * strrchr
X */
X it = "strrchr";
X check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */
X (void) strcpy(one, "abcd");
X check(strrchr(one, 'c') == one+2, 2); /* Basic test. */
X check(strrchr(one, 'd') == one+3, 3); /* End of string. */
X check(strrchr(one, 'a') == one, 4); /* Beginning. */
X check(strrchr(one, '\0') == one+4, 5); /* Finding NUL. */
X (void) strcpy(one, "ababa");
X check(strrchr(one, 'b') == one+3, 6); /* Finding last. */
X (void) strcpy(one, "");
X check(strrchr(one, 'b') == NULL, 7); /* Empty string. */
X check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */
X
X /*
X * rindex - just like strrchr
X */
X it = "rindex";
X check(rindex("abcd", 'z') == NULL, 1); /* Not found. */
X (void) strcpy(one, "abcd");
X check(rindex(one, 'c') == one+2, 2); /* Basic test. */
X check(rindex(one, 'd') == one+3, 3); /* End of string. */
X check(rindex(one, 'a') == one, 4); /* Beginning. */
X check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */
X (void) strcpy(one, "ababa");
X check(rindex(one, 'b') == one+3, 6); /* Finding last. */
X (void) strcpy(one, "");
X check(rindex(one, 'b') == NULL, 7); /* Empty string. */
X check(rindex(one, '\0') == one, 8); /* NUL in empty string. */
}
X
second()
{
X /*
X * strpbrk - somewhat like strchr
X */
X it = "strpbrk";
X check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
X (void) strcpy(one, "abcd");
X check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
X check(strpbrk(one, "d") == one+3, 3); /* End of string. */
X check(strpbrk(one, "a") == one, 4); /* Beginning. */
X check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
X check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
X (void) strcpy(one, "abcabdea");
X check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
X check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
X check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
X (void) strcpy(one, "");
X check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
X check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
X
#if 0
X /*
X * strstr - somewhat like strchr
X */
X it = "strstr";
X check(strstr("abcd", "z") == NULL, 1); /* Not found. */
X check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
X (void) strcpy(one, "abcd");
X check(strstr(one, "c") == one+2, 3); /* Basic test. */
X check(strstr(one, "bc") == one+1, 4); /* Multichar. */
X check(strstr(one, "d") == one+3, 5); /* End of string. */
X check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
X check(strstr(one, "abc") == one, 7); /* Beginning. */
X check(strstr(one, "abcd") == one, 8); /* Exact match. */
X check(strstr(one, "abcde") == NULL, 9); /* Too long. */
X check(strstr(one, "de") == NULL, 10); /* Past end. */
X check(strstr(one, "") == one+4, 11); /* Finding empty. */
X (void) strcpy(one, "ababa");
X check(strstr(one, "ba") == one+1, 12); /* Finding first. */
X (void) strcpy(one, "");
X check(strstr(one, "b") == NULL, 13); /* Empty string. */
X check(strstr(one, "") == one, 14); /* Empty in empty string. */
X (void) strcpy(one, "bcbca");
X check(strstr(one, "bca") == one+2, 15); /* False start. */
X (void) strcpy(one, "bbbcabbca");
X check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
#endif
X
X /*
X * strspn
X */
X it = "strspn";
X check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
X check(strspn("abcba", "ab") == 2, 2); /* Partial. */
X check(strspn("abc", "qx") == 0, 3); /* None. */
X check(strspn("", "ab") == 0, 4); /* Null string. */
X check(strspn("abc", "") == 0, 5); /* Null search list. */
X
X /*
X * strcspn
X */
X it = "strcspn";
X check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
X check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
X check(strcspn("abc", "abc") == 0, 3); /* None. */
X check(strcspn("", "ab") == 0, 4); /* Null string. */
X check(strcspn("abc", "") == 3, 5); /* Null search list. */
X
X /*
X * strtok - the hard one
X */
X it = "strtok";
X (void) strcpy(one, "first, second, third");
X equal(strtok(one, ", "), "first", 1); /* Basic test. */
X equal(one, "first", 2);
X equal(strtok((char *)NULL, ", "), "second", 3);
X equal(strtok((char *)NULL, ", "), "third", 4);
X check(strtok((char *)NULL, ", ") == NULL, 5);
X (void) strcpy(one, ", first, ");
X equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
X check(strtok((char *)NULL, ", ") == NULL, 7);
X (void) strcpy(one, "1a, 1b; 2a, 2b");
X equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
X equal(strtok((char *)NULL, "; "), "1b", 9);
X equal(strtok((char *)NULL, ", "), "2a", 10);
X (void) strcpy(two, "x-y");
X equal(strtok(two, "-"), "x", 11); /* New string before done. */
X equal(strtok((char *)NULL, "-"), "y", 12);
X check(strtok((char *)NULL, "-") == NULL, 13);
X (void) strcpy(one, "a,b, c,, ,d");
X equal(strtok(one, ", "), "a", 14); /* Different separators. */
X equal(strtok((char *)NULL, ", "), "b", 15);
X equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
X equal(strtok((char *)NULL, " ,"), "d", 17);
X check(strtok((char *)NULL, ", ") == NULL, 18);
X check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
X (void) strcpy(one, ", ");
X check(strtok(one, ", ") == NULL, 20); /* No tokens. */
X (void) strcpy(one, "");
X check(strtok(one, ", ") == NULL, 21); /* Empty string. */
X (void) strcpy(one, "abc");
X equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
X check(strtok((char *)NULL, ", ") == NULL, 23);
X (void) strcpy(one, "abc");
X equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
X check(strtok((char *)NULL, "") == NULL, 25);
X (void) strcpy(one, "abcdefgh");
X (void) strcpy(one, "a,b,c");
X equal(strtok(one, ","), "a", 26); /* Basics again... */
X equal(strtok((char *)NULL, ","), "b", 27);
X equal(strtok((char *)NULL, ","), "c", 28);
X check(strtok((char *)NULL, ",") == NULL, 29);
X equal(one+6, "gh", 30); /* Stomped past end? */
X equal(one, "a", 31); /* Stomped old tokens? */
X equal(one+2, "b", 32);
X equal(one+4, "c", 33);
X
X /*
X * memcmp
X */
X it = "memcmp";
X check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
X check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
X check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
X check(memcmp("abce", "abcd", 4) > 0, 4);
X check(memcmp("alph", "beta", 4) < 0, 5);
X if (charsigned) /* Sign-bit comparison. */
X check(memcmp("a\203", "a\003", 2) < 0, 6);
X else
X check(memcmp("a\203", "a\003", 2) > 0, 6);
X check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
X check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
X
X /*
X * memchr
X */
X it = "memchr";
X check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
X (void) strcpy(one, "abcd");
X check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
X check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
X check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
X check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
X (void) strcpy(one, "ababa");
X check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
X check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
X check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
X (void) strcpy(one, "a\203b");
X check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
X
X /*
X * memcpy
X *
X * Note that X3J11 says memcpy must work regardless of overlap.
X * The SVID says it might fail.
X */
X it = "memcpy";
X check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
X equal(one, "abc", 2); /* Did the copy go right? */
X
X (void) strcpy(one, "abcdefgh");
X (void) memcpy(one+1, "xyz", 2);
X equal(one, "axydefgh", 3); /* Basic test. */
X
X (void) strcpy(one, "abc");
X (void) memcpy(one, "xyz", 0);
X equal(one, "abc", 4); /* Zero-length copy. */
X
X (void) strcpy(one, "hi there");
X (void) strcpy(two, "foo");
X (void) memcpy(two, one, 9);
X equal(two, "hi there", 5); /* Just paranoia. */
X equal(one, "hi there", 6); /* Stomped on source? */
X
X (void) strcpy(one, "abcdefgh");
X (void) memcpy(one+1, one, 9);
X equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
X
X (void) strcpy(one, "abcdefgh");
X (void) memcpy(one+1, one+2, 7);
X equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
X
X (void) strcpy(one, "abcdefgh");
X (void) memcpy(one, one, 9);
X equal(one, "abcdefgh", 9); /* 100% overlap. */
X
X /*
X * memccpy - first test like memcpy, then the search part
X *
X * The SVID, the only place where memccpy is mentioned, says
X * overlap might fail, so we don't try it. Besides, it's hard
X * to see the rationale for a non-left-to-right memccpy.
X */
X it = "memccpy";
X check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
X equal(one, "abc", 2); /* Did the copy go right? */
X
X (void) strcpy(one, "abcdefgh");
X (void) memccpy(one+1, "xyz", 'q', 2);
X equal(one, "axydefgh", 3); /* Basic test. */
X
X (void) strcpy(one, "abc");
X (void) memccpy(one, "xyz", 'q', 0);
X equal(one, "abc", 4); /* Zero-length copy. */
X
X (void) strcpy(one, "hi there");
X (void) strcpy(two, "foo");
X (void) memccpy(two, one, 'q', 9);
X equal(two, "hi there", 5); /* Just paranoia. */
X equal(one, "hi there", 6); /* Stomped on source? */
X
X (void) strcpy(one, "abcdefgh");
X (void) strcpy(two, "horsefeathers");
X check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
X equal(one, "abcdefgh", 8); /* Source intact? */
X equal(two, "abcdefeathers", 9); /* Copy correct? */
X
X (void) strcpy(one, "abcd");
X (void) strcpy(two, "bumblebee");
X check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
X equal(two, "aumblebee", 11);
X check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
X equal(two, "abcdlebee", 13);
X (void) strcpy(one, "xyz");
X check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
X equal(two, "xbcdlebee", 15);
X
X /*
X * memset
X */
X it = "memset";
X (void) strcpy(one, "abcdefgh");
X check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
X equal(one, "axxxefgh", 2); /* Basic test. */
X
X (void) memset(one+2, 'y', 0);
X equal(one, "axxxefgh", 3); /* Zero-length set. */
X
X (void) memset(one+5, 0, 1);
X equal(one, "axxxe", 4); /* Zero fill. */
X equal(one+6, "gh", 5); /* And the leftover. */
X
X (void) memset(one+2, 010045, 1);
X equal(one, "ax\045xe", 6); /* Unsigned char convert. */
X
X /*
X * bcopy - much like memcpy
X *
X * Berklix manual is silent about overlap, so don't test it.
X */
X it = "bcopy";
X (void) bcopy("abc", one, 4);
X equal(one, "abc", 1); /* Simple copy. */
X
X (void) strcpy(one, "abcdefgh");
X (void) bcopy("xyz", one+1, 2);
X equal(one, "axydefgh", 2); /* Basic test. */
X
X (void) strcpy(one, "abc");
X (void) bcopy("xyz", one, 0);
X equal(one, "abc", 3); /* Zero-length copy. */
X
X (void) strcpy(one, "hi there");
X (void) strcpy(two, "foo");
X (void) bcopy(one, two, 9);
X equal(two, "hi there", 4); /* Just paranoia. */
X equal(one, "hi there", 5); /* Stomped on source? */
X
X /*
X * bzero
X */
X it = "bzero";
X (void) strcpy(one, "abcdef");
X bzero(one+2, 2);
X equal(one, "ab", 1); /* Basic test. */
X equal(one+3, "", 2);
X equal(one+4, "ef", 3);
X
X (void) strcpy(one, "abcdef");
X bzero(one+2, 0);
X equal(one, "abcdef", 4); /* Zero-length copy. */
X
X /*
X * bcmp - somewhat like memcmp
X */
X it = "bcmp";
X check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
X check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
X check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
X check(bcmp("abce", "abcd", 4) != 0, 4);
X check(bcmp("alph", "beta", 4) != 0, 5);
X check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
X check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
X
#ifdef ERR
X /*
X * strerror - VERY system-dependent
X */
X it = "strerror";
X f = open("/", 1); /* Should always fail. */
X check(f < 0 && errno > 0 && errno < sys_nerr, 1);
X equal(strerror(errno), sys_errlist[errno], 2);
#ifdef UNIXERR
X equal(strerror(errno), "Is a directory", 3);
#endif
#ifdef BERKERR
X equal(strerror(errno), "Permission denied", 3);
#endif
#endif
}
SHAR_EOF
chmod 0640 dmake/dbug/malloc/testmem.c ||
echo 'restore of dmake/dbug/malloc/testmem.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/testmem.c'`"
test 20192 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/testmem.c: original size 20192, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/testmlc.c ==============
if test -f 'dmake/dbug/malloc/testmlc.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/testmlc.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/testmlc.c' &&
/* NOT copyright by SoftQuad Inc. -- msb, 1988 */
#ifndef lint
static char *SQ_SccsId = "@(#)mtest3.c 1.2 88/08/25";
#endif
#include <stdio.h>
/*
** looptest.c -- intensive allocator tester
**
** Usage: looptest
**
** History:
** 4-Feb-1987 rtech!daveb
*/
X
# ifdef SYS5
# define random rand
# else
# include <sys/vadvise.h>
# endif
X
# include <stdio.h>
# include <signal.h>
# include <setjmp.h>
X
# define MAXITER 1000000 /* main loop iterations */
# define MAXOBJS 1000 /* objects in pool */
# define BIGOBJ 90000 /* max size of a big object */
# define TINYOBJ 80 /* max size of a small object */
# define BIGMOD 100 /* 1 in BIGMOD is a BIGOBJ */
# define STATMOD 10000 /* interation interval for status */
X
main( argc, argv )
int argc;
char **argv;
{
X register int **objs; /* array of objects */
X register int *sizes; /* array of object sizes */
X register int n; /* iteration counter */
X register int i; /* object index */
X register int size; /* object size */
X register int r; /* random number */
X
X int objmax; /* max size this iteration */
X int cnt; /* number of allocated objects */
X int nm = 0; /* number of mallocs */
X int nre = 0; /* number of reallocs */
X int nal; /* number of allocated objects */
X int nfre; /* number of free list objects */
X long alm; /* memory in allocated objects */
X long frem; /* memory in free list */
X long startsize; /* size at loop start */
X long endsize; /* size at loop exit */
X long maxiter = 0; /* real max # iterations */
X
X extern char end; /* memory before heap */
X char *calloc();
X char *malloc();
X char *sbrk();
X long atol();
X
# ifndef SYS5
X /* your milage may vary... */
X vadvise( VA_ANOM );
# endif
X
X if (argc > 1)
X maxiter = atol (argv[1]);
X if (maxiter <= 0)
X maxiter = MAXITER;
X
X printf("MAXITER %d MAXOBJS %d ", maxiter, MAXOBJS );
X printf("BIGOBJ %d, TINYOBJ %d, nbig/ntiny 1/%d\n",
X BIGOBJ, TINYOBJ, BIGMOD );
X fflush( stdout );
X
X if( NULL == (objs = (int **)calloc( MAXOBJS, sizeof( *objs ) ) ) )
X {
X fprintf(stderr, "Can't allocate memory for objs array\n");
X exit(1);
X }
X
X if( NULL == ( sizes = (int *)calloc( MAXOBJS, sizeof( *sizes ) ) ) )
X {
X fprintf(stderr, "Can't allocate memory for sizes array\n");
X exit(1);
X }
X
X /* as per recent discussion on net.lang.c, calloc does not
X ** necessarily fill in NULL pointers...
X */
X for( i = 0; i < MAXOBJS; i++ )
X objs[ i ] = NULL;
X
X startsize = sbrk(0) - &end;
X printf( "Memory use at start: %d bytes\n", startsize );
X fflush(stdout);
X
X printf("Starting the test...\n");
X fflush(stdout);
X for( n = 0; n < maxiter ; n++ )
X {
X if( !(n % STATMOD) )
X {
X printf("%d iterations\n", n);
X fflush(stdout);
X }
X
X /* determine object of interst and it's size */
X
X r = random();
X objmax = ( r % BIGMOD ) ? TINYOBJ : BIGOBJ;
X size = r % objmax;
X i = r % (MAXOBJS - 1);
X
X /* either replace the object of get a new one */
X
X if( objs[ i ] == NULL )
X {
X objs[ i ] = (int *)malloc( size );
X nm++;
X }
X else
X {
X /* don't keep bigger objects around */
X if( size > sizes[ i ] )
X {
X objs[ i ] = (int *)realloc( objs[ i ], size );
X nre++;
X }
X else
X {
X free( objs[ i ] );
X objs[ i ] = (int *)malloc( size );
X nm++;
X }
X }
X
X sizes[ i ] = size;
X if( objs[ i ] == NULL )
X {
X printf("\nCouldn't allocate %d byte object!\n",
X size );
X break;
X }
X } /* for() */
X
X printf( "\n" );
X cnt = 0;
X for( i = 0; i < MAXOBJS; i++ )
X if( objs[ i ] )
X cnt++;
X
X printf( "Did %d iterations, %d objects, %d mallocs, %d reallocs\n",
X n, cnt, nm, nre );
X printf( "Memory use at end: %d bytes\n", sbrk(0) - &end );
X fflush( stdout );
X
X /* free all the objects */
X for( i = 0; i < MAXOBJS; i++ )
X if( objs[ i ] != NULL )
X free( objs[ i ] );
X
X endsize = sbrk(0) - &end;
X printf( "Memory use after free: %d bytes\n", endsize );
X fflush( stdout );
X
X if( startsize != endsize )
X printf("startsize %d != endsize %d\n", startsize, endsize );
X
X free( objs );
X free( sizes );
X
X malloc_dump(2);
X exit( 0 );
}
X
SHAR_EOF
chmod 0640 dmake/dbug/malloc/testmlc.c ||
echo 'restore of dmake/dbug/malloc/testmlc.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/testmlc.c'`"
test 3971 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/testmlc.c: original size 3971, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/tostring.c ==============
if test -f 'dmake/dbug/malloc/tostring.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/tostring.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/tostring.c' &&
/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
#include "tostring.h"
X
/*
X * Function: tostring()
X *
X * Purpose: to convert an integer to an ascii display string
X *
X * Arguments: buf - place to put the
X * val - integer to convert
X * len - length of output field (0 if just enough to hold data)
X * base - base for number conversion (only works for base <= 16)
X * fill - fill char when len > # digits
X *
X * Returns: length of string
X *
X * Narrative: IF fill character is non-blank
X * Determine base
X * If base is HEX
X * add "0x" to begining of string
X * IF base is OCTAL
X * add "0" to begining of string
X *
X * While value is greater than zero
X * use val % base as index into xlation str to get cur char
X * divide val by base
X *
X * Determine fill-in length
X *
X * Fill in fill chars
X *
X * Copy in number
X *
X *
X * Mod History:
X * 90/01/24 cpcahil Initial revision.
X */
X
#ifndef lint
static
char rcs_hdr[] = "$Id: tostring.c,v 1.4 90/05/11 00:13:11 cpcahil Exp $";
#endif
X
#define T_LEN 10
X
int
tostring(buf,val,len,base,fill)
X int base;
X char * buf;
X char fill;
X int len;
X int val;
X
{
X char * bufstart = buf;
X int i = T_LEN;
X char * xbuf = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
X char tbuf[T_LEN];
X
X /*
X * if we are filling with non-blanks, make sure the
X * proper start string is added
X */
X if( fill != ' ' )
X {
X switch(base)
X {
X case B_HEX:
X *(buf++) = '0';
X *(buf++) = 'x';
X if( len )
X {
X len -= 2;
X }
X break;
X case B_OCTAL:
X *(buf++) = fill;
X if( len )
X {
X len--;
X }
X break;
X default:
X break;
X }
X }
X
X while( val > 0 )
X {
X tbuf[--i] = xbuf[val % base];
X val = val / base;
X }
X
X if( len )
X {
X len -= (T_LEN - i);
X
X if( len > 0 )
X {
X while(len-- > 0)
X {
X *(buf++) = fill;
X }
X }
X else
X {
X /*
X * string is too long so we must truncate
X * off some characters. We do this the easiest
X * way by just incrementing i. This means the
X * most significant digits are lost.
X */
X while( len++ < 0 )
X {
X i++;
X }
X }
X }
X
X while( i < T_LEN )
X {
X *(buf++) = tbuf[i++];
X }
X
X return( (int) (buf - bufstart) );
X
} /* tostring(... */
X
/*
X * $Log: tostring.c,v $
X * Revision 1.4 90/05/11 00:13:11 cpcahil
X * added copyright statment
X *
X * Revision 1.3 90/02/24 21:50:33 cpcahil
X * lots of lint fixes
X *
X * Revision 1.2 90/02/24 17:29:42 cpcahil
X * changed $Header to $Id so full path wouldnt be included as part of rcs
X * id string
X *
X * Revision 1.1 90/02/22 23:17:44 cpcahil
X * Initial revision
X *
X */
SHAR_EOF
chmod 0640 dmake/dbug/malloc/tostring.c ||
echo 'restore of dmake/dbug/malloc/tostring.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/tostring.c'`"
test 2716 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/tostring.c: original size 2716, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/tostring.h ==============
if test -f 'dmake/dbug/malloc/tostring.h' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/tostring.h (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/tostring.h' &&
/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
/*
X * $Id: tostring.h,v 1.2 90/05/11 00:13:11 cpcahil Exp $
X */
#define B_BIN 2
#define B_DEC 10
#define B_HEX 16
#define B_OCTAL 8
X
/*
X * $Log: tostring.h,v $
X * Revision 1.2 90/05/11 00:13:11 cpcahil
X * added copyright statment
X *
X * Revision 1.1 90/02/23 07:09:05 cpcahil
X * Initial revision
X *
X */
SHAR_EOF
chmod 0640 dmake/dbug/malloc/tostring.h ||
echo 'restore of dmake/dbug/malloc/tostring.h failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/tostring.h'`"
test 491 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/tostring.h: original size 491, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dmake.c ==============
if test -f 'dmake/dmake.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dmake.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dmake.c' &&
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.c,v 1.1 91/05/06 15:23:06 dvadura Exp $
-- SYNOPSIS -- The main program.
--
-- DESCRIPTION
--
-- dmake [-#dbug_string] [ options ]
-- [ macro definitions ] [ target ... ]
--
-- This file contains the main command line parser for the
-- make utility. The valid flags recognized are as follows:
--
-- -f file - use file as the makefile
-- -C file - duplicate console output to file (MSDOS only)
-- -K file - .KEEP_STATE file
-- -#dbug_string - dump out debugging info, see below
-- -v{dfimt} - verbose, print what we are doing, as we do it.
--
-- options: (can be catenated, ie -irn == -i -r -n)
--
-- -A - enable AUGMAKE special target mapping
-- -c - use non-standard comment scanning
-- -i - ignore errors
-- -n - trace and print, do not execute commands
-- -t - touch, update dates without executing commands
-- -T - do not apply transitive closure
-- -r - don't use internal rules
-- -s - do your work silently
-- -S - force Sequential make, overrides -P
-- -q - check if target is up to date. Does not
-- do anything. Returns 0 if up to date, -1
-- otherwise.
-- -p - print out a version of the makefile
-- -P# - set value of MAXPROCESS
-- -e - define environment strings as macros
-- -E - as -e but done after parsing makefile
-- -u - force unconditional update of target
-- -k - make all independent targets even if errors
-- -V - print out this make version number
-- -M - Microsoft make compatibility, (* disabled *)
-- -h - print out usage info
-- -x - export macro defs to environment
--
-- NOTE: - #ddbug_string is only availabe for versions of dmake that
-- have been compiled with -DDBUG switch on. Not the case for
-- distributed versions. Any such versions must be linked
-- together with a version of Fred Fish's debug code.
--
-- NOTE: - in order to compile the code the include file stddef.h
-- must be shipped with the bundled code.
--
-- AUTHOR
-- Dennis Vadura, dvadura at watdragon.uwaterloo.ca
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
--
-- COPYRIGHT
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- (version 1), as published by the Free Software Foundation, and
-- found in the file 'LICENSE' included with this distribution.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--
-- LOG
-- $Log: dmake.c,v $
X * Revision 1.1 91/05/06 15:23:06 dvadura
X * dmake Release Version 3.7
X *
*/
X
/* Set this flag to one, and the global variables in vextern.h will not
X * be defined as 'extern', instead they will be defined as global vars
X * when this module is compiled. */
#define _DEFINE_GLOBALS_ 1
X
#include "extern.h"
#include "patchlvl.h"
#include "version.h"
X
#ifndef MSDOS
#define USAGE \
"Usage:\n%s [-AeEhiknpqrsStTuVx] [-v{dfimt}] [-P#] [-{f|K} file] [macro[*][+][:]=value ...] [target ...]\n"
#else
#define USAGE \
"Usage:\n%s [-AeEhiknpqrsStTuVx] [-v{dfimt}] [-P#] [-{f|C|K} file] [macro[*][+][:]=value ...] [target ...]\n"
#endif
X
static char *sccid = "Copyright (c) 1990,1991 by Dennis Vadura";
static char _warn = TRUE; /* warnings on by default */
X
static void _do_VPATH();
static void _do_ReadEnvironment();
static void _do_f_flag ANSI((char, char *, char **));
X
PUBLIC int
main(argc, argv)
int argc;
char **argv;
{
#ifdef MSDOS
X char* std_fil_name = NIL(char);
#endif
X
X char* fil_name = NIL(char);
X char* state_name = NIL(char);
X char* cmdmacs;
X char* targets;
X FILE* mkfil;
X int ex_val;
X int m_export;
X
X DB_ENTER("main");
X
X /* Initialize Global variables to their default values */
X Prolog(argc, argv);
X Create_macro_vars();
X Catch_signals(Quit);
X
X Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT );
X Pname = basename(Pname);
X
X DB_PROCESS(Pname);
X (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
X
X Continue = FALSE;
X Comment = FALSE;
X Get_env = FALSE;
X Force = FALSE;
X Target = FALSE;
X If_expand = FALSE;
X Listing = FALSE;
X Readenv = FALSE;
X Rules = TRUE;
X Trace = FALSE;
X Touch = FALSE;
X Check = FALSE;
X Microsoft = FALSE;
X Makemkf = FALSE;
X m_export = FALSE;
X cmdmacs = NIL(char);
X targets = NIL(char);
X
X Verbose = V_NONE;
X Transitive = TRUE;
X Nest_level = 0;
X Line_number = 0;
X Suppress_temp_file = FALSE;
X
X while( --argc > 0 ) {
X register char *p;
X char *q;
X
X if( *(p = *++argv) == '-' ) {
X if( p[1] == '\0' ) Fatal("Missing option letter");
X
X /* copy options to Buffer for $(MFLAGS), strip 'f' and 'C'*/
X q = strchr(Buffer, '\0');
X while (*p != '\0') {
X char c = (*q++ = *p++);
X if( c == 'f' || c == 'C' ) q--;
X }
X
X if( *(q-1) == '-' )
X q--;
X else
X *q++ = ' ';
X
X *q = '\0';
X
X for( p = *argv+1; *p; p++) switch (*p) {
X case 'f':
X _do_f_flag( 'f', *++argv, &fil_name ); argc--;
X break;
X
#ifdef MSDOS
X case 'C':
X _do_f_flag( 'C', *++argv, &std_fil_name ); argc--;
X Hook_std_writes( std_fil_name );
X break;
#endif
X
X case 'K':
X _do_f_flag( 'K', *++argv, &state_name ); argc--;
X Def_macro(".KEEP_STATE", state_name, M_EXPANDED|M_PRECIOUS);
X break;
X
X case 'k': Continue = TRUE; break;
X case 'c': Comment = TRUE; break;
X case 'p': Listing = TRUE; break;
X case 'r': Rules = FALSE; break;
X case 'n': Trace = TRUE; break;
X case 't': Touch = TRUE; break;
X case 'q': Check = TRUE; break;
X case 'u': Force = TRUE; break;
X case 'x': m_export = TRUE; break;
X case 'T': Transitive = FALSE; break;
X case 'e': Get_env = 'e'; break;
X case 'E': Get_env = 'E'; break;
X
X case 'V': Version(); Quit(NIL(CELL)); break;
X case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
X case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
X case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
X case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
X
X case 'v':
X if( p[-1] != '-' ) Usage(TRUE);
X while( p[1] ) switch( *++p ) {
X case 'd': Verbose |= V_PRINT_DIR; break;
X case 'f': Verbose |= V_FILE_IO; break;
X case 'i': Verbose |= V_INFER; break;
X case 'm': Verbose |= V_MAKE; break;
X case 't': Verbose |= V_LEAVE_TMP; break;
X
X default: Usage(TRUE); break;
X }
X if( !Verbose ) Verbose = V_ALL;
X break;
X
X case 'P':
X if( p[1] ) {
X Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
X p += strlen(p)-1;
X }
X else
X Fatal( "Missing number for -P flag" );
X break;
X
#ifdef DBUG
X case '#':
X DB_PUSH(p+1);
X p += strlen(p)-1;
X break;
#endif
X
X case 'h': Usage(FALSE); break;
X default: Usage(TRUE); break;
X }
X }
X else if( (q = strchr(p, '=')) != NIL(char) ) {
X cmdmacs = _stradd( cmdmacs, _strdup(p), TRUE );
X Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT );
X }
X else {
X register CELLPTR cp;
X targets = _stradd( targets, _strdup(p), TRUE );
X Add_prerequisite(Root, cp = Def_cell(p), FALSE, FALSE);
X cp->ce_flag |= F_TARGET;
X cp->ce_attr |= A_FRINGE;
X Target = TRUE;
X }
X }
X
X Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS|M_NOEXPORT );
X Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT );
X if( cmdmacs != NIL(char) ) FREE(cmdmacs);
X if( targets != NIL(char) ) FREE(targets);
X
X Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
X Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
X
X if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
X
X _warn = FALSE; /* disable warnings for builtin rules */
X ex_val = Target; /* make sure we don't mark any */
X Target = TRUE; /* of the default rules as */
X Make_rules(); /* potential targets */
X _warn = TRUE;
X
X if( Rules ) {
X char *fname;
X
X if( (mkfil=Search_file("MAKESTARTUP", &fname)) != NIL(FILE) ) {
X Parse(mkfil);
X mkfil = NIL(FILE);
X }
X else
X Fatal( "Configuration file `%s' not found", fname );
X }
X
X Target = ex_val;
X
X if( Get_env == 'e' ) _do_ReadEnvironment();
X
X if( fil_name != NIL(char) )
X mkfil = Openfile( fil_name, FALSE, TRUE );
X else {
X /* Search .MAKEFILES dependent list looking for a makefile.
X */
X register CELLPTR cp;
X register LINKPTR lp;
X
X cp = Def_cell( ".MAKEFILES" );
X
X if( (lp = cp->CE_PRQ) != NIL(LINK) ) {
X int s_n, s_t, s_q;
X
X s_n = Trace;
X s_t = Touch;
X s_q = Check;
X
X Trace = Touch = Check = FALSE;
X Makemkf = Wait_for_completion = TRUE;
X mkfil = NIL(FILE);
X
X for(; lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) {
X if( lp->cl_prq->ce_attr & A_FRINGE ) continue;
X
X mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
X
X if( mkfil == NIL(FILE) &&
X Make(lp->cl_prq, lp, NIL(CELL)) != -1 )
X mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
X }
X
X Trace = s_n;
X Touch = s_t;
X Check = s_q;
X Makemkf = Wait_for_completion = FALSE;
X }
X }
X
X if( mkfil != NIL(FILE) ) {
X char *f = Filename();
X char *p;
X
X if( strcmp(f, "stdin") == 0 ) f = "-";
X p = _stradd( "-f", f, FALSE );
X Def_macro( "MAKEFILE", p, M_PRECIOUS|M_NOEXPORT );
X Parse( mkfil );
X }
X else if( !Rules )
X Fatal( "No `makefile' present" );
X
X if( Nest_level ) Fatal( "Missing .END for .IF" );
X if( Get_env == 'E' ) _do_ReadEnvironment();
X
X _do_VPATH(); /* kludge it up with .SOURCE */
X
X if( Listing ) Dump(); /* print out the structures */
X if( Trace ) Glob_attr &= ~A_SILENT; /* make sure we see the trace */
X
X if( !Target )
X Fatal( "No target" );
X else {
X Test_circle( Root, TRUE );
X Check_circle_dfa();
X }
X
X Push_dir( Start_dir, ".SETDIR", (int)(Glob_attr & A_IGNORE ));
X
X if( m_export ) {
X int i;
X
X for( i=0; i<HASH_TABLE_SIZE; ++i ) {
X HASHPTR hp = Macs[i];
X char *tmpstr = hp->ht_value;
X
X if( tmpstr != NIL(char)
X && !(hp->ht_flag & M_NOEXPORT)
X && Write_env_string(hp->ht_name, tmpstr) != 0 )
X Warning( "Could not export %s", hp->ht_name );
X }
X }
X
X if( Buffer != NIL(char) ) {FREE( Buffer ); Buffer = NIL(char);}
X if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED);
X if( Glob_attr & A_SEQ ) Def_macro( "MAXPROCESS", "1", M_EXPANDED|M_FORCE );
X
X ex_val = Make_targets();
X
X Pop_dir( (Glob_attr & A_IGNORE) != 0 );
X Clear_signals();
X Epilog(ex_val); /* Does not return -- EVER */
}
X
X
static void
_do_f_flag( flag, name, fname )
char flag;
char *name;
char **fname;
{
X if( *fname == NIL(char) ) {
X if( name != NIL(char) ) {
X *fname = name;
X } else
X Fatal("No file name for -%c", flag);
X } else
X Fatal("Only one `-%c file' allowed", flag);
}
X
X
static void
_do_ReadEnvironment()
{
X t_attr saveattr = Glob_attr;
X
X Glob_attr |= A_SILENT;
X ReadEnvironment();
X Glob_attr = saveattr;
}
X
X
static void
_do_VPATH()
{
X HASHPTR hp;
X char *_rl[2];
X extern char **Rule_tab;
X
X hp = GET_MACRO("VPATH");
X if( hp == NIL(HASH) ) return;
X
X _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
X _rl[1] = NIL(char);
X
X Rule_tab = _rl;
X Parse( NIL(FILE) );
}
X
X
/* The file table and pointer to the next FREE slot for use by both
X Openfile and Closefile. Each open stacks the new file onto the open
X file stack, and a corresponding close will close the passed file, and
X return the next file on the stack. The maximum number of nested
X include files is limited by the value of MAX_INC_DEPTH */
X
static struct {
X FILE *file; /* file pointer */
X char *name; /* name of file */
X int numb; /* line number */
} ftab[ MAX_INC_DEPTH ];
X
static int next_file_slot = 0;
X
/* Set the proper macro value to reflect the depth of the .INCLUDE directives.
X */
static void
_set_inc_depth()
{
X char buf[10];
X sprintf( buf, "%d", next_file_slot-1 );
X Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT );
}
X
X
PUBLIC FILE *
Openfile(name, mode, err)/*
===========================
X This routine opens a file for input or output depending on mode.
X If the file name is `-' then it returns standard input.
X The file is pushed onto the open file stack. */
char *name;
int mode;
int err;
{
X FILE *fil;
X
X DB_ENTER("Openfile");
X
X if( name == NIL(char) || !*name )
X if( !err )
X DB_RETURN(NIL(FILE));
X else
X Fatal( "Openfile: NIL filename" );
SHAR_EOF
true || echo 'restore of dmake/dmake.c failed'
fi
echo 'End of part 7, continue with part 8'
echo 8 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list