Browse Source

Initial revision

ceriel 37 years ago
parent
commit
e49bbfbe1f
100 changed files with 3853 additions and 0 deletions
  1. 22 0
      lang/cem/libcc/gen/_c2type.c
  2. 7 0
      lang/cem/libcc/gen/abort.e
  3. 3 0
      lang/cem/libcc/gen/abs.c
  4. 61 0
      lang/cem/libcc/gen/asctime.c
  5. 80 0
      lang/cem/libcc/gen/atof.c
  6. 20 0
      lang/cem/libcc/gen/atoi.c
  7. 19 0
      lang/cem/libcc/gen/atol.c
  8. 12 0
      lang/cem/libcc/gen/bcmp.c
  9. 12 0
      lang/cem/libcc/gen/bcopy.c
  10. 8 0
      lang/cem/libcc/gen/bfill.c
  11. 6 0
      lang/cem/libcc/gen/bmove.c
  12. 5 0
      lang/cem/libcc/gen/bzero.c
  13. 16 0
      lang/cem/libcc/gen/calloc.c
  14. 14 0
      lang/cem/libcc/gen/closedir.c
  15. 294 0
      lang/cem/libcc/gen/crypt.c
  16. 11 0
      lang/cem/libcc/gen/ctime.c
  17. 102 0
      lang/cem/libcc/gen/ecvt.c
  18. 36 0
      lang/cem/libcc/gen/execvp.c
  19. 10 0
      lang/cem/libcc/gen/ffc.c
  20. 10 0
      lang/cem/libcc/gen/ffs.c
  21. 29 0
      lang/cem/libcc/gen/frexp.e
  22. 61 0
      lang/cem/libcc/gen/gcvt.c
  23. 14 0
      lang/cem/libcc/gen/getenv.c
  24. 26 0
      lang/cem/libcc/gen/getlogin.c
  25. 57 0
      lang/cem/libcc/gen/getopt.c
  26. 39 0
      lang/cem/libcc/gen/gmtime.c
  27. 9 0
      lang/cem/libcc/gen/index.c
  28. 9 0
      lang/cem/libcc/gen/isatty.c
  29. 24 0
      lang/cem/libcc/gen/l3.c
  30. 34 0
      lang/cem/libcc/gen/ldexp.c
  31. 52 0
      lang/cem/libcc/gen/localtime.c
  32. 99 0
      lang/cem/libcc/gen/malloc.c
  33. 11 0
      lang/cem/libcc/gen/memccpy.c
  34. 14 0
      lang/cem/libcc/gen/memchr.c
  35. 15 0
      lang/cem/libcc/gen/memcmp.c
  36. 16 0
      lang/cem/libcc/gen/memcpy.c
  37. 12 0
      lang/cem/libcc/gen/memset.c
  38. 26 0
      lang/cem/libcc/gen/mktemp.c
  39. 33 0
      lang/cem/libcc/gen/modf.e
  40. 62 0
      lang/cem/libcc/gen/monitor.c
  41. 27 0
      lang/cem/libcc/gen/opendir.c
  42. 57 0
      lang/cem/libcc/gen/perror.c
  43. 42 0
      lang/cem/libcc/gen/procentry.c
  44. 133 0
      lang/cem/libcc/gen/qsort.c
  45. 13 0
      lang/cem/libcc/gen/rand.c
  46. 64 0
      lang/cem/libcc/gen/readdir.c
  47. 12 0
      lang/cem/libcc/gen/rindex.c
  48. 37 0
      lang/cem/libcc/gen/seekdir.c
  49. 147 0
      lang/cem/libcc/gen/setjmp.e
  50. 38 0
      lang/cem/libcc/gen/sleep.c
  51. 11 0
      lang/cem/libcc/gen/stb.c
  52. 14 0
      lang/cem/libcc/gen/strcat.c
  53. 9 0
      lang/cem/libcc/gen/strchr.c
  54. 15 0
      lang/cem/libcc/gen/strcmp.c
  55. 9 0
      lang/cem/libcc/gen/strcpy.c
  56. 13 0
      lang/cem/libcc/gen/strcspn.c
  57. 10 0
      lang/cem/libcc/gen/strlen.c
  58. 22 0
      lang/cem/libcc/gen/strncat.c
  59. 18 0
      lang/cem/libcc/gen/strncmp.c
  60. 13 0
      lang/cem/libcc/gen/strncpy.c
  61. 13 0
      lang/cem/libcc/gen/strpbrk.c
  62. 12 0
      lang/cem/libcc/gen/strrchr.c
  63. 13 0
      lang/cem/libcc/gen/strspn.c
  64. 12 0
      lang/cem/libcc/gen/strstr.c
  65. 25 0
      lang/cem/libcc/gen/strtok.c
  66. 10 0
      lang/cem/libcc/gen/swab.c
  67. 13 0
      lang/cem/libcc/gen/telldir.c
  68. 43 0
      lang/cem/libcc/gen/ttyname.c
  69. 71 0
      lang/cem/libcc/gen/ttyslot.c
  70. 56 0
      lang/cem/libcc/gen/tzset.c
  71. 7 0
      lang/cem/libcc/stdio/clearerr.c
  72. 23 0
      lang/cem/libcc/stdio/data.c
  73. 242 0
      lang/cem/libcc/stdio/doprnt.c
  74. 278 0
      lang/cem/libcc/stdio/doscan.c
  75. 22 0
      lang/cem/libcc/stdio/fclose.c
  76. 38 0
      lang/cem/libcc/stdio/fdopen.c
  77. 26 0
      lang/cem/libcc/stdio/fflush.c
  78. 7 0
      lang/cem/libcc/stdio/fgetc.c
  79. 21 0
      lang/cem/libcc/stdio/fgets.c
  80. 37 0
      lang/cem/libcc/stdio/fillbuf.c
  81. 57 0
      lang/cem/libcc/stdio/fltpr.c
  82. 71 0
      lang/cem/libcc/stdio/flushbuf.c
  83. 56 0
      lang/cem/libcc/stdio/fopen.c
  84. 11 0
      lang/cem/libcc/stdio/fprintf.c
  85. 7 0
      lang/cem/libcc/stdio/fputc.c
  86. 9 0
      lang/cem/libcc/stdio/fputs.c
  87. 25 0
      lang/cem/libcc/stdio/fread.c
  88. 59 0
      lang/cem/libcc/stdio/freopen.c
  89. 10 0
      lang/cem/libcc/stdio/fscanf.c
  90. 39 0
      lang/cem/libcc/stdio/fseek.c
  91. 25 0
      lang/cem/libcc/stdio/ftell.c
  92. 23 0
      lang/cem/libcc/stdio/fwrite.c
  93. 8 0
      lang/cem/libcc/stdio/getchar.c
  94. 115 0
      lang/cem/libcc/stdio/getgrent.c
  95. 29 0
      lang/cem/libcc/stdio/getpass.c
  96. 35 0
      lang/cem/libcc/stdio/getpw.c
  97. 125 0
      lang/cem/libcc/stdio/getpwent.c
  98. 17 0
      lang/cem/libcc/stdio/gets.c
  99. 15 0
      lang/cem/libcc/stdio/getw.c
  100. 54 0
      lang/cem/libcc/stdio/popen.c

+ 22 - 0
lang/cem/libcc/gen/_c2type.c

@@ -0,0 +1,22 @@
+/*  File   : _c2type.c
+    Author : Richard A. O'Keefe.
+    Updated: 23 April 1984
+    Purpose: Map character codes to types
+
+    The mapping used here is such that we can use it for converting
+    numbers expressed in a variety of radices to binary as well as for
+    classifying characters.
+*/
+
+char _c2type[129] =
+    {	37,			/* EOF == -1 */
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 39, 39, 39, 39, 37, 37,
+	37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+	38, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+	00, 01, 02, 03, 04, 05, 06, 07,  8,  9, 36, 36, 36, 36, 36, 36,
+	36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36,
+	36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+	25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36
+    };
+

+ 7 - 0
lang/cem/libcc/gen/abort.e

@@ -0,0 +1,7 @@
+#include <em_abs.h>
+ mes 2,EM_WSIZE,EM_PSIZE
+ exp $abort
+ pro $abort,0
+ loc EILLINS
+ trp
+ end

+ 3 - 0
lang/cem/libcc/gen/abs.c

@@ -0,0 +1,3 @@
+abs(i){
+  return i < 0 ? -i : i;
+}

+ 61 - 0
lang/cem/libcc/gen/asctime.c

@@ -0,0 +1,61 @@
+#include <time.h>
+
+#define DATE_STR "??? ??? ?? ??:??:?? ????\n"
+
+static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+
+static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+			  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+static char *two_digits();
+static char *four_digits();
+
+char *
+asctime(tm)
+	register struct tm *tm;
+{
+	static char buf[32];
+	register char *pb = buf, *ps;
+	
+	strcpy(pb, DATE_STR);
+	ps = days[tm->tm_wday];
+	while (*ps) *pb++ = *ps++;
+	pb++;
+	ps = months[tm->tm_mon];
+	while (*ps) *pb++ = *ps++; 
+	pb++;
+	pb = two_digits(
+		two_digits(
+		   two_digits(
+		      two_digits(pb, tm->tm_mday),
+		      tm->tm_hour),
+		   tm->tm_min),
+		tm->tm_sec);
+	four_digits(pb, tm->tm_year+1900);
+	return(buf);
+}
+
+static char *
+two_digits(pb, i)
+	register char *pb;
+{
+	*pb = (i / 10) % 10 + '0';
+	if (*pb == '0') *pb = ' ';
+	pb++;
+	*pb++ = (i % 10) + '0';
+	return ++pb;
+}
+
+static char *
+four_digits(pb, i)
+	register char *pb;
+{
+	i %= 10000;
+	*pb++ = (i / 1000) + '0';
+	i %= 1000;
+	*pb++ = (i / 100) + '0';
+	i %= 100;
+	*pb++ = (i / 10) + '0';
+	*pb++ = (i % 10) + '0';
+	return ++pb;
+}

+ 80 - 0
lang/cem/libcc/gen/atof.c

@@ -0,0 +1,80 @@
+#ifndef NOFLOAT
+#include <ctype.h>
+
+extern double ldexp();
+
+double
+atof(p)
+	register char *p;
+{
+	register int c;
+	int exp = 0, sign = 1, expsign = 0;
+	double fl;
+	double big = (double)(1L << 30) * (1L << 22);
+
+	while (isspace(*p)) p++;
+	c = *p;
+
+	switch (c) {
+	case '-':
+		sign = -1;
+	case '+': 
+		p++;
+	}
+
+	fl = 0.0;
+	while (isdigit(c = *p++)) {
+		if (fl < big)
+			fl = 10.0 * fl + (double)(c - '0');
+		else
+			exp++;
+	}
+	if (c == '.') {
+		while (isdigit(c = *p++)) {
+			if (fl < big) {
+				fl = 10.0 * fl + (double) (c - '0');
+				exp--;
+			}
+		}
+	}
+	if (fl == 0) return 0;
+	if (c == 'E' || c == 'e') {
+		int exp1 = 0;
+		int sign = 1;
+
+		switch (*p) {
+		case '-':
+			sign = -1;
+		case '+':
+			p++;
+		}
+		while (isdigit(c = *p++)) {
+			exp1 = 10 * exp1 + c - '0';
+		}
+		exp += sign * exp1;
+	}
+
+	if (exp < 0) {
+		expsign = 1;
+		exp = -exp;
+	}
+
+	if (exp != 0) {
+		int oldexp = exp;
+		double exp5 = 5;
+		double correction = 1;
+
+		while (exp) {
+			if (exp % 2) correction *= exp5;
+			exp /= 2;
+			exp5 *= exp5;
+		}
+		if (expsign) fl = fl / correction;
+		else	fl = fl * correction;
+
+		fl = ldexp(fl, expsign ? -oldexp : oldexp);
+	}
+
+	return sign * fl;
+}
+#endif

+ 20 - 0
lang/cem/libcc/gen/atoi.c

@@ -0,0 +1,20 @@
+atoi(s)
+register char *s;
+{
+  register int total = 0;
+  register unsigned digit;
+  int minus = 0;
+
+  while (*s == ' ' || *s == '\t')
+	s++;
+  if (*s == '+') s++;
+  else if (*s == '-') {
+	s++;
+	minus = 1;
+  }
+  while ((digit = *s++ - '0') < 10) {
+	total *= 10;
+	total += digit;
+  }
+  return(minus ? -total : total);
+}

+ 19 - 0
lang/cem/libcc/gen/atol.c

@@ -0,0 +1,19 @@
+long atol(s)
+register char *s;
+{
+  register long total = 0;
+  register unsigned digit;
+  int minus = 0;
+
+  while (*s == ' ' || *s == '\t') s++;
+  if (*s == '+') s++;
+  else if (*s == '-') {
+	s++;
+	minus = 1;
+  }
+  while ((digit = *s++ - '0') < 10) {
+	total *= 10;
+	total += digit;
+  }
+  return(minus ? -total : total);
+}

+ 12 - 0
lang/cem/libcc/gen/bcmp.c

@@ -0,0 +1,12 @@
+int
+bcmp(b1, b2, n)
+	register char *b1, *b2;
+	register int n;
+{
+	register int i;
+
+	while (n--) {
+		if (i = *b2++ - *b1++) return i;
+	}
+	return 0;
+}

+ 12 - 0
lang/cem/libcc/gen/bcopy.c

@@ -0,0 +1,12 @@
+bcopy(old, new, n)
+register char *old, *new;
+register int n;
+{
+/* Copy a block of data. */
+
+	if (old <= new && old + (n-1) >= new) {
+		old += n; new += n;
+		while (n-- > 0) *--new = *--old;
+	}
+	else	while (n-- > 0) *new++ = *old++;
+}

+ 8 - 0
lang/cem/libcc/gen/bfill.c

@@ -0,0 +1,8 @@
+bfill(dst, len, fill)
+	register char *dst;
+	register int len;
+	register int fill;
+{
+	while (--len >= 0)
+		*dst++ = fill;
+}

+ 6 - 0
lang/cem/libcc/gen/bmove.c

@@ -0,0 +1,6 @@
+bmove(dst, src, len)
+	char *dst, *src;
+	int len;
+{
+	bcopy(src, dst, len);
+}

+ 5 - 0
lang/cem/libcc/gen/bzero.c

@@ -0,0 +1,5 @@
+bzero(b, l)
+	register char *b;
+{
+	while (l-- > 0) *b++ = 0;
+}

+ 16 - 0
lang/cem/libcc/gen/calloc.c

