source: git/MP/examples/node.c @ f78374

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