FORM 4.3
comtool.c
Go to the documentation of this file.
1
5/* #[ License : */
6/*
7 * Copyright (C) 1984-2022 J.A.M. Vermaseren
8 * When using this file you are requested to refer to the publication
9 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
10 * This is considered a matter of courtesy as the development was paid
11 * for by FOM the Dutch physics granting agency and we would like to
12 * be able to track its scientific use to convince FOM of its value
13 * for the community.
14 *
15 * This file is part of FORM.
16 *
17 * FORM is free software: you can redistribute it and/or modify it under the
18 * terms of the GNU General Public License as published by the Free Software
19 * Foundation, either version 3 of the License, or (at your option) any later
20 * version.
21 *
22 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
23 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
25 * details.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with FORM. If not, see <http://www.gnu.org/licenses/>.
29 */
30/* #] License : */
31/*
32 #[ Includes :
33*/
34
35#include "form3.h"
36
37/*
38 #] Includes :
39 #[ inicbufs :
40*/
41
47int inicbufs(VOID)
48{
49 int i, num = AC.cbufList.num;
50 CBUF *C = cbuf;
51 for ( i = 0; i < num; i++, C++ ) {
52 if ( C->Buffer == 0 ) break;
53 }
54 if ( i >= num ) C = (CBUF *)FromList(&AC.cbufList);
55 else num = i;
56 C->BufferSize = 2000;
57 C->Buffer = (WORD *)Malloc1(C->BufferSize*sizeof(WORD),"compiler buffer-1");
58 C->Pointer = C->Buffer;
59 C->Top = C->Buffer + C->BufferSize;
60 C->maxlhs = 10;
61 C->lhs = (WORD **)Malloc1(C->maxlhs*sizeof(WORD *),"compiler buffer-2");
62 C->numlhs = 0;
63 C->mnumlhs = 0;
64 C->maxrhs = 25;
65 C->rhs = (WORD **)Malloc1(C->maxrhs*(sizeof(WORD *)+2*sizeof(LONG)+2*sizeof(WORD)),"compiler buffer-3");
66 C->CanCommu = (LONG *)(C->rhs+C->maxrhs);
67 C->NumTerms = C->CanCommu+C->maxrhs;
68 C->numdum = (WORD *)(C->NumTerms+C->maxrhs);
69 C->dimension = C->numdum + C->maxrhs;
70 C->numrhs = 0;
71 C->mnumrhs = 0;
72 C->rhs[0] = C->rhs[1] = C->Pointer;
73 C->boomlijst = 0;
74 RedoTree(C,C->maxrhs);
75 ClearTree(num);
76 return(num);
77}
78
79/*
80 #] inicbufs :
81 #[ finishcbuf :
82*/
83
89void finishcbuf(WORD num)
90{
91 CBUF *C = cbuf+num;
92 if ( C->Buffer ) M_free(C->Buffer,"compiler buffer-1");
93 if ( C->rhs ) M_free(C->rhs,"compiler buffer-3");
94 if ( C->lhs ) M_free(C->lhs,"compiler buffer-2");
95 if ( C->boomlijst ) M_free(C->boomlijst,"boomlijst");
96 C->Top = C->Pointer = C->Buffer = 0;
97 C->rhs = C->lhs = 0;
98 C->CanCommu = 0;
99 C->NumTerms = 0;
100 C->BufferSize = 0;
101 C->boomlijst = 0;
102 C->numlhs = C->numrhs = C->maxlhs = C->maxrhs = C->mnumlhs =
103 C->mnumrhs = C->numtree = C->rootnum = C->MaxTreeSize = 0;
104}
105
106/*
107 #] finishcbuf :
108 #[ clearcbuf :
109*/
110
116void clearcbuf(WORD num)
117{
118 CBUF *C = cbuf+num;
119 if ( C->boomlijst ) M_free(C->boomlijst,"boomlijst");
120 C->Pointer = C->Buffer;
121 C->numrhs = C->numlhs = 0;
122 C->mnumlhs = 0;
123 C->boomlijst = 0;
124 C->mnumrhs = 0;
125 C->rhs[0] = C->rhs[1] = C->Pointer;
126 C->numtree = C->rootnum = C->MaxTreeSize = 0;
127 RedoTree(C,C->maxrhs);
128 ClearTree(num);
129}
130
131/*
132 #] clearcbuf :
133 #[ DoubleCbuffer :
134*/
135
143WORD *DoubleCbuffer(int num, WORD *w,int par)
144{
145 CBUF *C = cbuf + num;
146 LONG newsize = C->BufferSize*2;
147 WORD *newbuffer = (WORD *)Malloc1(newsize*sizeof(WORD),"compiler buffer-4");
148 WORD *w1, *w2;
149 LONG offset, j, i;
150 DUMMYUSE(par)
151/*
152 MLOCK(ErrorMessageLock);
153 MesPrint(" doubleCbuffer: par = %d",par);
154 MUNLOCK(ErrorMessageLock);
155*/
156 w1 = C->Buffer; w2 = newbuffer;
157 i = w - w1;
158 j = i & 7;
159 while ( --j >= 0 ) *w2++ = *w1++;
160 i >>= 3;
161 while ( --i >= 0 ) {
162 *w2++ = *w1++; *w2++ = *w1++; *w2++ = *w1++; *w2++ = *w1++;
163 *w2++ = *w1++; *w2++ = *w1++; *w2++ = *w1++; *w2++ = *w1++;
164 }
165 offset = newbuffer - C->Buffer;
166 for ( i = 0; i <= C->numlhs; i++ ) C->lhs[i] += offset;
167 for ( i = 1; i <= C->numrhs; i++ ) C->rhs[i] += offset;
168 w1 = C->Buffer;
169 C->Pointer += offset;
170 C->Top = newbuffer + newsize;
171 C->BufferSize = newsize;
172 C->Buffer = newbuffer;
173 M_free(w1,"DoubleCbuffer");
174 return(w2);
175}
176
177/*
178 #] DoubleCbuffer :
179 #[ AddLHS :
180*/
181
188WORD *AddLHS(int num)
189{
190 CBUF *C = cbuf + num;
191 C->numlhs++;
192 if ( C->numlhs >= (C->maxlhs-2) ) {
193 WORD ***ppp = &(C->lhs); /* to avoid compiler warning */
194 if ( DoubleList((VOID ***)ppp,&(C->maxlhs),sizeof(WORD *),
195 "statement lists") ) Terminate(-1);
196 }
197 C->lhs[C->numlhs] = C->Pointer;
198 C->lhs[C->numlhs+1] = 0;
199 return(C->Pointer);
200}
201
202/*
203 #] AddLHS :
204 #[ AddRHS :
205*/
206
214WORD *AddRHS(int num, int type)
215{
216 LONG fullsize, *lold, newsize;
217 int i;
218 WORD **old, *wold;
219 CBUF *C;
220restart:;
221 C = cbuf + num;
222 if ( C->numrhs >= (C->maxrhs-2) ) {
223 if ( C->maxrhs == 0 ) newsize = 100;
224 else newsize = C->maxrhs * 2;
225 if ( newsize > MAXCOMBUFRHS ) newsize = MAXCOMBUFRHS;
226 if ( newsize == C->maxrhs ) {
227 if ( AC.tablefilling ) {
228 TABLES T = functions[AC.tablefilling].tabl;
229/*
230 We add a compiler buffer, change a few settings and continue.
231*/
232 if ( T->buffersfill >= T->bufferssize ) {
233 int new1 = 2*T->bufferssize;
234 WORD *nbufs = (WORD *)Malloc1(new1*sizeof(WORD),"Table compile buffers");
235 for ( i = 0; i < T->buffersfill; i++ )
236 nbufs[i] = T->buffers[i];
237 for ( ; i < new1; i++ ) nbufs[i] = 0;
238 M_free(T->buffers,"Table compile buffers");
239 T->buffers = nbufs;
240 T->bufferssize = new1;
241 }
242 T->buffers[T->buffersfill++] = T->bufnum = inicbufs();
243 AC.cbufnum = num = T->bufnum;
244 goto restart;
245 }
246 else {
247 MesPrint("@Compiler buffer overflow. Try to make modules smaller");
248 Terminate(-1);
249 }
250 }
251 old = C->rhs;
252 fullsize = newsize * (sizeof(WORD *) + 2*sizeof(LONG) + 2*sizeof(WORD));
253 C->rhs = (WORD **)Malloc1(fullsize,"subexpression lists");
254 for ( i = 0; i < C->maxrhs; i++ ) C->rhs[i] = old[i];
255 lold = C->CanCommu; C->CanCommu = (LONG *)(C->rhs+newsize);
256 for ( i = 0; i < C->maxrhs; i++ ) C->CanCommu[i] = lold[i];
257 lold = C->NumTerms; C->NumTerms = (LONG *)(C->rhs+2*newsize);
258 for ( i = 0; i < C->maxrhs; i++ ) C->NumTerms[i] = lold[i];
259 wold = C->numdum; C->numdum = (WORD *)(C->NumTerms+newsize);
260 for ( i = 0; i < C->maxrhs; i++ ) C->numdum[i] = wold[i];
261 wold = C->dimension; C->dimension = (WORD *)(C->numdum+newsize);
262 for ( i = 0; i < C->maxrhs; i++ ) C->dimension[i] = wold[i];
263 if ( old ) M_free(old,"subexpression lists");
264 C->maxrhs = newsize;
265 if ( type == 0 ) RedoTree(C,C->maxrhs);
266 }
267 C->numrhs++;
268 C->CanCommu[C->numrhs] = 0;
269 C->NumTerms[C->numrhs] = 0;
270 C->numdum[C->numrhs] = 0;
271 C->dimension[C->numrhs] = 0;
272 C->rhs[C->numrhs] = C->Pointer;
273 return(C->Pointer);
274}
275
276/*
277 #] AddRHS :
278 #[ AddNtoL :
279*/
280
288int AddNtoL(int n, WORD *array)
289{
290 int i;
291 CBUF *C = cbuf+AC.cbufnum;
292#ifdef COMPBUFDEBUG
293 MesPrint("LH: %a",n,array);
294#endif
295 AddLHS(AC.cbufnum);
296 while ( C->Pointer+n >= C->Top ) DoubleCbuffer(AC.cbufnum,C->Pointer,1);
297 for ( i = 0; i < n; i++ ) *(C->Pointer)++ = *array++;
298 return(0);
299}
300
301/*
302 #] AddNtoL :
303 #[ AddNtoC :
304
305 Commentary: added the bufnum on 14-sep-2010 to make the whole a bit
306 more flexible (JV). Still to do with AddNtoL.
307*/
308
317int AddNtoC(int bufnum, int n, WORD *array,int par)
318{
319 int i;
320 WORD *w;
321 CBUF *C = cbuf+bufnum;
322#ifdef COMPBUFDEBUG
323 MesPrint("RH: %a",n,array);
324#endif
325 while ( C->Pointer+n+1 >= C->Top ) DoubleCbuffer(bufnum,C->Pointer,50+par);
326 w = C->Pointer;
327 for ( i = 0; i < n; i++ ) *w++ = *array++;
328 C->Pointer = w;
329 return(0);
330}
331
332/*
333 #] AddNtoC :
334 #[ InsTree :
335
336 Routines for balanced tree searching and insertion.
337 Compared to Knuth we have a parent link. This minimizes the
338 number of compares. That is better for anything that is more
339 complicated than just single numbers.
340 There are no provisions for removing elements from the tree.
341 The routines are:
342 void RedoTree(size) Re-allocates the tree space. There will
343 be MaxTreeSize = size elements.
344 void ClearTree() Prunes the tree down to the root element.
345 int InsTree(int,int)Searches for the requested element. If not found it
346 will allocate a new element, balance the tree if
347 necessary and return the called number.
348 If it was in the tree, it returns the tree 'value'.
349
350 Commentary: added the bufnum on 14-sep-2010 to make the whole a bit
351 more flexible (JV).
352*/
353static COMPTREE comptreezero = {0,0,0,0,0,0};
354
355int InsTree(int bufnum, int h)
356{
357 CBUF *C = cbuf + bufnum;
358 COMPTREE *boomlijst = C->boomlijst, *q = boomlijst + C->rootnum, *p, *s;
359 WORD *v1, *v2, *v3;
360 int ip, iq, is;
361
362 if ( C->numtree + 1 >= C->MaxTreeSize ) {
363 if ( C->MaxTreeSize == 0 ) {
364 COMPTREE *root;
365 C->MaxTreeSize = 125;
366 C->boomlijst = (COMPTREE *)Malloc1((C->MaxTreeSize+1)*sizeof(COMPTREE),
367 "ClearInsTree");
368 root = C->boomlijst;
369 C->numtree = 0;
370 C->rootnum = 0;
371 root->left = -1;
372 root->right = -1;
373 root->parent = -1;
374 root->blnce = 0;
375 root->value = -1;
376 root->usage = 0;
377 for ( ip = 1; ip < C->MaxTreeSize; ip++ ) { C->boomlijst[ip] = comptreezero; }
378 }
379 else {
380 is = C->MaxTreeSize * 2;
381 s = (COMPTREE *)Malloc1((is+1)*sizeof(COMPTREE),"InsTree");
382 for ( ip = 0; ip < C->MaxTreeSize; ip++ ) { s[ip] = C->boomlijst[ip]; }
383 for ( ip = C->MaxTreeSize; ip <= is; ip++ ) { s[ip] = comptreezero; }
384 if ( C->boomlijst ) M_free(C->boomlijst,"InsTree");
385 C->boomlijst = s;
386 C->MaxTreeSize = is;
387 }
388 boomlijst = C->boomlijst;
389 q = boomlijst + C->rootnum;
390 }
391
392 if ( q->right == -1 ) { /* First element */
393 C->numtree++;
394 s = boomlijst+C->numtree;
395 q->right = C->numtree;
396 s->parent = C->rootnum;
397 s->left = s->right = -1;
398 s->blnce = 0;
399 s->value = h;
400 s->usage = 1;
401 return(h);
402 }
403 ip = q->right;
404 while ( ip >= 0 ) {
405 p = boomlijst + ip;
406 v1 = C->rhs[p->value]; v2 = v3 = C->rhs[h];
407 while ( *v3 ) v3 += *v3; /* find the 0 that indicates end-of-expr */
408 while ( *v1 == *v2 && v2 < v3 ) { v1++; v2++; }
409 if ( *v1 > *v2 ) {
410 iq = p->right;
411 if ( iq >= 0 ) { ip = iq; }
412 else {
413 C->numtree++;
414 is = C->numtree;
415 p->right = is;
416 s = boomlijst + is;
417 s->parent = ip; s->left = s->right = -1;
418 s->blnce = 0; s->value = h; s->usage = 1;
419 p->blnce++;
420 if ( p->blnce == 0 ) return(h);
421 goto balance;
422 }
423 }
424 else if ( *v1 < *v2 ) {
425 iq = p->left;
426 if ( iq >= 0 ) { ip = iq; }
427 else {
428 C->numtree++;
429 is = C->numtree;
430 s = boomlijst+is;
431 p->left = is;
432 s->parent = ip; s->left = s->right = -1;
433 s->blnce = 0; s->value = h; s->usage = 1;
434 p->blnce--;
435 if ( p->blnce == 0 ) return(h);
436 goto balance;
437 }
438 }
439 else {
440 p->usage++;
441 return(p->value);
442 }
443 }
444 MesPrint("We vallen uit de boom!");
445 Terminate(-1);
446 return(h);
447balance:;
448 for (;;) {
449 p = boomlijst + ip;
450 iq = p->parent;
451 if ( iq == C->rootnum ) break;
452 q = boomlijst + iq;
453 if ( ip == q->left ) q->blnce--;
454 else q->blnce++;
455 if ( q->blnce == 0 ) break;
456 if ( q->blnce == -2 ) {
457 if ( p->blnce == -1 ) { /* single rotation */
458 q->left = p->right;
459 p->right = iq;
460 p->parent = q->parent;
461 q->parent = ip;
462 if ( boomlijst[p->parent].left == iq ) boomlijst[p->parent].left = ip;
463 else boomlijst[p->parent].right = ip;
464 if ( q->left >= 0 ) boomlijst[q->left].parent = iq;
465 q->blnce = p->blnce = 0;
466 }
467 else { /* double rotation */
468 s = boomlijst + is;
469 q->left = s->right;
470 p->right = s->left;
471 s->right = iq;
472 s->left = ip;
473 if ( p->right >= 0 ) boomlijst[p->right].parent = ip;
474 if ( q->left >= 0 ) boomlijst[q->left].parent = iq;
475 s->parent = q->parent;
476 q->parent = is;
477 p->parent = is;
478 if ( boomlijst[s->parent].left == iq )
479 boomlijst[s->parent].left = is;
480 else boomlijst[s->parent].right = is;
481 if ( s->blnce > 0 ) { q->blnce = s->blnce = 0; p->blnce = -1; }
482 else if ( s->blnce < 0 ) { p->blnce = s->blnce = 0; q->blnce = 1; }
483 else { p->blnce = s->blnce = q->blnce = 0; }
484 }
485 break;
486 }
487 else if ( q->blnce == 2 ) {
488 if ( p->blnce == 1 ) { /* single rotation */
489 q->right = p->left;
490 p->left = iq;
491 p->parent = q->parent;
492 q->parent = ip;
493 if ( boomlijst[p->parent].left == iq ) boomlijst[p->parent].left = ip;
494 else boomlijst[p->parent].right = ip;
495 if ( q->right >= 0 ) boomlijst[q->right].parent = iq;
496 q->blnce = p->blnce = 0;
497 }
498 else { /* double rotation */
499 s = boomlijst + is;
500 q->right = s->left;
501 p->left = s->right;
502 s->left = iq;
503 s->right = ip;
504 if ( p->left >= 0 ) boomlijst[p->left].parent = ip;
505 if ( q->right >= 0 ) boomlijst[q->right].parent = iq;
506 s->parent = q->parent;
507 q->parent = is;
508 p->parent = is;
509 if ( boomlijst[s->parent].left == iq ) boomlijst[s->parent].left = is;
510 else boomlijst[s->parent].right = is;
511 if ( s->blnce < 0 ) { q->blnce = s->blnce = 0; p->blnce = 1; }
512 else if ( s->blnce > 0 ) { p->blnce = s->blnce = 0; q->blnce = -1; }
513 else { p->blnce = s->blnce = q->blnce = 0; }
514 }
515 break;
516 }
517 is = ip; ip = iq;
518 }
519 return(h);
520}
521
522/*
523 #] InsTree :
524 #[ FindTree :
525
526 Routines for balanced tree searching.
527 Is like InsTree but without the insertions.
528 Returns -1 if the element is not in the tree.
529 The advantage of this routine over InsTree is that this routine
530 can be run in parallel.
531*/
532
533int FindTree(int bufnum, WORD *subexpr)
534{
535 CBUF *C = cbuf + bufnum;
536 COMPTREE *boomlijst = C->boomlijst, *q = boomlijst + C->rootnum, *p;
537 WORD *v1, *v2, *v3;
538 int ip, iq;
539
540 ip = q->right;
541 while ( ip >= 0 ) {
542 p = boomlijst + ip;
543 v1 = C->rhs[p->value]; v2 = v3 = subexpr;
544 while ( *v3 ) v3 += *v3; /* find the 0 that indicates end-of-expr */
545 while ( *v1 == *v2 && v2 < v3 ) { v1++; v2++; }
546 if ( *v1 > *v2 ) {
547 iq = p->right;
548 if ( iq >= 0 ) { ip = iq; }
549 else { return(-1); }
550 }
551 else if ( *v1 < *v2 ) {
552 iq = p->left;
553 if ( iq >= 0 ) { ip = iq; }
554 else { return(-1); }
555 }
556 else {
557 p->usage++;
558 return(p->value);
559 }
560 }
561 return(-1);
562}
563
564/*
565 #] FindTree :
566 #[ RedoTree :
567*/
568
569void RedoTree(CBUF *C, int size)
570{
571 COMPTREE *newboomlijst;
572 int i;
573 newboomlijst = (COMPTREE *)Malloc1((size+1)*sizeof(COMPTREE),"newboomlijst");
574 if ( C->boomlijst ) {
575 if ( C->MaxTreeSize > size ) C->MaxTreeSize = size;
576 for ( i = 0; i < C->MaxTreeSize; i++ ) newboomlijst[i] = C->boomlijst[i];
577 M_free(C->boomlijst,"boomlijst");
578 }
579 C->boomlijst = newboomlijst;
580 C->MaxTreeSize = size;
581}
582
583/*
584 #] RedoTree :
585 #[ ClearTree :
586*/
587
588void ClearTree(int i)
589{
590 CBUF *C = cbuf + i;
591 COMPTREE *root = C->boomlijst;
592 if ( root ) {
593 C->numtree = 0;
594 C->rootnum = 0;
595 root->left = -1;
596 root->right = -1;
597 root->parent = -1;
598 root->blnce = 0;
599 root->value = -1;
600 root->usage = 0;
601 }
602}
603
604/*
605 #] ClearTree :
606 #[ IniFbuffer :
607*/
614int IniFbuffer(WORD bufnum)
615{
616 CBUF *C = cbuf + bufnum;
617 COMPTREE *root;
618 int i;
619 LONG fullsize;
620 C->maxrhs = AM.fbuffersize;
621 C->MaxTreeSize = AM.fbuffersize;
622
623 /*
624 * Note that bufnum is a return value of inicbufs(). So C has been already
625 * initialized. (TU 20 Dec 2011)
626 */
627 if ( C->boomlijst ) M_free(C->boomlijst, "IniFbuffer-tree");
628 if ( C->rhs ) M_free(C->rhs, "IniFbuffer-rhs");
629
630 C->boomlijst = (COMPTREE *)Malloc1((C->MaxTreeSize+1)*sizeof(COMPTREE),"IniFbuffer-tree");
631 root = C->boomlijst;
632 C->numtree = 0;
633 C->rootnum = 0;
634 root->left = -1;
635 root->right = -1;
636 root->parent = -1;
637 root->blnce = 0;
638 root->value = -1;
639 root->usage = 0;
640 for ( i = 1; i < C->MaxTreeSize; i++ ) { C->boomlijst[i] = comptreezero; }
641
642 fullsize = (C->maxrhs+1) * (sizeof(WORD *) + 2*sizeof(LONG) + 2*sizeof(WORD));
643 C->rhs = (WORD **)Malloc1(fullsize,"IniFbuffer-rhs");
644 C->CanCommu = (LONG *)(C->rhs+C->maxrhs);
645 C->NumTerms = (LONG *)(C->rhs+2*C->maxrhs);
646 C->numdum = (WORD *)(C->NumTerms+C->maxrhs);
647 C->dimension = (WORD *)(C->numdum+C->maxrhs);
648
649 return(0);
650}
651
652/*
653 #] IniFbuffer :
654 #[ numcommute :
655
656 Returns the number of non-commuting terms in the expression
657*/
658
659LONG numcommute(WORD *terms, LONG *numterms)
660{
661 LONG num = 0;
662 WORD *t, *m;
663 *numterms = 0;
664 while ( *terms ) {
665 *numterms += 1;
666 t = terms + 1;
667 GETSTOP(terms,m);
668 while ( t < m ) {
669 if ( *t >= FUNCTION ) {
670 if ( functions[*t-FUNCTION].commute ) { num++; break; }
671 }
672 t += t[1];
673 }
674 terms = terms + *terms;
675 }
676 return(num);
677}
678
679/*
680 #] numcommute :
681*/
int AddNtoL(int n, WORD *array)
Definition comtool.c:288
WORD * AddRHS(int num, int type)
Definition comtool.c:214
void finishcbuf(WORD num)
Definition comtool.c:89
WORD * DoubleCbuffer(int num, WORD *w, int par)
Definition comtool.c:143
int IniFbuffer(WORD bufnum)
Definition comtool.c:614
int AddNtoC(int bufnum, int n, WORD *array, int par)
Definition comtool.c:317
void clearcbuf(WORD num)
Definition comtool.c:116
int inicbufs(VOID)
Definition comtool.c:47
WORD * AddLHS(int num)
Definition comtool.c:188
LONG BufferSize
Definition structs.h:949
WORD * numdum
Definition structs.h:946
LONG * NumTerms
Definition structs.h:945
WORD * Top
Definition structs.h:940
COMPTREE * boomlijst
Definition structs.h:948
WORD * dimension
Definition structs.h:947
WORD ** rhs
Definition structs.h:943
WORD ** lhs
Definition structs.h:942
WORD * Buffer
Definition structs.h:939
WORD * Pointer
Definition structs.h:941
LONG * CanCommu
Definition structs.h:944
WORD * buffers
Definition structs.h:364
WORD buffersfill
Definition structs.h:379
WORD bufferssize
Definition structs.h:378
WORD bufnum
Definition structs.h:377
int blnce
Definition structs.h:298
int right
Definition structs.h:296
int parent
Definition structs.h:294
int value
Definition structs.h:297
int left
Definition structs.h:295
int usage
Definition structs.h:299