@@ -0,0 +1,16 @@
+#define ALIGN(sz)	(((sz) + (sizeof(long) - 1) / sizeof(long)) * sizeof(long))
+char *
+calloc(nelem, elsize)
+	unsigned int nelem, elsize;
+{
+	register char *p;
+	register long *q;
+	unsigned int size = ALIGN(nelem * elsize);
+	extern char *malloc();
+
+	p = malloc(size);
+	if (p == 0) return 0;
+	q = (long *) (p + size);
+	while ((char *) q > p) *--q = 0;
+	return p;
+}

+ 14 - 0
lang/cem/libcc/gen/closedir.c

@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/dir.h>
+
+/*
+ * close a directory.
+ */
+closedir(dirp)
+register DIR *dirp;
+{
+	close(dirp->dd_fd);
+	dirp->dd_fd = -1;
+	dirp->dd_loc = 0;
+	free(dirp);
+}

+ 294 - 0
lang/cem/libcc/gen/crypt.c

@@ -0,0 +1,294 @@
+/*	From Andy Tanenbaum's book "Computer Networks",
+	rewritten in C
+*/
+
+struct block {
+	unsigned char b_data[64];
+};
+
+struct ordering {
+	unsigned char o_data[64];
+};
+
+static struct block key;
+
+static struct ordering InitialTr = {
+	58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
+	62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
+	57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
+	61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
+};
+
+static struct ordering FinalTr = {
+	40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
+	38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
+	36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
+	34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25,
+};
+
+static struct ordering swap = {
+	33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
+	49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
+	 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
+	17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
+};
+
+static struct ordering KeyTr1 = {
+	57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
+	10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
+	63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
+	14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4,
+};
+
+static struct ordering KeyTr2 = {
+	14,17,11,24, 1, 5, 3,28,15, 6,21,10,
+	23,19,12, 4,26, 8,16, 7,27,20,13, 2,
+	41,52,31,37,47,55,30,40,51,45,33,48,
+	44,49,39,56,34,53,46,42,50,36,29,32,
+};
+
+static struct ordering etr = {
+	32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
+	 8, 9,10,11,12,13,12,13,14,15,16,17,
+	16,17,18,19,20,21,20,21,22,23,24,25,
+	24,25,26,27,28,29,28,29,30,31,32, 1,
+};
+
+static struct ordering ptr = {
+	16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
+	 2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,
+};
+
+static unsigned char s_boxes[8][64] = {
+{	14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
+	 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
+	 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
+	15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
+},
+
+{	15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
+	 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
+	 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
+	13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
+},
+
+{	10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
+	13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
+	13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
+	 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
+},
+
+{	 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
+	13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
+	10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
+	 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
+},
+
+{	 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
+	14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
+	 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
+	11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
+},
+
+{	12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
+	10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
+	 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
+	 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
+},
+
+{	 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
+	13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
+	 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
+	 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
+},
+
+{	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
+	 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
+	 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
+	 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
+},
+};
+
+static int rots[] = {
+	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
+};
+
+static
+transpose(data, t, n)
+	register struct block *data;
+	register struct ordering *t;
+	register int n;
+{
+	struct block x;
+
+	x = *data;
+
+	while (n-- > 0) {
+		data->b_data[n] = x.b_data[t->o_data[n] - 1];
+	}
+}
+
+static
+rotate(key)
+	register struct block *key;
+{
+	register unsigned char *p = key->b_data;
+	register unsigned char *ep = &(key->b_data[55]);
+	int data0 = key->b_data[0], data28 = key->b_data[28];
+
+	while (p++ < ep) *(p-1) = *p;
+	key->b_data[27] = data0;
+	key->b_data[55] = data28;
+}
+
+static struct ordering *EP = &etr;
+
+static
+f(i, key, a, x)
+	struct block *key, *a;
+	register struct block *x;
+{
+	struct block e, ikey, y;
+	int k;
+	register unsigned char *p, *q, *r;
+
+	e = *a;
+	transpose(&e, EP, 48);
+	for (k = rots[i]; k; k--) rotate(key);
+	ikey = *key;
+	transpose(&ikey, &KeyTr2, 48);
+	p = &(y.b_data[48]);
+	q = &(e.b_data[48]);
+	r = &(ikey.b_data[48]);
+	while (p > y.b_data) {
+		*--p = *--q ^ *--r;
+	}
+	q = x->b_data;
+	for (k = 0; k < 8; k++) {
+		register int xb, r;
+
+		r = *p++ << 5;
+		r += *p++ << 3;
+		r += *p++ << 2;
+		r += *p++ << 1;
+		r += *p++;
+		r += *p++ << 4;
+
+		xb = s_boxes[k][r];
+
+		*q++ = (xb >> 3) & 1;
+		*q++ = (xb>>2) & 1;
+		*q++ = (xb>>1) & 1;
+		*q++ = (xb & 1);
+	}
+	transpose(x, &ptr, 32);
+}
+
+setkey(k)
+	register char *k;
+{
+
+	key = *((struct block *) k);
+	transpose(&key, &KeyTr1, 56);
+}
+
+encrypt(blck, edflag)
+	char *blck;
+{
+	register struct block *p = (struct block *) blck;
+	register int i;
+
+	transpose(p, &InitialTr, 64);
+	for (i = 15; i>= 0; i--) {
+		int j = edflag ? i : 15 - i;
+		register int k;
+		struct block b, x;
+
+		b = *p;
+		for (k = 31; k >= 0; k--) {
+			p->b_data[k] = b.b_data[k + 32];
+		}
+		f(j, &key, p, &x);
+		for (k = 31; k >= 0; k--) {
+			p->b_data[k+32] = b.b_data[k] ^ x.b_data[k];
+		}
+	}
+	transpose(p, &swap, 64);
+	transpose(p, &FinalTr, 64);
+}
+
+char *
+crypt(pw,salt)
+	register char *pw;
+	char *salt;
+{
+	/*	Unfortunately, I had to look at the sources of V7 crypt.
+		There was no other way to find out what this routine
+		actually does.
+	*/
+	
+	char pwb[66];
+	static char result[16];
+	register char *p = pwb;
+	struct ordering new_etr;
+	register int i;
+
+	while (*pw && p < &pwb[64]) {
+		register int j = 7;
+
+		while (j--) {
+			*p++ = (*pw >> j) & 01;
+		}
+		pw++;
+		*p++ = 0;
+	}
+	while (p < &pwb[64]) *p++ = 0;
+
+	setkey(p = pwb);
+
+	while (p < &pwb[66]) *p++ = 0;
+
+	new_etr = etr;
+	EP = &new_etr;
+	for (i = 0; i < 2; i++) {
+		register char c = *salt++;
+		register int j;
+
+		result[i] = c;
+		if ( c > 'Z') c -= 6 + 7 + '.';	/* c was a lower case letter */
+		else if ( c > '9') c -= 7 + '.';/* c was upper case letter */
+		else c -= '.';			/* c was digit, '.' or '/'. */
+						/* now, 0 <= c <= 63 */
+		for (j = 0; j < 6; j++) {
+			if ((c >> j) & 01) {
+				int t = 6*i + j;
+				int temp = new_etr.o_data[t];
+				new_etr.o_data[t] = new_etr.o_data[t+24];
+				new_etr.o_data[t+24] = temp;
+			}
+		}
+	}
+
+	if (result[1] == 0) result[1] = result[0];
+
+	for (i = 0; i < 25; i++) encrypt(pwb,0);
+	EP = &etr;
+
+	p = pwb;
+	pw = result+2;
+	while (p < &pwb[66]) {
+		register int c = 0;
+		register int j = 6;
+
+		while (j--) {
+			c <<= 1;
+			c |= *p++;
+		}
+		c += '.';		/* becomes >= '.' */
+		if (c > '9') c += 7;	/* not in [./0-9], becomes upper */
+		if (c > 'Z') c += 6;	/* not in [A-Z], becomes lower */
+		*pw++ = c;
+	}
+	*pw = 0;
+	return result;
+}

+ 11 - 0
lang/cem/libcc/gen/ctime.c

@@ -0,0 +1,11 @@
+#include <time.h>
+
+extern struct tm *localtime();
+extern char *asctime();
+
+char *
+ctime(clock)
+	long *clock;
+{
+	return asctime(localtime(clock));
+}

+ 102 - 0
lang/cem/libcc/gen/ecvt.c

@@ -0,0 +1,102 @@
+#ifndef NOFLOAT
+extern double modf();
+static char *cvt();
+#define NDIGITS	128
+
+char *
+ecvt(value, ndigit, decpt, sign)
+	double value;
+	int ndigit, *decpt, *sign;
+{
+	return cvt(value, ndigit, decpt, sign, 1);
+}
+
+char *
+fcvt(value, ndigit, decpt, sign)
+	double value;
+	int ndigit, *decpt, *sign;
+{
+	return cvt(value, ndigit, decpt, sign, 0);
+}
+
+static char *
+cvt(value, ndigit, decpt, sign, ecvtflag)
+	double value;
+	int ndigit, *decpt, *sign;
+{
+	double intpart, fractpart;
+	static char buf[NDIGITS];
+	char buf1[NDIGITS];
+	register char *pe = buf1;
+	register  char *pb = buf;
+	int pointpos = 0;
+
+
+	if (ndigit < 0) ndigit = 0;
+	if (ndigit >= NDIGITS - 1) ndigit = NDIGITS - 2;
+
+	*sign = 0;
+	if (value < 0) {
+		*sign = 1;
+		value = -value;
+	}
+
+	fractpart = modf(value, &intpart);
+	if (intpart != 0) {
+		do {	/* get digits of integer part, low order digit
+			   first
+			*/
+			value = modf(intpart/10, &intpart);
+			/* compensate for rounding errors, because
+			   the conversion to "int" truncates
+			*/
+			*pe++ = (int)((value+.05) * 10) + '0';
+			pointpos++;
+		} while (intpart != 0);
+		while (pe > buf1) *pb++ = *--pe;
+	}
+	else if (value > 0) {
+		fractpart = value;
+		while ((value = value*10) < 1) {
+			fractpart = value;
+			pointpos--;
+		}
+	}
+	pe = &buf[ndigit];
+	if (! ecvtflag) {
+		/* for fcvt() we need ndigit digits behind the dot */
+		pe += pointpos;
+		if (pe < buf) {
+			/* pointpos was too far left of the beginning */
+			buf[0] = 0;
+			*decpt = pointpos;
+			return buf;
+		}
+		if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
+	}
+	while (pb <= pe) {
+		fractpart = modf(fractpart * 10, &value);
+		*pb++ = (int)value + '0';
+	}
+	pe = pb;
+	*pb += 5;	/* round of at the end */
+	while (*pb > '9') {
+		*pb = '0';
+		if (pb > buf) ++*--pb;
+		else {
+			*pb = '1';
+			pointpos++;
+			if (! ecvtflag) {
+				/* maybe add another digit at the end,
+				   because the point was shifted right
+				*/
+				if (pe > buf) *pe = '0';
+				pe++;
+			}
+		}
+	}
+	*decpt = pointpos;
+	*pe = '\0';
+	return(buf);
+}
+#endif

+ 36 - 0
lang/cem/libcc/gen/execvp.c

@@ -0,0 +1,36 @@
+char    *getenv();
+char	*index();
+
+execlp(name, argv)
+char *name, *argv;
+{
+	return(execvp(name, &argv));
+}
+
+execvp(name, argv)
+char *name, **argv;
+{
+	char *path = getenv("PATH");
+	register char *c = "";
+	char progname[1024];
+
+	if (path == 0) path = ":/bin:/usr/bin";
+	if (! index(name, '/')) c = path;
+
+	do {
+		register char *p = progname;
+		register char *n = name;
+		char *c1 = c;
+
+		while (*c && *c != ':') {
+			*p++ = *c++;
+		}
+		if (c != c1) *p++ = '/';
+		if (*c) c++;
+		while (*n) *p++ = *n++;
+		*p = 0;
+
+		execv(progname, argv);
+	} while (*c);
+	return(-1);
+}

+ 10 - 0
lang/cem/libcc/gen/ffc.c

@@ -0,0 +1,10 @@
+ffc(i)
+	register int i;
+{
+	register int n;
+
+	for (n = 8*sizeof(int); n > 0; n--, i >>= 1)
+		if (!(i&1))
+			return (8*sizeof(int) + 1) - n;
+	return -1;
+}

+ 10 - 0
lang/cem/libcc/gen/ffs.c

@@ -0,0 +1,10 @@
+ffs(i)
+	register int i;
+{
+	register int n;
+
+	for (n = 8*sizeof(int); n > 0; n--, i >>= 1)
+		if ((i&1))
+			return (8*sizeof(int) + 1) - n;
+	return -1;
+}

+ 29 - 0
lang/cem/libcc/gen/frexp.e

@@ -0,0 +1,29 @@
+#
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ *          This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ *      Dr. Andrew S. Tanenbaum
+ *      Wiskundig Seminarium
+ *      Vrije Universiteit
+ *      Postbox 7161
+ *      1007 MC Amsterdam
+ *      The Netherlands
+ *
+ */
+
+ mes 2,EM_WSIZE,EM_PSIZE
+ exp $frexp
+ pro $frexp,0
+ lal 0
+ loi EM_DSIZE
+ fef EM_DSIZE
+ lal EM_DSIZE
+ loi EM_PSIZE
+ sti EM_WSIZE
+ ret EM_DSIZE
+ end

+ 61 - 0
lang/cem/libcc/gen/gcvt.c

@@ -0,0 +1,61 @@
+#ifndef NOFLOAT
+extern char	*ecvt();
+
+#define NDIGINEXP	2
+
+char *
+gcvt(value, ndigit, buf)
+	double value;
+	char *buf;
+	register int ndigit;
+{
+	int sign, dp;
+	register char *s1, *s2;
+	register int i;
+
+	s1 = ecvt(value, ndigit, &dp, &sign);
+	s2 = buf;
+	if (sign) *s2++ = '-';
+	for (i = ndigit - 1; i > 0 && s1[i] == '0'; i--) ndigit--;
+	if (dp - ndigit > NDIGINEXP + 2 || dp < -NDIGINEXP - 1) {
+		/* Use E format, otherwise we need too many '0''s */
+		dp--;
+		*s2++ = *s1++;
+		*s2++ = '.';
+		while (--ndigit > 0) *s2++ = *s1++;
+		*s2++ = 'e';
+		if (dp < 0) {
+			*s2++ = '-';
+			dp = -dp;
+		}
+		else	 *s2++ = '+';
+		s2 += NDIGINEXP;
+		for (i = NDIGINEXP; i > 0; i--) {
+			*--s2 = dp % 10 + '0';
+			dp /= 10;
+		}
+		return buf;
+	}
+	if (dp <= 0) {
+		if (*s1 != '0')	{
+			/* otherwise the whole number is 0 */
+			*s2++ = '.';
+		}
+		while (dp < 0) {
+			dp++;
+			*s2++ = '0';
+		}
+	}
+	for (i = 1; i <= ndigit; i++) {
+		*s2++ = *s1++;
+		if (i == dp) *s2++ = '.';
+	}
+	if (i <= dp) {
+		while (i++ <= dp) *s2++ = '0';
+		*s2++ = '.';
+	}
+	if (s2[-1]=='.') s2--;
+	*s2 = '\0';
+	return buf;
+}
+#endif

