Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / libcc / gen / tail_cc.2g.a
1 eÿabs.c\0\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\ 1\ 1/* $Id: abs.c,v 1.4 1994/06/24 12:12:28 ceriel Exp $ */
2
3 /*
4  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
5  * See the copyright notice in the ACK home directory, in the file "Copyright".
6  */
7
8 abs(i){
9   return i < 0 ? -i : i;
10 }
11 \0atof.c\0\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0°\0/* $Id: atof.c,v 1.6 1994/06/24 12:12:34 ceriel Exp $ */
12 #ifndef NOFLOAT
13
14 extern double strtod();
15
16 double
17 atof(p)
18         register char *p;
19 {
20         return strtod(p, (char **) 0);
21 }
22 #endif
23 strtod.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0¬\ 1/* $Id: strtod.c,v 2.5 1994/06/24 12:15:40 ceriel Exp $ */
24 #ifndef NOFLOAT
25
26 struct mantissa {
27         unsigned long h_32;
28         unsigned long l_32;
29 };
30
31 struct EXTEND {
32         short   sign;
33         short   exp;
34         struct mantissa mantissa;
35 #define m1 mantissa.h_32
36 #define m2 mantissa.l_32
37 };
38         
39
40 extern double _ext_dbl_cvt();
41
42 double
43 strtod(p, pp)
44         char *p, **pp;
45 {
46         struct EXTEND e;
47
48         _str_ext_cvt(p, pp, &e);
49         return _ext_dbl_cvt(&e);
50 }
51 #endif /* NOFLOAT */
52 atoi.c\0c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0u\ 1/* $Id: atoi.c,v 1.3 1994/06/24 12:12:37 ceriel Exp $ */
53 atoi(s)
54 register char *s;
55 {
56   register int total = 0;
57   register unsigned digit;
58   int minus = 0;
59
60   while (*s == ' ' || *s == '\t')
61         s++;
62   if (*s == '+') s++;
63   else if (*s == '-') {
64         s++;
65         minus = 1;
66   }
67   while ((digit = *s++ - '0') < 10) {
68         total *= 10;
69         total += digit;
70   }
71   return(minus ? -total : total);
72 }
73  atol.c\0c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0z\ 1/* $Id: atol.c,v 1.3 1994/06/24 12:12:40 ceriel Exp $ */
74 long atol(s)
75 register char *s;
76 {
77   register long total = 0;
78   register unsigned digit;
79   int minus = 0;
80
81   while (*s == ' ' || *s == '\t') s++;
82   if (*s == '+') s++;
83   else if (*s == '-') {
84         s++;
85         minus = 1;
86   }
87   while ((digit = *s++ - '0') < 10) {
88         total *= 10;
89         total += digit;
90   }
91   return(minus ? -total : total);
92 }
93 strtol.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ô\ 4/*
94  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
95  * See the copyright notice in the ACK home directory, in the file "Copyright".
96  */
97 /* $Id: strtol.c,v 1.2 1994/06/24 12:15:50 ceriel Exp $ */
98
99 #include        <ctype.h>
100
101 long int
102 strtol(nptr, endptr, base)
103         register char   *nptr;
104         char            **endptr;
105 {
106         register int v;
107         register long val = 0;
108         register int c;
109         int sign = 1;
110         char *startnptr = nptr, *nrstart;
111
112         if (endptr) *endptr = (char *)nptr;
113         while (isspace(*nptr)) nptr++;
114         c = *nptr;
115
116         if (c == '-' || c == '+') {
117                 if (c == '-') sign = -1;
118                 nptr++;
119         }
120         nrstart = nptr;                 /* start of the number */
121
122         /* When base is 0, the syntax determines the actual base */
123         if (base == 0)
124                 if (*nptr == '0')
125                         if (*++nptr == 'x' || *nptr == 'X') {
126                                 base = 16;
127                                 nptr++;
128                         }
129                         else    base = 8;
130                 else    base = 10;
131         else if (base==16 && *nptr=='0' && (*++nptr =='x' || *nptr =='X'))
132                 nptr++;
133
134         while (isdigit(c = *nptr) || isalpha(c)) {
135                 if (isalpha(c))
136                         v = 10 + (isupper(c) ? c - 'A' : c - 'a');
137                 else
138                         v = c - '0';
139                 if (v >= base) break;
140                 val = (val * base) + v;
141                 nptr++;
142         }
143         if (endptr) {
144                 if (nrstart == nptr) *endptr = (char *)startnptr;
145                 else *endptr = (char *)nptr;
146         }
147         return (long) sign * val;
148 }
149 bcmp.c\0c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Í\0/* $Id: bcmp.c,v 1.3 1994/06/24 12:12:43 ceriel Exp $ */
150 int
151 bcmp(b1, b2, n)
152         register char *b1, *b2;
153         register int n;
154 {
155         register int i;
156
157         while (n--) {
158                 if (i = *b2++ - *b1++) return i;
159         }
160         return 0;
161 }
162 0bfill.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0µ\0/* $Id: bfill.c,v 1.3 1994/06/24 12:12:49 ceriel Exp $ */
163 bfill(dst, len, fill)
164         register char *dst;
165         register int len;
166         register int fill;
167 {
168         while (--len >= 0)
169                 *dst++ = fill;
170 }
171 tbmove.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\86\0/* $Id: bmove.c,v 1.3 1994/06/24 12:12:52 ceriel Exp $ */
172 bmove(dst, src, len)
173         char *dst, *src;
174         int len;
175 {
176         bcopy(src, dst, len);
177 }
178 bzero.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0x\0/* $Id: bzero.c,v 1.3 1994/06/24 12:12:55 ceriel Exp $ */
179 bzero(b, l)
180         register char *b;
181 {
182         while (l-- > 0) *b++ = 0;
183 }
184 calloc.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0¥\ 1/* $Id: calloc.c,v 1.4 1994/06/24 12:12:58 ceriel Exp $ */
185 #define ALIGN(sz)       ((((sz) + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long))
186 char *
187 calloc(nelem, elsize)
188         unsigned int nelem, elsize;
189 {
190         register char *p;
191         register long *q;
192         unsigned int size = ALIGN(nelem * elsize);
193         extern char *malloc();
194
195         p = malloc(size);
196         if (p == 0) return 0;
197         q = (long *) (p + size);
198         while ((char *) q > p) *--q = 0;
199         return p;
200 }
201 rcrypt.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0@\1a/* $Id: crypt.c,v 1.3 1994/06/24 12:13:04 ceriel Exp $ */
202 /*      From Andy Tanenbaum's book "Computer Networks",
203         rewritten in C
204 */
205
206 struct block {
207         unsigned char b_data[64];
208 };
209
210 struct ordering {
211         unsigned char o_data[64];
212 };
213
214 static struct block key;
215
216 static struct ordering InitialTr = {
217         58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
218         62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
219         57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
220         61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
221 };
222
223 static struct ordering FinalTr = {
224         40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
225         38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
226         36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
227         34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25,
228 };
229
230 static struct ordering swap = {
231         33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
232         49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
233          1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
234         17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
235 };
236
237 static struct ordering KeyTr1 = {
238         57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
239         10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
240         63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
241         14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4,
242 };
243
244 static struct ordering KeyTr2 = {
245         14,17,11,24, 1, 5, 3,28,15, 6,21,10,
246         23,19,12, 4,26, 8,16, 7,27,20,13, 2,
247         41,52,31,37,47,55,30,40,51,45,33,48,
248         44,49,39,56,34,53,46,42,50,36,29,32,
249 };
250
251 static struct ordering etr = {
252         32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
253          8, 9,10,11,12,13,12,13,14,15,16,17,
254         16,17,18,19,20,21,20,21,22,23,24,25,
255         24,25,26,27,28,29,28,29,30,31,32, 1,
256 };
257
258 static struct ordering ptr = {
259         16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
260          2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,
261 };
262
263 static unsigned char s_boxes[8][64] = {
264 {       14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
265          0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
266          4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
267         15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
268 },
269
270 {       15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
271          3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
272          0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
273         13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
274 },
275
276 {       10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
277         13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
278         13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
279          1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
280 },
281
282 {        7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
283         13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
284         10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
285          3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
286 },
287
288 {        2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
289         14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
290          4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
291         11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
292 },
293
294 {       12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
295         10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
296          9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
297          4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
298 },
299
300 {        4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
301         13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
302          1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
303          6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
304 },
305
306 {       13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
307          1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
308          7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
309          2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
310 },
311 };
312
313 static int rots[] = {
314         1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
315 };
316
317 static
318 transpose(data, t, n)
319         register struct block *data;
320         register struct ordering *t;
321         register int n;
322 {
323         struct block x;
324
325         x = *data;
326
327         while (n-- > 0) {
328                 data->b_data[n] = x.b_data[t->o_data[n] - 1];
329         }
330 }
331
332 static
333 rotate(key)
334         register struct block *key;
335 {
336         register unsigned char *p = key->b_data;
337         register unsigned char *ep = &(key->b_data[55]);
338         int data0 = key->b_data[0], data28 = key->b_data[28];
339
340         while (p++ < ep) *(p-1) = *p;
341         key->b_data[27] = data0;
342         key->b_data[55] = data28;
343 }
344
345 static struct ordering *EP = &etr;
346
347 static
348 f(i, key, a, x)
349         struct block *key, *a;
350         register struct block *x;
351 {
352         struct block e, ikey, y;
353         int k;
354         register unsigned char *p, *q, *r;
355
356         e = *a;
357         transpose(&e, EP, 48);
358         for (k = rots[i]; k; k--) rotate(key);
359         ikey = *key;
360         transpose(&ikey, &KeyTr2, 48);
361         p = &(y.b_data[48]);
362         q = &(e.b_data[48]);
363         r = &(ikey.b_data[48]);
364         while (p > y.b_data) {
365                 *--p = *--q ^ *--r;
366         }
367         q = x->b_data;
368         for (k = 0; k < 8; k++) {
369                 register int xb, r;
370
371                 r = *p++ << 5;
372                 r += *p++ << 3;
373                 r += *p++ << 2;
374                 r += *p++ << 1;
375                 r += *p++;
376                 r += *p++ << 4;
377
378                 xb = s_boxes[k][r];
379
380                 *q++ = (xb >> 3) & 1;
381                 *q++ = (xb>>2) & 1;
382                 *q++ = (xb>>1) & 1;
383                 *q++ = (xb & 1);
384         }
385         transpose(x, &ptr, 32);
386 }
387
388 setkey(k)
389         register char *k;
390 {
391
392         key = *((struct block *) k);
393         transpose(&key, &KeyTr1, 56);
394 }
395
396 encrypt(blck, edflag)
397         char *blck;
398 {
399         register struct block *p = (struct block *) blck;
400         register int i;
401
402         transpose(p, &InitialTr, 64);
403         for (i = 15; i>= 0; i--) {
404                 int j = edflag ? i : 15 - i;
405                 register int k;
406                 struct block b, x;
407
408                 b = *p;
409                 for (k = 31; k >= 0; k--) {
410                         p->b_data[k] = b.b_data[k + 32];
411                 }
412                 f(j, &key, p, &x);
413                 for (k = 31; k >= 0; k--) {
414                         p->b_data[k+32] = b.b_data[k] ^ x.b_data[k];
415                 }
416         }
417         transpose(p, &swap, 64);
418         transpose(p, &FinalTr, 64);
419 }
420
421 char *
422 crypt(pw,salt)
423         register char *pw;
424         char *salt;
425 {
426         /*      Unfortunately, I had to look at the sources of V7 crypt.
427                 There was no other way to find out what this routine
428                 actually does.
429         */
430         
431         char pwb[66];
432         static char result[16];
433         register char *p = pwb;
434         struct ordering new_etr;
435         register int i;
436
437         while (*pw && p < &pwb[64]) {
438                 register int j = 7;
439
440                 while (j--) {
441                         *p++ = (*pw >> j) & 01;
442                 }
443                 pw++;
444                 *p++ = 0;
445         }
446         while (p < &pwb[64]) *p++ = 0;
447
448         setkey(p = pwb);
449
450         while (p < &pwb[66]) *p++ = 0;
451
452         new_etr = etr;
453         EP = &new_etr;
454         for (i = 0; i < 2; i++) {
455                 register char c = *salt++;
456                 register int j;
457
458                 result[i] = c;
459                 if ( c > 'Z') c -= 6 + 7 + '.'; /* c was a lower case letter */
460                 else if ( c > '9') c -= 7 + '.';/* c was upper case letter */
461                 else c -= '.';                  /* c was digit, '.' or '/'. */
462                                                 /* now, 0 <= c <= 63 */
463                 for (j = 0; j < 6; j++) {
464                         if ((c >> j) & 01) {
465                                 int t = 6*i + j;
466                                 int temp = new_etr.o_data[t];
467                                 new_etr.o_data[t] = new_etr.o_data[t+24];
468                                 new_etr.o_data[t+24] = temp;
469                         }
470                 }
471         }
472
473         if (result[1] == 0) result[1] = result[0];
474
475         for (i = 0; i < 25; i++) encrypt(pwb,0);
476         EP = &etr;
477
478         p = pwb;
479         pw = result+2;
480         while (p < &pwb[66]) {
481                 register int c = 0;
482                 register int j = 6;
483
484                 while (j--) {
485                         c <<= 1;
486                         c |= *p++;
487                 }
488                 c += '.';               /* becomes >= '.' */
489                 if (c > '9') c += 7;    /* not in [./0-9], becomes upper */
490                 if (c > 'Z') c += 6;    /* not in [A-Z], becomes lower */
491                 *pw++ = c;
492         }
493         *pw = 0;
494         return result;
495 }
496 ctime.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Î\0/* $Id: ctime.c,v 1.6 1994/06/24 12:13:07 ceriel Exp $ */
497 #include <time.h>
498
499 extern struct tm *localtime();
500 extern char *asctime();
501
502 char *
503 ctime(clock)
504         long *clock;
505 {
506         return asctime(localtime(clock));
507 }
508 asctime.c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Â\ 4/* $Id: asctime.c,v 1.6 1994/06/24 12:12:31 ceriel Exp $ */
509 #include <time.h>
510
511 #define DATE_STR "??? ??? ?? ??:??:?? ????\n"
512
513 static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
514
515 static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
516                           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
517
518 static char *two_digits();
519 static char *four_digits();
520
521 char *
522 asctime(tm)
523         register struct tm *tm;
524 {
525         static char buf[32];
526         register char *pb = buf, *ps;
527         
528         strcpy(pb, DATE_STR);
529         ps = days[tm->tm_wday];
530         while (*ps) *pb++ = *ps++;
531         pb++;
532         ps = months[tm->tm_mon];
533         while (*ps) *pb++ = *ps++; 
534         pb++;
535         pb = two_digits(
536                 two_digits(
537                    two_digits(
538                       two_digits(pb, tm->tm_mday, 0),
539                       tm->tm_hour, 1),
540                    tm->tm_min, 1),
541                 tm->tm_sec, 1);
542         four_digits(pb, tm->tm_year+1900);
543         return(buf);
544 }
545
546 static char *
547 two_digits(pb, i, nospace)
548         register char *pb;
549 {
550         *pb = (i / 10) % 10 + '0';
551         if (!nospace && *pb == '0') *pb = ' ';
552         pb++;
553         *pb++ = (i % 10) + '0';
554         return ++pb;
555 }
556
557 static char *
558 four_digits(pb, i)
559         register char *pb;
560 {
561         i %= 10000;
562         *pb++ = (i / 1000) + '0';
563         i %= 1000;
564         *pb++ = (i / 100) + '0';
565         i %= 100;
566         *pb++ = (i / 10) + '0';
567         *pb++ = (i % 10) + '0';
568         return ++pb;
569 }
570 execvp.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0q\ 2/* $Id: execvp.c,v 1.3 1994/06/24 12:13:13 ceriel Exp $ */
571 char    *getenv();
572 char    *index();
573
574 execlp(name, argv)
575 char *name, *argv;
576 {
577         return(execvp(name, &argv));
578 }
579
580 execvp(name, argv)
581 char *name, **argv;
582 {
583         char *path = getenv("PATH");
584         register char *c = "";
585         char progname[1024];
586
587         if (path == 0) path = ":/bin:/usr/bin";
588         if (! index(name, '/')) c = path;
589
590         do {
591                 register char *p = progname;
592                 register char *n = name;
593                 char *c1 = c;
594
595                 while (*c && *c != ':') {
596                         *p++ = *c++;
597                 }
598                 if (c != c1) *p++ = '/';
599                 if (*c) c++;
600                 while (*n) *p++ = *n++;
601                 *p = 0;
602
603                 execv(progname, argv);
604         } while (*c);
605         return(-1);
606 }
607  ffc.c\0.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ñ\0/* $Id: ffc.c,v 1.3 1994/06/24 12:13:20 ceriel Exp $ */
608 ffc(i)
609         register int i;
610 {
611         register int n;
612
613         for (n = 8*sizeof(int); n > 0; n--, i >>= 1)
614                 if (!(i&1))
615                         return (8*sizeof(int) + 1) - n;
616         return -1;
617 }
618 cffs.c\0.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ð\0/* $Id: ffs.c,v 1.3 1994/06/24 12:13:23 ceriel Exp $ */
619 ffs(i)
620         register int i;
621 {
622         register int n;
623
624         for (n = 8*sizeof(int); n > 0; n--, i >>= 1)
625                 if ((i&1))
626                         return (8*sizeof(int) + 1) - n;
627         return -1;
628 }
629 gcvt.c\0c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ñ\ 4/* $Id: gcvt.c,v 1.6 1994/06/24 12:13:26 ceriel Exp $ */
630 #ifndef NOFLOAT
631 extern char     *ecvt();
632
633 #define NDIGINEXP(exp)  (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
634
635 char *
636 gcvt(value, ndigit, buf)
637         double value;
638         char *buf;
639         int ndigit;
640 {
641         int sign, dp;
642         register char *s1, *s2;
643         register int i;
644         register int nndigit = ndigit;
645
646         s1 = ecvt(value, ndigit, &dp, &sign);
647         s2 = buf;
648         if (sign) *s2++ = '-';
649         for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--) nndigit--;
650         if (dp > ndigit || dp < -(NDIGINEXP(dp)+1)) {
651                 /* Use E format, otherwise we need too many '0''s */
652                 dp--;
653                 *s2++ = *s1++;
654                 *s2++ = '.';
655                 while (--nndigit > 0) *s2++ = *s1++;
656                 *s2++ = 'e';
657                 if (dp < 0) {
658                         *s2++ = '-';
659                         dp = -dp;
660                 }
661                 else     *s2++ = '+';
662                 s2 += NDIGINEXP(dp);
663                 *s2 = 0;
664                 for (i = NDIGINEXP(dp); i > 0; i--) {
665                         *--s2 = dp % 10 + '0';
666                         dp /= 10;
667                 }
668                 return buf;
669         }
670         if (dp <= 0) {
671                 if (*s1 != '0') {
672                         /* otherwise the whole number is 0 */
673                         *s2++ = '0';
674                         *s2++ = '.';
675                 }
676                 while (dp < 0) {
677                         dp++;
678                         *s2++ = '0';
679                 }
680         }
681         for (i = 1; i <= nndigit; i++) {
682                 *s2++ = *s1++;
683                 if (i == dp) *s2++ = '.';
684         }
685         if (i <= dp) {
686                 while (i++ <= dp) *s2++ = '0';
687                 *s2++ = '.';
688         }
689         if (s2[-1]=='.') s2--;
690         *s2 = '\0';
691         return buf;
692 }
693 #endif
694  ecvt.c\0c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\11\ 3/* $Id: ecvt.c,v 1.13 1994/06/24 12:13:10 ceriel Exp $ */
695
696 #ifndef NOFLOAT
697
698 struct mantissa {
699         unsigned long h_32;
700         unsigned long l_32;
701 };
702
703 struct EXTEND {
704         short   sign;
705         short   exp;
706         struct mantissa mantissa;
707 #define m1 mantissa.h_32
708 #define m2 mantissa.l_32
709 };
710         
711 extern char *_ext_str_cvt();
712
713 static char *
714 cvt(value, ndigit, decpt, sign, ecvtflag)
715         double value;
716         int ndigit, *decpt, *sign;
717 {
718         struct EXTEND e;
719
720         _dbl_ext_cvt(value, &e);
721         return _ext_str_cvt(&e, ndigit, decpt, sign, ecvtflag);
722 }
723
724 char *
725 ecvt(value, ndigit, decpt, sign)
726         double value;
727         int ndigit, *decpt, *sign;
728 {
729
730         return cvt(value, ndigit, decpt, sign, 1);
731 }
732
733 char *
734 fcvt(value, ndigit, decpt, sign)
735         double value;
736         int ndigit, *decpt, *sign;
737 {
738         return cvt(value, ndigit, decpt, sign, 0);
739 }
740
741 #endif /* NOFLOAT */
742 ;ext_comp.c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0#:/*
743   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
744   See the copyright notice in the ACK home directory, in the file "Copyright".
745 */
746
747 /* $Id: ext_comp.c,v 2.6 1994/06/24 12:13:16 ceriel Exp $ */
748
749 /* extended precision arithmetic for the strtod() and cvt() routines */
750
751 /* This may require some more work when long doubles get bigger than 8
752    bytes. In this case, these routines may become obsolete. ???
753 */
754
755 static int b64_add();
756 static int b64_sft();
757
758 #include <ctype.h>
759
760 struct mantissa {
761         unsigned long h_32;
762         unsigned long l_32;
763 };
764
765 struct EXTEND {
766         short   sign;
767         short   exp;
768         struct mantissa mantissa;
769 #define m1 mantissa.h_32
770 #define m2 mantissa.l_32
771 };
772
773 static
774 mul_ext(e1,e2,e3)
775 struct EXTEND   *e1,*e2,*e3;
776 {
777         /*      Multiply the extended numbers e1 and e2, and put the
778                 result in e3.
779         */
780         register int    i,j;            /* loop control */
781         unsigned short  mp[4];
782         unsigned short  mc[4];
783         unsigned short  result[8];      /* result */
784
785         register unsigned short *pres;
786
787         /* first save the sign (XOR)                    */
788         e3->sign = e1->sign ^ e2->sign;
789
790         /* compute new exponent */
791         e3->exp = e1->exp + e2->exp + 1;
792
793         /* check for overflow/underflow ??? */
794
795         /* 128 bit multiply of mantissas        */
796
797         /* assign unknown long formats          */
798         /* to known unsigned word formats       */
799         mp[0] = e1->m1 >> 16;
800         mp[1] = (unsigned short) e1->m1;
801         mp[2] = e1->m2 >> 16;
802         mp[3] = (unsigned short) e1->m2;
803         mc[0] = e2->m1 >> 16;
804         mc[1] = (unsigned short) e2->m1;
805         mc[2] = e2->m2 >> 16;
806         mc[3] = (unsigned short) e2->m2;
807         for (i = 8; i--;) {
808                 result[i] = 0;
809         }
810         /*
811          *      fill registers with their components
812          */
813         for(i=4, pres = &result[4];i--;pres--) if (mp[i]) {
814                 unsigned short k = 0;
815                 unsigned long mpi = mp[i];
816                 for(j=4;j--;) {
817                         unsigned long tmp = (unsigned long)pres[j] + k;
818                         if (mc[j]) tmp += mpi * mc[j];
819                         pres[j] = tmp;
820                         k = tmp >> 16;
821                 }
822                 pres[-1] = k;
823         }
824
825         if (! (result[0] & 0x8000)) {
826                 e3->exp--;
827                 for (i = 0; i <= 3; i++) {
828                         result[i] <<= 1;
829                         if (result[i+1]&0x8000) result[i] |= 1;
830                 }
831                 result[4] <<= 1;
832         }       
833         /*
834          *      combine the registers to a total
835          */
836         e3->m1 = ((unsigned long)(result[0]) << 16) + result[1];
837         e3->m2 = ((unsigned long)(result[2]) << 16) + result[3];
838         if (result[4] & 0x8000) {
839                 if (++e3->m2 == 0) {
840                         if (++e3->m1 == 0) {
841                                 e3->m1 = 0x80000000;
842                                 e3->exp++;
843                         }
844                 }
845         }
846 }
847
848 static
849 add_ext(e1,e2,e3)
850 struct EXTEND   *e1,*e2,*e3;
851 {
852         /*      Add two extended numbers e1 and e2, and put the result
853                 in e3
854         */
855         struct EXTEND ce2;
856         int diff;
857
858         if ((e2->m1 | e2->m2) == 0L) {
859                 *e3 = *e1;
860                 return;
861         }
862         if ((e1->m1 | e1->m2) == 0L) {
863                 *e3 = *e2;
864                 return;
865         }
866         ce2 = *e2;
867         *e3 = *e1;
868         e1 = &ce2;
869
870         /* adjust mantissas to equal power */
871         diff = e3->exp - e1->exp;
872         if (diff < 0) {
873                 diff = -diff;
874                 e3->exp += diff;
875                 b64_sft(&(e3->mantissa), diff);
876         }
877         else if (diff > 0) {
878                 e1->exp += diff;
879                 b64_sft(&(e1->mantissa), diff);
880         }
881         if (e1->sign != e3->sign) {
882                 /* e3 + e1 = e3 - (-e1) */
883                 if (e1->m1 > e3->m1 ||
884                     (e1->m1 == e3->m1 && e1->m2 > e3->m2)) {
885                         /*      abs(e1) > abs(e3) */
886                         if (e3->m2 > e1->m2) {
887                                 e1->m1 -= 1;    /* carry in */
888                         }
889                         e1->m1 -= e3->m1;
890                         e1->m2 -= e3->m2;
891                         *e3 = *e1;
892                 }
893                 else {
894                         if (e1->m2 > e3->m2)
895                                 e3->m1 -= 1;    /* carry in */
896                         e3->m1 -= e1->m1;
897                         e3->m2 -= e1->m2;
898                 }
899         }
900         else {
901                 if (b64_add(&e3->mantissa,&e1->mantissa)) {/* addition carry */
902                         b64_sft(&e3->mantissa,1);/* shift mantissa one bit RIGHT */
903                         e3->m1 |= 0x80000000L;  /* set max bit  */
904                         e3->exp++;              /* increase the exponent */
905                 }
906         }
907         if ((e3->m2 | e3->m1) != 0L) {
908                 /* normalize */
909                 if (e3->m1 == 0L) {
910                         e3->m1 = e3->m2; e3->m2 = 0L; e3->exp -= 32;
911                 }
912                 if (!(e3->m1 & 0x80000000)) {
913                         unsigned long l = 0x40000000;
914                         int cnt = -1;
915
916                         while (! (l & e3->m1)) {
917                                 l >>= 1; cnt--;
918                         }
919                         e3->exp += cnt;
920                         b64_sft(&(e3->mantissa), cnt);
921                 }
922         }
923 }
924
925 static int
926 cmp_ext(e1, e2)
927         struct EXTEND *e1, *e2;
928 {
929         struct EXTEND tmp;
930
931         e2->sign = ! e2->sign;
932         add_ext(e1, e2, &tmp);
933         e2->sign = ! e2->sign;
934         if (tmp.m1 == 0 && tmp.m2 == 0) return 0;
935         if (tmp.sign) return -1;
936         return 1;
937 }
938
939 static
940 b64_sft(e1,n)
941         struct mantissa *e1;
942         int             n;
943 {
944         if (n > 0) {
945                 if (n > 63) {
946                         e1->l_32 = 0;
947                         e1->h_32 = 0;
948                         return;
949                 }
950                 if (n >= 32) {
951                         e1->l_32 = e1->h_32;
952                         e1->h_32 = 0;
953                         n -= 32;
954                 }
955                 if (n > 0) {
956                         e1->l_32 >>= n;
957                         if (e1->h_32 != 0) {
958                                 e1->l_32 |= (e1->h_32 << (32 - n));
959                                 e1->h_32 >>= n;
960                         }
961                 }
962                 return;
963         }
964         n = -n;
965         if (n > 0) {
966                 if (n > 63) {
967                         e1->l_32 = 0;
968                         e1->h_32 = 0;
969                         return;
970                 }
971                 if (n >= 32) {
972                         e1->h_32 = e1->l_32;
973                         e1->l_32 = 0;
974                         n -= 32;
975                 }
976                 if (n > 0) {
977                         e1->h_32 <<= n;
978                         if (e1->l_32 != 0) {
979                                 e1->h_32 |= (e1->l_32 >> (32 - n));
980                                 e1->l_32 <<= n;
981                         }
982                 }
983         }
984 }
985
986 static int
987 b64_add(e1,e2)
988                 /*
989                  * pointers to 64 bit 'registers'
990                  */
991         struct mantissa *e1,*e2;
992 {
993         register int    overflow;
994         int             carry;
995
996                         /* add higher pair of 32 bits */
997         overflow = ((unsigned long) 0xFFFFFFFF - e1->h_32 < e2->h_32);
998         e1->h_32 += e2->h_32;
999
1000                         /* add lower pair of 32 bits */
1001         carry = ((unsigned long) 0xFFFFFFFF - e1->l_32 < e2->l_32);
1002         e1->l_32 += e2->l_32;
1003         if ((carry) && (++e1->h_32 == 0))
1004                 return(1);              /* had a 64 bit overflow */
1005         else
1006                 return(overflow);       /* return status from higher add */
1007 }
1008
1009 /* The following tables can be computed with the following bc(1)
1010    program:
1011
1012 obase=16
1013 scale=0
1014 define t(x){
1015         auto a, b, c
1016         a=2;b=1;c=2^32;n=1
1017         while(a<x) {
1018                 b=a;n+=n;a*=a
1019         }
1020         n/=2
1021         a=b
1022         while(b<x) {
1023                 a=b;b*=c;n+=32
1024         }
1025         n-=32
1026         b=a
1027         while(a<x) {
1028                 b=a;a+=a;n+=1
1029         }
1030         n-=1
1031         x*=16^16
1032         b=x%a
1033         x/=a
1034         if(a<=(2*b)) x+=1
1035         obase=10
1036         n
1037         obase=16
1038         return(x)
1039 }
1040 for (i=1;i<28;i++) {
1041         t(10^i)
1042 }
1043 0
1044 for (i=1;i<20;i++) {
1045         t(10^(28*i))
1046 }
1047 0
1048 define r(x){
1049         auto a, b, c
1050         a=2;b=1;c=2^32;n=1
1051         while(a<x) {
1052                 b=a;n+=n;a*=a
1053         }
1054         n/=2
1055         a=b
1056         while(b<x) {
1057                 a=b;b*=c;n+=32
1058         }
1059         n-=32
1060         b=a
1061         while(a<x) {
1062                 b=a;a+=a;n+=1
1063         }
1064         a=b
1065         a*=16^16
1066         b=a%x
1067         a/=x
1068         if(x<=(2*b)) a+=1
1069         obase=10
1070         -n
1071         obase=16
1072         return(a)
1073 }
1074 for (i=1;i<28;i++) {
1075         r(10^i)
1076 }
1077 0
1078 for (i=1;i<20;i++) {
1079         r(10^(28*i))
1080 }
1081 0
1082
1083 */
1084 static struct EXTEND ten_powers[] = {   /* representation of 10 ** i */
1085         { 0,    0,      0x80000000,     0 },
1086         { 0,    3,      0xA0000000,     0 },
1087         { 0,    6,      0xC8000000,     0 },
1088         { 0,    9,      0xFA000000,     0 },
1089         { 0,    13,     0x9C400000,     0 },
1090         { 0,    16,     0xC3500000,     0 },
1091         { 0,    19,     0xF4240000,     0 },
1092         { 0,    23,     0x98968000,     0 },
1093         { 0,    26,     0xBEBC2000,     0 },
1094         { 0,    29,     0xEE6B2800,     0 },
1095         { 0,    33,     0x9502F900,     0 },
1096         { 0,    36,     0xBA43B740,     0 },
1097         { 0,    39,     0xE8D4A510,     0 },
1098         { 0,    43,     0x9184E72A,     0 },
1099         { 0,    46,     0xB5E620F4,     0x80000000 },
1100         { 0,    49,     0xE35FA931,     0xA0000000 },
1101         { 0,    53,     0x8E1BC9BF,     0x04000000 },
1102         { 0,    56,     0xB1A2BC2E,     0xC5000000 },
1103         { 0,    59,     0xDE0B6B3A,     0x76400000 },
1104         { 0,    63,     0x8AC72304,     0x89E80000 },
1105         { 0,    66,     0xAD78EBC5,     0xAC620000 },
1106         { 0,    69,     0xD8D726B7,     0x177A8000 },
1107         { 0,    73,     0x87867832,     0x6EAC9000 },
1108         { 0,    76,     0xA968163F,     0x0A57B400 },
1109         { 0,    79,     0xD3C21BCE,     0xCCEDA100 },
1110         { 0,    83,     0x84595161,     0x401484A0 },
1111         { 0,    86,     0xA56FA5B9,     0x9019A5C8 },
1112         { 0,    89,     0xCECB8F27,     0xF4200F3A }
1113 };
1114 static struct EXTEND big_ten_powers[] = {  /* representation of 10 ** (28*i) */
1115         { 0,    0,      0x80000000,     0 },
1116         { 0,    93,     0x813F3978,     0xF8940984 },
1117         { 0,    186,    0x82818F12,     0x81ED44A0 },
1118         { 0,    279,    0x83C7088E,     0x1AAB65DB },
1119         { 0,    372,    0x850FADC0,     0x9923329E },
1120         { 0,    465,    0x865B8692,     0x5B9BC5C2 },
1121         { 0,    558,    0x87AA9AFF,     0x79042287 },
1122         { 0,    651,    0x88FCF317,     0xF22241E2 },
1123         { 0,    744,    0x8A5296FF,     0xE33CC930 },
1124         { 0,    837,    0x8BAB8EEF,     0xB6409C1A },
1125         { 0,    930,    0x8D07E334,     0x55637EB3 },
1126         { 0,    1023,   0x8E679C2F,     0x5E44FF8F },
1127         { 0,    1116,   0x8FCAC257,     0x558EE4E6 },
1128         { 0,    1209,   0x91315E37,     0xDB165AA9 },
1129         { 0,    1302,   0x929B7871,     0xDE7F22B9 },
1130         { 0,    1395,   0x940919BB,     0xD4620B6D },
1131         { 0,    1488,   0x957A4AE1,     0xEBF7F3D4 },
1132         { 0,    1581,   0x96EF14C6,     0x454AA840 },
1133         { 0,    1674,   0x98678061,     0x27ECE4F5 },
1134         { 0,    1767,   0x99E396C1,     0x3A3ACFF2 }
1135 };
1136
1137 static struct EXTEND r_ten_powers[] = { /* representation of 10 ** -i */
1138         { 0,    0,      0x80000000,     0 },
1139         { 0,    -4,     0xCCCCCCCC,     0xCCCCCCCD },
1140         { 0,    -7,     0xA3D70A3D,     0x70A3D70A },
1141         { 0,    -10,    0x83126E97,     0x8D4FDF3B },
1142         { 0,    -14,    0xD1B71758,     0xE219652C },
1143         { 0,    -17,    0xA7C5AC47,     0x1B478423 },
1144         { 0,    -20,    0x8637BD05,     0xAF6C69B6 },
1145         { 0,    -24,    0xD6BF94D5,     0xE57A42BC },
1146         { 0,    -27,    0xABCC7711,     0x8461CEFD },
1147         { 0,    -30,    0x89705F41,     0x36B4A597 },
1148         { 0,    -34,    0xDBE6FECE,     0xBDEDD5BF },
1149         { 0,    -37,    0xAFEBFF0B,     0xCB24AAFF },
1150         { 0,    -40,    0x8CBCCC09,     0x6F5088CC },
1151         { 0,    -44,    0xE12E1342,     0x4BB40E13 },
1152         { 0,    -47,    0xB424DC35,     0x095CD80F },
1153         { 0,    -50,    0x901D7CF7,     0x3AB0ACD9 },
1154         { 0,    -54,    0xE69594BE,     0xC44DE15B },
1155         { 0,    -57,    0xB877AA32,     0x36A4B449 },
1156         { 0,    -60,    0x9392EE8E,     0x921D5D07 },
1157         { 0,    -64,    0xEC1E4A7D,     0xB69561A5 },
1158         { 0,    -67,    0xBCE50864,     0x92111AEB },
1159         { 0,    -70,    0x971DA050,     0x74DA7BEF },
1160         { 0,    -74,    0xF1C90080,     0xBAF72CB1 },
1161         { 0,    -77,    0xC16D9A00,     0x95928A27 },
1162         { 0,    -80,    0x9ABE14CD,     0x44753B53 },
1163         { 0,    -84,    0xF79687AE,     0xD3EEC551 },
1164         { 0,    -87,    0xC6120625,     0x76589DDB },
1165         { 0,    -90,    0x9E74D1B7,     0x91E07E48 }
1166 };
1167
1168 static struct EXTEND r_big_ten_powers[] = { /* representation of 10 ** -(28*i) */
1169         { 0,    0,      0x80000000,     0 },
1170         { 0,    -94,    0xFD87B5F2,     0x8300CA0E },
1171         { 0,    -187,   0xFB158592,     0xBE068D2F },
1172         { 0,    -280,   0xF8A95FCF,     0x88747D94 },
1173         { 0,    -373,   0xF64335BC,     0xF065D37D },
1174         { 0,    -466,   0xF3E2F893,     0xDEC3F126 },
1175         { 0,    -559,   0xF18899B1,     0xBC3F8CA2 },
1176         { 0,    -652,   0xEF340A98,     0x172AACE5 },
1177         { 0,    -745,   0xECE53CEC,     0x4A314EBE },
1178         { 0,    -838,   0xEA9C2277,     0x23EE8BCB },
1179         { 0,    -931,   0xE858AD24,     0x8F5C22CA },
1180         { 0,    -1024,  0xE61ACF03,     0x3D1A45DF },
1181         { 0,    -1117,  0xE3E27A44,     0x4D8D98B8 },
1182         { 0,    -1210,  0xE1AFA13A,     0xFBD14D6E },
1183         { 0,    -1303,  0xDF82365C,     0x497B5454 },
1184         { 0,    -1396,  0xDD5A2C3E,     0xAB3097CC },
1185         { 0,    -1489,  0xDB377599,     0xB6074245 },
1186         { 0,    -1582,  0xD91A0545,     0xCDB51186 },
1187         { 0,    -1675,  0xD701CE3B,     0xD387BF48 },
1188         { 0,    -1768,  0xD4EEC394,     0xD6258BF8 }
1189 };
1190
1191 static
1192 add_exponent(e, exp)
1193         struct EXTEND   *e;
1194 {
1195         int neg = exp < 0;
1196         int divsz, modsz;
1197         struct EXTEND x;
1198
1199         if (neg) exp = -exp;
1200         divsz = exp / (sizeof(ten_powers)/sizeof(ten_powers[0]));
1201         modsz = exp % (sizeof(ten_powers)/sizeof(ten_powers[0]));
1202         if (neg) {
1203                 mul_ext(e, &r_ten_powers[modsz], &x);
1204                 mul_ext(&x, &r_big_ten_powers[divsz], e);
1205         }
1206         else {
1207                 mul_ext(e, &ten_powers[modsz], &x);
1208                 mul_ext(&x, &big_ten_powers[divsz], e);
1209         }
1210 }
1211
1212 _str_ext_cvt(s, ss, e)
1213         char            *s, **ss;
1214         struct EXTEND   *e;
1215 {
1216         /*      Like strtod, but for extended precision */
1217         register int    c;
1218         int             dotseen = 0;
1219         int             digitseen = 0;
1220         int             exp = 0;
1221
1222         if (ss) *ss = s;
1223         while (isspace(*s)) s++;
1224
1225         e->sign = 0;
1226         e->exp = 0;
1227         e->m1 = e->m2 = 0;
1228
1229         c = *s;
1230         switch(c) {
1231         case '-':
1232                 e->sign = 1;
1233         case '+':
1234                 s++;
1235         }
1236         while (c = *s++, isdigit(c) || (c == '.' && ! dotseen++)) {
1237                 if (c == '.') continue;
1238                 digitseen = 1;
1239                 if (e->m1 <= (unsigned long)(0xFFFFFFFF)/10) {
1240                         struct mantissa a1;
1241
1242                         a1 = e->mantissa;
1243                         b64_sft(&(e->mantissa), -3);
1244                         b64_sft(&a1, -1);
1245                         b64_add(&(e->mantissa), &a1);
1246                         a1.h_32 = 0;
1247                         a1.l_32 = c - '0';
1248                         b64_add(&(e->mantissa), &a1);
1249                 }
1250                 else exp++;
1251                 if (dotseen) exp--;
1252         }
1253         if (! digitseen) return;
1254
1255         if (ss) *ss = s - 1;
1256
1257         if (c == 'E' || c == 'e') {
1258                 int     exp1 = 0;
1259                 int     sign = 1;
1260
1261                 switch(*s) {
1262                 case '-':
1263                         sign = -1;
1264                 case '+':
1265                         s++;
1266                 }
1267                 if (c = *s, isdigit(c)) {
1268                         do {
1269                                 exp1 = 10 * exp1 + (c - '0');
1270                         } while (c = *++s, isdigit(c));
1271                         if (ss) *ss = s;
1272                 }
1273                 exp += sign * exp1;
1274         }
1275         if (e->m1 == 0 && e->m2 == 0) return;
1276         e->exp = 63;
1277         while (! (e->m1 & 0x80000000)) {
1278                 b64_sft(&(e->mantissa),-1);
1279                 e->exp--;
1280         }
1281         add_exponent(e, exp);
1282 }
1283
1284 extern double ldexp(), frexp(), modf();
1285
1286 #define NDIGITS 128
1287
1288 char *
1289 _ext_str_cvt(e, ndigit, decpt, sign, ecvtflag)
1290         struct EXTEND *e;
1291         int ndigit, *decpt, *sign;
1292 {
1293         /*      Like cvt(), but for extended precision */
1294
1295         static char buf[NDIGITS+1];
1296         register char *p = buf;
1297         register char *pe;
1298         int findex = 0;
1299
1300         if (ndigit < 0) ndigit = 0;
1301         if (ndigit > NDIGITS) ndigit = NDIGITS;
1302         pe = &buf[ndigit];
1303         buf[0] = '\0';
1304
1305         *sign = 0;
1306         if (e->sign) {
1307                 *sign = 1;
1308                 e->sign = 0;
1309         }
1310
1311         *decpt = 0;
1312         if (e->m1 != 0) {
1313                 register struct EXTEND *pp = &big_ten_powers[1];
1314
1315                 while(cmp_ext(e,pp) >= 0) pp++;
1316                 pp--;
1317                 findex = pp - big_ten_powers;
1318                 mul_ext(e,&r_big_ten_powers[findex],e);
1319                 *decpt += findex * (sizeof(ten_powers)/sizeof(ten_powers[0]));
1320                 pp = &ten_powers[1];
1321                 while(pp<&ten_powers[(sizeof(ten_powers)/sizeof(ten_powers[0]))] &&
1322                       cmp_ext(e, pp) >= 0) pp++;
1323                 pp--;
1324                 findex = pp - ten_powers;
1325                 *decpt += findex;
1326
1327                 if (cmp_ext(e, &ten_powers[0]) < 0) {
1328                         pp = &r_big_ten_powers[1];
1329                         while(cmp_ext(e,pp) < 0) pp++;
1330                         pp--;
1331                         findex = pp - r_big_ten_powers;
1332                         mul_ext(e,&big_ten_powers[findex],e);
1333                         *decpt -= findex *
1334                                 (sizeof(ten_powers)/sizeof(ten_powers[0]));
1335                         /* here, value >= 10 ** -28 */
1336                         mul_ext(e, &ten_powers[1], e);
1337                         (*decpt)--;
1338                         pp = &r_ten_powers[0];
1339                         while(cmp_ext(e, pp) < 0) pp++;
1340                         findex = -(pp - r_ten_powers);
1341                         mul_ext(e, &ten_powers[-findex], e);
1342                         *decpt += findex;
1343                         findex = 0;
1344                 }
1345                 (*decpt)++;     /* because now value in [1.0, 10.0) */
1346         }
1347         if (! ecvtflag) {
1348                 /* for fcvt() we need ndigit digits behind the dot */
1349                 pe += *decpt;
1350                 if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
1351         }
1352         while (p <= pe) {
1353                 if (findex) {
1354                         struct EXTEND tc, oldtc;
1355                         int count = 0;
1356
1357                         oldtc.exp = 0;
1358                         oldtc.sign = 0;
1359                         oldtc.m1 = 0;
1360                         oldtc.m2 = 0;
1361                         tc = ten_powers[findex];
1362                         while (cmp_ext(e, &tc) >= 0) {
1363                                 oldtc = tc;
1364                                 add_ext(&tc, &ten_powers[findex], &tc);
1365                                 count++;
1366                         }
1367                         *p++ = count + '0';
1368                         oldtc.sign = 1;
1369                         add_ext(e, &oldtc, e);
1370                         findex--;
1371                         continue;
1372                 }
1373                 if (e->exp >= 0 && e->m1 != 0) {
1374                         struct EXTEND x;
1375
1376                         x.m2 = 0; x.exp = e->exp;
1377                         x.sign = 1;
1378                         x.m1 = e->m1>>(31-e->exp);
1379                         *p++ = (x.m1) + '0';
1380                         if (x.m1) {
1381                                 x.m1 = x.m1 << (31-e->exp);
1382                                 add_ext(e, &x, e);
1383                         }
1384                 }
1385                 else *p++ = '0';
1386                 if (e->m1) mul_ext(e, &ten_powers[1], e);
1387         }
1388         if (pe >= buf) {
1389                 p = pe;
1390                 *p += 5;        /* round of at the end */
1391                 while (*p > '9') {
1392                         *p = '0';
1393                         if (p > buf) ++*--p;
1394                         else {
1395                                 *p = '1';
1396                                 ++*decpt;
1397                                 if (! ecvtflag) {
1398                                         /* maybe add another digit at the end,
1399                                            because the point was shifted right
1400                                         */
1401                                         if (pe > buf) *pe = '0';
1402                                         pe++;
1403                                 }
1404                         }
1405                 }
1406                 *pe = '\0';
1407         }
1408         return buf;
1409 }
1410
1411 _dbl_ext_cvt(value, e)
1412         double value;
1413         struct EXTEND *e;
1414 {
1415         /*      Convert double to extended
1416         */
1417         int exponent;
1418         register int i;
1419
1420         value = frexp(value, &exponent);
1421         e->sign = value < 0.0;
1422         if (e->sign) value = -value;
1423         e->exp = exponent - 1;
1424         e->m1 = 0;
1425         e->m2 = 0;
1426         for (i = 64; i > 0 && value != 0; i--) {
1427                 double ipart;
1428
1429                 b64_sft(&(e->mantissa),-1);
1430                 value = modf(2.0*value, &ipart);
1431                 if (ipart) {
1432                         e->m2 |= 1;
1433                 }
1434         }
1435         if (i > 0) b64_sft(&(e->mantissa),-i);
1436 }
1437
1438 double
1439 _ext_dbl_cvt(e)
1440         struct EXTEND *e;
1441 {
1442         /*      Convert extended to double
1443         */
1444         double f = ldexp(ldexp((double)e->m1, 32) + (double)e->m2, e->exp-63);
1445         if (e->sign) f = -f;
1446         return f;
1447 }
1448         getlogin.c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0W\ 3/* $Id: getlogin.c,v 1.5 1994/06/24 12:13:32 ceriel Exp $ */
1449 #define UTMPFILE "/etc/utmp"
1450
1451 #ifdef __USG
1452 struct utmp {
1453         char ut_name[8];
1454         char ut_id[4];
1455         char ut_line[12];
1456         short ut_pid;
1457         short ut_type;
1458         struct exit_status {
1459                 short e_termination;
1460                 short e_exit;
1461         } ut_exit;
1462         long ut_time;
1463 };
1464 #else
1465 struct utmp {
1466         char    ut_line[8];
1467         char    ut_name[8];
1468 #ifdef __BSD4_2
1469         char    ut_host[16];
1470 #endif
1471         long    ut_time;
1472 };
1473 #endif
1474
1475 char *
1476 getlogin()
1477 {
1478         struct utmp ut;
1479         static char name[sizeof(ut.ut_name) + 1];
1480         int     slotno = ttyslot();
1481         int     fd;
1482         register char *p, *q;
1483
1484         if (! slotno || !(fd = open(UTMPFILE, 0))) return 0;
1485         lseek(fd, (long) slotno * sizeof(ut), 0);
1486         if (read(fd, (char *) &ut, sizeof(ut)) < sizeof(ut)) return 0;
1487         close(fd);
1488         ut.ut_name[sizeof(ut.ut_name)] = ' ';
1489         p = ut.ut_name;
1490         q = name;
1491         while (*p != ' ') *q++ = *p++;
1492         *q = '\0';
1493         return name;
1494 }
1495 1index.c\0.c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0«\0/* $Id: index.c,v 1.3 1994/06/24 12:13:38 ceriel Exp $ */
1496 char *index(s, c)
1497 register char *s, c;
1498 {
1499   do {
1500         if (*s == c)
1501                 return(s);
1502   } while (*s++ != 0);
1503   return(0);
1504 }
1505         l3.c\0.c\0.c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\9e\ 1/* $Id: l3.c,v 1.3 1994/06/24 12:13:44 ceriel Exp $ */
1506 ltol3(cp, lp, n)
1507 register char   *cp;
1508 register long   *lp;
1509 register int    n;
1510 {
1511         while (n-- > 0) {
1512                 *cp++ = (*lp >> 16);
1513                 *cp++ = (*lp > 8);
1514                 *cp++ = *lp;
1515         }
1516 }
1517
1518 l3tol(lp, cp, n)
1519 register long   *lp;
1520 char    *cp;
1521 register int    n;
1522 {
1523         unsigned char *a = (unsigned char *) cp;
1524
1525         while (n-- > 0) {
1526                 *lp++ = ((long)(*a)<<16) + ((long)(*(a+1)) << 8) + *(a+2);
1527                 a += 3;
1528         }
1529 }
1530 ldexp.c\0.c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ÿ\ 1/* $Id: ldexp.c,v 1.3 1994/06/24 12:13:47 ceriel Exp $ */
1531 #ifndef NOFLOAT
1532 extern double frexp();
1533
1534 double
1535 ldexp(fl,exp)
1536         double fl;
1537         int exp;
1538 {
1539         int sign = 1;
1540         int currexp;
1541
1542         if (fl<0) {
1543                 fl = -fl;
1544                 sign = -1;
1545         }
1546         fl = frexp(fl,&currexp);
1547         exp += currexp;
1548         if (exp > 0) {
1549                 while (exp>30) {
1550                         fl *= (double) (1L << 30);
1551                         exp -= 30;
1552                 }
1553                 fl *= (double) (1L << exp);
1554         }
1555         else    {
1556                 while (exp<-30) {
1557                         fl /= (double) (1L << 30);
1558                         exp += 30;
1559                 }
1560                 fl /= (double) (1L << -exp);
1561         }
1562         return sign * fl;
1563 }
1564 #endif
1565 tlocaltime.c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ë\ 5/* $Id: localtime.c,v 1.9 1994/06/24 12:13:50 ceriel Exp $ */
1566 #include <time.h>
1567
1568 #define LEAPYEAR(year)  (!((year) % 4) && (((year) % 100) || !((year) % 400)))
1569 #define YEARSIZE(year)  (LEAPYEAR(year) ? 366 : 365)
1570 #define FIRSTSUNDAY(t)  (((t)->tm_yday - (t)->tm_wday + 420) % 7)
1571
1572 static int
1573 last_sunday(d, t)
1574         register int d;
1575         register struct tm *t;
1576 {
1577         int first = FIRSTSUNDAY(t);
1578
1579         if (d >= 58 && LEAPYEAR(t->tm_year+1900)) d++;
1580         if (d < first) return first;
1581         return d - (d - first) % 7;
1582 }
1583
1584 dysize(y)
1585 {
1586         /* compatibility */
1587         return YEARSIZE(y);
1588 }
1589
1590 extern struct tm *gmtime();
1591
1592 struct tm *
1593 localtime(clock)
1594         long *clock;
1595 {
1596         register struct tm *gmt;
1597         long cl;
1598         int begindst, enddst;
1599         extern int __daylight;
1600         extern long __timezone;
1601
1602         tzset();
1603         cl = *clock - __timezone;
1604         gmt = gmtime(&cl);
1605         if (__daylight) {
1606                 /* daylight saving time.
1607                    Unfortunately, rules differ for different countries.
1608                    Implemented here are heuristics that got it right
1609                    in Holland, over the last couple of years.
1610                    Of course, there is no algorithm. It is all
1611                    politics ...
1612                 */
1613                 begindst = last_sunday(89, gmt); /* last Sun before Apr */
1614                 enddst = last_sunday(272, gmt);  /* last Sun in Sep */
1615                 if ((gmt->tm_yday>begindst ||
1616                      (gmt->tm_yday==begindst && gmt->tm_hour>=2)) &&
1617                     (gmt->tm_yday<enddst || 
1618                      (gmt->tm_yday==enddst && gmt->tm_hour<3))) {
1619                         /* it all happens between 2 and 3 */
1620                         cl += 1*60*60;
1621                         gmt = gmtime(&cl);
1622                         gmt->tm_isdst++;
1623                 }
1624         }
1625         return gmt;
1626 }
1627 fgmtime.c\0.c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0;\ 4/* $Id: gmtime.c,v 1.7 1994/06/24 12:13:35 ceriel Exp $ */
1628 #include <time.h>
1629
1630 static int monthsize[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1631
1632 #define SECS_DAY (24*60L*60L)
1633 #define LEAPYEAR(year)  (!((year) % 4) && (((year) % 100) || !((year) % 400)))
1634 #define YEARSIZE(year)  (LEAPYEAR(year) ? 366 : 365)
1635
1636 struct tm *
1637 gmtime(clock)
1638         long *clock;
1639 {
1640         long cl = *clock;
1641         long dayclock, dayno;
1642         static struct tm tm_buf;
1643         register struct tm *pbuf = &tm_buf;
1644         register int *months = monthsize;
1645         int year = 1970;
1646
1647         dayclock = cl % SECS_DAY;
1648         dayno = cl / SECS_DAY;
1649
1650         pbuf->tm_sec = dayclock % 60;
1651         pbuf->tm_min = (dayclock % 3600) / 60;
1652         pbuf->tm_hour = dayclock / 3600;
1653         pbuf->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */
1654         while (dayno >= YEARSIZE(year)) {
1655                 dayno -= YEARSIZE(year);
1656                 year++;
1657         }
1658         pbuf->tm_year = year - 1900;
1659         pbuf->tm_yday = dayno;
1660         pbuf->tm_isdst = 0;
1661         if (YEARSIZE(year) == 366) monthsize[1] = 29;
1662         while (dayno - *months >= 0) dayno -= *months++;
1663         pbuf->tm_mday = dayno + 1;
1664         pbuf->tm_mon = months - monthsize;
1665         monthsize[1] = 28;
1666         return pbuf;
1667 }
1668 smemccpy.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0à\0/* $Id: memccpy.c,v 1.3 1994/06/24 12:13:54 ceriel Exp $ */
1669 char *
1670 memccpy(dst, src, c, n)
1671         register char *dst, *src;
1672         register int n;
1673 {
1674         while (n-- > 0) {
1675                 if ((*dst++ = *src++) == c) return (char *) dst;
1676         }
1677
1678         return 0;
1679 }
1680 memchr.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ý\0/* $Id: memchr.c,v 1.3 1994/06/24 12:13:57 ceriel Exp $ */
1681 char *
1682 memchr(s, c, n)
1683 char *s;
1684 register int n;
1685 {
1686         register unsigned char *s1 = (unsigned char *) s;
1687         
1688         c &= 0377;
1689         while (n-- > 0) {
1690                 if (*s1 == c) return (char *) s1;
1691                 s1++;
1692         }
1693         return 0;
1694 }
1695 )memcmp.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ä\0/* $Id: memcmp.c,v 1.4 1994/06/24 12:14:01 ceriel Exp $ */
1696 int
1697 memcmp(s1, s2, n)
1698 register char *s1, *s2;
1699 {
1700 /* Compare 2 strings. */
1701
1702   while (n-- > 0) {
1703         if (*s1 != *s2) {
1704                 return(*s1 - *s2);
1705         }
1706         s1++;
1707         s2++;
1708   }
1709   return 0;
1710 }
1711 memcpy.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0>\ 1/* $Id: memcpy.c,v 1.3 1994/06/24 12:14:04 ceriel Exp $ */
1712 char *
1713 memcpy(s1, s2, n)
1714 register char *s1, *s2;
1715 register int n;
1716 {
1717 /* Copy a block of data. */
1718
1719         char *ret = s1;
1720
1721         if (s2 <= s1 && s2 + (n-1) >= s1) {
1722                 s1 += n; s2 += n;
1723                 while (n-- > 0) *--s1 = *--s2;
1724         }
1725         else    while (n-- > 0) *s1++ = *s2++;
1726         return ret;
1727 }
1728 memset.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0µ\0/* $Id: memset.c,v 1.3 1994/06/24 12:14:07 ceriel Exp $ */
1729 char *
1730 memset(s, c, n)
1731         char *s;
1732         register int n;
1733 {
1734         register char *s1 = s;
1735
1736         while (n--) {
1737                 *s1++ = c;
1738         }
1739         return(s);
1740 }
1741 <mktemp.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0,\ 2/* $Id: mktemp.c,v 1.3 1994/06/24 12:14:10 ceriel Exp $ */
1742 /* mktemp - make a name for a temporary file */
1743
1744 char *mktemp(template)
1745 char *template;
1746 {
1747   register int pid, k;
1748   register char *p;
1749
1750   pid = getpid();               /* get process id as semi-unique number */
1751   p = template;
1752   while (*p) p++;               /* find end of string */
1753
1754   /* Replace XXXXXX at end of template with pid. */
1755   while (*--p == 'X') {
1756         *p = '0' + (pid % 10);
1757         pid /= 10;
1758   }
1759   p++;
1760   for (k = 'a'; k <= 'z'; k++) {
1761         *p = k;
1762         if (access(template, 0) < 0) {
1763                 return template;
1764         }
1765   }
1766   return("/");
1767 }
1768 monitor.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0§\ 5/* $Id: monitor.c,v 1.4 1994/06/24 12:14:13 ceriel Exp $ */
1769 static int bs;
1770 static char *bp;
1771 static char *bufp;
1772 static int sc;
1773 static int bufs;
1774
1775 monitor(lowpc, highpc, buffer, bufsize, nfunc)
1776         int (*lowpc)(), (*highpc)();
1777         char *buffer;
1778 {
1779         long scale;
1780
1781         if (lowpc == 0) {
1782                 int fd;
1783
1784                 profil((char *) 0, 0, 0, 0);
1785                 if ((fd = creat("mon.out", 0666)) < 0 || !bp) return;
1786                 write(fd, bp, (int) bs);
1787                 close(fd);
1788                 return;
1789         }
1790
1791         bs = bufsize << 1;
1792         bp = buffer;
1793
1794         *(char **) buffer = (char *) lowpc;
1795         buffer += sizeof(char *);
1796         *(char **) buffer = (char *) highpc;
1797         buffer += sizeof(char *);
1798         *(int *) buffer = nfunc;
1799         buffer += sizeof(int);
1800         buffer += (sizeof (char *) + sizeof(long)) * nfunc;
1801         bufsize -= ((sizeof (char *) + sizeof(long)) * nfunc + 2 * sizeof(char *) + sizeof(int)) >> 1;
1802         if (bufsize < 0) return;
1803         scale = ((char *) highpc - (char *) lowpc) >> 1;
1804         if (bufsize < scale)
1805                 scale = ((long) bufsize << 15) / scale;
1806         else    scale = 0x8000;
1807         bufp = buffer;
1808         sc = scale << 1;
1809         bufs = bufsize << 1;
1810         profil(buffer, bufs, lowpc, sc);
1811 }
1812
1813 moncontrol(mode)
1814 {
1815         profil(bufp, bufs, *(char **) bp, !mode ? 0 : sc);
1816 }
1817
1818 #define NCOUNTS 300
1819
1820 monstartup(lowpc, highpc)
1821         int (*lowpc)(), (*highpc)();
1822 {
1823         int sz = (((char *) highpc - (char *) lowpc + 7) & ~7);
1824         char *s, *sbrk();
1825
1826         sz += NCOUNTS * (sizeof(long) + sizeof(char *)) + 2 * sizeof(char *) + sizeof(int);
1827         s = sbrk(sz);
1828         if ((int) s == -1) return;
1829         monitor(lowpc, highpc, s, sz >> 1, NCOUNTS);
1830 }
1831 -perror.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0§\ 5/* $Id: perror.c,v 1.3 1994/06/24 12:14:19 ceriel Exp $ */
1832 /* perror(s) print the current error message. */
1833
1834 extern int errno;
1835 char *sys_errlist[] = {
1836         "Error 0",
1837         "Not owner",
1838         "No such file or directory",
1839         "No such process",
1840         "Interrupted system call",
1841         "I/O error",
1842         "No such device or address",
1843         "Arg list too long",
1844         "Exec format error",
1845         "Bad file number",
1846         "No children",
1847         "No more processes",
1848         "Not enough core",
1849         "Permission denied",
1850         "Bad address",
1851         "Block device required",
1852         "Mount device busy",
1853         "File exists",
1854         "Cross-device link",
1855         "No such device",
1856         "Not a directory",
1857         "Is a directory",
1858         "Invalid argument",
1859         "File table overflow",
1860         "Too many open files",
1861         "Not a typewriter",
1862         "Text file busy",
1863         "File too large",
1864         "No space left on device",
1865         "Illegal seek",
1866         "Read-only file system",
1867         "Too many links",
1868         "Broken pipe",
1869         "Math argument",
1870         "Result too large"
1871 };
1872
1873 int     sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]);
1874
1875 perror(s)
1876         char *s;
1877 {
1878         char *c;
1879         if (errno < 0 || errno >= sizeof(sys_errlist) / sizeof(char *)) {
1880                 c = "unknown error";
1881         } else {
1882                 c = sys_errlist[errno];
1883         }
1884         write(2, s, strlen(s));
1885         write(2, ": ", 2);
1886         write(2, c, strlen(c));
1887         write(2, "\n", 1);
1888 }
1889 -procentry.c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0·\ 3/* $Id: procentry.c,v 1.3 1994/06/24 12:14:22 ceriel Exp $ */
1890 /*
1891  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
1892  *
1893  *          This product is part of the Amsterdam Compiler Kit.
1894  *
1895  * Permission to use, sell, duplicate or disclose this software must be
1896  * obtained in writing. Requests for such permissions may be sent to
1897  *
1898  *      Dr. Andrew S. Tanenbaum
1899  *      Wiskundig Seminarium
1900  *      Vrije Universiteit
1901  *      Postbox 7161
1902  *      1007 MC Amsterdam
1903  *      The Netherlands
1904  *
1905  */
1906
1907 /* Author: E.G. Keizer */
1908
1909 static int level = 0 ;
1910 static wrs() ;
1911 procentry(name) char *name ; {
1912         register int count ;
1913
1914         count=level++ ;
1915         while ( count-- ) {
1916                 wrs("  ") ;
1917         }
1918         wrs("Entering ");wrs(name);wrs("\n") ;
1919 }
1920 procexit(name) char *name ; {
1921         register int count ;
1922
1923         count= --level ;
1924         while ( count-- ) {
1925                 wrs("  ") ;
1926         }
1927         wrs("Leaving  ");wrs(name);wrs("\n") ;
1928 }
1929 static wrs(s) register char *s ; {
1930         write(2,s,strlen(s)) ;
1931 }
1932 nqsort.c\0y.c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0)\f/* $Id: qsort.c,v 1.4 1994/06/24 12:14:25 ceriel Exp $ */
1933 static  qsort1();
1934 static  int (*qcompar)();
1935 static  qexchange();
1936 static  q3exchange();
1937
1938 qsort(base, nel, width, compar)
1939         char *base;
1940         int (*compar)();
1941 {
1942         qcompar = compar;
1943         if (sizeof(int) < sizeof(char *)) {
1944                 qsort1(base, base + (nel - 1) * (long) width, width);
1945         }
1946         else    qsort1(base, base + (nel - 1) * width, width);
1947 }
1948
1949 static
1950 qsort1(a1, a2, width)
1951         char *a1, *a2;
1952         register int width;
1953 {
1954         register char *left, *right;
1955         register char *lefteq, *righteq;
1956         int cmp;
1957
1958         for (;;) {
1959                 if (a2 <= a1) return;
1960                 left = a1;
1961                 right = a2;
1962                 if (sizeof(int) < sizeof(char *)) {
1963                         lefteq = righteq = a1 + width *
1964                                         ((((long)a2-(long)a1)+width)/(2*width));
1965                 }
1966                 else    lefteq = righteq = a1 + width *
1967                                         (((a2-a1)+width)/(2*width));
1968                 /*
1969                    Pick an element in the middle of the array.
1970                    We will collect the equals around it.
1971                    "lefteq" and "righteq" indicate the left and right
1972                    bounds of the equals respectively.
1973                    Smaller elements end up left of it, larger elements end
1974                    up right of it.
1975                 */
1976 again:
1977                 while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0) {
1978                         if (cmp < 0) {
1979                                 /* leave it where it is */
1980                                 left += width;
1981                         }
1982                         else {
1983                                 /* equal, so exchange with the element to
1984                                    the left of the "equal"-interval.
1985                                 */
1986                                 lefteq -= width;
1987                                 qexchange(left, lefteq, width);
1988                         }
1989                 }
1990                 while (right > righteq) {
1991                         if ((cmp = (*qcompar)(right, righteq)) < 0) {
1992                                 /* smaller, should go to left part
1993                                 */
1994                                 if (left < lefteq) {
1995                                         /* yes, we had a larger one at the
1996                                            left, so we can just exchange
1997                                         */
1998                                         qexchange(left, right, width);
1999                                         left += width;
2000                                         right -= width;
2001                                         goto again;
2002                                 }
2003                                 /* no more room at the left part, so we
2004                                    move the "equal-interval" one place to the
2005                                    right, and the smaller element to the
2006                                    left of it.
2007                                    This is best expressed as a three-way
2008                                    exchange.
2009                                 */
2010                                 righteq += width;
2011                                 q3exchange(left, righteq, right, width);
2012                                 lefteq += width;
2013                                 left = lefteq;
2014                         }
2015                         else if (cmp == 0) {
2016                                 /* equal, so exchange with the element to
2017                                    the right of the "equal-interval"
2018                                 */
2019                                 righteq += width;
2020                                 qexchange(right, righteq, width);
2021                         }
2022                         else    /* just leave it */ right -= width;
2023                 }
2024                 if (left < lefteq) {
2025                         /* larger element to the left, but no more room,
2026                            so move the "equal-interval" one place to the
2027                            left, and the larger element to the right
2028                            of it.
2029                         */
2030                         lefteq -= width;
2031                         q3exchange(right, lefteq, left, width);
2032                         righteq -= width;
2033                         right = righteq;
2034                         goto again;
2035                 }
2036                 /* now sort the "smaller" part */
2037                 qsort1(a1, lefteq - width, width);
2038                 /* and now the larger, saving a subroutine call
2039                    because of the for(;;)
2040                 */
2041                 a1 = righteq + width;
2042         }
2043         /*NOTREACHED*/
2044 }
2045
2046 static
2047 qexchange(p, q, n)
2048         register char *p, *q;
2049         register int n;
2050 {
2051         register int c;
2052
2053         while (n-- > 0) {
2054                 c = *p;
2055                 *p++ = *q;
2056                 *q++ = c;
2057         }
2058 }
2059
2060 static
2061 q3exchange(p, q, r, n)
2062         register char *p, *q, *r;
2063         register int n;
2064 {
2065         register int c;
2066
2067         while (n-- > 0) {
2068                 c = *p;
2069                 *p++ = *r;
2070                 *r++ = *q;
2071                 *q++ = c;
2072         }
2073 }
2074         bsearch.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0é\ 3/*  bsearch(3)
2075  *
2076  *  Author: Terrence Holm          Aug. 1988
2077  *
2078  *
2079  *  Performs a binary search for a given <key> within a sorted
2080  *  table. The table contains <count> entries of size <width>
2081  *  and starts at <base>.
2082  *
2083  *  Entries are compared using keycmp( key, entry ), each argument
2084  *  is a (char *), the function returns an int < 0, = 0 or > 0
2085  *  according to the order of the two arguments.
2086  *
2087  *  Bsearch(3) returns a pointer to the matching entry, if found,
2088  *  otherwise NULL is returned.
2089  */
2090
2091 #define  NULL   (char *) 0
2092
2093
2094 char *bsearch( key, base, count, width, keycmp )
2095   char *key;
2096   char *base;
2097   unsigned int count;
2098   unsigned int width;
2099   int  (*keycmp)();
2100
2101   {
2102   char *mid_point;
2103   int  cmp;
2104
2105   while ( count > 0 )
2106     {
2107     mid_point = base + width * (count >> 1);
2108
2109     cmp = (*keycmp)( key, mid_point );
2110
2111     if ( cmp == 0 )
2112         return( mid_point );
2113
2114     if ( cmp < 0 )
2115         count >>= 1;
2116     else
2117         {
2118         base  = mid_point + width;
2119         count = (count - 1) >> 1;
2120         }
2121     }
2122
2123   return( NULL );
2124   }
2125 prand.c\0.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\17\ 1/* $Id: rand.c,v 1.5 1994/06/24 12:14:29 ceriel Exp $ */
2126 static long seed = 1L;
2127
2128 int rand()
2129 {
2130   seed = (1103515245L * seed + 12345) & 0x7FFFFFFF;
2131 #if _EM_WSIZE == 4
2132   return (int) seed;
2133 #else
2134   return ((int)(seed >> 8) & 0x7FFF);
2135 #endif
2136 }
2137
2138 srand(n)
2139   unsigned n;
2140 {
2141   seed = n;
2142 }
2143 hseekdir.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0î\ 2/* $Id: seekdir.c,v 1.5 1994/06/24 12:14:39 ceriel Exp $ */
2144 #include <sys/types.h>
2145 #include <sys/dir.h>
2146
2147 /*
2148  * seek to an entry in a directory.
2149  * Only values returned by "telldir" should be passed to seekdir.
2150  */
2151 seekdir(dirp, loc)
2152 register DIR *dirp;
2153 long loc;
2154 {
2155         long curloc, base, offset;
2156         extern long telldir();
2157         extern struct direct *readdir();
2158
2159         curloc = telldir(dirp);
2160         if (loc == curloc)
2161                 return;
2162         offset = loc % dirp->dd_bsize;
2163         base = loc - offset;
2164         if (dirp->dd_loc != -1 &&
2165             (curloc - (curloc % dirp->dd_bsize)) ==  base) {
2166                 dirp->dd_loc = offset;
2167                 return;
2168         }
2169         (void) lseek(dirp->dd_fd, base, 0);
2170         dirp->dd_loc = -1;
2171         dirp->dd_size = 0;
2172         while (dirp->dd_loc < offset) {
2173                 if (readdir(dirp) == (struct direct *) 0)
2174                         return;
2175         }
2176 }
2177 sleep.c\0c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0å\ 2/* $Id: sleep.c,v 1.5 1994/06/24 12:14:42 ceriel Exp $ */
2178 #include <signal.h>
2179 #include <setjmp.h>
2180
2181 static jmp_buf  setjmpbuf;
2182
2183 static void
2184 alfun(){
2185         longjmp(setjmpbuf, 1);
2186 }               /* used with sleep() below */
2187
2188 sleep(n)
2189         int n;
2190 {
2191 /* sleep(n) pauses for 'n' seconds by scheduling an alarm interrupt. */
2192         unsigned oldalarm;
2193         void (*oldsig)();
2194
2195   if (n <= 0) return;
2196   if (setjmp(setjmpbuf)) {
2197         signal(SIGALRM, oldsig);
2198         alarm(oldalarm);
2199         return;
2200   }
2201   oldalarm = alarm(5000);       /* Who cares how long, as long as it is long
2202                                    enough
2203                                 */
2204   if (oldalarm > n) oldalarm -= n;
2205   else if (oldalarm) {
2206                 n = oldalarm;
2207                 oldalarm = 1;
2208   }
2209   oldsig = signal(SIGALRM, alfun);
2210   alarm(n);
2211   for (;;)  {
2212         /* allow for other handlers ... */
2213         pause();
2214   }
2215 }
2216 rstb.c\0c\0c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0É\0/* $Id: stb.c,v 1.2 1994/06/24 12:14:45 ceriel Exp $ */
2217 /* library routine for copying structs */
2218
2219 __stb(n, f, t)
2220         register char *f, *t; register n;
2221 {
2222         if (n > 0)
2223                 do
2224                         *t++ = *f++;
2225                 while (--n);
2226 }
2227 *strstr.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\e\ 1/* $Id: strstr.c,v 1.3 1994/06/24 12:15:34 ceriel Exp $ */
2228 /* find first occurrence of wanted in s */
2229 char *
2230 strstr(s, wanted)
2231         register char *s, *wanted;
2232 {
2233         int len = strlen(wanted);
2234
2235         while (*s != *wanted || strncmp(s, wanted, len)) {
2236                 if (*s++ == '\0') return 0;
2237         }
2238         return s;
2239 }
2240 nstrchr.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0­\0/* $Id: strchr.c,v 1.3 1994/06/24 12:14:50 ceriel Exp $ */
2241 char *strchr(s, c)
2242 register char *s, c;
2243 {
2244   do {
2245         if (*s == c)
2246                 return(s);
2247   } while (*s++ != 0);
2248   return(0);
2249 }
2250 nstrcmp.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0¯\0/* $Id: strcmp.c,v 1.4 1994/06/24 12:14:53 ceriel Exp $ */
2251 int
2252 strcmp(s, t)
2253         register char *s, *t;
2254 {
2255         while (*s == *t++)
2256                 if (*s++ == '\0')
2257                         return 0;
2258         return *s - *--t;
2259 }
2260 wstrcspn.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\17\ 1/* $Id: strcspn.c,v 1.3 1994/06/24 12:14:59 ceriel Exp $ */
2261 int
2262 strcspn(string, notin)
2263         char *string;
2264         char *notin;
2265 {
2266         register char *s1, *s2;
2267
2268         for (s1 = string; *s1; s1++) {
2269                 for(s2 = notin; *s2 != *s1 && *s2; s2++) /* nothing */ ;
2270                 if (*s2) break;
2271         }
2272         return s1 - string;
2273 }
2274 ;strncat.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0©\ 1/* $Id: strncat.c,v 1.4 1994/06/24 12:15:05 ceriel Exp $ */
2275 char *strncat(s1, s2, n)
2276 register char *s1, *s2;
2277 int n;
2278 {
2279 /* Append s2 to the end of s1, but no more than n characters */
2280
2281   char *original = s1;
2282
2283   if (n <= 0) return(s1);
2284
2285   /* Find the end of s1. */
2286   while (*s1++ != 0) ;
2287
2288   s1--;
2289
2290   /* Now copy s2 to the end of s1. */
2291   while (*s1++ = *s2++) {
2292         if (--n == 0) {
2293                 *s1 = 0;
2294                 break;
2295         }
2296   }
2297   return(original);
2298 }
2299 mstrrchr.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ù\0/* $Id: strrchr.c,v 1.3 1994/06/24 12:15:24 ceriel Exp $ */
2300 char *strrchr(s, c)
2301 register char *s, c;
2302 {
2303   register char *result;
2304
2305   result = 0;
2306   do
2307         if (*s == c)
2308                 result = s;
2309   while (*s++ != 0);
2310   return(result);
2311 }
2312  strtok.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ê\ 1/* $Id: strtok.c,v 1.3 1994/06/24 12:15:45 ceriel Exp $ */
2313 extern char *strpbrk();
2314
2315 char *
2316 strtok(string, separators)
2317         register char *string;
2318         char *separators;
2319 {
2320         register char *s1, *s2;
2321         static char *savestring;
2322
2323         if (!string) string = savestring;
2324
2325         if (!string) return 0;
2326
2327         if (*(s1 = string + strspn(string, separators)) == '\0') {
2328                 savestring = 0;
2329                 return 0;
2330         }
2331
2332         if (s2 = strpbrk(s1, separators)) {
2333                 *s2++ = '\0';
2334         }
2335         savestring = s2;
2336         return s1;
2337 }
2338 strpbrk.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\14\ 1/* $Id: strpbrk.c,v 1.3 1994/06/24 12:15:19 ceriel Exp $ */
2339 char *
2340 strpbrk(string, brk)
2341         register char *string, *brk;
2342 {
2343         register char *s1;
2344
2345         while (*string) {
2346                 for (s1 = brk; *s1 && *s1 != *string; s1++) /* nothing */ ;
2347                 if (*s1) return string;
2348                 string++;
2349         }
2350         return 0;
2351 }
2352 strspn.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\ f\ 1/* $Id: strspn.c,v 1.3 1994/06/24 12:15:28 ceriel Exp $ */
2353 int
2354 strspn(string, in)
2355         char *string;
2356         char *in;
2357 {
2358         register char *s1, *s2;
2359
2360         for (s1 = string; *s1; s1++) {
2361                 for (s2 = in; *s2 && *s2 != *s1; s2++) /* nothing */ ;
2362                 if (! *s2) break;
2363         }
2364         return s1 - string;
2365 }
2366 0swab.c\0c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0É\0/* $Id: swab.c,v 1.3 1994/06/24 12:15:54 ceriel Exp $ */
2367 swab(from, to, nbytes)
2368         register char *from, *to;
2369 {
2370         nbytes /= 2;
2371         while (nbytes-- > 0) {
2372                 *(to+1) = *from++;
2373                 *to = *from++;
2374                 to += 2;
2375         }
2376 }
2377 ;telldir.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0@\ 1/* $Id: telldir.c,v 1.4 1994/06/24 12:15:59 ceriel Exp $ */
2378 #include <sys/types.h>
2379 #include <sys/dir.h>
2380
2381 /*
2382  * return a pointer into a directory
2383  */
2384 long telldir(dirp)
2385 DIR *dirp;
2386 {
2387         extern long lseek();
2388
2389         if (dirp->dd_fd >= 0)
2390                 return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
2391         return dirp->dd_loc;
2392 }
2393 ttyslot.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\10\ 6/* $Id: ttyslot.c,v 1.6 1994/06/24 12:16:07 ceriel Exp $ */
2394 #ifdef __USG
2395 /*      system V, so no /etc/ttys file. In this case, scan the
2396         /etc/utmp file
2397 */
2398 struct utmp {
2399         char ut_name[8];
2400         char ut_id[4];
2401         char ut_line[12];
2402         short ut_pid;
2403         short ut_type;
2404         struct exit_status {
2405                 short e_termination;
2406                 short e_exit;
2407         } ut_exit;
2408         long ut_time;
2409 };
2410 #define FILENAME "/etc/utmp"
2411 #else
2412 #define FILENAME "/etc/ttys"
2413 #endif
2414
2415 char    *ttyname();
2416 char    *rindex();
2417
2418 ttyslot()
2419 {
2420         register char *tp, *p;
2421         int fd;
2422         int retval = 1;
2423 #ifdef __USG
2424         struct utmp buf;
2425 #else
2426         char buf[32];
2427 #endif
2428
2429         if (! (tp=ttyname(0)) && ! (tp=ttyname(1)) && !(tp=ttyname(2)))
2430                 return 0;
2431         if (! (p = rindex(tp, '/')))
2432                 p = tp;
2433         else
2434                 p++;
2435         if ((fd = open(FILENAME, 0)) < 0) return 0;
2436 #ifdef __USG
2437         while (read(fd, (char *) &buf, sizeof(buf)) == sizeof(buf)) {
2438                 /* processes associated with a terminal ...
2439                    unfortunately we cannot use the include file because
2440                    some systems have a different one ...
2441                    INIT_PROCESS, DEAD_PROCESS, USER_PROCESS, LOGIN_PROCESS
2442                 */
2443                 if ((buf.ut_type >= 5 && buf.ut_type <= 8) &&
2444                     ! strncmp(buf.ut_line, p, sizeof(buf.ut_line))) {
2445                         close(fd);
2446                         return retval;
2447                 }
2448                 retval++;
2449         }
2450         close(fd);
2451         return 0;
2452 #else
2453         for (;;) {
2454                 tp = buf;
2455                 for (;;tp++) {
2456                         if (read(fd, tp, 1) != 1) {
2457                                 close(fd);
2458                                 return 0;
2459                         }
2460                         if (*tp == '\n' || tp >= &buf[31]) {
2461                                 *tp = 0;
2462                                 if (tp < buf+2) buf[2] = '\0';
2463                                 tp = buf+2;
2464                                 break;
2465                         }
2466                 }
2467                 if (! strcmp(p, tp)) {
2468                         close(fd);
2469                         return retval;
2470                 }
2471                 retval++;
2472         }
2473         /*NOTREACHED*/
2474 #endif
2475 }
2476 rindex.c\0\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0×\0/* $Id: rindex.c,v 1.3 1994/06/24 12:14:36 ceriel Exp $ */
2477 char *rindex(s, c)
2478 register char *s, c;
2479 {
2480   register char *result;
2481
2482   result = 0;
2483   do
2484         if (*s == c)
2485                 result = s;
2486   while (*s++ != 0);
2487   return(result);
2488 }
2489 ;strncmp.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0õ\0/* $Id: strncmp.c,v 1.4 1994/06/24 12:15:10 ceriel Exp $ */
2490 int
2491 strncmp(s, t, n)
2492         register char *s, *t;
2493         register int n;
2494 {
2495         while (n-- > 0) {
2496                 if (*s == *t++) {
2497                         if (*s++ == '\0')
2498                                 return 0;
2499                 }
2500                 else
2501                         return *s - *--t;
2502         }
2503         return 0;
2504 }
2505 ettyname.c\0c\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0|\ 3/* $Id: ttyname.c,v 1.3 1994/06/24 12:16:03 ceriel Exp $ */
2506 #include <sys/types.h>
2507 #include <sys/stat.h>
2508 #include <sys/dir.h>
2509
2510 #define DEV "/dev/"
2511
2512 extern char *strcpy(), *strcat();
2513
2514 char *
2515 ttyname(filedes)
2516 {
2517         static char result[MAXNAMLEN + 1 + 5];
2518         DIR *dirp;
2519         register struct direct *dp;
2520         struct stat fdstat;
2521         ino_t inode;
2522         dev_t device;
2523         char *name;
2524
2525         if (! isatty(filedes) ||
2526             fstat(filedes, &fdstat) < 0 ||
2527             (fdstat.st_mode & S_IFMT) != S_IFCHR ||
2528             (dirp = opendir(DEV)) == NULL) {
2529                 return 0;
2530         }
2531
2532         inode = fdstat.st_ino;
2533         device = fdstat.st_rdev;
2534
2535         while ((dp = readdir(dirp)) != NULL) {
2536                 if (dp->d_ino != inode) continue;
2537                 strcpy(result, DEV);
2538                 strcat(result, dp->d_name);
2539                 if (stat(result, &fdstat) < 0) continue;
2540                 if (fdstat.st_rdev == device &&
2541                     (fdstat.st_mode & S_IFMT) == S_IFCHR) {
2542                         closedir(dirp);
2543                         return result;
2544                 }
2545         }
2546         closedir(dirp);
2547         return 0;
2548 }
2549 closedir.c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0*\ 1/* $Id: closedir.c,v 1.5 1994/06/24 12:13:01 ceriel Exp $ */
2550 #include <sys/types.h>
2551 #include <sys/dir.h>
2552
2553 /*
2554  * close a directory.
2555  */
2556 closedir(dirp)
2557 register DIR *dirp;
2558 {
2559         if (dirp->dd_fd >= 0) close(dirp->dd_fd);
2560         dirp->dd_fd = -1;
2561         dirp->dd_loc = -1;
2562         free(dirp->dd_buf);
2563         free((char *)dirp);
2564 }
2565 isatty.c\0c\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0)\ 1/* $Id: isatty.c,v 1.6 1994/06/24 12:13:41 ceriel Exp $ */
2566 isatty(f)
2567 {
2568         char buf[128];
2569         /* not a sgttyb struct; it might not be large enough;
2570            I know for a fact that it is'nt large enough on PC/IX,
2571            where gtty is an ioctl(..., TCGETA, ...)
2572         */
2573
2574         if (gtty(f, buf) < 0) return 0;
2575         return 1;
2576 }
2577
2578 opendir.c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\ e\ 5/* $Id: opendir.c,v 1.9 1994/06/24 12:14:16 ceriel Exp $ */
2579 #include <sys/types.h>
2580 #include <sys/stat.h>
2581 #include <sys/dir.h>
2582
2583 /*
2584  * open a directory.
2585  */
2586 DIR *opendir(name)
2587 char *name;
2588 {
2589         register DIR *dirp;
2590         register int fd;
2591         struct stat stbuf;
2592         long siz;
2593         extern char *malloc();
2594
2595 #ifdef __BSD4_2
2596         siz = stbuf.st_blksize;
2597 #else
2598         siz = DIRBLKSIZ;
2599 #endif
2600         if ((fd = open(name, 0)) == -1)
2601                 return NULL;
2602         fstat(fd, &stbuf);
2603         if (((stbuf.st_mode & S_IFDIR) == 0) ||
2604             ((dirp = (DIR *)malloc(sizeof (DIR))) == NULL)) {
2605                 close (fd);
2606                 return NULL;
2607         }
2608         if (stbuf.st_size > siz) siz = stbuf.st_size;
2609         if ((unsigned) siz == siz &&
2610             (dirp->dd_buf = malloc((unsigned) siz))) {
2611                 dirp->dd_bsize = siz;
2612 #ifdef __BSD4_2
2613                 dirp->dd_size = getdirentries(fd,
2614                                               (char *) dirp->dd_buf,
2615                                               (int) siz,
2616                                               &siz);
2617                 if (dirp->dd_size < 0 )
2618 #endif
2619                 dirp->dd_size = read(fd, dirp->dd_buf, dirp->dd_bsize);
2620                 close(fd);
2621                 dirp->dd_fd = -2;
2622                 dirp->dd_loc = 0;
2623                 return dirp;
2624         }
2625 #ifndef __BSD4_2
2626         else if (dirp->dd_buf = malloc(8*DIRBLKSIZ)) {
2627                 dirp->dd_bsize = 8 * DIRBLKSIZ;
2628         }
2629         else if (dirp->dd_buf = malloc(DIRBLKSIZ)) {
2630                 dirp->dd_bsize =  DIRBLKSIZ;
2631         }
2632 #endif
2633         else {
2634                 close(fd);
2635                 free((char *) dirp);
2636                 return NULL;
2637         }
2638         dirp->dd_fd = fd;
2639         dirp->dd_loc = -1;
2640         return dirp;
2641 }
2642 malloc.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0ä\10/* replace undef by define */
2643 #undef   DEBUG          /* check assertions */
2644 #undef   SLOWDEBUG      /* some extra test loops (requires DEBUG) */
2645
2646 #ifdef DEBUG
2647 #define ASSERT(b)       if (!(b)) assert_failed();
2648 #else
2649 #define ASSERT(b)       /* empty */
2650 #endif
2651
2652 #if _EM_WSIZE == _EM_PSIZE
2653 #define ptrint          int
2654 #else
2655 #define ptrint          long
2656 #endif
2657
2658 #if _EM_PSIZE == 2
2659 #define BRKSIZE         1024
2660 #else
2661 #define BRKSIZE         4096
2662 #endif
2663 #define PTRSIZE         sizeof(char *)
2664 #define Align(x,a)      (((x) + (a - 1)) & ~(ptrint)(a - 1))
2665 #define NextSlot(p)     (* (char **) ((p) - PTRSIZE))
2666 #define NextFree(p)     (* (char **) (p))
2667
2668 /*
2669  * A short explanation of the data structure and algorithms.
2670  * An area returned by malloc() is called a slot. Each slot
2671  * contains the number of bytes requested, but preceeded by
2672  * an extra pointer to the next the slot in memory.
2673  * '_bottom' and '_top' point to the first/last slot.
2674  * More memory is asked for using brk() and appended to top.
2675  * The list of free slots is maintained to keep malloc() fast.
2676  * '_empty' points the the first free slot. Free slots are
2677  * linked together by a pointer at the start of the
2678  * user visable part, so just after the next-slot pointer.
2679  * Free slots are merged together by free().
2680  */
2681
2682 extern char *sbrk(), *brk();
2683 static char *_bottom, *_top, *_empty;
2684
2685 static grow(len)
2686 unsigned len;
2687 {
2688   register char *p;
2689
2690   ASSERT(NextSlot(_top) == 0);
2691   p = (char *) Align((ptrint)_top + len, BRKSIZE);
2692   if (p < _top || brk(p) != 0)
2693         return(0);
2694   NextSlot(_top) = p;
2695   NextSlot(p) = 0;
2696   free(_top);
2697   _top = p;
2698   return(1);
2699 }
2700
2701 char *malloc(size)
2702 unsigned size;
2703 {
2704   register char *prev, *p, *next, *new;
2705   register unsigned len, ntries;
2706
2707   if (size == 0)
2708         size = PTRSIZE;         /* avoid slots less that 2*PTRSIZE */
2709   for (ntries = 0; ntries < 2; ntries++) {
2710         len = Align(size, PTRSIZE) + PTRSIZE;
2711         if (_bottom == 0) {
2712                 p = sbrk(2 * PTRSIZE);
2713                 p = (char *) Align((ptrint)p, PTRSIZE);
2714                 p += PTRSIZE;
2715                 _top = _bottom = p;
2716                 NextSlot(p) = 0;
2717         }
2718 #ifdef SLOWDEBUG
2719         for (p = _bottom; (next = NextSlot(p)) != 0; p = next)
2720                 ASSERT(next > p);
2721         ASSERT(p == _top);
2722 #endif
2723         for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) {
2724                 next = NextSlot(p);
2725                 new = p + len;
2726                 if (new > next)
2727                         continue;               /* too small */
2728                 if (new + PTRSIZE < next) {     /* too big, so split */
2729                         /* + PTRSIZE avoids tiny slots on free list */
2730                         NextSlot(new) = next;
2731                         NextSlot(p) = new;
2732                         NextFree(new) = NextFree(p);
2733                         NextFree(p) = new;
2734                 }
2735                 if (prev)
2736                         NextFree(prev) = NextFree(p);
2737                 else
2738                         _empty = NextFree(p);
2739                 return(p);
2740         }
2741         if (grow(len) == 0)
2742                 break;
2743   }
2744   ASSERT(ntries != 2);
2745   return(0);
2746 }
2747
2748 char *realloc(old, size)
2749 char *old;
2750 unsigned size;
2751 {
2752   register char *prev, *p, *next, *new;
2753   register unsigned len, n;
2754
2755   len = Align(size, PTRSIZE) + PTRSIZE;
2756   next = NextSlot(old);
2757   n = (int)(next - old);                        /* old length */
2758   /*
2759    * extend old if there is any free space just behind it
2760    */
2761   for (prev = 0, p = _empty; p != 0; prev = p, p = NextFree(p)) {
2762         if (p > next)
2763                 break;
2764         if (p == next) {        /* 'next' is a free slot: merge */
2765                 NextSlot(old) = NextSlot(p);
2766                 if (prev)
2767                         NextFree(prev) = NextFree(p);
2768                 else
2769                         _empty = NextFree(p);
2770                 next = NextSlot(old);
2771                 break;
2772         }
2773   }
2774   new = old + len;
2775   /*
2776    * Can we use the old, possibly extended slot?
2777    */
2778   if (new <= next) {                            /* it does fit */
2779         if (new + PTRSIZE < next) {             /* too big, so split */
2780                 /* + PTRSIZE avoids tiny slots on free list */
2781                 NextSlot(new) = next;
2782                 NextSlot(old) = new;
2783                 free(new);
2784         }
2785         return(old);
2786   }
2787   if ((new = malloc(size)) == 0)                /* it didn't fit */
2788         return(0);
2789   bcopy(old, new, n);                           /* n < size */
2790   free(old);
2791   return(new);
2792 }
2793
2794 free(p)
2795 char *p;
2796 {
2797   register char *prev, *next;
2798
2799   ASSERT(NextSlot(p) > p);
2800   for (prev = 0, next = _empty; next != 0; prev = next, next = NextFree(next))
2801         if (p < next)
2802                 break;
2803   NextFree(p) = next;
2804   if (prev)
2805         NextFree(prev) = p;
2806   else
2807         _empty = p;
2808   if (next) {
2809         ASSERT(NextSlot(p) <= next);
2810         if (NextSlot(p) == next) {              /* merge p and next */
2811                 NextSlot(p) = NextSlot(next);
2812                 NextFree(p) = NextFree(next);
2813         }
2814   }
2815   if (prev) {
2816         ASSERT(NextSlot(prev) <= p);
2817         if (NextSlot(prev) == p) {              /* merge prev and p */
2818                 NextSlot(prev) = NextSlot(p);
2819                 NextFree(prev) = NextFree(p);
2820         }
2821   }
2822 }
2823
2824 #ifdef DEBUG
2825 static assert_failed()
2826 {
2827         write(2, "assert failed in lib/malloc.c\n", 30);
2828         abort();
2829 }
2830 #endif
2831 bcopy.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0$\ 1/* $Id: bcopy.c,v 1.3 1994/06/24 12:12:46 ceriel Exp $ */
2832 bcopy(old, new, n)
2833 register char *old, *new;
2834 register int n;
2835 {
2836 /* Copy a block of data. */
2837
2838         if (old <= new && old + (n-1) >= new) {
2839                 old += n; new += n;
2840                 while (n-- > 0) *--new = *--old;
2841         }
2842         else    while (n-- > 0) *new++ = *old++;
2843 }
2844 readdir.c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0¦\ 5/* $Id: readdir.c,v 1.6 1994/06/24 12:14:32 ceriel Exp $ */
2845 #include <sys/types.h>
2846 #include <sys/dir.h>
2847
2848 #ifndef __BSD4_2
2849 /*
2850  * read an old stlye directory entry and present it as a new one
2851  */
2852 #define ODIRSIZ 14
2853
2854 struct  olddirect {
2855         ino_t   od_ino;
2856         char    od_name[ODIRSIZ];
2857 };
2858 #else
2859 #define olddirect direct
2860 #endif
2861
2862 /*
2863  * get next entry in a directory.
2864  */
2865 struct direct *readdir(dirp)
2866 register DIR *dirp;
2867 {
2868         register struct olddirect *dp;
2869         static struct direct dir;
2870
2871         for (;;) {
2872                 if (dirp->dd_loc == -1) {
2873                         dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
2874                                              dirp->dd_bsize);
2875                         if (dirp->dd_size <= 0) {
2876                                 dirp->dd_size = 0;
2877                                 return NULL;
2878                         }
2879                         dirp->dd_loc = 0;
2880 #ifdef __BSD4_2
2881                         if (! ((struct direct *) dirp->dd_buf)->d_ino) {
2882                                 dirp->dd_loc = ((struct direct *)dirp->dd_buf)->d_reclen;
2883                         }
2884 #endif
2885                 }
2886                 if (dirp->dd_loc >= dirp->dd_size) {
2887                         dirp->dd_loc = -1;
2888                         continue;
2889                 }
2890                 dp = (struct olddirect *) (dirp->dd_buf + dirp->dd_loc);
2891 #ifndef __BSD4_2
2892                 dirp->dd_loc += sizeof (struct olddirect);
2893                 if (dp->od_ino == 0)
2894                         continue;
2895                 dir.d_ino = dp->od_ino;
2896                 strncpy(dir.d_name, dp->od_name, ODIRSIZ);
2897                 dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
2898                 dir.d_reclen = DIRSIZ(&dir);
2899                 dir.d_namlen = strlen(dir.d_name);
2900 #else
2901                 dirp->dd_loc += dp->d_reclen;
2902                 dir.d_ino = dp->d_ino;
2903                 strcpy(dir.d_name, dp->d_name);
2904                 dir.d_reclen = dp->d_reclen;
2905                 dir.d_namlen = dp->d_namlen;
2906 #endif
2907                 return &dir;
2908         }
2909 }
2910 strcat.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0G\ 1/* $Id: strcat.c,v 1.4 1994/06/24 12:14:47 ceriel Exp $ */
2911 char *strcat(s1, s2)
2912 register char *s1, *s2;
2913 {
2914   /* Append s2 to the end of s1. */
2915
2916   char *original = s1;
2917
2918   /* Find the end of s1. */
2919   while (*s1++ != 0) ;
2920
2921   s1--;
2922   /* Now copy s2 to the end of s1. */
2923   while (*s1++ = *s2++) /* nothing */ ;
2924   return(original);
2925 }
2926 tstrcpy.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0Ô\0/* $Id: strcpy.c,v 1.3 1994/06/24 12:14:56 ceriel Exp $ */
2927 char *strcpy(s1, s2)
2928 register char *s1, *s2;
2929 {
2930 /* Copy s2 to s1. */
2931   char *original = s1;
2932
2933   while (*s1++ = *s2++) /* nothing */;
2934   return(original);
2935 }
2936 strlen.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\94\0/* $Id: strlen.c,v 1.4 1994/06/24 12:15:02 ceriel Exp $ */
2937 int
2938 strlen(s)
2939         char *s;
2940 {
2941         register char *b = s;
2942
2943         while (*b++)
2944                 ;
2945         return b - s - 1;
2946 }
2947 tzset.c\0\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0X\ 5/* $Id: tzset.c,v 1.9 1994/06/24 12:16:10 ceriel Exp $ */
2948 #ifdef __BSD4_2
2949 struct timeval {
2950         long tv_sec, tv_usec;
2951 };
2952 struct timezone {
2953         int tz_minuteswest, tz_dsttime;
2954 };
2955 #else
2956 #ifndef __USG
2957 #include <sys/types.h>
2958 struct timeb
2959 {
2960         time_t  time;
2961         ushort  millitm;
2962         short   timezone;
2963         short   dstflag;
2964 };
2965 #endif
2966 #endif
2967
2968 #ifdef __USG
2969 long    timezone = -1 * 60;
2970 int     daylight = 1;
2971 char    *tzname[] = {"MET", "MDT",};
2972 #endif
2973
2974 long __timezone = -1 * 60;
2975 int __daylight = 1;
2976 char *__tzname[] = {"MET", "MDT", };
2977
2978 tzset()
2979 {
2980 #ifdef __BSD4_2
2981         struct timeval tval;
2982         struct timezone tzon;
2983
2984         gettimeofday(&tval, &tzon);
2985         __timezone = tzon.tz_minuteswest * 60L;
2986         __daylight = tzon.tz_dsttime;
2987 #else
2988 #ifndef __USG
2989 #if minix || minixST
2990         __timezone = 0L;
2991         __daylight = 0;
2992 #else
2993         struct timeb time;
2994
2995         ftime(&time);
2996         __timezone = time.timezone*60L;
2997         __daylight = time.dstflag;
2998 #endif
2999 #endif
3000 #endif
3001
3002         {
3003         extern char *getenv();
3004         register char *p = getenv("TZ");
3005
3006         if (p && *p) {
3007                 register int n = 0;
3008                 int sign = 1;
3009
3010                 strncpy(__tzname[0], p, 3);
3011                 if (*(p += 3) == '-') {
3012                         sign = -1;
3013                         p++;
3014                 }
3015
3016                 while(*p >= '0' && *p <= '9')
3017                         n = 10 * n + (*p++ - '0');
3018                 n *= sign;
3019                 __timezone = ((long)(n * 60)) * 60;
3020                 __daylight = (*p != '\0');
3021                 strncpy(__tzname[1], p, 3);
3022         }
3023         }
3024 #ifdef __USG
3025         timezone = __timezone;
3026         daylight = __daylight;
3027         tzname[0] = __tzname[0];
3028         tzname[1] = __tzname[1];
3029 #endif
3030 }
3031 getenv.c\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0_\ 1/* $Id: getenv.c,v 1.5 1994/06/24 12:13:29 ceriel Exp $ */
3032 char *getenv(name)
3033 register char *name;
3034 {
3035   extern char **environ;
3036   register char **v = environ, *p, *q;
3037
3038   if (v == 0 || name == 0) return 0;
3039   while ((p = *v++) != 0) {
3040         q = name;
3041         while (*q && *q++ == *p++) /* nothing */ ;
3042         if (*q || *p != '=') continue;
3043         return(p+1);
3044   }
3045   return(0);
3046 }
3047 tstrncpy.c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\1c\ 1/* $Id: strncpy.c,v 1.3 1994/06/24 12:15:15 ceriel Exp $ */
3048 char
3049 *strncpy(s1, s2, n)
3050 register char *s1, *s2;
3051 int n;
3052 {
3053 /* Copy s2 to s1, but at most n characters. */
3054
3055   char *original = s1;
3056
3057   while (*s2 && n-- > 0) *s1++ = *s2++;
3058   while (n-- > 0) *s1++ = '\0';
3059   return(original);
3060 }
3061 _c2type.c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0¤\ 3/* $Id: _c2type.c,v 1.3 1994/06/24 12:12:26 ceriel Exp $ */
3062 /*  File   : _c2type.c
3063     Author : Richard A. O'Keefe.
3064     Updated: 23 April 1984
3065     Purpose: Map character codes to types
3066
3067     The mapping used here is such that we can use it for converting
3068     numbers expressed in a variety of radices to binary as well as for
3069     classifying characters.
3070 */
3071
3072 char _c2type[129] =
3073     {   37,                     /* EOF == -1 */
3074         37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 39, 39, 39, 39, 37, 37,
3075         37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
3076         38, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
3077         00, 01, 02, 03, 04, 05, 06, 07,  8,  9, 36, 36, 36, 36, 36, 36,
3078         36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
3079         25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36,
3080         36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
3081         25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36
3082     };
3083
3084 abort.e\0c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0^\0#include <em_abs.h>
3085  mes 2,EM_WSIZE,EM_PSIZE
3086  exp $abort
3087  pro $abort,0
3088  loc EILLINS
3089  trp
3090  end
3091 frexp.e\0c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0y\ 2#
3092 /*
3093  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
3094  *
3095  *          This product is part of the Amsterdam Compiler Kit.
3096  *
3097  * Permission to use, sell, duplicate or disclose this software must be
3098  * obtained in writing. Requests for such permissions may be sent to
3099  *
3100  *      Dr. Andrew S. Tanenbaum
3101  *      Wiskundig Seminarium
3102  *      Vrije Universiteit
3103  *      Postbox 7161
3104  *      1007 MC Amsterdam
3105  *      The Netherlands
3106  *
3107  */
3108
3109  mes 2,EM_WSIZE,EM_PSIZE
3110 #ifndef NOFLOAT
3111  exp $frexp
3112  pro $frexp,0
3113  lal 0
3114  loi EM_DSIZE
3115  fef EM_DSIZE
3116  lal EM_DSIZE
3117  loi EM_PSIZE
3118  sti EM_WSIZE
3119  ret EM_DSIZE
3120  end
3121 #endif
3122  modf.e\0\0c\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0\9f\ 2#
3123 /*
3124  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
3125  *
3126  *          This product is part of the Amsterdam Compiler Kit.
3127  *
3128  * Permission to use, sell, duplicate or disclose this software must be
3129  * obtained in writing. Requests for such permissions may be sent to
3130  *
3131  *      Dr. Andrew S. Tanenbaum
3132  *      Wiskundig Seminarium
3133  *      Vrije Universiteit
3134  *      Postbox 7161
3135  *      1007 MC Amsterdam
3136  *      The Netherlands
3137  *
3138  */
3139
3140  mes 2,EM_WSIZE,EM_PSIZE
3141 #ifndef NOFLOAT
3142  exp $modf
3143  pro $modf,0
3144  lal 0
3145  loi EM_DSIZE
3146  loc 1
3147  loc EM_WSIZE
3148  loc EM_DSIZE
3149  cif
3150  fif EM_DSIZE
3151  lal EM_DSIZE
3152  loi EM_PSIZE
3153  sti EM_DSIZE
3154  ret EM_DSIZE
3155  end
3156 #endif
3157 0setjmp.e\0\0\0\0\0\0\0\0\0\0\ 2\ 2¤\ 1\0\0*\a#
3158  mes 2,EM_WSIZE,EM_PSIZE
3159
3160 ;
3161 ; layout of a setjmp buffer:
3162 ;
3163 ;  -----------------
3164 ; |   signal mask   |           (only for Berkeley 4.[2-])
3165 ;  -----------------
3166 ; |                 |
3167 ; |  GTO descriptor |
3168 ; |   (SP, LB, PC)  |
3169 ; |                 |
3170 ;  -----------------
3171 ;
3172 ; setjmp saves the signalmask, PC, SP, and LB of caller, and creates a
3173 ; GTO descriptor from this.
3174 ; The big problem here is how to get the return address, i.e. the PC of
3175 ; the caller; This problem is solved by the front-end, which must pass
3176 ; it as an extra parameter to setjmp.
3177
3178 ; a GTO descriptor must be in the global data area
3179 gtobuf
3180  bss 3*EM_PSIZE,0,0
3181
3182  inp $fill_ret_area
3183  exp $setjmp
3184  pro $setjmp,0
3185 #ifdef __BSD4_2
3186 ; save mask of currently blocked signals. 
3187 ; longjmp must restore this mask
3188  loc 0
3189  cal $sigblock
3190  asp EM_WSIZE
3191  lfr EM_WSIZE
3192  lal 0
3193  loi EM_PSIZE
3194  stf 3*EM_PSIZE
3195 #endif
3196 ; create GTO descriptor for longjmp
3197  lxl 0
3198  dch            ; Local Base of caller
3199  lxa 0          ; Stackpointer of caller
3200  lal EM_PSIZE
3201  loi EM_PSIZE   ; Return address of caller
3202  lal 0
3203  loi EM_PSIZE   ; address of jmpbuf
3204  sti 3*EM_PSIZE ; LB, SP, and PC stored in jmpbuf
3205  loc 0
3206  ret EM_WSIZE   ; setjmp must return 0
3207  end 0
3208
3209  pro $fill_ret_area,0
3210 ; put argument in function result area
3211  lol 0
3212  ret EM_WSIZE
3213  end 0
3214
3215  exp $longjmp
3216  pro $longjmp,?
3217 #ifdef __BSD4_2
3218 ; restore signal mask
3219  lal 0
3220  loi EM_PSIZE
3221  lof 3*EM_PSIZE
3222  cal $sigsetmask
3223  asp EM_WSIZE
3224  lfr EM_WSIZE
3225  asp EM_WSIZE
3226 #endif
3227  lal 0
3228  loi EM_PSIZE   ; address of jmpbuf
3229  lae gtobuf
3230  blm 3*EM_PSIZE ; fill GTO descriptor from jmpbuf
3231  lol EM_PSIZE   ; second parameter of longjmp: the return value
3232  dup EM_WSIZE
3233  zne *3
3234 ; of course, longjmp may not return 0!
3235  asp EM_WSIZE
3236  loc 1
3237 3
3238 ; put return value in function result area
3239  cal $fill_ret_area
3240  asp EM_WSIZE
3241  gto gtobuf     ; there we go ...
3242 ; ASP and GTO do not damage function result area
3243  end 0