source: git/MP/mp-pvm3/node.c @ 678cfd

spielwiese
Last change on this file since 678cfd was 678cfd, checked in by Olaf Bachmann <obachman@…>, 27 years ago
This commit was generated by cvs2svn to compensate for changes in r337, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@338 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 24.3 KB
Line 
1/*
2   node.c -  Code to support building a linked version of an MP tree
3             in the server.  Label and Reference annotations are
4             supported, but the Label must occur before the Reference.
5
6   CHANGE LOG:
7   May 21, 1995 - SG fixed m_get_node() to properly handle dummy
8                  nodes when a reference annotation is found.
9                  Also discovered that free_tree() will croak
10                  trying to access a shared substructure that
11                  was previously freed.
12   May 27, 1995 - SG added routines to copy a node and its descendants,
13                  including annotations.  This solves, for the time being,
14                  the problem of freeing memory for shared substructures.
15                  Whenever a reference annotation is found, we copy the
16                  shared substructure.  The alternative is to do our own
17                  memory management, maintaining a reference count for each
18                  node, and allow multiple pointers to the same node.
19*/
20#include "MP.h"
21#include "gmp.h"
22#include "node.h"
23#include "label.h"
24
25/*
26   We maintain a table a labels and a pointer to the root of the
27   subtree to which the label refers.  This TABLE is freed after
28   processing each tree to ensure that we don't get labels
29   confused across trees.  The TABLE is a linear linked list of
30   label entries.  In the future we might want to make it a
31   hashed table(?).
32*/
33static label_entry_t  *TABLE = NULL;
34
35void process_label();
36label_entry_t  * find_label();
37static void make_entry();
38node_t *copy_node();
39
40IMP_ApIntCopy(dest, src)
41MP_INT *dest;
42MP_INT *src;
43{
44  int size;
45 
46  dest->_mp_alloc = src->_mp_alloc;
47  dest->_mp_size  = src->_mp_size;
48  size = (src->_mp_size < 0) ? -1 * src->_mp_size : src->_mp_size;
49  dest->_mp_d     = (unsigned long *)malloc(sizeof(long) * size);
50  bcopy((char *)src->_mp_d, (char *)dest->_mp_d, sizeof(long) * size);
51}
52
53IMP_ApRealCopy(dest, src)
54mpf_t dest;
55mpf_t src;
56{
57  int size;
58
59  dest->_mp_prec = src->_mp_prec;
60  dest->_mp_size = src->_mp_size;
61  dest->_mp_exp  = src->_mp_exp;
62  size = (src->_mp_size < 0) ? -1 * src->_mp_size : src->_mp_size;
63  dest->_mp_d     = (unsigned long *)malloc(sizeof(long) * size);
64  bcopy((char *)src->_mp_d, (char *)dest->_mp_d, sizeof(long) * size);
65}
66
67annot_t *copy_annotation(original)
68annot_t *original;
69{
70  annot_t *cpy = (annot_t *) malloc(sizeof(annot_t));
71 
72  cpy->type  = original->type;
73  cpy->dtag  = original->dtag;
74  cpy->flags = original->flags;
75  cpy->node = NULL;
76  cpy->next = NULL;
77  if (original->node != NULL)
78    cpy->node = copy_node(original->node);
79  if (original->next != NULL)
80    cpy->next = copy_annotation(original->next);
81
82  return cpy;
83}
84
85
86node_t* copy_node(original)
87node_t *original;
88{
89  node_t **ochild, **child, *cpy = (node_t *) malloc(sizeof(node_t));
90  int    i, datasize;
91 
92  cpy->annot_list   = NULL;
93  cpy->child_list   = NULL;
94  cpy->num_children = original->num_children;
95  cpy->num_annots   = original->num_annots;
96  cpy->type         = original->type;
97  cpy->dtag         = original->dtag;
98 
99  switch (cpy->type) {
100  case MP_Sint8Type:
101  case MP_Uint8Type:
102  case MP_BooleanType:             datasize = 1; break;     
103  case MP_Sint32Type:
104  case MP_Uint32Type:
105  case MP_Real32Type:              datasize = 4; break;
106  case MP_Real64Type:              datasize = 8; break;
107  case MP_IdentifierType:
108  case MP_ConstantType:
109  case MP_StringType:
110  case MP_MetaType:
111  case MP_OperatorType:            datasize = strlen(original->data) + 1; 
112                                   break;
113  case MP_RawType:                 datasize = original->num_children; break;
114  case MP_CommonConstantType:
115  case MP_CommonOperatorType:
116  case MP_CommonLatinIdentifierType:
117  case MP_CommonGreekIdentifierType: datasize = 1; break;
118  case MP_ApIntType:                 datasize = sizeof(MP_INT); break;
119  case MP_ApRealType:                datasize = sizeof(__mpf_struct);
120  default:
121    fprintf(stderr,"copy_node: unknown type %d\n", cpy->type);
122    free(cpy);
123    return NULL;
124  }
125  cpy->data = (char *) malloc(datasize);
126  if (cpy->type == MP_ApIntType) {
127    mpz_init((MP_INT *)cpy->data);
128    IMP_ApIntCopy(cpy->data, original->data);
129    } 
130  else if (cpy->type == MP_ApRealType) {
131    mpf_init((__mpf_struct *)cpy->data);
132    IMP_ApRealCopy(cpy->data, original->data);
133  }
134  else bcopy(original->data, cpy->data, datasize);
135
136  if ((original->num_children > 0) && (original->type != MP_RawType)) {
137    cpy->child_list = (node_t **)malloc(cpy->num_children * sizeof(node_t *));
138    for (i = 0, child = cpy->child_list, ochild = original->child_list;
139         i < cpy->num_children; i++, child++, ochild++) {
140       *child = copy_node(*ochild);
141       }
142    }
143
144  if (original->annot_list != NULL) 
145     cpy->annot_list = copy_annotation(original->annot_list);
146
147  return cpy;
148}
149 
150     
151 
152/******************************************************************
153 *   FUNCTION: m_get_annot
154 *   ARGUMENT: link - pointer to a stream structure
155 *   RETURN:   pointer to an annotation structure
156 *   PURPOSE:  Retrieve a single annotation from the data stream
157 *           associated with link.  If the annotation is valuated,
158 *           fetch the MP tree associated with the annotation.
159 ******************************************************************/
160annot_t *
161m_get_annot(link)
162MP_Link_t  *link;
163{
164       char  *s = NULL;
165       annot_t  *anp = (annot_t *)malloc(sizeof(annot_t));
166       node_t   *dnp;
167
168       anp->type =  anp->flags = 0;
169       anp->node = NULL;
170       anp->next = NULL;
171
172       MP_GetAnnotationPacket(link, &(anp->dtag), &(anp->type), &(anp->flags));
173       if (anp->flags & MP_AnnotValuated) 
174         anp->node = m_get_node(link);
175               
176       return anp;
177}
178
179/******************************************************************
180 *   FUNCTION: m_get_node
181 *   ARGUMENT: link - pointer to a stream structure
182 *   RETURN:   pointer to a node structure
183 *   PURPOSE:  Retrieve a node from the data stream associated with
184 *             link.  If the node has annotations, fetch them. 
185 *             Then if the node has children, fetch them too.
186 *             
187 *             This routine handles Label and Reference annotations.
188 *             Label annotations are placed in the label TABLE along
189 *             with a pointer to the labelled node.  Finding a
190 *             Reference annotation causes a lookup in the label
191 *             TABLE.  An error message is printed to stderr if
192 *             the Referenced label is not found in the TABLE and
193 *             the Referencing node is left unchanged.  If the label
194 *             is found, the Referencing node is freed and a pointer
195 *             to the labelled node is returned in its place. 
196 *             Further annotations of the Referencing node are read,
197 *             but ignored.  It is assumed that the Referencing node
198 *             has no children.  No check is made for this!
199 ******************************************************************/
200node_t *
201m_get_node(link)
202MP_Link_t *link;
203{
204  MP_NodeType_t    node_type  = 0;
205  MP_AnnotType_t   annot_type = 0;
206  MP_NumAnnot_t    num_annots = 0;
207  MP_NumChild_t    num_child  = 0;
208  MP_NodeHeader_t  hdr        = 0;
209  MP_Common_t      cval       = 0;
210  MP_ApInt_t       apint;
211  MP_ApReal_t      apreal;
212  int  i, more = 1, referenced_node = 0;
213  node_t   *dnp = (node_t *)malloc(sizeof(node_t));
214  annot_t  *annotp;
215  node_t   **child, *ref_nodep = NULL;
216  label_entry_t *labelp = NULL;
217  char c, *cp;
218  unsigned char uc;
219  u_long ui;
220
221  dnp->type = 0;
222  dnp->data = NULL;
223  dnp->dtag = 0;
224  dnp->annot_list = NULL;
225  dnp->child_list = NULL;
226  dnp->num_children = dnp->num_annots = 0;
227
228  IMP_GetNodeHeader(link, &(dnp->type), &(dnp->dtag), &cval, 
229                    &(dnp->num_annots), &(dnp->num_children));
230  switch(dnp->type) {
231      case MP_Sint32Type: 
232            dnp->data = (char *)malloc(sizeof(MP_Sint32_t));
233            IMP_GetSint32(link, (long*) dnp->data); 
234            break;
235      case MP_Uint32Type: 
236            dnp->data = (char *)malloc(sizeof(MP_Uint32_t));
237            IMP_GetUint32(link, (unsigned long *)dnp->data);
238            break;
239      case MP_Sint8Type:
240            dnp->data = (char *)malloc(sizeof(MP_Sint8_t));
241            *(dnp->data) = (MP_Sint8_t) cval;
242            break;
243      case MP_Uint8Type:
244            dnp->data = (char *)malloc(sizeof(MP_Uint8_t));
245            *(dnp->data) = (MP_Uint8_t) cval;
246            /*  bcopy (&ui, dnp->data, 4);*/
247            break;
248      case MP_BooleanType:
249            dnp->data = (char *)malloc(sizeof(MP_Boolean_t));
250            *(dnp->data) = (MP_Boolean_t) cval;
251            /* bcopy (&ui, dnp->data, 4);*/
252            break;
253      case MP_Real32Type: 
254            dnp->data = (char *)malloc(sizeof(float));
255            IMP_GetReal32(link, (float *)dnp->data);
256            break;
257      case MP_Real64Type: 
258            dnp->data = (char *)malloc(sizeof(double));
259            IMP_GetReal64(link, (double *)dnp->data);
260            break;
261      case MP_IdentifierType: 
262            IMP_GetIdentifier(link, &(dnp->data));
263            break;
264      case MP_CommonLatinIdentifierType: 
265      case MP_CommonGreekIdentifierType: 
266      case MP_CommonConstantType:
267      case MP_CommonOperatorType:       
268            dnp->data = (char *)malloc(1);
269            *(dnp->data) = cval; 
270            break;
271      case MP_ConstantType: 
272            IMP_GetString(link, &(dnp->data));
273            break;
274      case MP_StringType: 
275            IMP_GetString(link, &(dnp->data));
276            break;
277      case MP_MetaType: 
278            IMP_GetMetaType(link, &(dnp->data));
279            break;
280      case MP_RawType: 
281            IMP_GetRaw(link, &(dnp->data), &(dnp->num_children));
282            break;
283      case MP_ApIntType: 
284            dnp->data = (char *)malloc(sizeof(__mpz_struct));
285            mpz_init((mpz_ptr)dnp->data);
286            IMP_GetApInt(link, (MP_ApInt_t)&(dnp->data));
287            break;
288      case MP_ApRealType: 
289            dnp->data = (char *)malloc(sizeof(__mpf_struct));
290            mpf_init((mpf_ptr)dnp->data); 
291            IMP_GetApReal(link, (MP_ApReal_t)&(dnp->data));
292            break;
293      case MP_OperatorType: 
294            IMP_GetOperator(link, &(dnp->data));
295            break;
296      default : fprintf(stderr, "server - m_get_node: unknown type %d\n", node_type);
297                exit(1);
298      }
299
300      /* first we get the annotations, if there are any */
301      if (dnp->num_annots > 0)  {
302         annotp = dnp->annot_list = m_get_annot(link);
303         /* look for Label and Reference annotations */
304         if (annotp->type == MP_AnnotMpLabel) 
305            process_label(annotp->node->data, dnp);
306         else if (annotp->type == MP_AnnotMpRef) {
307           if ((labelp = find_label(annotp->node->data)) != NULL) {
308             referenced_node = MP_TRUE;
309             ref_nodep= labelp->lnode;
310             }
311           else 
312              fprintf(stderr, "unknown label reference: %s\n",
313                  annotp->node->data);
314           } 
315         for (i = 0; i < dnp->num_annots - 1; i++) {
316           annotp->next = m_get_annot(link);
317           annotp = annotp->next;
318           if (annotp->type == MP_AnnotMpLabel) 
319             process_label(annotp->node->data, dnp);
320           else if (annotp->type == MP_AnnotMpRef) {
321             if ((labelp = find_label(annotp->node->data)) != NULL) {
322                referenced_node = MP_TRUE;
323                ref_nodep = labelp->lnode;
324                }
325             else 
326                fprintf(stderr, "unknown reference: %s\n",
327                  annotp->node->data);
328           }
329          } 
330         }
331
332      /* For now assume that a node with a referenced label is   */
333      /* a dummy node and that the child field is 0.  We _don't_ */
334      /* check this.  Return a pointer to the _labelled_ node.   */
335      /* Also, we are abandoning all remaining annotations.      */
336      /* What does the specification have to say about this?     */
337
338      if (referenced_node == MP_TRUE) {
339        free(dnp->data); free(dnp);
340        return ref_nodep;
341        }
342
343      /* now get the children : do special check for raw type since */
344      /* we have a double use of the num_children field.            */
345      if ((dnp->num_children > 0) && (dnp->type != MP_RawType)) {
346        dnp->child_list = (node_t **)malloc(dnp->num_children * sizeof(node_t *));
347        for (i = 0,child = dnp->child_list; i < dnp->num_children; i++,child++)
348           *child = m_get_node(link);
349        }
350      return dnp;
351}
352
353
354/******************************************************************
355 *   FUNCTION: print_node
356 *   ARGUMENT: dnp - a pointer to the root of a subtree.
357 *             fd  - file descriptor where we will print the tree.
358 *   RETURN:   int indicating if there are more trees to retrieve.
359 *             This is indicated by the absence of the MP_QUIT node.
360 *             1 = there are more trees to retrieve.
361 *             0 = this is the MP_QUIT node, we are done.
362 *   PURPOSE:  Print a node in the data stream.  This includes any
363 *             annotations the node may have as well as its
364 *             children.  The data is sent to standard out and to
365 *             the file associated with file descriptor fd.
366 ******************************************************************/
367int
368print_node(dnp, fd)
369node_t  *dnp;
370FILE    *fd;
371{
372  char   *str = NULL, c;
373  node_t **p;
374  MP_INT apint;
375  short flags;
376  int  i, j, more = 1;
377  MP_Uint8_t t;
378
379  switch(dnp->type){
380      case MP_Sint32Type: 
381            printf("%-20s       %-30d %d\n", "MP_Sint32" , 
382                (long) *((long *)dnp->data), dnp->num_annots);
383            fprintf(fd,"MP_Sint32Type %d %d\n", 
384                (long) *((long *)dnp->data), dnp->num_annots);
385            break;
386      case MP_Uint32Type: 
387            printf("%-20s       %-30u %d\n", "MP_Uint32", 
388                (long) *((long *)dnp->data), dnp->num_annots);
389            fprintf(fd, "MP_Uint32Type %d %u\n", 
390                (long) *((long *)dnp->data), dnp->num_annots);
391            break;
392      case MP_Sint8Type:
393            printf("%-20s       %-30d %d\n", "MP_Sint8", 
394                 *(dnp->data), dnp->num_annots);
395            fprintf(fd,"MP_Sint8Type %d %u\n", *(dnp->data) ,dnp->num_annots);
396            break;
397      case MP_Uint8Type:
398            t = (MP_Uint8_t)*((MP_Uint8_t *)dnp->data);
399            printf("%-20s       %-30d %d\n", "MP_Uint8", t, dnp->num_annots);
400            fprintf(fd,"MP_Uint8Type %u %u\n", t, dnp->num_annots);
401            break;
402      case MP_BooleanType:
403            c = (*((MP_Boolean_t *)dnp->data) == 1) ? 'T' : 'F';
404            printf("%-20s       %-30c %d\n", "MP_Boolean", c, dnp->num_annots);
405            fprintf(fd,"MP_BooleanType %c %d\n", c, dnp->num_annots);
406            break;
407       case MP_Real32Type: 
408            printf("%-20s       %-30.10G %d\n", "MP_Real32", 
409                   (float) *((float *)dnp->data), dnp->num_annots);
410            fprintf(fd, "MP_Real32Type %d %20.10G\n", 
411                   (float) *((float *)dnp->data), dnp->num_annots);
412            break;
413      case MP_Real64Type: 
414            printf("%-20s       %-30.15lG %d\n", "MP_Real64", 
415                   (double) *((double *)dnp->data), dnp->num_annots);
416            fprintf(fd, "MP_Real64Type %d %20.15lG\n",
417                   (double) *((double *)dnp->data), dnp->num_annots);
418            break;
419      case MP_CommonLatinIdentifierType: 
420            printf("%-20s %-5d %-30c %-7d\n", "MP_LatinIdentifier",
421                   dnp->dtag, *(dnp->data), dnp->num_annots);
422            fprintf(fd, "MP_CommonLatinIdentifierType %d %c %d\n", 
423                   dnp->dtag, *(dnp->data), dnp->num_annots);
424            break;
425      case MP_CommonGreekIdentifierType: 
426            printf("%-20s %-5d %-30c %-7d\n", "MP_GreekIdentifier",
427                   dnp->dtag, *(dnp->data), dnp->num_annots);
428            fprintf(fd, "MP_CommonGreekIdentifierType %d %c %d\n", 
429                   dnp->dtag, *(dnp->data), dnp->num_annots);
430            break;
431      case MP_IdentifierType: 
432            printf("%-20s %-5d %-30s %-7d\n", "MP_Identifier",
433                    dnp->dtag, dnp->data, dnp->num_annots);
434            fprintf(fd, "MP_IdentifierType %d %s %d\n", 
435                    dnp->dtag, dnp->data, dnp->num_annots);
436            break;
437      case MP_ConstantType: 
438            printf("%-20s %-5d %-30s %-7d\n", "MP_Constant", 
439                    dnp->dtag, dnp->data, dnp->num_annots);
440            fprintf(fd, "MP_ConstantType %d %s %d\n",
441                    dnp->dtag, dnp->data, dnp->num_annots);
442            break;
443      case MP_CommonConstantType: 
444            printf("%-20s %-5d %-30d %-7d\n", "MP_CommonCnst", 
445                   dnp->dtag, *((MP_Common_t *)dnp->data), dnp->num_annots);
446            fprintf(fd, "MP_CommonConstantType %d %d %d\n", 
447                   dnp->dtag, *((MP_Common_t *)dnp->data), dnp->num_annots);
448            break;
449      case MP_StringType: 
450            printf("%-20s       %-20s %d\n", "MP_String", 
451                   dnp->data, dnp->num_annots);
452            fprintf(fd, "MP_StringType %s %d\n", 
453                   dnp->data, dnp->num_annots); 
454            break;
455      case MP_MetaType: 
456            printf("%-20s %-5d %-30s %-7d\n", "MP_Meta", 
457                    dnp->dtag, dnp->data, dnp->num_annots); 
458            fprintf(fd, "MP_MetaType %d %s %d\n", 
459                   dnp->dtag, dnp->data, dnp->num_annots); 
460            break;
461      case MP_RawType: 
462            str = malloc(dnp->num_children + 1);
463            memcpy(str, dnp->data, dnp->num_children);
464            str[dnp->num_children] = '\0';   /* make the output nice */
465            printf("%-20s       %-30s %d\n", "MP_Raw", str, dnp->num_annots);
466            fprintf(fd, "MP_RawType %s %d\n", str, dnp->num_annots);
467            free(str); 
468            break;
469      case MP_ApIntType: 
470            printf("%-20s       ", "MP_ApInt");
471            fprintf(fd, "MP_ApIntType ");
472            printf(" %d\n",  dnp->num_annots);
473            fprintf(fd, " %d\n", dnp->num_annots);
474            mpz_out_str(stdout,10, (mpz_ptr) dnp->data);
475            mpz_out_str(fd, 10, (mpz_ptr) dnp->data); 
476            printf(" %d\n",  dnp->num_annots);
477            fprintf(fd, " %d\n", dnp->num_annots);
478            fflush(stdout);fflush(fd);
479            break;
480      case MP_ApRealType: 
481            printf("%-20s       ", "MP_ApReal");
482            fprintf(fd, "MP_ApRealType "); 
483            mpf_out_str(stdout, 10, 0, (mpf_ptr) dnp->data);
484            mpf_out_str(fd, 10, 0, (mpf_ptr) dnp->data); 
485            printf(" %d\n",dnp->num_annots);
486            fprintf(fd, " %d\n", dnp->num_annots);
487            fflush(stdout);fflush(fd);
488            break;
489      case MP_OperatorType: 
490            printf("%-20s %-5d %-30s %-7d %-9d\n", "MP_Op", 
491               dnp->dtag, dnp->data, dnp->num_annots, dnp->num_children);
492            fprintf(fd, "MP_OperatorType %d %s %d %d\n",
493               dnp->dtag, dnp->data, dnp->num_annots, dnp->num_children);
494            break;
495      case MP_CommonOperatorType: 
496            printf(" %-20s %-5d %-30d %-7d% -5d\n", "MP_CommonOp", 
497                   dnp->dtag, *((MP_Common_t *)dnp->data), dnp->num_annots, 
498                   dnp->num_children);
499            fprintf(fd, "MP_CommonOperatorType %d %d %d %d\n",
500                   dnp->dtag, *((MP_Common_t *)dnp->data), dnp->num_annots, 
501                   dnp->num_children);
502            if (!(more = !(dnp->dtag == MP_MpDict && 
503                           *((MP_Common_t *)dnp->data) == MP_CopMpEndSession)))
504                return 0;
505            break;
506      default : fprintf(stderr, "server: unknown type %d\n", dnp->type);
507      }
508  if (dnp->annot_list != NULL) print_annot(dnp->annot_list, fd);
509 
510  if ((dnp->num_children > 0) && (dnp->type != MP_RawType)) {
511    p = dnp->child_list;
512    for (i = 0; i < dnp->num_children; i++, p++){
513      print_node(*p, fd);
514      }
515    }
516  return more;
517}
518
519
520/******************************************************************
521 *   FUNCTION: print_annot
522 *   ARGUMENT: anp - a pointer to an annotation structure.
523 *             fd  - file descriptor where we will print the tree.
524 *   RETURN:   none.
525 *   PURPOSE:  Print an annotation node to standard output and to
526 *             the file associated with file descriptor fd.  This
527 *             includes any arguments the annotation has (if it
528 *             is valuated).  The next annotation in the list, if
529 *             it exists, is recursively printed.
530 ******************************************************************/
531void
532print_annot(anp, fd)
533annot_t  *anp;
534FILE *fd;
535{  char *annotstr = NULL;
536
537    annotstr = (char *) annot_to_str(anp->dtag, anp->type);
538    printf("%-20s %-5d flags: 0x%X\n", annotstr, anp->dtag,
539          anp->flags);
540   fprintf(fd,"%s  %d  %X\n", annotstr, anp->dtag, anp->flags);
541   if (anp->node != NULL) 
542     print_node(anp->node, fd);
543   if (anp->next != NULL)  print_annot(anp->next, fd);
544}
545
546
547/******************************************************************
548 *   FUNCTION: find_label
549 *   ARGUMENT: label - a char string containing the label.
550 *   RETURN:   Success - a pointer to the entry in the label TABLE
551 *                       containing label.
552 *             Failure - NULL.
553 *   PURPOSE:  Look for label among the collection of label entries
554 *             maintained by TABLE.  This TABLE is cleaned out (freed)
555 *             after each tree is processed.
556 ******************************************************************/
557label_entry_t  *
558find_label(label)
559char *label;
560{
561  label_entry_t *cp, *p = TABLE;
562 
563  while (p != NULL) {
564     if (strcmp(p->label, label) == 0)  break;
565     p = p->next;
566     }
567  if (p != NULL) {
568   cp = (label_entry_t *) malloc(sizeof(label_entry_t));
569   cp->lnode = copy_node(p->lnode);
570   return cp;
571  }                                       
572  else return p; 
573}
574
575
576node_t *
577process_ref(label, node)
578char  *label;
579node_t **node;
580{
581   ref_node_t *r;
582   label_entry_t *p;
583
584   if ((p = find_label(label)) == NULL) {
585      /* p = make_entry(label, *node); */
586      r = (ref_node_t *)malloc (sizeof(ref_node_t));
587      r->next = p->ref_list;
588      p->ref_list = r;
589      }
590    return (p->lnode);
591}
592
593
594
595/******************************************************************
596 *   FUNCTION: process_label
597 *   ARGUMENT: label - a char string containing the label.
598 *             node  - a pointer to the node structure associated
599 *                     with this label.
600 *   RETURN:   None.
601 *   PURPOSE:  Determine if the label is already in the label TABLE.
602 *             If yes, print an error announcing the duplicate and
603 *                return (don't do anything else).
604 *             If no, place the label in the TABLE and associated
605 *                node with it.
606 *
607 *   COMMENT:  Consider having the routine return an error value
608 *             to identify duplicate labels so the caller can
609 *             decide what should be done.
610 ******************************************************************/
611void 
612process_label(label, node)
613char    *label;
614node_t  *node;
615{
616  label_entry_t  *p;
617
618  if ((p = find_label(label)) != NULL)  /* check for a duplicate */
619    fprintf(stderr,"duplicate label found: %s\n", label);
620  else    /* not a duplicate, so put it in the table */
621    make_entry(label, node);
622   
623}
624
625
626/******************************************************************
627 *   FUNCTION: make_entry
628 *   ARGUMENT: label - a char string containing the label.
629 *             node  - a pointer to the node structure associated
630 *                     with this label.
631 *   RETURN:   None.
632 *   PURPOSE:  Make an entry in TABLE for the (label, node) pair.
633 *             It is assumed at this point that label is not
634 *             already in the TABLE.
635 ******************************************************************/
636static void 
637make_entry (label, node)
638char *label;
639node_t *node;
640{
641  label_entry_t  *p = (label_entry_t *)malloc(sizeof(label_entry_t));
642
643  p->label = (char *)malloc(strlen(label) + 1);
644  strcpy(p->label, label);
645  p->ref_list = NULL;
646  p->lnode = node;
647  p->next = TABLE;
648  TABLE = p;
649}
650
651
652/******************************************************************
653 *   FUNCTION: free_annotation
654 *   ARGUMENT: annotp - a pointer to an annotation structure.
655 *   RETURN:   None.
656 *   PURPOSE:  Free the memory allocated to the annotation structure.
657 *             If the annotation is valuated, free its argument first.
658 ******************************************************************/
659static void
660free_annotation(annotp)
661annot_t *annotp;
662{
663  if (annotp->node != NULL) free_tree(annotp->node);
664  free(annotp);
665}
666
667
668/******************************************************************
669 *   FUNCTION: free_tree
670 *   ARGUMENT: dnp - a pointer to a node structure.
671 *   RETURN:   None.
672 *   PURPOSE:  Free up the memory of the nodes and annotations
673 *             rooted at the subtree pointed to by dnp.
674 ******************************************************************/
675void
676free_tree(dnp)
677node_t *dnp;
678{
679  annot_t *annotp, *next_annotp;
680  node_t **childp;
681  int  i;
682
683  /* first we free the annotations */
684  for (i = 0, annotp = dnp->annot_list; i < dnp->num_annots; i++) {
685    next_annotp = annotp->next;
686    free_annotation(annotp);
687    annotp = next_annotp;
688    }
689
690  /* free the children, if there are any */
691  if ((dnp->num_children > 0) && (dnp->type != MP_RawType)) 
692    for (i = 0, childp = dnp->child_list; i < dnp->num_children; i++, childp++) 
693      free_tree(*childp);
694     
695  if (dnp->type == MP_ApIntType) mpz_clear((MP_INT *)dnp->data);
696  else free(dnp->data);
697
698  /* now free the pointers to the children and the node itself */
699  free(dnp->child_list);
700  free(dnp);
701
702}
703
704/******************************************************************
705 *   FUNCTION: free_label_table
706 *   ARGUMENT: None.  TABLE is accessed globally.
707 *   RETURN:   None.
708 *   PURPOSE:  Free up the memory of the label entries pointed
709 *             to by TABLE.  Set TABLE to NULL on exit.
710 ******************************************************************/
711void
712free_label_table()
713{
714  label_entry_t *lp = TABLE, *nlp;
715
716  while (lp != NULL) {
717    nlp = lp->next;
718    free(lp->label);
719    free(lp);
720    lp = nlp;
721    }
722  TABLE = NULL;
723}
724   
725/*
726static void
727fix_refs(node, ref_list)
728node_t          *node;
729ref_node_t      **ref_list;
730{
731    ref_node_t  *p = *ref_list;
732
733   while (p != NULL) {
734       *(p->node) = node;
735       p = p->next;
736       free(*ref_list);
737       *ref_list = p;
738   }
739}
740*/
Note: See TracBrowser for help on using the repository browser.