+ 14 - 0
lang/cem/libcc/gen/getenv.c

@@ -0,0 +1,14 @@
+char *getenv(name)
+register char *name;
+{
+  extern char **environ;
+  register char **v = environ, *p, *q;
+
+  while ((p = *v++) != 0) {
+	q = name;
+	while (*q && *q++ == *p++) /* nothing */ ;
+	if (*q || *p != '=') continue;
+	return(p);
+  }
+  return(0);
+}

+ 26 - 0
lang/cem/libcc/gen/getlogin.c

@@ -0,0 +1,26 @@
+#define UTMPFILE "/etc/utmp"
+
+/* some systems require inclusion of sys/types.h before utmp.h */
+#include <sys/types.h>
+#include <utmp.h>
+
+char *
+getlogin()
+{
+	struct utmp ut;
+	static char name[sizeof(ut.ut_name) + 1];
+	int	slotno = ttyslot();
+	int	fd;
+	register char *p, *q;
+
+	if (! slotno || !(fd = open(UTMPFILE, 0))) return 0;
+	lseek(fd, (long) slotno * sizeof(ut), 0);
+	if (read(fd, (char *) &ut, sizeof(ut)) < sizeof(ut)) return 0;
+	close(fd);
+	ut.ut_name[sizeof(ut.ut_name)] = ' ';
+	p = ut.ut_name;
+	q = name;
+	while (*p != ' ') *q++ = *p++;
+	*q = '\0';
+	return name;
+}

+ 57 - 0
lang/cem/libcc/gen/getopt.c

@@ -0,0 +1,57 @@
+#include	<stdio.h>
+#define ERR(s, c)       if(opterr){\
+	fputs(argv[0], stderr);\
+	fputs(s, stderr);\
+	fputc(c, stderr);\
+	fputc('\n', stderr);}
+
+int     opterr = 1;
+int     optind = 1;
+int	optopt;
+char    *optarg;
+char    *index();
+
+int
+getopt (argc, argv, opts)
+char **argv, *opts;
+{
+	static int sp = 1;
+	register c;
+	register char *cp;
+
+	if (sp == 1)
+		if (optind >= argc ||
+		   argv[optind][0] != '-' || argv[optind][1] == '\0')
+			return EOF;
+		else if (strcmp(argv[optind], "--") == NULL) {
+			optind++;
+			return EOF;
+		}
+	optopt = c = argv[optind][sp];
+	if (c == ':' || (cp=index(opts, c)) == NULL) {
+		ERR (": illegal option -- ", c);
+		if (argv[optind][++sp] == '\0') {
+			optind++;
+			sp = 1;
+		}
+		return '?';
+	}
+	if (*++cp == ':') {
+		if (argv[optind][sp+1] != '\0')
+			optarg = &argv[optind++][sp+1];
+		else if (++optind >= argc) {
+			ERR (": option requires an argument -- ", c);
+			sp = 1;
+			return '?';
+		} else
+			optarg = argv[optind++];
+		sp = 1;
+	} else {
+		if (argv[optind][++sp] == '\0') {
+			sp = 1;
+			optind++;
+		}
+		optarg = NULL;
+	}
+	return c;
+}

+ 39 - 0
lang/cem/libcc/gen/gmtime.c

@@ -0,0 +1,39 @@
+#include <time.h>
+
+static int monthsize[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+#define SECS_DAY 24*60L*60L
+#define YEARSIZE(year)	((year) % 4 ? 365 : 366)
+
+struct tm *
+gmtime(clock)
+	long *clock;
+{
+	unsigned long cl = *clock;
+	long dayclock, dayno;
+	struct tm tm_buf;
+	register struct tm *pbuf = &tm_buf;
+	register int *months = monthsize;
+	int year = 1970;
+
+	dayclock = cl % SECS_DAY;
+	dayno = cl / SECS_DAY;
+
+	pbuf->tm_sec = dayclock % 60;
+	pbuf->tm_min = (dayclock % 3600) / 60;
+	pbuf->tm_hour = dayclock / 3600;
+	pbuf->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */
+	while (dayno >= YEARSIZE(year)) {
+		dayno -= YEARSIZE(year);
+		year++;
+	}
+	pbuf->tm_year = year;
+	pbuf->tm_yday = dayno;
+	pbuf->tm_isdst = 0;
+	if (YEARSIZE(year) == 366) monthsize[1] = 29;
+	while (dayno - *months >= 0) dayno -= *months++;
+	pbuf->tm_mday = dayno + 1;
+	pbuf->tm_mon = months - monthsize;
+	monthsize[1] = 28;
+	return pbuf;
+}

+ 9 - 0
lang/cem/libcc/gen/index.c

@@ -0,0 +1,9 @@
+char *index(s, c)
+register char *s, c;
+{
+  do {
+	if (*s == c)
+		return(s);
+  } while (*s++ != 0);
+  return(0);
+}

+ 9 - 0
lang/cem/libcc/gen/isatty.c

@@ -0,0 +1,9 @@
+#include <sgtty.h>
+
+isatty(f)
+{
+	struct sgttyb ttyb;
+
+	if (gtty(f, &ttyb) < 0) return 0;
+	return 1;
+}

+ 24 - 0
lang/cem/libcc/gen/l3.c

@@ -0,0 +1,24 @@
+ltol3(cp, lp, n)
+register char	*cp;
+register long	*lp;
+register int	n;
+{
+	while (n-- > 0) {
+		*cp++ = (*lp >> 16);
+		*cp++ = (*lp > 8);
+		*cp++ = *lp;
+	}
+}
+
+l3tol(lp, cp, n)
+register long	*lp;
+char	*cp;
+register int	n;
+{
+	unsigned char *a = (unsigned char *) cp;
+
+	while (n-- > 0) {
+		*lp++ = ((long)(*a)<<16) + ((long)(*(a+1)) << 8) + *(a+2);
+		a += 3;
+	}
+}

+ 34 - 0
lang/cem/libcc/gen/ldexp.c

@@ -0,0 +1,34 @@
+#ifndef NOFLOAT
+extern double frexp();
+
+double
+ldexp(fl,exp)
+	double fl;
+	int exp;
+{
+	int sign = 1;
+	int currexp;
+
+	if (fl<0) {
+		fl = -fl;
+		sign = -1;
+	}
+	fl = frexp(fl,&currexp);
+	exp += currexp;
+	if (exp > 0) {
+		while (exp>30) {
+			fl *= (double) (1L << 30);
+			exp -= 30;
+		}
+		fl *= (double) (1L << exp);
+	}
+	else	{
+		while (exp<-30) {
+			fl /= (double) (1L << 30);
+			exp += 30;
+		}
+		fl /= (double) (1L << -exp);
+	}
+	return sign * fl;
+}
+#endif

+ 52 - 0
lang/cem/libcc/gen/localtime.c

@@ -0,0 +1,52 @@
+#include <time.h>
+
+#define YEARSIZE(year)	((year) % 4 ? 365 : 366)
+#define FIRSTSUNDAY(t)	(((t)->tm_yday - (t)->tm_wday + 420) % 7)
+#define SUNDAY(day, t)	((day) < 58 ? \
+			  ((day) < FIRSTSUNDAY(t) ? FIRSTSUNDAY(t) :
+static int
+last_sunday(d, t)
+	register int d;
+	register struct tm *t;
+{
+	int first = FIRSTSUNDAY(t);
+
+	if (d >= 58 && YEARSIZE(t->tm_year)) d++;
+	if (d < first) return first;
+	return d - (d - first) % 7;
+}
+
+struct tm *
+localtime(clock)
+	long *clock;
+{
+	register struct tm *gmt;
+	long cl;
+	int begindst, enddst;
+	extern int daylight;
+	extern long timezone;
+
+	tzset();
+	cl = *clock - timezone;
+	gmt = gmtime(&cl);
+	if (daylight) {
+		/* daylight saving time.
+		   Unfortunately, rules differ for different countries.
+		   Implemented here are heuristics that got it right
+		   in Holland, over the last couple of years.
+		   Of course, there is no algorithm. It is all
+		   politics ...
+		*/
+		begindst = last_sunday(89, gmt); /* last Sun before Apr */
+		enddst = last_sunday(272, gmt);  /* last Sun in Sep */
+	    	if ((gmt->tm_yday>begindst ||
+		     (gmt->tm_yday==begindst && gmt->tm_hour>=2)) &&
+	    	    (gmt->tm_yday<enddst || 
+		     (gmt->tm_yday==enddst && gmt->tm_hour<3))) {
+			cl += 1*60*60;
+			gmt = gmtime(&cl);
+			gmt->tm_isdst++;
+		}
+	}
+	return gmt;
+}

+ 99 - 0
lang/cem/libcc/gen/malloc.c

@@ -0,0 +1,99 @@
+
+#define CLICK_SIZE	16
+#if EM_WSIZE == EM_PSIZE
+typedef unsigned int vir_bytes;
+#else
+typedef long vir_bytes;
+#endif
+extern bcopy();
+
+#define ALIGN(x, a)	(((x) + (a - 1)) & ~(a - 1))
+#define BUSY		1
+#define NEXT(p)		(* (char **) (p))
+
+#ifdef pdp11
+#define BUGFIX	64
+#else
+#define BUGFIX	0
+#endif
+
+extern char *sbrk();
+static char *bottom, *top;
+
+static grow(len)
+unsigned len;
+{
+  register char *p;
+
+  p = (char *) ALIGN((vir_bytes) top + sizeof(char *) + len, CLICK_SIZE)
+							+ BUGFIX
+							- sizeof(char *);
+  if (p < top || brk(p - BUGFIX) < 0)
+	return(0);
+  top = p;
+  for (p = bottom; NEXT(p) != 0; p = (char *) (* (vir_bytes *) p & ~BUSY))
+	;
+  NEXT(p) = top;
+  NEXT(top) = 0;
+  return(1);
+}
+
+char *malloc(size)
+unsigned size;
+{
+  register char *p, *next, *new;
+  register unsigned len = ALIGN(size, sizeof(char *)) + sizeof(char *);
+
+  if ((p = bottom) == 0) {
+	top = bottom = p = sbrk(sizeof(char *));
+	NEXT(top) = 0;
+  }
+  while ((next = NEXT(p)) != 0)
+	if ((vir_bytes) next & BUSY)			/* already in use */
+		p = (char *) ((vir_bytes) next & ~BUSY);
+	else {
+		while ((new = NEXT(next)) != 0 && !((vir_bytes) new & BUSY))
+			next = new;
+		if (next - p >= len) {			/* fits */
+			if ((new = p + len) < next)	/* too big */
+				NEXT(new) = next;
+			NEXT(p) = (char *) ((vir_bytes) new | BUSY);
+			return(p + sizeof(char *));
+		}
+		p = next;
+	}
+  return grow(len) ? malloc(size) : 0;
+}
+
+char *realloc(old, size)
+char *old;
+unsigned size;
+{
+  register char *p = old - sizeof(char *), *next, *new;
+  register unsigned len = ALIGN(size, sizeof(char *)) + sizeof(char *), n;
+
+  next = (char *) (* (vir_bytes *) p & ~BUSY);
+  n = next - old;					/* old size */
+  while ((new = NEXT(next)) != 0 && !((vir_bytes) new & BUSY))
+	next = new;
+  if (next - p >= len) {				/* does it still fit */
+	if ((new = p + len) < next) {			/* even too big */
+		NEXT(new) = next;
+		NEXT(p) = (char *) ((vir_bytes) new | BUSY);
+	}
+	else
+		NEXT(p) = (char *) ((vir_bytes) next | BUSY);
+	return(old);
+  }
+  if ((new = malloc(size)) == 0)			/* it didn't fit */
+	return(0);
+  bcopy(old, new, n);					/* n < size */
+  * (vir_bytes *) p &= ~BUSY;
+  return(new);
+}
+
+free(p)
+char *p;
+{
+  * (vir_bytes *) (p - sizeof(char *)) &= ~BUSY;
+}

+ 11 - 0
lang/cem/libcc/gen/memccpy.c

@@ -0,0 +1,11 @@
+char *
+memccpy(dst, src, c, n)
+	register char *dst, *src;
+	register int n;
+{
+	while (n-- > 0) {
+		if ((*dst++ = *src++) == c) return (char *) dst;
+	}
+
+	return 0;
+}

+ 14 - 0
lang/cem/libcc/gen/memchr.c

@@ -0,0 +1,14 @@
+char *
+memchr(s, c, n)
+char *s;
+register int n;
+{
+	register unsigned char *s1 = (unsigned char *) s;
+	
+	c &= 0377;
+	while (n-- > 0) {
+		if (*s1 == c) return (char *) s1;
+		s1++;
+	}
+	return 0;
+}

+ 15 - 0
lang/cem/libcc/gen/memcmp.c

@@ -0,0 +1,15 @@
+int
+memcmp(s1, s2, n)
+register char *s1, *s2;
+{
+/* Compare 2 strings. */
+
+  while (n-- > 0)
+	if (*s1 != *s2) {
+		return(*s1 - *s2);
+	}
+	s1++;
+	s2++;
+  }
+  return 0;
+}

+ 16 - 0
lang/cem/libcc/gen/memcpy.c

@@ -0,0 +1,16 @@
+char *
+memcpy(s1, s2, n)
+register char *s1, *s2;
+register int n;
+{
+/* Copy a block of data. */
+
+	char *ret = s1;
+
+	if (s2 <= s1 && s2 + (n-1) >= s1) {
+		s1 += n; s2 += n;
+		while (n-- > 0) *--s1 = *--s2;
+	}
+	else	while (n-- > 0) *s1++ = *s2++;
+	return ret;
+}

+ 12 - 0
lang/cem/libcc/gen/memset.c

@@ -0,0 +1,12 @@
+char *
+memset(s, c, n)
+	char *s;
+	register int n;
+{
+	register char *s1 = s;
+
+	while (n--) {
+		*s1++ = c;
+	}
+	return(s);
+}

+ 26 - 0
lang/cem/libcc/gen/mktemp.c

@@ -0,0 +1,26 @@
+/* mktemp - make a name for a temporary file */
+
+char *mktemp(template)
+char *template;
+{
+  register int pid, k;
+  register char *p;
+
+  pid = getpid();		/* get process id as semi-unique number */
+  p = template;
+  while (*p) p++;		/* find end of string */
+
+  /* Replace XXXXXX at end of template with pid. */
+  while (*--p == 'X') {
+	*p = '0' + (pid % 10);
+	pid /= 10;
+  }
+  p++;
+  for (k = 'a'; k <= 'z'; k++) {
+	*p = k;
+	if (access(template, 0) < 0) {
+		return template;
+	}
+  }
+  return("/");
+}

+ 33 - 0
lang/cem/libcc/gen/modf.e

@@ -0,0 +1,33 @@
+#
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ *          This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ *      Dr. Andrew S. Tanenbaum
+ *      Wiskundig Seminarium
+ *      Vrije Universiteit
+ *      Postbox 7161
+ *      1007 MC Amsterdam
+ *      The Netherlands
+ *
+ */
+
+ mes 2,EM_WSIZE,EM_PSIZE
+ exp $modf
+ pro $modf,0
+ lal 0
+ loi EM_DSIZE
+ loc 1
+ loc EM_WSIZE
+ loc EM_DSIZE
+ cif
+ fif EM_DSIZE
+ lal EM_DSIZE
+ loi EM_PSIZE
+ sti EM_DSIZE
+ ret EM_DSIZE
+ end

+ 62 - 0
lang/cem/libcc/gen/monitor.c

@@ -0,0 +1,62 @@
+static int bs;
+static char *bp;
+static char *bufp;
+static int sc;
+static int bufs;
+
+monitor(lowpc, highpc, buffer, bufsize, nfunc)
+	int (*lowpc)(), (*highpc)();
+	char *buffer;
+{
+	long scale;
+
+	if (lowpc == 0) {
+		int fd;
+
+		profil((char *) 0, 0, 0, 0);
+		if ((fd = creat("mon.out", 0666)) < 0 || !bp) return;
+		write(fd, bp, (int) bs);
+		close(fd);
+		return;
+	}
+
+	bs = bufsize << 1;
+	bp = buffer;
+
+	*(char **) buffer = (char *) lowpc;
+	buffer += sizeof(char *);
+	*(char **) buffer = (char *) highpc;
+	buffer += sizeof(char *);
+	*(short *) buffer = nfunc;
+	buffer += 2;
+	buffer += (sizeof (char *) + sizeof(long)) * nfunc;
+	bufsize -= ((sizeof (char *) + sizeof(long)) * nfunc + 2 * sizeof(char *) + sizeof(int)) >> 1;
+	if (bufsize < 0) return;
+	scale = ((char *) highpc - (char *) lowpc) >> 1;
+	if (bufsize < scale)
+		scale = ((long) bufsize << 15) / scale;
+	else	scale = 0x7fff;
+	bufp = buffer;
+	sc = scale << 1;
+	bufs = bufsize << 1;
+	profil(buffer, bufs, lowpc, sc);
+}
+
+moncontrol(mode)
+{
+	profil(bs, bufs, *(char **) bufp, !mode ? 0 : sc);
+}
+
+#define NCOUNTS 300
+
+monstartup(lowpc, highpc)
+	int (*lowpc)(), (*highpc)();
+{
+	int sz = (((char *) highpc - (char *) lowpc + 7) & ~7) << 1;
+	char *s, *sbrk();
+
+	sz += NCOUNTS * (sizeof(long) + sizeof(char *)) + 2 * sizeof(char *) + sizeof(int);
+	s = sbrk(sz);
+	if ((int) s == -1) return;
+	monitor(lowpc, highpc, s, sz >> 1, NCOUNTS);
+}

+ 27 - 0
lang/cem/libcc/gen/opendir.c

@@ -0,0 +1,27 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+
+/*
+ * open a directory.
+ */
+DIR *opendir(name)
+char *name;
+{
+	register DIR *dirp;
+	register int fd;
+	struct stat stbuf;
+	extern char *malloc();
+
+	if ((fd = open(name, 0)) == -1)
+		return NULL;
+	fstat(fd, &stbuf);
+	if (((stbuf.st_mode & S_IFDIR) == 0) ||
+	    ((dirp = (DIR *)malloc(sizeof (DIR))) == NULL)) {
+		close (fd);
+		return NULL;
+	}
+	dirp->dd_fd = fd;
+	dirp->dd_loc = 0;
+	return dirp;
+}

+ 57 - 0
lang/cem/libcc/gen/perror.c

@@ -0,0 +1,57 @@
+/* perror(s) print the current error message. */
+
+extern int errno;
+char *sys_errlist[] = {
+        "Error 0",
+        "Not owner",
+        "No such file or directory",
+        "No such process",
+        "Interrupted system call",
+        "I/O error",
+        "No such device or address",
+        "Arg list too long",
+        "Exec format error",
+        "Bad file number",
+        "No children",
+        "No more processes",
+        "Not enough core",
+        "Permission denied",
+        "Bad address",
+        "Block device required",
+        "Mount device busy",
+        "File exists",
+        "Cross-device link",
+        "No such device",
+        "Not a directory",
+        "Is a directory",
+        "Invalid argument",
+        "File table overflow",
+        "Too many open files",
+        "Not a typewriter",
+        "Text file busy",
+        "File too large",
+        "No space left on device",
+        "Illegal seek",
+        "Read-only file system",
+        "Too many links",
+        "Broken pipe",
+        "Math argument",
+        "Result too large"
+};
+
+int	sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]);
+
+perror(s)
+	char *s;
+{
+  	char *c;
+  	if (errno < 0 || errno >= sizeof(sys_errlist) / sizeof(char *)) {
+		c = "unknown error";
+  	} else {
+		c = sys_errlist[errno];
+  	}
+	write(2, s, strlen(s));
+	write(2, ": ", 2);
+	write(2, c, strlen(c));
+	write(2, "\n", 1);
+}

