CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Views: 418346
1
/****************************************************************************
2
**
3
*W infuncs.c GAP source Martin Schönert
4
** & Alice Niemeyer
5
** & Werner Nickel
6
**
7
**
8
*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
9
*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
10
*Y Copyright (C) 2002 The GAP Group
11
**
12
** This file contains integer related functions which are independent of the
13
** large integer representation in use. See integer.c and gmpints.c for
14
** other things
15
*/
16
17
18
#include "system.h" /* Ints, UInts */
19
20
21
#include "gasman.h" /* garbage collector */
22
#include "objects.h" /* objects */
23
#include "scanner.h" /* scanner */
24
25
#include "gvars.h" /* global variables */
26
27
#include "calls.h" /* generic call mechanism */
28
#include "opers.h" /* generic operations */
29
30
#include "ariths.h" /* basic arithmetic */
31
32
#include "bool.h" /* booleans */
33
34
#include "intfuncs.h" /* integers */
35
36
#include "integer.h"
37
38
#include "gap.h" /* error handling, initialisation */
39
40
#include "records.h" /* generic records */
41
#include "precord.h" /* plain records */
42
43
#include "lists.h" /* generic lists */
44
#include "string.h" /* strings */
45
46
#include "saveload.h" /* saving and loading */
47
48
#include "code.h" /* coder */
49
#include "thread.h" /* threads */
50
#include "tls.h" /* thread-local storage */
51
52
53
#include <stdio.h>
54
55
56
/****************************************************************************
57
**
58
*F FuncSIZE_OBJ(<self>,<obj>)
59
**
60
** 'SIZE_OBJ( <obj> )' returns the size of a nonimmediate object. It can be
61
** used to debug memory use.
62
*/
63
Obj FuncSIZE_OBJ (
64
Obj self,
65
Obj a)
66
{
67
return INTOBJ_INT(SIZE_OBJ(a));
68
}
69
70
71
/****************************************************************************
72
**
73
** * * * * * * * "Mersenne twister" random numbers * * * * * * * * * * * * *
74
**
75
** Part of this code for fast generation of 32 bit pseudo random numbers with
76
** a period of length 2^19937-1 and a 623-dimensional equidistribution is
77
** taken from:
78
** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
79
** (Also look in Wikipedia for "Mersenne twister".)
80
** We use the file mt19937ar.c, version 2002/1/26.
81
*/
82
83
/****************************************************************************
84
**
85
*F InitRandomMT( <initstr> )
86
**
87
** Returns a string that can be used as data structure of a new MT random
88
** number generator. <initstr> can be an arbitrary string as seed.
89
*/
90
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
91
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
92
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
93
94
void initGRMT(UInt4 *mt, UInt4 s)
95
{
96
UInt4 mti;
97
mt[0]= s & 0xffffffffUL;
98
for (mti=1; mti<624; mti++) {
99
mt[mti] =
100
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
101
mt[mti] &= 0xffffffffUL;
102
}
103
/* store mti as last entry of mt[] */
104
mt[624] = mti;
105
}
106
107
/* to read a seed string independently of endianness */
108
static inline UInt4 uint4frombytes(UChar *s)
109
{
110
UInt4 res;
111
res = s[3]; res <<= 8;
112
res += s[2]; res <<= 8;
113
res += s[1]; res <<= 8;
114
res += s[0];
115
return res;
116
}
117
118
Obj FuncInitRandomMT( Obj self, Obj initstr)
119
{
120
Obj str;
121
UChar *init_key;
122
UInt4 *mt, key_length, i, j, k, N=624;
123
124
/* check the seed, given as string */
125
while (! IsStringConv(initstr)) {
126
initstr = ErrorReturnObj(
127
"<initstr> must be a string, not a %s)",
128
(Int)TNAM_OBJ(initstr), 0L,
129
"you can replace <initstr> via 'return <initstr>;'" );
130
}
131
132
/* store array of 624 UInt4 and one UInt4 as counter "mti" and an
133
endianness marker */
134
str = NEW_STRING(4*626);
135
SET_LEN_STRING(str, 4*626);
136
mt = (UInt4*) CHARS_STRING(str);
137
/* here the counter mti is set to 624 */
138
initGRMT(mt, 19650218UL);
139
i=1; j=0;
140
/* Do not set these up until all garbage collection is done */
141
init_key = CHARS_STRING(initstr);
142
key_length = GET_LEN_STRING(initstr) / 4;
143
k = (N>key_length ? N : key_length);
144
for (; k; k--) {
145
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
146
+ uint4frombytes(init_key+4*j) + j;
147
mt[i] &= 0xffffffffUL;
148
i++; j++;
149
if (i>=N) { mt[0] = mt[N-1]; i=1; }
150
if (j>=key_length) j=0;
151
}
152
for (k=N-1; k; k--) {
153
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i;
154
mt[i] &= 0xffffffffUL;
155
i++;
156
if (i>=N) { mt[0] = mt[N-1]; i=1; }
157
}
158
mt[0] = 0x80000000UL;
159
/* gives string "1234" in little endian as marker */
160
mt[625] = 875770417UL;
161
return str;
162
}
163
164
165
/* internal, generates a random number on [0,0xffffffff]-interval
166
** argument <mt> is pointer to a string generated by InitRandomMT
167
** (the first 4*624 bytes are the random numbers, the last 4 bytes contain
168
** a counter)
169
*/
170
UInt4 nextrandMT_int32(UInt4* mt)
171
{
172
UInt4 mti, y, N=624, M=397;
173
static UInt4 mag01[2]={0x0UL, MATRIX_A};
174
175
mti = mt[624];
176
if (mti >= N) {
177
int kk;
178
179
for (kk=0;kk<N-M;kk++) {
180
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
181
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
182
}
183
for (;kk<N-1;kk++) {
184
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
185
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
186
}
187
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
188
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
189
190
mti = 0;
191
}
192
193
y = mt[mti++];
194
mt[624] = mti;
195
196
/* Tempering */
197
y ^= (y >> 11);
198
y ^= (y << 7) & 0x9d2c5680UL;
199
y ^= (y << 15) & 0xefc60000UL;
200
y ^= (y >> 18);
201
202
return y;
203
}
204
205
/****************************************************************************
206
**
207
*F FuncHASHKEY_BAG(<self>,<obj>,<seed>,<offset>,<maxlen>)
208
**
209
** 'FuncHASHKEY_BAG' implements the internal function 'HASHKEY_BAG'.
210
**
211
** 'HASHKEY_BAG( <obj>, <seed>, <offset>, <maxlen> )'
212
**
213
** takes an non-immediate object and a small integer <int> and computes a
214
** hash value for the contents of the bag from these. (For this to be
215
** usable in algorithms, we need that objects of this kind are stored uniquely
216
** internally.
217
** The offset and the maximum number of bytes to process both count in
218
** bytes. The values passed to these parameters might depend on the word
219
** length of the computer.
220
** A <maxlen> value of -1 indicates infinity.
221
*/
222
223
224
//-----------------------------------------------------------------------------
225
// MurmurHash3 was written by Austin Appleby, and is placed in the public
226
// domain. The author hereby disclaims copyright to this source code.
227
228
// Note - The x86 and x64 versions do _not_ produce the same results, as the
229
// algorithms are optimized for their respective platforms. You can still
230
// compile and run any of them on any platform, but your performance with the
231
// non-native version will be less than optimal.
232
233
//-----------------------------------------------------------------------------
234
// MurmurHash3 was written by Austin Appleby, and is placed in the public
235
// domain. The author hereby disclaims copyright to this source code.
236
237
/* Minor modifications to get it to compile in C rather than C++ and
238
integrate with GAP SL*/
239
240
241
#if HAVE_STDINT_H
242
#include <stdint.h>
243
#endif
244
245
246
//-----------------------------------------------------------------------------
247
// Platform-specific functions and macros
248
249
250
#define FORCE_INLINE static inline
251
252
static inline uint32_t rotl32 ( uint32_t x, int8_t r )
253
{
254
return (x << r) | (x >> (32 - r));
255
}
256
#define ROTL32(x,y) rotl32(x,y)
257
258
259
static inline uint64_t rotl64 ( uint64_t x, int8_t r )
260
{
261
return (x << r) | (x >> (64 - r));
262
}
263
264
#define ROTL64(x,y) rotl64(x,y)
265
266
267
268
#define BIG_CONSTANT(x) (x##LLU)
269
270
271
//-----------------------------------------------------------------------------
272
// Block read - if your platform needs to do endian-swapping or can only
273
// handle aligned reads, do the conversion here
274
275
FORCE_INLINE uint32_t getblock4 ( const uint32_t * p, int i )
276
{
277
return p[i];
278
}
279
280
FORCE_INLINE uint64_t getblock8 ( const uint64_t * p, int i )
281
{
282
return p[i];
283
}
284
285
//-----------------------------------------------------------------------------
286
// Finalization mix - force all bits of a hash block to avalanche
287
288
FORCE_INLINE uint32_t fmix4 ( uint32_t h )
289
{
290
h ^= h >> 16;
291
h *= 0x85ebca6b;
292
h ^= h >> 13;
293
h *= 0xc2b2ae35;
294
h ^= h >> 16;
295
296
return h;
297
}
298
299
//----------
300
301
FORCE_INLINE uint64_t fmix8 ( uint64_t k )
302
{
303
k ^= k >> 33;
304
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
305
k ^= k >> 33;
306
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
307
k ^= k >> 33;
308
309
return k;
310
}
311
312
//-----------------------------------------------------------------------------
313
314
void MurmurHash3_x86_32 ( const void * key, int len,
315
UInt4 seed, void * out )
316
{
317
const uint8_t * data = (const uint8_t*)key;
318
const int nblocks = len / 4;
319
320
uint32_t h1 = seed;
321
322
uint32_t c1 = 0xcc9e2d51;
323
uint32_t c2 = 0x1b873593;
324
325
//----------
326
// body
327
328
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
329
330
int i;
331
for(i = -nblocks; i; i++)
332
{
333
uint32_t k1 = getblock4(blocks,i);
334
335
k1 *= c1;
336
k1 = ROTL32(k1,15);
337
k1 *= c2;
338
339
h1 ^= k1;
340
h1 = ROTL32(h1,13);
341
h1 = h1*5+0xe6546b64;
342
}
343
344
//----------
345
// tail
346
347
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
348
349
uint32_t k1 = 0;
350
351
switch(len & 3)
352
{
353
case 3: k1 ^= tail[2] << 16;
354
case 2: k1 ^= tail[1] << 8;
355
case 1: k1 ^= tail[0];
356
k1 *= c1; k1 = ROTL32(k1,16); k1 *= c2; h1 ^= k1;
357
};
358
359
//----------
360
// finalization
361
362
h1 ^= len;
363
364
h1 = fmix4(h1);
365
366
*(uint32_t*)out = h1;
367
}
368
369
//-----------------------------------------------------------------------------
370
371
void MurmurHash3_x86_128 ( const void * key, const int len,
372
uint32_t seed, void * out )
373
{
374
const uint8_t * data = (const uint8_t*)key;
375
const int nblocks = len / 16;
376
377
uint32_t h1 = seed;
378
uint32_t h2 = seed;
379
uint32_t h3 = seed;
380
uint32_t h4 = seed;
381
382
uint32_t c1 = 0x239b961b;
383
uint32_t c2 = 0xab0e9789;
384
uint32_t c3 = 0x38b34ae5;
385
uint32_t c4 = 0xa1e38b93;
386
387
//----------
388
// body
389
390
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
391
392
int i;
393
for(i = -nblocks; i; i++)
394
{
395
uint32_t k1 = getblock4(blocks,i*4+0);
396
uint32_t k2 = getblock4(blocks,i*4+1);
397
uint32_t k3 = getblock4(blocks,i*4+2);
398
uint32_t k4 = getblock4(blocks,i*4+3);
399
400
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
401
402
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
403
404
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
405
406
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
407
408
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
409
410
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
411
412
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
413
414
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
415
}
416
417
//----------
418
// tail
419
420
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
421
422
uint32_t k1 = 0;
423
uint32_t k2 = 0;
424
uint32_t k3 = 0;
425
uint32_t k4 = 0;
426
427
switch(len & 15)
428
{
429
case 15: k4 ^= tail[14] << 16;
430
case 14: k4 ^= tail[13] << 8;
431
case 13: k4 ^= tail[12] << 0;
432
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
433
434
case 12: k3 ^= tail[11] << 24;
435
case 11: k3 ^= tail[10] << 16;
436
case 10: k3 ^= tail[ 9] << 8;
437
case 9: k3 ^= tail[ 8] << 0;
438
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
439
440
case 8: k2 ^= tail[ 7] << 24;
441
case 7: k2 ^= tail[ 6] << 16;
442
case 6: k2 ^= tail[ 5] << 8;
443
case 5: k2 ^= tail[ 4] << 0;
444
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
445
446
case 4: k1 ^= tail[ 3] << 24;
447
case 3: k1 ^= tail[ 2] << 16;
448
case 2: k1 ^= tail[ 1] << 8;
449
case 1: k1 ^= tail[ 0] << 0;
450
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
451
};
452
453
//----------
454
// finalization
455
456
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
457
458
h1 += h2; h1 += h3; h1 += h4;
459
h2 += h1; h3 += h1; h4 += h1;
460
461
h1 = fmix4(h1);
462
h2 = fmix4(h2);
463
h3 = fmix4(h3);
464
h4 = fmix4(h4);
465
466
h1 += h2; h1 += h3; h1 += h4;
467
h2 += h1; h3 += h1; h4 += h1;
468
469
((uint32_t*)out)[0] = h1;
470
((uint32_t*)out)[1] = h2;
471
((uint32_t*)out)[2] = h3;
472
((uint32_t*)out)[3] = h4;
473
}
474
475
//-----------------------------------------------------------------------------
476
477
void MurmurHash3_x64_128 ( const void * key, const int len,
478
const UInt4 seed, void * out )
479
{
480
const uint8_t * data = (const uint8_t*)key;
481
const int nblocks = len / 16;
482
483
uint64_t h1 = seed;
484
uint64_t h2 = seed;
485
486
uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
487
uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
488
489
//----------
490
// body
491
492
const uint64_t * blocks = (const uint64_t *)(data);
493
494
int i;
495
for(i = 0; i < nblocks; i++)
496
{
497
uint64_t k1 = getblock8(blocks,i*2+0);
498
uint64_t k2 = getblock8(blocks,i*2+1);
499
500
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
501
502
h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
503
504
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
505
506
h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
507
}
508
509
//----------
510
// tail
511
512
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
513
514
uint64_t k1 = 0;
515
uint64_t k2 = 0;
516
517
switch(len & 15)
518
{
519
case 15: k2 ^= (uint64_t)(tail[14]) << 48;
520
case 14: k2 ^= (uint64_t)(tail[13]) << 40;
521
case 13: k2 ^= (uint64_t)(tail[12]) << 32;
522
case 12: k2 ^= (uint64_t)(tail[11]) << 24;
523
case 11: k2 ^= (uint64_t)(tail[10]) << 16;
524
case 10: k2 ^= (uint64_t)(tail[ 9]) << 8;
525
case 9: k2 ^= (uint64_t)(tail[ 8]) << 0;
526
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
527
528
case 8: k1 ^= (uint64_t)(tail[ 7]) << 56;
529
case 7: k1 ^= (uint64_t)(tail[ 6]) << 48;
530
case 6: k1 ^= (uint64_t)(tail[ 5]) << 40;
531
case 5: k1 ^= (uint64_t)(tail[ 4]) << 32;
532
case 4: k1 ^= (uint64_t)(tail[ 3]) << 24;
533
case 3: k1 ^= (uint64_t)(tail[ 2]) << 16;
534
case 2: k1 ^= (uint64_t)(tail[ 1]) << 8;
535
case 1: k1 ^= (uint64_t)(tail[ 0]) << 0;
536
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
537
};
538
539
//----------
540
// finalization
541
542
h1 ^= len; h2 ^= len;
543
544
h1 += h2;
545
h2 += h1;
546
547
h1 = fmix8(h1);
548
h2 = fmix8(h2);
549
550
h1 += h2;
551
h2 += h1;
552
553
((uint64_t*)out)[0] = h1;
554
((uint64_t*)out)[1] = h2;
555
}
556
557
558
Obj FuncHASHKEY_BAG(Obj self, Obj obj, Obj opSeed, Obj opOffset, Obj opMaxLen)
559
{
560
Int n;
561
Int offs;
562
563
/* check the arguments */
564
while ( TNUM_OBJ(opSeed) != T_INT ) {
565
opSeed = ErrorReturnObj(
566
"HASHKEY_BAG: <seed> must be a small integer (not a %s)",
567
(Int)TNAM_OBJ(opSeed), 0L,
568
"you can replace <seed> via 'return <seed>;'" );
569
}
570
571
do {
572
offs = -1;
573
574
while ( TNUM_OBJ(opOffset) != T_INT ) {
575
opOffset = ErrorReturnObj(
576
"HASHKEY_BAG: <offset> must be a small integer (not a %s)",
577
(Int)TNAM_OBJ(opOffset), 0L,
578
"you can replace <offset> via 'return <offset>;'" );
579
}
580
offs = INT_INTOBJ(opOffset);
581
if ( offs < 0 || offs > SIZE_OBJ(obj)) {
582
opOffset = ErrorReturnObj(
583
"HashKeyBag: <offset> must be non-negative and less than the bag size",
584
0L, 0L,
585
"you can replace <offset> via 'return <offset>;'" );
586
offs = -1;
587
}
588
} while (offs < 0);
589
590
while ( TNUM_OBJ(opMaxLen) != T_INT ) {
591
opMaxLen = ErrorReturnObj(
592
"HASHKEY_BAG: <maxlen> must be a small integer (not a %s)",
593
(Int)TNAM_OBJ(opMaxLen), 0L,
594
"you can replace <maxlen> via 'return <maxlen>;'" );
595
}
596
597
n=SIZE_OBJ(obj)-offs;
598
599
/* maximal number of bytes to read */
600
Int maxlen=INT_INTOBJ(opMaxLen);
601
if ((n>maxlen)&&(maxlen!=-1)) {n=maxlen;};
602
603
return INTOBJ_INT(HASHKEY_BAG_NC( obj, (UInt4)INT_INTOBJ(opSeed), offs, (int) n));
604
}
605
606
Int HASHKEY_BAG_NC (Obj obj, UInt4 seed, Int skip, int maxread){
607
#ifdef SYS_IS_64_BIT
608
UInt8 hashout[2];
609
MurmurHash3_x64_128 ( (const void *)((UChar *)ADDR_OBJ(obj)+skip),
610
maxread, seed, (void *) hashout);
611
return hashout[0] % (1UL << 60);
612
#else
613
UInt4 hashout;
614
MurmurHash3_x86_32 ( (const void *)((UChar *)ADDR_OBJ(obj)+skip),
615
maxread, seed, (void *) &hashout);
616
return hashout % (1UL << 28);
617
#endif
618
}
619
620
Obj FuncJenkinsHash(Obj self, Obj op, Obj size)
621
{
622
return FuncHASHKEY_BAG(self, op, INTOBJ_INT(0L), INTOBJ_INT(0L), size);
623
}
624
625
626
/****************************************************************************
627
**
628
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
629
*/
630
631
632
/****************************************************************************
633
**
634
*V GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export
635
*/
636
static StructGVarFunc GVarFuncs [] = {
637
638
639
{ "HASHKEY_BAG", 4, "obj, int,int,int",
640
FuncHASHKEY_BAG, "src/integer.c:HASHKEY_BAG" },
641
642
{ "JENKINS_HASH", 2, "obj, len",
643
FuncJenkinsHash, "src/integer.c:JENKINS_HASH" },
644
645
{ "SIZE_OBJ", 1, "obj",
646
FuncSIZE_OBJ, "src/integer.c:SIZE_OBJ" },
647
648
{ "InitRandomMT", 1, "initstr",
649
FuncInitRandomMT, "src/integer.c:InitRandomMT" },
650
651
{ 0 }
652
653
};
654
655
656
/****************************************************************************
657
**
658
*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures
659
*/
660
static Int InitKernel (
661
StructInitInfo * module )
662
{
663
664
665
/* init filters and functions */
666
InitHdlrFuncsFromTable( GVarFuncs );
667
668
return 0;
669
}
670
671
672
/****************************************************************************
673
**
674
*F InitLibrary( <module> ) . . . . . . . initialise library data structures
675
*/
676
static Int InitLibrary (
677
StructInitInfo * module )
678
{
679
/* init filters and functions */
680
InitGVarFuncsFromTable( GVarFuncs );
681
682
/* return success */
683
return 0;
684
}
685
686
687
/****************************************************************************
688
**
689
*F InitInfoIntFuncs() . . . . . . . . . . . . . . . . . . table of init functions
690
*/
691
static StructInitInfo module = {
692
MODULE_BUILTIN, /* type */
693
"intfuncs", /* name */
694
0, /* revision entry of c file */
695
0, /* revision entry of h file */
696
0, /* version */
697
0, /* crc */
698
InitKernel, /* initKernel */
699
InitLibrary, /* initLibrary */
700
0, /* checkInit */
701
0, /* preSave */
702
0, /* postSave */
703
0 /* postRestore */
704
};
705
706
StructInitInfo * InitInfoIntFuncs ( void )
707
{
708
return &module;
709
}
710
711
712
/****************************************************************************
713
**
714
*E intfuncs.c . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
715
*/
716
717