source: git/MP/MPT/MPT_Tree.cc @ c794a9

spielwiese
Last change on this file since c794a9 was c794a9, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: code cleanup git-svn-id: file:///usr/local/Singular/svn/trunk@5571 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.0 KB
Line 
1/******************************************************************
2 *
3 * File:    MPT_Tree.c
4 * Purpose: Copying/Deleting MPT Trees
5 * Author:  Olaf Bachman (obachman@mathematik.uni-kl.de)
6 * Created: 12/96
7 *
8 * Change History (most recent first):
9 *     
10 ******************************************************************/
11#include "MPT.h"
12#include <string.h>
13
14#ifndef __64_BIT__
15#define MPT_Delete64BitType(arg) IMP_MemFreeFnc(arg, sizeof(MP_Real64_t))
16static void  MPT_Cpy64BitType(MPT_Arg_t *odest, MPT_Arg_t src)
17{
18  MP_Real64_t *r64_pt = (MP_Real64_t *) IMP_MemAllocFnc(sizeof(MP_Real64_t));
19  *r64_pt = MP_REAL64_T(src);
20  *odest = r64_pt;
21}
22#else
23#define MPT_Delete64BitType(arg) ((void *) 0)
24#define MPT_Cpy64BitType(dest, src) *(dest) = src
25#endif
26
27/*******************************************************************
28 *
29 * Deleting a tree
30 *
31 *******************************************************************/
32
33void MPT_DeleteTree(MPT_Tree_pt tree)
34{
35  if (tree != NULL)
36  {
37    MPT_Assume(tree->node != NULL);
38
39    /* Delete the args, if there are any */
40    if (tree->node->type == MP_CommonOperatorType ||
41        tree->node->type == MP_OperatorType)
42      MPT_DeleteArgs(tree->args, tree->node->numchild,
43                     MPT_ProtoAnnotValue(tree->node));
44    /* Check for external data */
45    else if (tree->node->type == MPT_ExternalDataType)
46      MPT_DeleteExternalData(tree->args);
47    /* else, it is a node which has no arguments */
48
49    MPT_DeleteNode(tree->node);
50
51    IMP_MemFreeFnc(tree, sizeof(MPT_Tree_t));
52  }
53}
54 
55
56void MPT_DeleteNode(MPT_Node_pt node)
57{
58  MP_NumAnnot_t numannot = node->numannot;
59  MP_NodeType_t type = node->type;
60  /* take care of annots, if there are any */
61  if (numannot > 0)
62  {
63    MP_Uint32_t i;
64    MPT_Annot_pt *annots = node->annots, annot;
65
66    MPT_Assume(annots != NULL);
67   
68    for (i=0; i<numannot; i++)
69    {
70      annot = annots[i];
71      MPT_Assume(annot != NULL);
72      if (MP_IsAnnotValuated(annot->flags))
73        MPT_DeleteTree(annot->value);
74      IMP_MemFreeFnc(annot, sizeof(MPT_Annot_t));
75    }
76
77    IMP_MemFreeFnc(node->annots, numannot*sizeof(MPT_Annot_pt));
78  }
79
80  /* delet nvalue, if necessary */
81  if (node->nvalue != NULL)
82  {
83    if (MP_IsStringBasedType(type) ||
84        type == MP_OperatorType ||
85        type == MP_MetaOperatorType)
86      IMP_RawMemFreeFnc(node->nvalue);
87    else if (type == MP_ApIntType)
88      MPT_DeleteApInt(node->nvalue);
89    else if (type == MP_ApRealType)
90      MPT_DeleteApReal(node->nvalue);
91    else if (MP_Is64BitNumericType(type))
92      MPT_Delete64BitType(node->nvalue);
93  }
94 
95  IMP_MemFreeFnc(node, sizeof(MPT_Node_t));
96}
97
98void MPT_DeleteArgs(MPT_Arg_pt args, MP_NumChild_t nc,
99                    MPT_Tree_pt typespec)
100{
101  MP_NumChild_t i;
102  MP_Uint32_t size = 0;
103 
104  /* return, if args == NULL, i.e. node is a leave node of a tree */
105  if (args == NULL || nc == 0) return;
106
107  /* Check for non-prototyped  data */
108  if (typespec == NULL)
109  {
110    for (i=0; i<nc; i++)
111      MPT_DeleteTree(MPT_TREE_PT(args[i]));
112    size = nc*sizeof(MPT_Arg_t);
113  }
114  else
115  {
116    /* Now we are in the realm of prototyped data */
117    MPT_Node_pt pnode = typespec->node;
118    MP_NodeType_t ptype = pnode->type;
119    MP_DictTag_t  pdict = pnode->dict;
120
121    /* Check only for arrays of basic numeric types */
122    if (ptype == MP_CommonMetaType && pdict == MP_ProtoDict)
123    {
124      MP_Common_t metatype = MP_COMMON_T(pnode->nvalue);
125     
126      if (IMP_Is8BitNumericMetaType(metatype))
127        size = nc*sizeof(MP_Uint8_t);
128      else if (IMP_Is32BitNumericMetaType(metatype))
129        size = nc*sizeof(MP_Uint32_t);
130      else if (IMP_Is64BitNumericMetaType(metatype))
131        size = nc*sizeof(MP_Real64_t);
132    }
133
134    /* Everything else is handled item by item */
135    if (size == 0)
136    {
137      for (i=0;i<nc; i++)
138        MPT_DeleteTypespecedArg(args[i], typespec);
139      size = nc*sizeof(MPT_Arg_t);
140    }
141  }
142 
143  /* Delete Args */
144  IMP_MemFreeFnc(args, size);
145}
146
147
148void MPT_DeleteTypespecedArg(MPT_Arg_t arg, MPT_Tree_pt typespec)
149{
150  /* check for trivial cases */
151  if (arg == NULL) return;
152
153  if (typespec != NULL)
154  {
155    MPT_Node_pt typespec_node = typespec->node;
156    MPT_Arg_pt   typespec_args = typespec->args;
157    MP_DictTag_t  ndict = typespec_node->dict;
158    MP_NodeType_t ntype = typespec_node->type;
159    MP_NumChild_t nc =  typespec_node->numchild;
160    MP_Common_t   cvalue = MP_COMMON_T(typespec_node->nvalue);
161
162    /* check special Common Meta types from ProtoDict */
163    if (ndict == MP_ProtoDict && ntype == MP_CommonMetaType)
164    {
165      /* do nothing for types with sizeof <= sizeof(MPT_Arg_t) */
166      if (IMP_Is32BitNumericMetaType(cvalue) ||
167          IMP_Is8BitNumericMetaType(cvalue))
168        return;
169
170      if (cvalue == MP_CmtProtoIMP_ApInt)
171      {
172        MPT_DeleteApInt(arg);
173        return;
174      }
175      else if (cvalue == MP_CmtProtoIMP_ApReal)
176      {
177        MPT_DeleteApReal(arg);
178        return;
179      }
180      else if (IMP_Is64BitNumericMetaType(cvalue))
181      {
182        MPT_Delete64BitType(arg);
183        return;
184      }
185      else if (IMP_IsStringBasedMetaType(cvalue))
186      {
187        IMP_RawMemFreeFnc(arg);
188        return;
189      }
190      else if (cvalue == MP_CmtProtoRecStruct)
191      {
192        MPT_DeleteTypespecedArg(arg, MPT_RecStructTree);
193        return;
194      }
195      else if (cvalue == MP_CmtProtoRecUnion)
196      {
197        MPT_DeleteTypespecedArg(arg, MPT_RecUnionTree);
198        return;
199      }
200    }
201
202    /* special MP Operators */
203    if (ntype == MP_CommonOperatorType && ndict == MP_ProtoDict)
204    {
205      /* ProtoD:Union */
206      if (cvalue == MP_CopProtoUnion || cvalue == MP_CopProtoRecUnion)
207      {
208        MPT_Union_pt mun = MPT_UNION_PT(arg);
209        MPT_Assume(mun->tag <= nc);
210        if (mun->tag > 0)
211          MPT_DeleteTypespecedArg(mun->arg, 
212                                  MPT_TREE_PT(typespec_args[mun->tag -1]));
213        IMP_MemFreeFnc(mun, sizeof(MPT_Union_t));
214        return;
215      }
216
217      /* ProtoD:Struct */
218      if (cvalue == MP_CopProtoStruct || cvalue == MP_CopProtoRecStruct)
219      {
220        MP_NumChild_t i;
221        MPT_Arg_pt st_args = MPT_ARG_PT(arg);
222        for (i=0; i<nc; i++)
223          MPT_DeleteTypespecedArg(st_args[i], MPT_TREE_PT(typespec_args[i]));
224        IMP_MemFreeFnc(arg, nc*sizeof(MPT_Arg_t));
225        return;
226      }
227    }
228 
229    /* Meta Operators */
230    if (ntype == MP_CommonMetaOperatorType || ntype == MP_MetaOperatorType)
231    {
232      MPT_DynArgs_pt dynargs = NULL;
233      MPT_Arg_pt args;
234      typespec = MPT_ProtoAnnotValue(typespec_node);
235   
236      if (nc == 0)
237      {
238        dynargs = MPT_DYNARGS_PT(arg);
239        nc = dynargs->length;
240        args = dynargs->args;
241      }
242      else
243        args = MPT_ARG_PT(arg);
244
245      MPT_DeleteArgs(args, nc, typespec);
246      if (dynargs != NULL)
247        IMP_MemFreeFnc(dynargs, sizeof(MPT_DynArgs_t));
248      return;
249    }
250  }
251
252  /* Everything else is taken to be a tree */
253  MPT_DeleteTree(MPT_TREE_PT(arg));
254}
255
256/*******************************************************************
257 *
258 * Copying a tree
259 *
260 *******************************************************************/
261
262void MPT_CpyTree(MPT_Tree_pt *otree, MPT_Tree_pt src)
263{
264  if (src == NULL)
265    *otree = NULL;
266  else
267  {
268    MPT_Tree_pt dest = (MPT_Tree_pt) IMP_MemAllocFnc(sizeof(MPT_Tree_t));
269    MPT_Node_pt snode = src->node;
270    MP_NodeType_t stype = snode->type;
271
272    *otree = dest;
273    MPT_CpyNode(&(dest->node), src->node);
274   
275    /* Copy Args, if necessary */
276    if (stype == MP_CommonOperatorType || stype == MP_OperatorType)
277    {
278      MP_Common_t nvalue = MP_COMMON_T(snode->nvalue);
279      MP_DictTag_t  ndict = snode->dict;
280
281      /* we might have to push the current tree onto the stack of
282         recursive typespecs */
283      if (ndict == MP_ProtoDict)
284      {
285        if (nvalue == MP_CopProtoRecUnion)
286          MPT_PushRecUnion(dest);
287        else if (nvalue == MP_CopProtoRecStruct)
288          MPT_PushRecStruct(dest);
289      }
290
291      /* Copy Args */
292      MPT_CpyArgs(&(dest->args), src->args,
293                  snode->numchild, MPT_ProtoAnnotValue(snode)); 
294
295      /* And, pop the recursive typesepcs again */
296      if (ndict == MP_ProtoDict)
297      {
298        if (nvalue == MP_CopProtoRecUnion)
299          MPT_PopRecUnion();
300        else if (nvalue == MP_CopProtoRecStruct)
301          MPT_PopRecStruct();
302      }
303    }
304    /* No args */
305    else if (stype == MPT_ExternalDataType)
306      MPT_CpyExternalData(MPT_ARG_PT(&(dest->args)), src->args);
307    else
308      dest->args = NULL;
309  }
310}
311
312void MPT_CpyNode(MPT_Node_pt *onode, MPT_Node_pt node)
313{
314  MPT_Node_pt dest = (MPT_Node_pt) IMP_MemAllocFnc(sizeof(MPT_Node_t));
315  MP_NumAnnot_t numannot = node->numannot;
316  MP_NodeType_t type = node->type;
317
318  *onode = dest;
319  memcpy(dest, node, sizeof(MPT_Node_t));
320
321  /* take care of annots, if there are any */
322  if (numannot > 0)
323  {
324    MP_Uint32_t i;
325    MPT_Annot_pt annot, dannot,
326      *annots = node->annots, 
327      *dannots = (MPT_Annot_pt*)IMP_MemAllocFnc(numannot*sizeof(MPT_Annot_pt));
328    dest->annots = dannots;
329
330    for (i=0; i<numannot; i++)
331    {
332      annot = annots[i];
333      MPT_Assume(annot != NULL);
334
335      dannot = (MPT_Annot_pt) IMP_MemAllocFnc(sizeof(MPT_Annot_t));
336      dannots[i] = dannot;
337
338      memcpy(dannot, annot, sizeof(MPT_Annot_t));
339      if (MP_IsAnnotValuated(annot->flags))
340        MPT_CpyTree(&(dannot->value), annot->value);
341    }
342  }
343
344  /* cpy nvalue, if necessary */
345  if (MP_IsStringBasedType(type) ||
346      type == MP_OperatorType ||
347      type == MP_MetaOperatorType)
348  {
349    dest->nvalue
350      = IMP_RawMemAllocFnc(
351        (strlen(MP_STRING_T(node->nvalue))+1)*sizeof(char));
352    strcpy((char*) dest->nvalue, (char*) node->nvalue);
353  }
354  else if (type == MP_ApIntType)
355    MPT_InitCopyApInt(&(dest->nvalue), node->nvalue);
356  else if (type == MP_ApRealType)
357    MPT_InitCopyApReal(&(dest->nvalue), node->nvalue);
358  else if (type == MP_Real64Type)
359    MPT_Cpy64BitType(&(dest->nvalue), node->nvalue);
360}
361
362void MPT_CpyArgs(MPT_Arg_pt *oargs, MPT_Arg_pt args,
363                 MP_NumChild_t nc, MPT_Tree_pt typespec)
364{
365  /* return, if args == NULL, i.e. node is a leave node of a tree */
366  if (args == NULL || nc == 0)
367    *oargs = NULL;
368  else
369  {
370    MP_NumChild_t i;
371    MPT_Arg_pt dargs;
372
373    /* Check for non-prototyped  data */
374    if (typespec == NULL)
375    {
376      dargs = (MPT_Arg_pt) IMP_MemAllocFnc(nc*sizeof(MPT_Arg_t));
377      *oargs = dargs;
378   
379      for (i=0; i<nc; i++)
380        MPT_CpyTree((MPT_Tree_pt *) &(dargs[i]), MPT_TREE_PT(args[i]));
381    }
382    else
383    {
384      /* Now we are in the realm of prototyped data */
385      MPT_Node_pt pnode = typespec->node;
386      MP_NodeType_t ptype = pnode->type;
387      MP_DictTag_t  pdict = pnode->dict;
388      MP_Uint32_t size = 0;
389
390      /* Check only for arrays of basic numeric types */
391      if (ptype == MP_CommonMetaType && pdict == MP_ProtoDict)
392      {
393        MP_Common_t metatype = MP_COMMON_T(pnode->nvalue);
394     
395        if (IMP_Is8BitNumericMetaType(metatype))
396          size = nc*sizeof(MP_Uint8_t);
397        else if (IMP_Is32BitNumericMetaType(metatype))
398          size = nc*sizeof(MP_Uint32_t);
399        else if (IMP_Is64BitNumericMetaType(metatype))
400          size = nc*sizeof(MP_Real64_t);
401      }
402 
403      /* Everything else is handled item by item */
404      if (size == 0)
405      {
406        dargs = (MPT_Arg_pt) IMP_MemAllocFnc(nc*sizeof(MPT_Arg_t));
407        *oargs = dargs;
408   
409        for (i=0;i<nc; i++)
410          MPT_CpyTypespecedArg(&(dargs[i]), args[i], typespec);
411      }
412      else
413      {
414        dargs = (MPT_Arg_pt) IMP_MemAllocFnc(size);
415        *oargs = dargs;
416        memcpy(dargs, args, size);
417      }
418    }
419  }
420}
421
422 
423
424void MPT_CpyTypespecedArg(MPT_Arg_t *oarg,
425                          MPT_Arg_t arg, MPT_Tree_pt typespec)
426{
427  /* check for trivial cases */
428  if (arg == NULL)
429  {
430    *oarg = NULL;
431    return;
432  }
433
434  if (typespec != NULL)
435  {
436    /* Non-trivial cases of typespeced data */
437    MPT_Node_pt typespec_node = typespec->node;
438    MPT_Arg_pt   typespec_args = typespec->args;
439    MP_DictTag_t  ndict = typespec_node->dict;
440    MP_NodeType_t ntype = typespec_node->type;
441    MP_NumChild_t nc =  typespec_node->numchild;
442    MP_Common_t   cvalue = MP_COMMON_T(typespec_node->nvalue);
443
444    *oarg = arg;
445    /* check special Common Meta types from ProtoDict */
446    if (ndict == MP_ProtoDict && ntype == MP_CommonMetaType)
447    {
448      /* do nothing for types with sizeof <= sizeof(MPT_Arg_t) */
449      if (IMP_Is32BitNumericMetaType(cvalue) ||
450          IMP_Is8BitNumericMetaType(cvalue))
451        return;
452
453      if (cvalue == MP_CmtProtoIMP_ApInt)
454      {
455        MPT_InitCopyApInt(oarg, arg);
456        return;
457      }
458      else if (cvalue == MP_CmtProtoIMP_ApReal)
459      {
460        MPT_InitCopyApReal(oarg, arg);
461        return;
462      }
463      else if (IMP_Is64BitNumericMetaType(cvalue))
464      {
465        MPT_Cpy64BitType(oarg, arg);
466        return;
467      }
468      else if (IMP_IsStringBasedMetaType(cvalue))
469      {
470        *oarg = IMP_RawMemAllocFnc((strlen(MP_STRING_T(arg))+1)*sizeof(char));
471        strcpy(MP_STRING_T(*oarg), MP_STRING_T(arg));
472        return;
473      }
474      else if (cvalue == MP_CmtProtoRecStruct)
475      {
476        MPT_CpyTypespecedArg(oarg, arg, MPT_RecStructTree);
477        return;
478      }
479      else if (cvalue == MP_CmtProtoRecUnion)
480      {
481        MPT_CpyTypespecedArg(oarg, arg, MPT_RecUnionTree);
482        return;
483      }
484    }
485
486    /* special MP Operators */
487    if (ntype == MP_CommonOperatorType && ndict == MP_ProtoDict)
488    {
489      /* ProtoD:Union */
490      if (cvalue == MP_CopProtoUnion || cvalue == MP_CopProtoRecUnion)
491      {
492        MPT_Union_pt mun = MPT_UNION_PT(arg),
493          dun = (MPT_Union_pt) IMP_MemAllocFnc(sizeof(MPT_Union_t));
494
495        MPT_Assume(mun->tag <= nc);
496        dun->tag = mun->tag;
497        *oarg = (MPT_Arg_t) dun;
498        if (mun->tag > 0)
499          MPT_CpyTypespecedArg(&(dun->arg), mun->arg,
500                               MPT_TREE_PT(typespec_args[mun->tag-1]));
501        else
502          dun->arg = NULL;
503        return;
504      }
505
506      /* ProtoD:Struct */
507      if (cvalue == MP_CopProtoStruct || cvalue == MP_CopProtoRecStruct)
508      {
509        MPT_Arg_pt st_args = MPT_ARG_PT(arg),
510          dst_args = (MPT_Arg_pt) IMP_MemAllocFnc(nc*sizeof(MPT_Arg_t));
511        MP_NumChild_t i;
512
513        *oarg = dst_args;
514        for (i=0; i<nc; i++)
515          MPT_CpyTypespecedArg(&(dst_args[i]), st_args[i], 
516                               MPT_TREE_PT(typespec_args[i]));
517        return;
518      }
519    }
520 
521    /* Meta Operators */
522    if (ntype == MP_CommonMetaOperatorType || ntype == MP_MetaOperatorType)
523    {
524      MPT_Arg_pt args, *dargs;
525      typespec = MPT_ProtoAnnotValue(typespec_node);
526   
527      if (nc == 0)
528      {
529        MPT_DynArgs_pt dynargs = MPT_DYNARGS_PT(arg), ddynargs;
530     
531        nc = dynargs->length;
532        ddynargs = (MPT_DynArgs_pt) IMP_MemAllocFnc(sizeof(MPT_DynArgs_t));
533        *oarg = ddynargs;
534        ddynargs->length = nc;
535
536        args = dynargs->args;
537        dargs = &(ddynargs->args);
538      }
539      else
540      {
541        args = MPT_ARG_PT(arg);
542        dargs = (MPT_Arg_pt *) oarg;
543      }
544   
545      MPT_CpyArgs(dargs, args, nc, typespec);
546      return;
547    }
548  }
549
550  /* Everything else is taken to be a tree */
551  MPT_CpyTree((MPT_Tree_pt *) oarg, MPT_TREE_PT(arg));
552}
553
Note: See TracBrowser for help on using the repository browser.