+ 42 - 0
lang/cem/libcc/gen/procentry.c

@@ -0,0 +1,42 @@
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ *          This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ *      Dr. Andrew S. Tanenbaum
+ *      Wiskundig Seminarium
+ *      Vrije Universiteit
+ *      Postbox 7161
+ *      1007 MC Amsterdam
+ *      The Netherlands
+ *
+ */
+
+/* Author: E.G. Keizer */
+
+static int level = 0 ;
+static wrs() ;
+procentry(name) char *name ; {
+	register int count ;
+
+	count=level++ ;
+	while ( count-- ) {
+		wrs("  ") ;
+	}
+	wrs("Entering ");wrs(name);wrs("\n") ;
+}
+procexit(name) char *name ; {
+	register int count ;
+
+	count= --level ;
+	while ( count-- ) {
+		wrs("  ") ;
+	}
+	wrs("Leaving  ");wrs(name);wrs("\n") ;
+}
+static wrs(s) register char *s ; {
+	write(2,s,strlen(s)) ;
+}

+ 133 - 0
lang/cem/libcc/gen/qsort.c

@@ -0,0 +1,133 @@
+static	qsort1();
+static	int (*qcompar)();
+static	qexchange();
+static	q3exchange();
+
+qsort(base, nel, width, compar)
+	char *base;
+	int (*compar)();
+{
+	qcompar = compar;
+	qsort1(base, base + (nel - 1) * width, width);
+}
+
+static
+qsort1(a1, a2, width)
+	char *a1, *a2;
+	register int width;
+{
+	register char *left, *right;
+	register char *lefteq, *righteq;
+	int cmp;
+
+	for (;;) {
+		if (a2 <= a1) return;
+		left = a1;
+		right = a2;
+		lefteq = righteq = a1 + width * (((a2-a1)+width)/(2*width));
+		/*
+		   Pick an element in the middle of the array.
+		   We will collect the equals around it.
+		   "lefteq" and "righteq" indicate the left and right
+		   bounds of the equals respectively.
+		   Smaller elements end up left of it, larger elements end
+		   up right of it.
+		*/
+again:
+		while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0) {
+			if (cmp < 0) {
+				/* leave it where it is */
+				left += width;
+			}
+			else {
+				/* equal, so exchange with the element to
+				   the left of the "equal"-interval.
+				*/
+				lefteq -= width;
+				qexchange(left, lefteq, width);
+			}
+		}
+		while (right > righteq) {
+			if ((cmp = (*qcompar)(right, righteq)) < 0) {
+				/* smaller, should go to left part
+				*/
+				if (left < lefteq) {
+					/* yes, we had a larger one at the
+					   left, so we can just exchange
+					*/
+					qexchange(left, right, width);
+					left += width;
+					right -= width;
+					goto again;
+				}
+				/* no more room at the left part, so we
+				   move the "equal-interval" one place to the
+				   right, and the smaller element to the
+				   left of it.
+				   This is best expressed as a three-way
+				   exchange.
+				*/
+				righteq += width;
+				q3exchange(left, righteq, right, width);
+				lefteq += width;
+				left = lefteq;
+			}
+			else if (cmp == 0) {
+				/* equal, so exchange with the element to
+				   the right of the "equal-interval"
+				*/
+				righteq += width;
+				qexchange(right, righteq, width);
+			}
+			else	/* just leave it */ right -= width;
+		}
+		if (left < lefteq) {
+			/* larger element to the left, but no more room,
+			   so move the "equal-interval" one place to the
+			   left, and the larger element to the right
+			   of it.
+			*/
+			lefteq -= width;
+			q3exchange(right, lefteq, left, width);
+			righteq -= width;
+			right = righteq;
+			goto again;
+		}
+		/* now sort the "smaller" part */
+		qsort1(a1, lefteq - width, width);
+		/* and now the larger, saving a subroutine call
+		   because of the for(;;)
+		*/
+		a1 = righteq + width;
+	}
+	/*NOTREACHED*/
+}
+
+static
+qexchange(p, q, n)
+	register char *p, *q;
+	register int n;
+{
+	register int c;
+
+	while (n-- > 0) {
+		c = *p;
+		*p++ = *q;
+		*q++ = c;
+	}
+}
+
+static
+q3exchange(p, q, r, n)
+	register char *p, *q, *r;
+	register int n;
+{
+	register int c;
+
+	while (n-- > 0) {
+		c = *p;
+		*p++ = *r;
+		*r++ = *q;
+		*q++ = c;
+	}
+}

+ 13 - 0
lang/cem/libcc/gen/rand.c

@@ -0,0 +1,13 @@
+static long seed = 1L;
+
+int rand()
+{
+  seed = (1103515245L * seed + 12345) & 0x7FFFFFFF;
+  return((int) ((seed >> 8) & 077777));
+}
+
+srand(n)
+  unsigned n;
+{
+  seed = n;
+}

+ 64 - 0
lang/cem/libcc/gen/readdir.c

@@ -0,0 +1,64 @@
+#include <sys/types.h>
+#include <sys/dir.h>
+
+#ifndef BSD4_2
+/*
+ * read an old stlye directory entry and present it as a new one
+ */
+#define	ODIRSIZ	14
+
+struct	olddirect {
+	ino_t	od_ino;
+	char	od_name[ODIRSIZ];
+};
+#else
+#define olddirect direct
+#endif
+
+/*
+ * get next entry in a directory.
+ */
+struct direct *readdir(dirp)
+register DIR *dirp;
+{
+	register struct olddirect *dp;
+	static struct direct dir;
+
+	for (;;) {
+		if (dirp->dd_loc == 0) {
+			dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
+					     DIRBLKSIZ);
+			if (dirp->dd_size <= 0) {
+				dirp->dd_size = 0;
+				return NULL;
+			}
+#ifdef BSD4_2
+			if (! ((struct direct *) dirp->dd_buf)->d_ino) {
+				dirp->dd_loc += ((struct direct *)dirp->dd_buf)->d_reclen;
+			}
+#endif
+		}
+		if (dirp->dd_loc >= dirp->dd_size) {
+			dirp->dd_loc = 0;
+			continue;
+		}
+		dp = (struct olddirect *) (dirp->dd_buf + dirp->dd_loc);
+#ifndef BSD4_2
+		dirp->dd_loc += sizeof (struct olddirect);
+		if (dp->od_ino == 0)
+			continue;
+		dir.d_ino = dp->od_ino;
+		strncpy(dir.d_name, dp->od_name, ODIRSIZ);
+		dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
+		dir.d_reclen = DIRSIZ(&dir);
+		dir.d_namlen = strlen(dir.d_name);
+#else
+		dirp->dd_loc += dp->d_reclen;
+		dir.d_ino = dp->d_ino;
+		strcpy(dir.d_name, dp->d_name);
+		dir.d_reclen = dp->d_reclen;
+		dir.d_namlen = dp->d_namlen;
+#endif
+		return &dir;
+	}
+}

+ 12 - 0
lang/cem/libcc/gen/rindex.c

@@ -0,0 +1,12 @@
+char *rindex(s, c)
+register char *s, c;
+{
+  register char *result;
+
+  result = 0;
+  do
+	if (*s == c)
+		result = s;
+  while (*s++ != 0);
+  return(result);
+}

+ 37 - 0
lang/cem/libcc/gen/seekdir.c

@@ -0,0 +1,37 @@
+#include <sys/types.h>
+#include <sys/dir.h>
+
+/*
+ * seek to an entry in a directory.
+ * Only values returned by "telldir" should be passed to seekdir.
+ */
+seekdir(dirp, loc)
+register DIR *dirp;
+long loc;
+{
+	long curloc, base, offset;
+	extern long telldir();
+	extern struct direct *readdir();
+
+	curloc = telldir(dirp);
+	if (loc == curloc)
+		return;
+	base = loc & ~(DIRBLKSIZ - 1);
+	offset = loc & (DIRBLKSIZ - 1);
+	if (dirp->dd_loc != 0 && offset != 0 &&
+	    (curloc & ~(DIRBLKSIZ-1)) ==  base) {
+		dirp->dd_loc = offset;
+		return;
+	}
+	(void) lseek(dirp->dd_fd, base, 0);
+	dirp->dd_loc = 0;
+	dirp->dd_size = 0;
+	if (offset == 0)
+		(void) readdir(dirp);
+	else {
+		while (dirp->dd_loc < offset) {
+			if (readdir(dirp) == (struct direct *) 0)
+				return;
+		}
+	}
+}

+ 147 - 0
lang/cem/libcc/gen/setjmp.e

@@ -0,0 +1,147 @@
+#
+ mes 2,EM_WSIZE,EM_PSIZE
+
+ exp $setjmp
+ pro $setjmp,2*EM_WSIZE
+
+; setjmp saves the StackPointer and the LocalBase, and the chunk of
+; memory between the StackPointer and the ArgumentBase, + its size in a
+; buffer, pointed to by the parameter.
+; longjump can then restore this buffer and return.
+; Notice that this does not work on EM implementations in which every
+; procedure frame has a different fragment in memory, because in this case
+; the ArgumentBase will point into the fragment of the caller.
+; What really is needed is a way to find out the size of the return
+; status block.
+; On EM-implementations in which the stack grows upwards it is untested,
+; as there are no such implementations available now.
+; This implementation of setjmp/longjmp
+; depends on the assumption that the routine calling
+; setjmp does not have register variables, and that it saves all registers
+; that are available for variables.
+
+ loc 0
+ stl -2*EM_WSIZE
+ lor 1		; load StackPointer
+ lal 0
+ loi EM_PSIZE
+ sti EM_PSIZE	; save it
+ lxl 0		; load LocalBase
+ lal 0
+ loi EM_PSIZE
+ adp EM_PSIZE
+ sti EM_PSIZE	; save it
+ lxa 0		; load ArgumentBase
+ lal 0
+ loi EM_PSIZE
+ loi EM_PSIZE	; load saved StackPointer
+ sbs EM_WSIZE	; gives size of block that is to be saved, or negative size
+ dup EM_WSIZE
+ zgt *5
+ ngi EM_WSIZE
+ loc 1
+ stl -2*EM_WSIZE; one if the stack grows upwards
+5
+ stl -EM_WSIZE	; save size of block in local
+ lol -EM_WSIZE
+ lal 0
+ loi EM_PSIZE
+ adp 2*EM_PSIZE
+ sti EM_WSIZE	; and also in the buffer
+ lal 0
+ loi EM_PSIZE
+ loi EM_PSIZE	; load saved StackPointer
+ lol -2*EM_WSIZE; positive if the stack grows upwards
+ zle *6
+ asp EM_PSIZE
+ lxa 0
+ adp EM_WSIZE	; in this case the source address = ArgumentBase+EM_WSIZE
+6
+ lal 0
+ loi EM_PSIZE
+ adp 2*EM_PSIZE+EM_WSIZE
+		; destination address
+ lol -EM_WSIZE	; count
+ bls EM_WSIZE	; block copy
+ loc 0
+ ret EM_WSIZE
+ end 2*EM_WSIZE
+
+ exp $longjmp
+ pro $longjmp,2*EM_WSIZE
+
+; first, find out wether the stack grows upwards
+ loc 0
+ stl -2*EM_WSIZE
+ lxa 0
+ lxl 0
+ cmp
+ zge *7
+ loc 1
+ stl -2*EM_WSIZE; this local contains 1 if it does, otherwise it contains 0
+7
+; then, adjust StackPointer until it is below the saved StackPointer (or
+; above if it grows upwards)
+; then push parameters
+; then copy the saved block in its proper place
+; notice that the parameters can not be used anymore now
+; then restore the LocalBase and the Stackpointer and return.
+1
+ loc 0
+2
+ lor 1
+ lal 0
+ loi EM_PSIZE
+ loi EM_PSIZE	; saved StackPointer
+ cmp		; compare with current one
+ lol -2*EM_WSIZE
+ zle *8
+ zlt *1
+ bra *10
+8
+ zgt *1
+10
+ lal 0
+ loi EM_PSIZE
+ loi EM_PSIZE	; push saved StackPointer
+ lol EM_PSIZE	; push value to be returned by longjmp
+ lal 0
+ loi EM_PSIZE
+ adp EM_PSIZE
+ loi EM_PSIZE	; push saved LocalBase
+ lal 0
+ loi EM_PSIZE
+ adp 2*EM_PSIZE+EM_WSIZE
+		; source address
+ lal 0
+ loi EM_PSIZE
+ loi EM_PSIZE	; saved stackpointer
+ lol -2*EM_WSIZE
+ zle *9		; if not positive, this is the destination address,
+		; otherwise subtract the size of the saved area and add EM_WSIZE
+ adp EM_WSIZE
+ lal 0
+ loi EM_PSIZE
+ adp 2*EM_PSIZE
+ loi EM_WSIZE
+ ngi EM_WSIZE
+ ads EM_WSIZE
+9		; destination address
+ lal 0
+ loi EM_PSIZE
+ adp 2*EM_PSIZE
+ loi EM_WSIZE	; size
+ bls EM_WSIZE	; now we have a frame exactly as it was in setjmp,
+		; and exactly at the same place
+ str 0		; restore LocalBase
+ stl -EM_WSIZE	; saves the return value
+ str 1		; restores the StackPointer
+ lol -EM_WSIZE
+ dup EM_WSIZE
+ zne *3
+		; of course, longjmp may not return 0!
+ asp EM_WSIZE
+ loc 1
+3
+ ret EM_WSIZE
+ end 2*EM_WSIZE

+ 38 - 0
lang/cem/libcc/gen/sleep.c

@@ -0,0 +1,38 @@
+#include <signal.h>
+#include <setjmp.h>
+
+static jmp_buf	setjmpbuf;
+
+static
+alfun(){
+	longjmp(setjmpbuf, 1);
+}		/* used with sleep() below */
+
+sleep(n)
+	int n;
+{
+/* sleep(n) pauses for 'n' seconds by scheduling an alarm interrupt. */
+	unsigned oldalarm;
+	int (*oldsig)();
+
+  if (n <= 0) return;
+  if (setjmp(setjmpbuf)) {
+	signal(SIGALRM, oldsig);
+	alarm(oldalarm);
+	return;
+  }
+  oldalarm = alarm(5000);	/* Who cares how long, as long as it is long
+				   enough
+				*/
+  if (oldalarm > n) oldalarm -= n;
+  else {
+	n = oldalarm;
+	oldalarm = 1;
+  }
+  oldsig = signal(SIGALRM, alfun);
+  alarm(n);
+  for (;;)  {
+	/* allow for other handlers ... */
+	pause();
+  }
+}

+ 11 - 0
lang/cem/libcc/gen/stb.c

@@ -0,0 +1,11 @@
+/* $Header$ */
+/* library routine for copying structs */
+
+__stb(n, f, t)
+	register char *f, *t; register n;
+{
+	if (n > 0)
+		do
+			*t++ = *f++;
+		while (--n);
+}

+ 14 - 0
lang/cem/libcc/gen/strcat.c

@@ -0,0 +1,14 @@
+char *strcat(s1, s2)
+register char *s1, *s2;
+{
+  /* Append s2 to the end of s1. */
+
+  char *original = s1;
+
+  /* Find the end of s1. */
+  while (*s1 != 0) s1++;
+
+  /* Now copy s2 to the end of s1. */
+  while (*s1++ = *s2++) /* nothing */ ;
+  return(original);
+}

+ 9 - 0
lang/cem/libcc/gen/strchr.c

@@ -0,0 +1,9 @@
+char *strchr(s, c)
+register char *s, c;
+{
+  do {
+	if (*s == c)
+		return(s);
+  } while (*s++ != 0);
+  return(0);
+}

+ 15 - 0
lang/cem/libcc/gen/strcmp.c

@@ -0,0 +1,15 @@
+int strcmp(s1, s2)
+register char *s1, *s2;
+{
+/* Compare 2 strings. */
+
+  for(;;) {
+	if (*s1 != *s2) {
+		if (!*s1) return -1;
+		if (!*s2) return 1;
+		return(*s1 - *s2);
+	}
+	if (*s1++ == 0) return(0);
+	s2++;
+  }
+}

+ 9 - 0
lang/cem/libcc/gen/strcpy.c

@@ -0,0 +1,9 @@
+char *strcpy(s1, s2)
+register char *s1, *s2;
+{
+/* Copy s2 to s1. */
+  char *original = s1;
+
+  while (*s1++ = *s2++) /* nothing */;
+  return(original);
+}

+ 13 - 0
lang/cem/libcc/gen/strcspn.c

@@ -0,0 +1,13 @@
+int
+strcspn(string, notin)
+	char *string;
+	char *notin;
+{
+	register char *s1, *s2;
+
+	for (s1 = string; *s1; s1++) {
+		for(s2 = notin; *s2 != *s1 && *s2; s2++) /* nothing */ ;
+		if (*s2) break;
+	}
+	return s1 - string;
+}

+ 10 - 0
lang/cem/libcc/gen/strlen.c

@@ -0,0 +1,10 @@
+int strlen(s)
+char *s;
+{
+/* Return length of s. */
+
+  char *original = s;
+
+  while (*s != 0) s++;
+  return(s - original);
+}

+ 22 - 0
lang/cem/libcc/gen/strncat.c

@@ -0,0 +1,22 @@
+char *strncat(s1, s2, n)
+register char *s1, *s2;
+int n;
+{
+/* Append s2 to the end of s1, but no more than n characters */
+
+  char *original = s1;
+
+  if (n <= 0) return(s1);
+
+  /* Find the end of s1. */
+  while (*s1 != 0) s1++;
+
+  /* Now copy s2 to the end of s1. */
+  while (*s1++ = *s2++) {
+	if (--n == 0) {
+		*s1 = 0;
+		break;
+	}
+  }
+  return(original);
+}

+ 18 - 0
lang/cem/libcc/gen/strncmp.c

@@ -0,0 +1,18 @@
+int
+strncmp(s1, s2, n)
+	register char *s1, *s2;
+	int n;
+{
+/* Compare two strings, but at most n characters. */
+
+  while (n-- > 0) {
+	if (*s1 != *s2) {
+		if (!*s1) return -1;
+		if (!*s2) return 1;
+		return(*s1 - *s2);
+	}
+	if (*s1++ == 0) break;
+	s2++;
+  }
+  return 0;
+}

+ 13 - 0
lang/cem/libcc/gen/strncpy.c

@@ -0,0 +1,13 @@
+char
+*strncpy(s1, s2, n)
+register char *s1, *s2;
+int n;
+{
+/* Copy s2 to s1, but at most n characters. */
+
+  char *original = s1;
+
+  while (*s2 && n-- > 0) *s1++ = *s2++;
+  while (n-- > 0) *s1++ = '\0';
+  return(original);
+}

+ 13 - 0
lang/cem/libcc/gen/strpbrk.c

@@ -0,0 +1,13 @@
+char *
+strpbrk(string, brk)
+	register char *string, *brk;
+{
+	register char *s1;
+
+	while (*string) {
+		for (s1 = brk; *s1 && *s1 != *string; s1++) /* nothing */ ;
+		if (*s1) return string;
+		string++;
+	}
+	return 0;
+}

+ 12 - 0
lang/cem/libcc/gen/strrchr.c

@@ -0,0 +1,12 @@
+char *strrchr(s, c)
+register char *s, c;
+{
+  register char *result;
+
+  result = 0;
+  do
+	if (*s == c)
+		result = s;
+  while (*s++ != 0);
+  return(result);
+}

+ 13 - 0
lang/cem/libcc/gen/strspn.c

@@ -0,0 +1,13 @@
+int
+strspn(string, in)
+	char *string;
+	char *in;
+{
+	register char *s1, *s2;
+
+	for (s1 = string; *s1; s1++) {
+		for (s2 = in; *s2 && *s2 != *s1; s2++) /* nothing */ ;
+		if (! *s2) break;
+	}
+	return s1 - string;
+}

+ 12 - 0
lang/cem/libcc/gen/strstr.c

@@ -0,0 +1,12 @@
+/* find first occurrence of wanted in s */
+char *
+strstr(s, wanted)
+	register char *s, *wanted;
+{
+	int len = strlen(wanted);
+
+	while (*s != *wanted || strncmp(s, wanted, len)) {
+		if (*s++ == '\0') return 0;
+	}
+	return s;
+}

+ 25 - 0
lang/cem/libcc/gen/strtok.c

@@ -0,0 +1,25 @@
+extern char *strpbrk();
+
+char *
+strtok(string, separators)
+	register char *string;
+	char *separators;
+{
+	register char *s1, *s2;
+	static char *savestring;
+
+	if (!string) string = savestring;
+
+	if (!string) return 0;
+
+	if (*(s1 = string + strspn(string, separators)) == '\0') {
+		savestring = 0;
+		return 0;
+	}
+
+	if (s2 = strpbrk(s1, separators)) {
+		*s2++ = '\0';
+	}
+	savestring = s2;
+	return s1;
+}

+ 10 - 0
lang/cem/libcc/gen/swab.c

@@ -0,0 +1,10 @@
+swab(from, to, nbytes)
+	register char *from, *to;
+{
+	nbytes /= 2;
+	while (nbytes-- > 0) {
+		*(to+1) = *from++;
+		*to = *from++;
+		to += 2;
+	}
+}

+ 13 - 0
lang/cem/libcc/gen/telldir.c

@@ -0,0 +1,13 @@
+#include <sys/types.h>
+#include <sys/dir.h>
+
+/*
+ * return a pointer into a directory
+ */
+long telldir(dirp)
+DIR *dirp;
+{
+	extern long lseek();
+
+	return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
+}

+ 43 - 0
lang/cem/libcc/gen/ttyname.c

@@ -0,0 +1,43 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+
+#define DEV "/dev/"
+
+extern char *strcpy(), *strcat();
+
+char *
+ttyname(filedes)
+{
+	static char result[MAXNAMLEN + 1 + 5];
+	DIR *dirp;
+	register struct direct *dp;
+	struct stat fdstat;
+	ino_t inode;
+	dev_t device;
+	char *name;
+
+	if (! isatty(filedes) ||
+	    fstat(filedes, &fdstat) < 0 ||
+	    (fdstat.st_mode & S_IFMT) != S_IFCHR ||
+	    (dirp = opendir(DEV)) == NULL) {
+		return 0;
+	}
+
+	inode = fdstat.st_ino;
+	device = fdstat.st_rdev;
+
+	while ((dp = readdir(dirp)) != NULL) {
+		if (dp->d_ino != inode) continue;
+		strcpy(result, DEV);
+		strcat(result, dp->d_name);
+		if (stat(result, &fdstat) < 0) continue;
+		if (fdstat.st_rdev == device &&
+		    (fdstat.st_mode & S_IFMT) == S_IFCHR) {
+			closedir(dirp);
+			return result;
+		}
+	}
+	closedir(dirp);
+	return 0;
+}

+ 71 - 0
lang/cem/libcc/gen/ttyslot.c

@@ -0,0 +1,71 @@
+#ifdef USG
+/* some systems require inclusion of sys/types.h before utmp.h */
+#include <sys/types.h>
+#include <utmp.h>
+
+/*	system V, so no /etc/ttys file. In this case, scan the
+	/etc/utmp file
+*/
+#define FILENAME "/etc/utmp"
+#else
+#define FILENAME "/etc/ttys"
+#endif
+
+char    *ttyname();
+char    *rindex();
+
+ttyslot()
+{
+	register char *tp, *p;
+	int fd;
+	int retval = 1;
+#ifdef USG
+	struct utmp buf;
+#else
+	char buf[32];
+#endif
+
+	if (! (tp=ttyname(0)) && ! (tp=ttyname(1)) && !(tp=ttyname(2)))
+		return 0;
+	if (! (p = rindex(tp, '/')))
+		p = tp;
+	else
+		p++;
+	if ((fd = open(FILENAME, 0)) < 0) return 0;
+#ifdef USG
+	while (read(fd, (char *) &buf, sizeof(buf)) == sizeof(buf)) {
+		if ((buf.ut_type == INIT_PROCESS ||
+		     buf.ut_type == LOGIN_PROCESS ||
+		     buf.ut_type == USER_PROCESS ||
+		     buf.ut_type == DEAD_PROCESS) &&
+		    ! strncmp(buf.ut_line, p, sizeof(buf.ut_line))) {
+			close(fd);
+			return retval;
+		}
+		retval++;
+	}
+	close(fd);
+	return 0;
+#else
+	for (;;) {
+		tp = buf;
+		for (;;) {
+			if (read(fd, tp, 1) != 1) {
+				close(fd);
+				return 0;
+			}
+			if (*tp == '\n' || tp >= &buf[31]) {
+				*tp = 0;
+				tp = buf+2;
+				break;
+			}
+		}
+		if (! strcmp(p, tp)) {
+			close(fd);
+			return retval;
+		}
+		retval++;
+	}
+	/*NOTREACHED*/
+#endif
+}

+ 56 - 0
lang/cem/libcc/gen/tzset.c

@@ -0,0 +1,56 @@
+#ifdef BSD4_2
+#include <sys/time.h>
+#else
+#ifndef USG
+#include <sys/types.h>
+#include <sys/timeb.h>
+#endif
+#endif
+
+long	timezone = -1 * 60;
+int	daylight = 1;
+char	*tzname[] = {"MET", "MDT",};
+
+tzset()
+{
+#ifdef BSD4_2
+	struct timeval tval;
+	struct timezone tzon;
+
+	gettimeofday(&tval, &tzon);
+	timezone = tzon.tz_minuteswest * 60L;
+	daylight = tzon.tz_dsttime;
+#else
+#ifndef USG
+	struct timeb time;
+
+	ftime(&time);
+	timezone = time.timezone*60L;
+	daylight = time.dstflag;
+#endif
+#endif
+
+	{
+	extern char *getenv();
+	register char *p = getenv("TZ");
+
+	if (p && *p) {
+		register int n = 0;
+		int sign = 1;
+
+		strncpy(tzname[0], p, 3);
+		p += 3;
+		if (*(p += 3) == '-') {
+			sign = -1;
+			p++;
+		}
+
+		while(*p >= '0' && *p <= '9')
+			n = 10 * n + (*p++ - '0');
+		n *= sign;
+		timezone = ((long)(n * 60)) * 60;
+		daylight = (*p != '\0');
+		strncpy(tzname[1], p, 3);
+	}
+	}
+}

+ 7 - 0
lang/cem/libcc/stdio/clearerr.c

@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+clearerr(iop)
+	FILE *iop;
+{
+	iop->_flags &= ~(IO_ERR|IO_EOF);
+}

+ 23 - 0
lang/cem/libcc/stdio/data.c

@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+unsigned char  __stdin[BUFSIZ];
+unsigned char  __stdout[BUFSIZ];
+
+struct _io_buf _stdin = {
+	0, 0, IO_READMODE , __stdin, __stdin
+};
+
+struct _io_buf _stdout = {
+	1, 0, IO_WRITEMODE, 0, 0
+};
+
+struct _io_buf _stderr = {
+	2, 0, IO_WRITEMODE + IO_UNBUFF, NULL, NULL
+};
+
+struct  _io_buf  *_io_table[_NFILES] = {
+	&_stdin,
+	&_stdout,
+	&_stderr,
+	0
+};

+ 242 - 0
lang/cem/libcc/stdio/doprnt.c

@@ -0,0 +1,242 @@
+#include <stdio.h>
+
+#ifndef NOFLOAT
+extern char     *_pfloat();
+extern char     *_pscien();
+#endif
+
+static int *nextarg ;
+
+static geta(p,size) int *p; int size; {
+	/* get 'size' words from arglist */
+
+	if ( (int *)&p - &size >0 ) {
+		p += size;
+		while ( size-- ) {
+			*--p = *nextarg--;
+		}
+	} else {
+		while ( size-- ) {
+			*p++ = *nextarg++ ;
+		}
+	}
+}
+
+# define wsize(par) ( (sizeof par) / sizeof (int) )
+
+
+static char *gnum(f,ip) register char *f; int *ip; {
+	register int    i,c;
+
+	if (*f == '*') {
+		geta(ip,wsize(i)) ;
+		f++;
+	} else {
+		i = 0;
+		while ((c = *f - '0') >= 0 && c <= 9) {
+			i = i*10 + c;
+			f++;
+		}
+		*ip = i;
+	}
+	return(f);
+}
+
+#define signbit(par) (1L<<(sizeof par*8 -1))
+
+static char *i_compute(val,base,s) unsigned val; char *s; {
+	int c;
+
+	c= val % base ;
+	val/= base ;
+	if (val)
+		s = i_compute(val,base,s);
+	*s++ = (c>9 ? c-10+'a' : c+'0');
+	return(s);
+}
+
+#ifndef NOLONG
+static char *l_compute(l1,d,s) long l1; char *s; {
+	int c;
+	long l2;
+
+	if ( l1<0 ) {
+		/* assumption: d is a multiple of 2 */
+		c= l1&1 ;
+		l2= ( (l1>>1) & ~signbit(l1) );
+		l1= l2/(d>>1) ;
+		c += (l2%(d>>1))<<1 ;
+	} else {
+		c= l1 % d ;
+		l1= l1 / d ;
+	}
+	if (l1)
+		s = l_compute(l1,d,s);
+	*s++ = (c>9 ? c-10+'a' : c+'0');
+	return(s);
+}
+#endif
+
+_doprnt(fmt,args,stream)
+	register char *fmt; int *args ; FILE *stream;
+{
+	register char   *s;
+#ifndef NOLONG
+	long            l;
+	int             lflag ;
+#else
+#define lflag 0
+#endif
+#ifndef NOFLOAT
+	double          dbl ;
+#endif
+	int             inte ;
+	unsigned int    uint ;
+	register int    j ;
+	int             i,c,rjust,width,ndigit,ndfnd,zfill;
+	char            *oldfmt,*s1,buf[40];
+
+	nextarg = args;
+	while (c = *fmt++) {
+		if (c != '%') {
+#ifdef  CPM
+			if (c == '\n') putc('\r',stream);
+#endif
+			putc(c,stream);
+			continue;
+		}
+#ifndef NOLONG
+		lflag = 0 ;
+#endif
+		j = 10 ;
+		rjust = 0;
+		if (*fmt == '-') {
+			fmt++;
+			rjust++;
+		}
+		zfill = ' ';
+		if (*fmt == '0') {
+			fmt++;
+			zfill = '0';
+		}
+		fmt = gnum(fmt,&width);
+		ndigit = 0; ndfnd = 0;
+		if (*fmt == '.') {
+			fmt++; oldfmt = fmt;
+			fmt = gnum(fmt,&ndigit);
+			ndfnd = (fmt != oldfmt);
+		}
+		s = s1 = buf;
+#ifndef NOLONG
+		if ( *fmt == 'l' || *fmt == 'L' ) {
+			fmt++ ; lflag++ ;
+		}
+#endif
+		switch (c = *fmt++) {
+		default:
+#ifdef  CPM
+			if (c == '\n') putc('r',stream);
+#endif
+			putc(c,stream);
+			continue;
+		case 's':
+			geta(&s1,wsize(s1)) ;
+			s = s1;
+			do {
+				if (*s == 0)
+					break;
+				s++;
+			} while (--ndigit);
+			break;
+		case 'b':
+			j = 2;
+		case 'u':
+		getu:
+			if ( !lflag ) {
+				geta(&inte,wsize(inte)) ;
+				goto i_unsignd ;
+			}
+#ifndef NOLONG
+		case 'U':
+		getlu:
+			geta( &l,wsize(l)) ;
+			goto l_unsignd ;
+		case 'B':
+			j = 2 ;
+			goto getlu ;
+		case 'X':
+			j = 16;
+			goto getlu ;
+		case 'O':
+			j = 8;
+			goto getlu ;
+		case 'D':
+		    l_signed:
+			geta(&l,wsize(l)) ;
+			if (l < 0) {
+				*s++ = '-';
+				l = -l;
+			}
+			goto do_l;
+		    l_unsignd:
+			if (l && ndigit)
+				*s++ = '0';
+		    do_l:
+			s = l_compute(l,j,s);
+			break;
+#endif
+
+		case 'x':
+			j = 16;
+			goto getu ;
+		case 'o':
+			j = 8;
+			goto getu ;
+		case 'd':
+			if ( lflag ) goto l_signed; ;
+			geta(&inte,wsize(inte)) ;
+			if ( inte<0 ) {
+				*s++ = '-';
+				inte= -inte ;
+			}
+			goto do_i ;
+		    i_unsignd:
+			if (inte && ndigit)
+				*s++ = '0';
+		    do_i:
+			s = i_compute(inte,j,s);
+			break;
+		case 'c':
+			geta ( &uint, wsize(uint)) ;
+			for ( i= sizeof uint -1  ; i>=0 ; i-- ) {
+				if ( *s = uint%256 ) s++;
+				uint/= 256 ;
+			}
+			break;
+#ifndef NOFLOAT
+		case 'e':
+			geta(&dbl,wsize(dbl)) ;
+			s = _pscien(dbl,s,ndigit,ndfnd);
+			break;
+		case 'f':
+			geta(&dbl,wsize(dbl)) ;
+			s = _pfloat(dbl,s,ndigit,ndfnd);
+			break;
+#endif
+		case 'r':
+			geta(&nextarg,wsize(nextarg)) ;
+			geta(&oldfmt,wsize(fmt)) ;
+			fmt=oldfmt;
+			continue;
+		}
+		j = s - s1;
+		if ((c = width - j) > 0)
+			if (rjust == 0)
+				do putc(zfill,stream);
+				while (--c);
+		while (--j >= 0)
+			putc(*s1++,stream);
+		while (--c >= 0)
+			putc(zfill,stream);
+	}
+}

+ 278 - 0
lang/cem/libcc/stdio/doscan.c

@@ -0,0 +1,278 @@
+#include <stdio.h>
+#include <ctype.h>
+
+union ptr_union {
+	char           *chr_p;
+	unsigned short *ushort_p;
+	unsigned int   *uint_p;
+	unsigned long  *ulong_p;
+#ifndef NOFLOAT
+	float		*float_p;
+	double		*double_p;
+#endif
+};
+
+static char	Xtable[128];
+
+/*
+ * the routine that does the job 
+ */
+
+_doscanf (iop, format, argp)
+register FILE	*iop;
+char           *format;		/* the format control string */
+union ptr_union *argp;		/* our argument list */
+{
+	int             done = 0;	/* number of items done */
+	int             base;		/* conversion base */
+	long            val;		/* an integer value */
+	int             sign;		/* sign flag */
+	int             do_assign;	/* assignment suppression flag */
+	unsigned        width;		/* width of field */
+	int             widflag;	/* width was specified */
+	int             longflag;	/* true if long */
+	int		shortflag;	/* true if short */
+	int             done_some;	/* true if we have seen some data */
+	int		reverse;	/* reverse the checking in [...] */
+	int		kind;
+	register int	ic;
+#ifndef NOFLOAT
+	extern double	atof();
+	int		dotseen;
+	int		expseen;
+	char		buffer[128];
+#endif
+
+	ic = getc(iop);
+	if (ic == EOF) {
+		done = EOF;
+		goto quit;
+	}
+
+	while (1) {
+		if (isspace(*format)) {
+			while (isspace (*format))
+				++format;	/* skip whitespace */
+			while (isspace (ic)) ic = getc(iop);
+		}
+		if (!*format)
+			goto all_done;	/* end of format */
+		if (ic < 0)
+			goto quit;	/* seen an error */
+		if (*format != '%') {
+			if (ic != *format)
+				goto all_done;
+			++format;
+			ic = getc(iop);
+			++done;
+			continue;
+		}
+		++format;
+		do_assign = 1;
+		if (*format == '*') {
+			++format;
+			do_assign = 0;
+		}
+		if (isdigit (*format)) {
+			widflag = 1;
+			for (width = 0; isdigit (*format);)
+				width = width * 10 + *format++ - '0';
+		} else
+			widflag = 0;	/* no width spec */
+		if (longflag = (tolower (*format) == 'l'))
+			++format;
+		else if (shortflag = (tolower(*format) == 'h'))
+			++format;
+		if (isupper(*format)) {
+			kind = tolower(*format);
+			longflag = 1;
+		}
+		else	kind = *format;
+		if (kind != 'c')
+			while (isspace (ic))
+				ic = getc(iop);
+		done_some = 0;	/* nothing yet */
+		switch (kind) {
+		case 'o':
+			base = 8;
+			goto decimal;
+		case 'u':
+		case 'd':
+			base = 10;
+			goto decimal;
+		case 'x':
+			base = 16;
+			if (((!widflag) || width >= 2) && ic == '0') {
+				ic = getc(iop);
+				if (tolower (ic) == 'x') {
+					width -= 2;
+					done_some = 1;
+					ic = getc(iop);
+				} else {
+					ungetc(ic, iop);
+					ic = '0';
+				}
+			}
+	decimal:
+			val = 0L;	/* our result value */
+			sign = 0;	/* assume positive */
+			if (!widflag)
+				width = 0xffff;	/* very wide */
+			if (width && ic == '+')
+				ic = getc(iop);
+			else if (width && ic == '-') {
+				sign = 1;
+				ic = getc(iop);
+			}
+			while (width--) {
+				if (isdigit (ic) && ic - '0' < base)
+					ic -= '0';
+				else if (base == 16 && tolower (ic) >= 'a' && tolower (ic) <= 'f')
+					ic = 10 + tolower (ic) - 'a';
+				else
+					break;
+				val = val * base + ic;
+				ic = getc(iop);
+				done_some = 1;
+			}
+			if (do_assign) {
+				if (sign)
+					val = -val;
+				if (longflag)
+					*(argp++)->ulong_p = (unsigned long) val;
+				else if (shortflag)
+					*(argp++)->ushort_p = (unsigned short) val;
+				else
+					*(argp++)->uint_p = (unsigned) val;
+			}
+			if (done_some)
+				++done;
+			else
+				goto all_done;
+			break;
+		case 'c':
+			if (!widflag)
+				width = 1;
+			while (width-- && ic >= 0) {
+				if (do_assign)
+					*(argp)->chr_p++ = (char) ic;
+				ic = getc(iop);
+				done_some = 1;
+			}
+			if (do_assign)
+				argp++;	/* done with this one */
+			if (done_some)
+				++done;
+			break;
+		case 's':
+			if (!widflag)
+				width = 0xffff;
+			while (width-- && !isspace (ic) && ic > 0) {
+				if (do_assign)
+					*(argp)->chr_p++ = (char) ic;
+				ic = getc(iop);
+				done_some = 1;
+			}
+			if (do_assign)		/* terminate the string */
+				*(argp++)->chr_p = '\0';	
+			if (done_some)
+				++done;
+			else
+				goto all_done;
+			break;
+		case '[':
+			if (!widflag)
+				width = 0xffff;
+
+			if ( *(++format) == '^' ) {
+				reverse = 1;
+				format++;
+			} else
+				reverse = 0;
+			
+			{ register char *c;
+			  for (c = Xtable; c < &Xtable[128]; c++) *c = 0;
+			}
+			while (*format && *format != ']') {
+				Xtable[*format] = 1;
+			}
+			if (!*format)
+				goto quit;
+			
+			while (width-- && !isspace (ic) && ic > 0 &&
+				(Xtable[ic] ^ reverse)) {
+				if (do_assign)
+					*(argp)->chr_p++ = (char) ic;
+				ic = getc(iop);
+				done_some = 1;
+			}
+			if (do_assign)		/* terminate the string */
+				*(argp++)->chr_p = '\0';	
+			if (done_some)
+				++done;
+			else
+				goto all_done;
+			break;
+#ifndef NOFLOAT:
+		case 'e':
+		case 'f': {
+			register char *c = buffer;
+
+			if (width >= 128) width = 127;
+			if (width && (ic == '+' || ic == '-')) {
+				*c++ = ic;
+				width--;
+				ic = getc(iop);
+			}
+			while (isdigit(ic) && width) {
+				width--;
+				*c++ = ic;
+				ic = getc(iop);
+			}
+			if (ic == '.' && width) {
+				width--;
+				*c++ = ic;
+				ic = getc(iop);
+			}
+			while (isdigit(ic) && width) {
+				width--;
+				*c++ = ic;
+				ic = getc(iop);
+			}
+			if (width && (ic == 'e' || ic == 'E')) {
+				width--;
+				*c++ = ic;
+				ic = getc(iop);
+				if (width && (ic == '+' || ic == '-')) {
+					width--;
+					*c++ = ic;
+					ic = getc(iop);
+				}
+			}
+			while (isdigit(ic) && width) {
+				width--;
+				*c++ = ic;
+				ic = getc(iop);
+			}
+			if (c == buffer) goto all_done;
+			*c = 0;
+			done++;
+
+			if (do_assign) {
+				if (longflag)
+					*(argp++)->double_p = atof(buffer);
+				else
+					*(argp++)->float_p = atof(buffer);
+			}
+			}
+			break;
+#endif
+		}		/* end switch */
+		++format;
+	}
+all_done:
+	if (ic >= 0)
+		ungetc(ic, iop);
+quit:
+	return done;
+}

+ 22 - 0
lang/cem/libcc/stdio/fclose.c

@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+fclose(fp)
+FILE *fp;
+{
+	register int i;
+
+	for (i=0; i<_NFILES; i++)
+		if (fp == _io_table[i]) {
+			_io_table[i] = 0;
+			break;
+		}
+	if (i >= _NFILES)
+		return(EOF);
+	fflush(fp);
+	close(fileno(fp));
+	if ( io_testflag(fp,IO_MYBUF) && fp->_buf )
+		free( fp->_buf );
+	free(fp);
+	return(NULL);
+}
+

+ 38 - 0
lang/cem/libcc/stdio/fdopen.c

@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+FILE *fdopen(fd,mode)
+char *mode;
+{
+	register int i;
+	FILE *fp;
+	char *malloc();
+	int flags = 0;
+
+	if (fd < 0) return NULL;
+	for (i = 0; _io_table[i] != 0 ; i++) 
+		if ( i >= _NFILES )
+			return(NULL);
+
+	switch(*mode) {
+	case 'r':
+		flags |= IO_READMODE;
+		break;
+	case 'a':
+		lseek(fd, 0L, 2);
+	case 'w':
+		flags |= IO_WRITEMODE;
+		break;
+	default:
+		return NULL;
+	}
+
+	if (( fp = (FILE *) malloc (sizeof( FILE))) == NULL ) {
+		return(NULL);
+	}
+
+	fp->_count = 0;
+	fp->_fd = fd;
+	fp->_flags = flags;
+	_io_table[i] = fp;
+	return(fp);
+}

+ 26 - 0
lang/cem/libcc/stdio/fflush.c

@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+
+fflush(iop)
+FILE *iop;
+{
+	int count, c1;
+
+	if ( io_testflag(iop,IO_UNBUFF) || !io_testflag(iop,IO_WRITEMODE) ) 
+		return(0);
+
+	count = BUFSIZ - iop->_count;
+	if ( count <= 0 )
+		return(0);
+
+	c1 = write(iop->_fd,iop->_buf,count);
+
+	if ( count == c1 ) {
+		iop->_count = BUFSIZ;
+		iop->_ptr   = iop->_buf;
+		return(count);
+	}
+
+	iop->_flags |= IO_ERR;
+	return(EOF); 
+}

+ 7 - 0
lang/cem/libcc/stdio/fgetc.c

@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+fgetc(f)
+	register FILE *f;
+{
+	return getc(f);
+}

+ 21 - 0
lang/cem/libcc/stdio/fgets.c

@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+char *fgets(str, n, file)
+char *str;
+unsigned n;
+FILE *file;
+{
+	register int ch;
+	register char *ptr;
+
+	ptr = str;
+	while ( --n > 0 && (ch = getc(file)) != EOF){
+		*ptr++ = ch;
+		if ( ch == '\n')
+			break;
+	}
+	if (ch == EOF && ptr==str)
+		return(NULL);
+	*ptr = '\0';
+	return(str);
+}

+ 37 - 0
lang/cem/libcc/stdio/fillbuf.c

@@ -0,0 +1,37 @@
+#include <stdio.h>
+
+_fillbuf(iop)
+register FILE *iop;
+{
+	unsigned char ch[_NFILES];
+
+	iop->_count = 0;
+	if (fileno(iop) < 0) return EOF;
+	if ( io_testflag(iop, (IO_EOF | IO_ERR )))
+		return (EOF); 
+
+	if ( !io_testflag(iop, IO_READMODE) ) 
+		return (EOF);
+
+	if (! io_testflag(iop, IO_UNBUFF) && ! iop->_buf) {
+		iop->_buf = (unsigned char *) malloc(BUFSIZ);
+		if (! iop->_buf) iop->_flags |= IO_UNBUFF;
+		else iop->_flags |= IO_MYBUF;
+	}
+	if (! iop->_buf) iop->_buf = &ch[fileno(iop)];
+	iop->_ptr = iop->_buf;
+	iop->_count = read(iop->_fd, iop->_buf, io_testflag(iop, IO_UNBUFF)? 1 : BUFSIZ);
+
+	if (iop->_count <= 0){
+		if (iop->_count == 0) {
+			iop->_flags |= IO_EOF;
+		}
+		else 
+			iop->_flags |= IO_ERR;
+
+		return (EOF);
+	}
+	iop->_count--;
+
+	return *iop->_ptr++;
+}

+ 57 - 0
lang/cem/libcc/stdio/fltpr.c

@@ -0,0 +1,57 @@
+#ifndef NOFLOAT
+extern char     *fcvt();
+extern char     *ecvt();
+
+char *
+_pfloat(r,s,n,b)
+	double r;
+	register char *s;
+{
+	int sign,dp,i; char *s1;
+
+	if (b == 0)
+		n = 6;
+	s1 = fcvt(r,n,&dp,&sign);
+	if (sign)
+		*s++ = '-';
+	if (dp<=0)
+		*s++ = '0';
+	for (i=dp; i>0; i--)
+		*s++ = *s1++;
+	if ((i=n) > 0)
+		*s++ = '.';
+	while (++dp <= 0) {
+		if (--i<0)
+			break;
+		*s++ = '0';
+	}
+	while (--i >= 0)
+		*s++ = *s1++;
+	return(s);
+}
+
+char *_pscien(r,s,n,b) float r; char *s; {
+	int sign,dp; char *s1;
+
+	if (b == 0)
+		n = 7;
+	else    n += 1;
+	s1 = ecvt(r,n,&dp,&sign);
+	if (sign)
+		*s++ = '-';
+	*s++ = *s1++;
+	*s++ = '.';
+	while (--n>0)
+		*s++ = *s1++;
+	*s++ = 'e';
+	if ( r ) --dp ;
+	if ( dp<0 ) {
+		*s++ = '-' ; dp= -dp ;
+	} else {
+		*s++ = '+' ;
+	}
+	*s++ = '0' + (dp/10);
+	*s++ = '0' + (dp%10);
+	return(s);
+}
+#endif

+ 71 - 0
lang/cem/libcc/stdio/flushbuf.c

@@ -0,0 +1,71 @@
+#include <stdio.h>
+
+int
+_flushbuf(c, iop)
+	register FILE *iop;
+{
+	if (fileno(iop) < 0) return EOF;
+	if (! io_testflag(iop, IO_UNBUFF)) {
+		if (iop->_buf == 0) {
+			if (iop == stdout) {
+				if (isatty(fileno(stdout))) {
+					iop->_flags |= IO_UNBUFF;
+				}
+				else {
+					extern unsigned char __stdout[];
+
+					iop->_buf = iop->_ptr = __stdout;
+					iop->_count = BUFSIZ;
+				}
+			}
+			else {
+				extern char *malloc();
+
+				if (!(iop->_buf = (unsigned char *) malloc(BUFSIZ))) {
+					iop->_flags |= IO_UNBUFF;
+				}
+				else {
+					iop->_ptr = iop->_buf;
+					iop->_flags |= IO_MYBUF;
+					iop->_count = BUFSIZ;
+				}
+			}
+		}
+	}
+
+	if (io_testflag(iop, IO_UNBUFF)) {
+		char c1 = c;
+
+		iop->_count = 0;
+		if (write(fileno(iop), &c1, 1) != 1) {
+			iop->_flags |= IO_ERR;
+			return EOF;
+		}
+		return c;
+	}
+	else {
+		int count = BUFSIZ - iop->_count;
+
+		iop->_count = BUFSIZ - 1;
+		iop->_ptr = iop->_buf + 1;
+
+		if (count > 0) {
+			if (write(fileno(iop), iop->_buf, count) != count) {
+				*(iop->_buf) = c;
+				iop->_flags |= IO_ERR;
+				return EOF;
+			}
+		}
+		*(iop->_buf) = c;
+	}
+	return c;
+}
+
+_cleanup()
+{
+	register int i;
+
+	for ( i = 0 ; i < _NFILES ; i++ )
+		if ( _io_table[i] != NULL )
+			fclose(_io_table[i]);
+}

+ 56 - 0
lang/cem/libcc/stdio/fopen.c

@@ -0,0 +1,56 @@
+#include <stdio.h>
+
+#define  PMODE    0666
+
+
+FILE *fopen(name,mode)
+char *name , *mode;
+{
+	register int i;
+	FILE *fp;
+	char *malloc();
+	int fd,
+	flags = 0;
+
+	for (i = 0; _io_table[i] != 0 ; i++) 
+		if ( i >= _NFILES )
+			return(NULL);
+
+	switch(*mode){
+
+	case 'w':
+		flags |= IO_WRITEMODE;
+		fd = creat (name,PMODE);
+		break;
+
+	case 'a': 
+		flags |= IO_WRITEMODE;
+		if (( fd = open(name, 1)) < 0 )
+			fd = creat(name, PMODE);
+		if (fd >= 0) lseek(fd,0L,2);
+		break;         
+
+	case 'r':
+		flags |= IO_READMODE;	
+		if (( fd = open (name, 0)) < 0 )
+			return(NULL);
+		break;
+
+	default:
+		return(NULL);
+	}
+
+
+	if (fd < 0) return NULL;
+
+	if (( fp = (FILE *) malloc (sizeof( FILE))) == NULL ) {
+		close(fd);
+		return(NULL);
+	}
+
+	fp->_count = 0;
+	fp->_fd = fd;
+	fp->_flags = flags;
+	_io_table[i] = fp;
+	return(fp);
+}

+ 11 - 0
lang/cem/libcc/stdio/fprintf.c

@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+fprintf (file, fmt, args)
+FILE *file;
+char *fmt;
+int args;
+{
+	_doprnt (fmt, &args, file);
+	if ( io_testflag(file,IO_PERPRINTF) )
+        	fflush(file);
+}

+ 7 - 0
lang/cem/libcc/stdio/fputc.c

@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+fputc(c, iop)
+	register FILE *iop;
+{
+	return putc(c, iop);
+}

+ 9 - 0
lang/cem/libcc/stdio/fputs.c

@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+fputs(s,file)
+register char *s;
+register FILE *file;
+{
+	while ( *s ) 
+		putc(*s++,file);
+}

+ 25 - 0
lang/cem/libcc/stdio/fread.c

@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+fread(ptr, size, count, file)
+register char *ptr;
+unsigned size, count;
+register FILE *file;
+{
+	int c;
+	unsigned ndone = 0, s;
+
+	ndone = 0;
+	if (size)
+		while ( ndone < count ) {
+			s = size;
+			do {
+				if ((c = getc(file)) != EOF)
+					*ptr++ = c;
+				else
+					return(ndone);
+			} while (--s);
+			ndone++;
+		}
+	return(ndone);
+}
+

+ 59 - 0
lang/cem/libcc/stdio/freopen.c

@@ -0,0 +1,59 @@
+#include <stdio.h>
+
+#define  PMODE    0666
+
+
+FILE *freopen(name,mode,fp)
+char *name , *mode;
+FILE *fp;
+{
+	FILE *fp;
+	char *malloc();
+	int fd,
+	flags = 0;
+
+	close(fileno(fp));
+	if (io_testflag(fp, IO_MYBUF) && fp->_buf) free(fp->_buf);
+
+	switch(*mode){
+
+	case 'w':
+		flags |= IO_WRITEMODE;
+		fd = creat (name,PMODE);
+		break;
+
+	case 'a': 
+		flags |= IO_WRITEMODE;
+		if (( fd = open(name, 1)) < 0 )
+			fd = creat(name, PMODE);
+		if (fd >= 0) lseek(fd,0L,2);
+		break;         
+
+	case 'r':
+		flags |= IO_READMODE;	
+		fd = open(name, 0);
+		break;
+
+	default:
+		fd = -1;
+	}
+
+	if (fd < 0) {
+		register int i;
+
+		for (i = 0; i < _NFILES; i++) {
+			if (fp == _io_table[i]) {
+				_io_table[i] = 0;
+				break;
+			}
+		}
+		free(fp);
+		return NULL;
+	}
+
+	fp->_count = 0;
+	fp->_fd = fd;
+	fp->_flags = flags;
+	fp->_buf = 0;
+	return(fp);
+}

+ 10 - 0
lang/cem/libcc/stdio/fscanf.c

@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int fscanf (fp, format, args)
+FILE           *fp;
+char           *format;
+unsigned        args;
+{
+	return _doscanf (fp, format, &args);
+}
+

+ 39 - 0
lang/cem/libcc/stdio/fseek.c

@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+
+fseek(iop, offset, where)
+FILE *iop;
+long offset;
+{
+	int  count;
+	long lseek();
+	long pos;
+
+	iop->_flags &= ~(IO_EOF | IO_ERR);
+	/* Clear both the end of file and error flags */
+
+	if ( io_testflag(iop,IO_READMODE) ) {
+		if ( where < 2 && iop->_buf && !io_testflag(iop,IO_UNBUFF) ) {
+			count = iop->_count;
+			pos = offset;
+
+			if ( where == 0 )
+				pos += count - lseek(fileno(iop), 0L,1);
+			else
+				offset -= count;
+
+			if ( count > 0 && pos <= count 
+			     && pos >= iop->_buf - iop->_ptr ) {
+		        	iop->_ptr += (int) pos;
+				iop->_count -= (int) pos;
+				return(0);
+			}
+		}
+		pos = lseek(fileno(iop), offset, where);
+		iop->_count = 0;
+	} else if ( io_testflag(iop,IO_WRITEMODE) ) {
+		fflush(iop);
+		pos = lseek(fileno(iop), offset, where);
+	}
+	return((pos == -1) ? -1 : 0 );
+}

+ 25 - 0
lang/cem/libcc/stdio/ftell.c

@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+
+long ftell(iop)
+FILE *iop;
+{
+	long result;
+	long lseek();
+	int adjust = 0;
+
+	if ( io_testflag(iop,IO_READMODE) )
+		adjust -= iop->_count;
+	else if ( io_testflag(iop,IO_WRITEMODE) && iop->_buf && !io_testflag(iop,IO_UNBUFF))
+		adjust = iop->_ptr - iop->_buf;
+	else
+		return(-1);
+	
+	result = lseek(fileno(iop), 0L, 1);
+
+	if ( result < 0 )
+		return ( result );
+
+	result += (long) adjust;
+	return(result);
+}

+ 23 - 0
lang/cem/libcc/stdio/fwrite.c

@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+fwrite(ptr, size, count, file)
+unsigned size, count;
+register char *ptr;
+register FILE *file;
+{
+	unsigned s;
+	unsigned ndone = 0;
+
+	if (size)
+		while ( ndone < count ) {
+			s = size;
+			do {
+				putc(*ptr++, file);
+				if (ferror(file))
+					return(ndone);
+			} 
+			while (--s);
+			ndone++;
+		}
+	return(ndone);
+}

+ 8 - 0
lang/cem/libcc/stdio/getchar.c

@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+#undef getchar
+
+getchar()
+{
+	return getc(stdin);
+}

+ 115 - 0
lang/cem/libcc/stdio/getgrent.c

@@ -0,0 +1,115 @@
+/*
+ * get entry from group file
+ * 
+ * By: Patrick van Kleef
+ */
+
+#include <grp.h>
+
+#define PRIVATE static
+
+PRIVATE char _gr_file[] = "/etc/group";
+PRIVATE char _grbuf[256];
+PRIVATE char _buffer[1024];
+PRIVATE char *_pnt;
+PRIVATE char *_buf;
+PRIVATE int  _gfd = -1;
+PRIVATE int  _bufcnt;
+PRIVATE struct group grp;
+
+setgrent ()
+{
+        if (_gfd >= 0)
+	        lseek (_gfd, 0L, 0);
+        else
+	        _gfd = open (_gr_file, 0);
+
+        _bufcnt = 0;
+        return (_gfd);
+}
+
+
+endgrent () 
+{
+        if (_gfd >= 0)
+	        close (_gfd);
+
+        _gfd = -1;
+        _bufcnt = 0;
+}
+
+
+static getline () 
+{
+        if (_gfd < 0 && setgrent () < 0)
+	        return (0);
+
+        _buf = _grbuf;
+        do {
+	        if (--_bufcnt <= 0){
+	                if ((_bufcnt = read (_gfd, _buffer, 1024)) <= 0)
+		                return (0);
+	                else
+		                _pnt = _buffer;
+		}
+	        *_buf++ = *_pnt++;
+        } while (*_pnt != '\n');
+        _pnt++;
+        _bufcnt--;
+        *_buf = 0;
+        _buf = _grbuf;
+        return (1);
+}
+
+static skip_period () 
+{
+        while (*_buf != ':')
+	        _buf++;
+        *_buf++ = '\0';
+}
+
+struct group   *getgrent () 
+{
+        if (getline () == 0)
+               return (0);
+
+        grp.gr_name = _buf;
+        skip_period ();
+        grp.gr_passwd = _buf;
+        skip_period ();
+        grp.gr_gid = atoi (_buf);
+        skip_period ();
+        return (&grp);
+}
+
+struct group   *getgrnam (name)
+char   *name;
+{
+        struct group *grp;
+
+        setgrent ();
+        while ((grp = getgrent ()) != 0)
+	        if (!strcmp (grp -> gr_name, name))
+	                break;
+        endgrent ();
+        if (grp != 0)
+	        return (grp);
+        else
+	        return (0);
+}
+
+struct group   *getgrgid (gid)
+int     gid;
+{
+        struct group   *grp;
+
+        setgrent ();
+        while ((grp = getgrent ()) != 0)
+	        if (grp -> gr_gid == gid)
+	                break;
+        endgrent ();
+        if (grp != 0)
+	        return (grp);
+        else
+	        return (0);
+}

+ 29 - 0
lang/cem/libcc/stdio/getpass.c

@@ -0,0 +1,29 @@
+#include <signal.h>
+#include <sgtty.h>
+
+char * getpass(prompt)
+char *prompt;
+{
+	int i = 0;
+	struct sgttyb tty, ttysave;
+	static char pwdbuf[9];
+	int fd;
+	int (*savesig)();
+
+	if ((fd = open("/dev/tty", 0)) < 0) fd = 0;
+	savesig = signal(SIGINT, SIG_IGN);
+	write(2, prompt, strlen(prompt));
+	gtty(fd, &tty);
+	ttysave = tty;
+	tty.sg_flags &= ~ECHO;
+	stty(fd, &tty);
+	i = read(fd, pwdbuf, 9);
+	while (pwdbuf[i - 1] != '\n')
+		read(fd, &pwdbuf[i - 1], 1);
+	pwdbuf[i - 1] = '\0';
+	stty(fd, &ttysave);
+	write(2, "\n", 1);
+	if (fd != 0) close(fd);
+	signal(SIGINT, savesig);
+	return(pwdbuf);
+}

+ 35 - 0
lang/cem/libcc/stdio/getpw.c

@@ -0,0 +1,35 @@
+#include	<stdio.h>
+
+getpw(uid, buf)
+	int uid;
+	char buf[];
+{
+	register FILE *pwf;
+	register int ch, i;
+	register char *bp;
+
+	pwf = fopen("/etc/passwd", "r");
+	if (pwf == NULL) return(1);
+
+	for (;;) {
+		bp = buf;
+		while ((ch = getc(pwf)) != '\n') {
+			if (ch == EOF) return 1;
+			*bp++ = ch;
+		}
+		*bp++ = '\0';
+		bp = buf;
+		for (i = 2; i; i--) {
+			while ((ch = *bp++) != ':') {
+				if(ch = '\0') return 1;
+			}
+		}
+		i = 0;
+		while ((ch = *bp++) != ':') {
+			if (ch < '0' || ch > '9') return 1;
+			i = i * 10 + (ch - '0');
+		}
+		if (i == uid) return(0);
+	}
+	/*NOTREACHED*/
+}

+ 125 - 0
lang/cem/libcc/stdio/getpwent.c

@@ -0,0 +1,125 @@
+/*
+ * get entry from password file
+ *
+ * By Patrick van Kleef
+ *
+ */
+
+
+#include <pwd.h>
+
+#define PRIVATE static
+
+
+PRIVATE char  _pw_file[] = "/etc/passwd";
+PRIVATE char  _pwbuf[256];
+PRIVATE char  _buffer[1024];
+PRIVATE char *_pnt;
+PRIVATE char *_buf;
+PRIVATE int   _pw = -1;
+PRIVATE int   _bufcnt;
+PRIVATE struct passwd    pwd;
+
+setpwent() 
+{
+	if (_pw >= 0)
+		lseek (_pw, 0L, 0);
+	else
+		_pw = open (_pw_file, 0);
+
+	_bufcnt = 0;
+	return (_pw);
+}
+
+
+endpwent () 
+{
+	if (_pw >= 0)
+		close (_pw);
+
+	_pw = -1;
+	_bufcnt = 0;
+}
+
+static getline () 
+{
+	if (_pw < 0 && setpwent () < 0)
+		return (0);
+	_buf = _pwbuf;
+	do {
+		if (--_bufcnt <= 0){
+			if ((_bufcnt = read (_pw, _buffer, 1024)) <= 0)
+				return (0);
+			else
+				_pnt = _buffer;
+		}
+		*_buf++ = *_pnt++;
+	} while (*_pnt != '\n');
+	_pnt++;
+	_bufcnt--;
+	*_buf = 0;
+	_buf = _pwbuf;
+	return (1);
+}
+
+static skip_period () 
+{
+	while (*_buf != ':')
+		_buf++;
+
+	*_buf++ = '\0';
+}
+
+struct passwd  *getpwent () 
+{
+	if (getline () == 0)
+		return (0);
+
+	pwd.pw_name = _buf;
+	skip_period ();
+	pwd.pw_passwd = _buf;
+	skip_period ();
+	pwd.pw_uid = atoi (_buf);
+	skip_period ();
+	pwd.pw_gid = atoi (_buf);
+	skip_period ();
+	pwd.pw_gecos = _buf;
+	skip_period ();
+	pwd.pw_dir = _buf;
+	skip_period ();
+	pwd.pw_shell = _buf;
+
+	return (&pwd);
+}
+
+struct passwd  *getpwnam (name)
+char   *name;
+{
+	struct passwd  *pwd;
+
+	setpwent ();
+	while ((pwd = getpwent ()) != 0)
+		if (!strcmp (pwd -> pw_name, name))
+			break;
+	endpwent ();
+	if (pwd != 0)
+		return (pwd);
+	else
+		return (0);
+}
+
+struct passwd  *getpwuid (uid)
+int     uid;
+{
+	struct passwd  *pwd;
+
+	setpwent ();
+	while ((pwd = getpwent ()) != 0)
+		if (pwd -> pw_uid == uid)
+			break;
+	endpwent ();
+	if (pwd != 0)
+		return (pwd);
+	else
+		return (0);
+}

+ 17 - 0
lang/cem/libcc/stdio/gets.c

@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+char *gets(str)
+char *str;
+{
+	register int ch;
+	register char *ptr;
+
+	ptr = str;
+	while ((ch = getc(stdin)) != EOF && ch != '\n')
+		*ptr++ = ch;
+
+	if (ch == EOF && ptr==str)
+		return(NULL);
+	*ptr = '\0';
+	return(str);
+}

+ 15 - 0
lang/cem/libcc/stdio/getw.c

@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int getw(iop)
+	register FILE *iop;
+{
+	register int cnt = sizeof(int);
+	int w;
+	register char *p = (char *) &w;
+
+	while (cnt--) {
+		*p++ = getc(iop);
+	}
+	if (foef(iop) || ferror(iop)) return EOF;
+	return w;
+}

+ 54 - 0
lang/cem/libcc/stdio/popen.c

@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <signal.h>
+
+static int pids[20];
+
+FILE *
+popen(command, type)
+	char *command, *type;
+{
+	int piped[2];
+	int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
+	int pid;
+
+	if (Xtype == 2 ||
+	    pipe(piped) < 0 ||
+	    (pid = fork()) < 0) return 0;
+	
+	if (pid == 0) {
+		/* child */
+		register int *p;
+
+		for (p = pids; p < &pids[20]; p++) {
+			if (*p) close(p - pids);
+		}
+		close(piped[Xtype]);
+		dup2(piped[!Xtype], !Xtype);
+		close(piped[!Xtype]);
+		execl("/bin/sh", "sh", "-c", command, (char *) 0);
+		_exit(127);	/* like system() ??? */
+	}
+
+	pids[piped[Xtype]] = pid;
+	close(piped[!Xtype]);
+	return fdopen(piped[Xtype], type);
+}
+
+pclose(iop)
+	FILE *iop;
+{
+	int fd = fileno(iop);
+	int status, wret;
+	int (*intsave)() = signal(SIGINT, SIG_IGN);
+	int (*quitsave)() = signal(SIGQUIT, SIG_IGN);
+
+	fclose(iop);
+	while ((wret = wait(&status)) != -1) {
+		if (wret == pids[fd]) break;
+	}
+	if (wret == -1) status = -1;
+	signal(SIGINT, intsave);
+	signal(SIGQUIT, quitsave);
+	pids[fd] = 0;
+	return status;
+}

Some files were not shown because too many files changed in this diff