source: git/Singular/newstruct.cc @ 72df18

fieker-DuValspielwiese
Last change on this file since 72df18 was 3dc7255, checked in by Hans Schoenemann <hannes@…>, 3 years ago
fix: memory leak in newstruct_String
  • Property mode set to 100644
File size: 22.7 KB
RevLine 
[a4b31c]1#include "kernel/mod2.h"
[fd1b1be]2
[a4b31c]3#include "Singular/ipid.h"
4#include "Singular/blackbox.h"
5#include "Singular/lists.h"
6#include "Singular/ipid.h"
7#include "Singular/ipshell.h"
[096909f]8#include "Singular/ipconv.h"
[a4b31c]9#include "Singular/newstruct.h"
[5c3bc3]10
[fd1b1be]11#include <ctype.h>
12
[5c3bc3]13struct newstruct_member_s;
14typedef struct newstruct_member_s *newstruct_member;
15struct  newstruct_member_s
16{
17  newstruct_member next;
18  char *         name;
19  int            typ;
20  int            pos;
21};
22
[06c0b3]23struct newstruct_proc_s;
24typedef struct newstruct_proc_a *newstruct_proc;
25struct  newstruct_proc_a
26{
27  newstruct_proc next;
28  int            t; /*tok id */
29  int            args; /* number of args */
30  procinfov      p;
31};
32
[5c3bc3]33struct newstruct_desc_s
34{
35  newstruct_member member;
[64cf44]36  newstruct_desc   parent;
[06c0b3]37  newstruct_proc   procs;
[5c3bc3]38  int            size; // number of mebers +1
[64cf44]39  int            id;   // the type id assigned to this bb
[5c3bc3]40};
41
[8357e21]42int newstruct_desc_size()
[b2aa08]43{
44  return sizeof(newstruct_desc_s);
45}
[4f08da]46static inline int NeedShadowRing(int t)
47{
48  return (RingDependend(t)|| (t==DEF_CMD) ||(t==LIST_CMD));
49}
[5c3bc3]50char * newstruct_String(blackbox *b, void *d)
51{
52  if (d==NULL) return omStrDup("oo");
53  else
54  {
[7f581e]55    newstruct_desc ad=(newstruct_desc)(b->data);
[3877fe]56
57    newstruct_proc p=ad->procs;
58    while((p!=NULL)&&(p->t!=STRING_CMD))
59      p=p->next;
60
61    if (p!=NULL)
62    {
63      sleftv tmp;
[95e3732]64      tmp.Init();
[3877fe]65      tmp.rtyp=ad->id;
66      void * newstruct_Copy(blackbox*, void *); //forward declaration
67      tmp.data=(void*)newstruct_Copy(b,d);
68      idrec hh;
[95e3732]69      hh.Init();
[3877fe]70      hh.id=Tok2Cmdname(p->t);
71      hh.typ=PROC_CMD;
72      hh.data.pinf=p->p;
[5701b2]73      BOOLEAN sl=iiMake_proc(&hh,NULL,&tmp);
[3877fe]74
[e3b071]75      if ((!sl)&& (iiRETURNEXPR.Typ() == STRING_CMD))
[3877fe]76      {
[5701b2]77        char *res = (char*)iiRETURNEXPR.CopyD();
[f92a39]78        iiRETURNEXPR.Init();
[3877fe]79        return res;
80      }
[5edb77]81      iiRETURNEXPR.CleanUp();
[f92a39]82      iiRETURNEXPR.Init();
[3877fe]83    }
84
[5c3bc3]85    lists l=(lists)d;
86    newstruct_member a=ad->member;
87    StringSetS("");
88    loop
89    {
90      StringAppendS(a->name);
[538512]91      StringAppendS("=");
[df2357c]92      if (((!RingDependend(a->typ)&&!RingDependend(l->m[a->pos].rtyp)))
93      || ((rEqual((ring)l->m[a->pos-1].data,currRing))
[5c3bc3]94         && (currRing!=NULL)))
95      {
[64cf44]96        if (l->m[a->pos].rtyp==LIST_CMD)
97        {
98          StringAppendS("<list>");
99        }
[937c89e]100        else if (l->m[a->pos].rtyp==STRING_CMD)
[4f08da]101        {
[937c89e]102          StringAppendS((char*)l->m[a->pos].Data());
[4f08da]103        }
104        else
[64cf44]105        {
[3dc7255]106          char *tmp2=l->m[a->pos].String();
[a8f29f]107          if ((strlen(tmp2)>80)||(strchr(tmp2,'\n')!=NULL))
108          {
[73c359d]109            StringAppendS("<");
110            StringAppendS(Tok2Cmdname(l->m[a->pos].rtyp));
111            StringAppendS(">");
[a8f29f]112          }
113          else StringAppendS(tmp2);
[64cf44]114          omFree(tmp2);
115        }
[5c3bc3]116      }
117      else StringAppendS("??");
118      if (a->next==NULL) break;
119      StringAppendS("\n");
120      if(errorreported) break;
121      a=a->next;
122    }
[538512]123    return StringEndS();
[5c3bc3]124  }
125}
[a2faa3]126lists lCopy_newstruct(lists L)
127{
128  lists N=(lists)omAlloc0Bin(slists_bin);
129  int n=L->nr;
130  ring save_ring=currRing;
131  N->Init(n+1);
132  for(;n>=0;n--)
133  {
[69d7df]134    if (RingDependend(L->m[n].rtyp)
135    ||((L->m[n].rtyp==LIST_CMD)&&lRingDependend((lists)L->m[n].data)))
[a2faa3]136    {
[5e147a]137      assume((L->m[n-1].rtyp==RING_CMD) || (L->m[n-1].data==NULL));
138      if(L->m[n-1].data!=NULL)
139      {
140        if (L->m[n-1].data!=(void*)currRing)
141          rChangeCurrRing((ring)(L->m[n-1].data));
142        N->m[n].Copy(&L->m[n]);
143      }
144      else
145      {
146        N->m[n].rtyp=L->m[n].rtyp;
147        N->m[n].data=idrecDataInit(L->m[n].rtyp);
148      }
149    }
[06c0b3]150    else if(L->m[n].rtyp==LIST_CMD)
[5e147a]151    {
152      N->m[n].rtyp=L->m[n].rtyp;
[06c0b3]153      N->m[n].data=(void *)lCopy((lists)(L->m[n].data));
[a2faa3]154    }
[06c0b3]155    else if(L->m[n].rtyp>MAX_TOK)
[46eef0]156    {
157      N->m[n].rtyp=L->m[n].rtyp;
[06c0b3]158      blackbox *b=getBlackboxStuff(N->m[n].rtyp);
159      N->m[n].data=(void *)b->blackbox_Copy(b,L->m[n].data);
[46eef0]160    }
[a2faa3]161    else
162      N->m[n].Copy(&L->m[n]);
163  }
164  if (currRing!=save_ring) rChangeCurrRing(save_ring);
165  return N;
166}
[06c0b3]167void * newstruct_Copy(blackbox*, void *d)
[5c3bc3]168{
169  lists n1=(lists)d;
[a2faa3]170  return (void*)lCopy_newstruct(n1);
[5c3bc3]171}
172
[a04a05]173// Used by newstruct_Assign for overloaded '='
[769a27]174BOOLEAN newstruct_Assign_user(int op, leftv l, leftv r)
[a04a05]175{
176  blackbox *ll=getBlackboxStuff(op);
177  assume(ll->data != NULL);
178  newstruct_desc nt=(newstruct_desc)ll->data;
179  newstruct_proc p=nt->procs;
[f92a39]180
[a04a05]181  while( (p!=NULL) && ((p->t!='=')||(p->args!=1)) ) p=p->next;
182
183  if (p!=NULL)
184  {
[5edb77]185    BOOLEAN sl;
[a04a05]186    idrec hh;
[95e3732]187    hh.Init();
[a04a05]188    hh.id=Tok2Cmdname(p->t);
189    hh.typ=PROC_CMD;
190    hh.data.pinf=p->p;
191    sleftv tmp;
192    tmp.Copy(r);
[5edb77]193    sl = iiMake_proc(&hh, NULL, &tmp);
194    if (!sl)
[a04a05]195    {
[5edb77]196      if (iiRETURNEXPR.Typ() == op)
[f92a39]197      {
[2b0c08e]198        memcpy(l,&iiRETURNEXPR,sizeof(sleftv));
[f92a39]199        iiRETURNEXPR.Init();
200        return FALSE;
201      }
[5edb77]202      iiRETURNEXPR.CleanUp();
[f92a39]203      iiRETURNEXPR.Init();
[a04a05]204    }
205  }
206  return TRUE;
207}
208
[bf7dfc]209void lClean_newstruct(lists l)
210{
211  if (l->nr>=0)
212  {
213    int i;
214    ring r=NULL;
215    for(i=l->nr;i>=0;i--)
216    {
217      if ((i>0) && (l->m[i-1].rtyp==RING_CMD))
218        r=(ring)(l->m[i-1].data);
219      else
220        r=NULL;
221      l->m[i].CleanUp(r);
222    }
223    omFreeSize((ADDRESS)l->m, (l->nr+1)*sizeof(sleftv));
224    l->nr=-1;
225  }
226  omFreeBin((ADDRESS)l,slists_bin);
227}
228
[769a27]229static BOOLEAN newstruct_Assign_same(leftv l, leftv r)
230{
231  assume(l->Typ() == r->Typ());
232  if (l->Data()!=NULL)
233  {
234    lists n1=(lists)l->Data();
235    lClean_newstruct(n1);
236  }
237  lists n2=(lists)r->Data();
238  n2=lCopy_newstruct(n2);
239  r->CleanUp();
240  if (l->rtyp==IDHDL)
241  {
242    IDDATA((idhdl)l->data)=(char *)n2;
243  }
244  else
245  {
246    l->data=(void *)n2;
247  }
248  return FALSE;
249}
250
[8d7e70]251BOOLEAN newstruct_Op1(int op, leftv res, leftv arg)
252{
253  // interpreter: arg is newstruct
254  blackbox *a=getBlackboxStuff(arg->Typ());
255  newstruct_desc nt=(newstruct_desc)a->data;
256  newstruct_proc p=nt->procs;
257
258  while((p!=NULL) &&( (p->t!=op) || (p->args!=1) )) p=p->next;
259
260  if (p!=NULL)
261  {
262    idrec hh;
[95e3732]263    hh.Init();
[8d7e70]264    hh.id=Tok2Cmdname(p->t);
265    hh.typ=PROC_CMD;
266    hh.data.pinf=p->p;
[5701b2]267    BOOLEAN sl=iiMake_proc(&hh,NULL,arg);
[8d7e70]268    if (sl) return TRUE;
269    else
270    {
[5701b2]271      memcpy(res,&iiRETURNEXPR,sizeof(sleftv));
[8d7e70]272      iiRETURNEXPR.Init();
273      return FALSE;
274    }
275  }
276  return blackboxDefaultOp1(op,res,arg);
277}
278
[5c3bc3]279BOOLEAN newstruct_Assign(leftv l, leftv r)
280{
[769a27]281  assume(l->Typ() > MAX_TOK);
282  if (l->Typ()==r->Typ())
283  {
284    return newstruct_Assign_same(l,r);
285  }
[5c3bc3]286  if (r->Typ()>MAX_TOK)
287  {
288    blackbox *rr=getBlackboxStuff(r->Typ());
[64cf44]289    if (l->Typ()!=r->Typ())
290    {
291      newstruct_desc rrn=(newstruct_desc)rr->data;
[90707f]292
[8d7e70]293      if (rrn==NULL) // this is not a newstruct
[90707f]294      {
[3d69257]295        Werror("custom type %s(%d) cannot be assigned to newstruct %s(%d)",
[90707f]296               Tok2Cmdname(r->Typ()), r->Typ(), Tok2Cmdname(l->Typ()), l->Typ());
297        return TRUE;
298      }
299
[8d7e70]300      // try to find a parent newstruct:
[64cf44]301      newstruct_desc rrp=rrn->parent;
302      while ((rrp!=NULL)&&(rrp->id!=l->Typ())) rrp=rrp->parent;
303      if (rrp!=NULL)
304      {
305        if (l->rtyp==IDHDL)
306        {
307          IDTYP((idhdl)l->data)=r->Typ();
308        }
309        else
310        {
311          l->rtyp=r->Typ();
312        }
313      }
[ed47aab]314      else                      // unrelated types - look for custom conversion
315      {
316        sleftv tmp;
317        if (! newstruct_Op1(l->Typ(), &tmp, r))  return newstruct_Assign(l, &tmp);
[8d7e70]318        if(!newstruct_Assign_user(l->Typ(), &tmp, r)) return newstruct_Assign(l, &tmp);
[ed47aab]319      }
[8d7e70]320    }
321    if (l->Typ()==r->Typ())
322    {
323      return  newstruct_Assign_same(l,r);
[64cf44]324    }
[7b156fb]325  }
[8d7e70]326  else
[0a64d50]327  {
328    sleftv tmp;
[8d7e70]329    if(!newstruct_Assign_user(l->Typ(), &tmp, r)) return newstruct_Assign(l, &tmp);
[0a64d50]330  }
[8d7e70]331  Werror("assign %s(%d) = %s(%d)",
332        Tok2Cmdname(l->Typ()),l->Typ(),Tok2Cmdname(r->Typ()),r->Typ());
333  return TRUE;
[0a64d50]334}
335
[5c3bc3]336BOOLEAN newstruct_Op2(int op, leftv res, leftv a1, leftv a2)
337{
[06c0b3]338  // interpreter: a1 or a2 is newstruct
[5c3bc3]339  blackbox *a=getBlackboxStuff(a1->Typ());
[06c0b3]340  newstruct_desc nt;
[5c3bc3]341  lists al=(lists)a1->Data();
[06c0b3]342  if (a!=NULL)
[5c3bc3]343  {
[06c0b3]344    nt=(newstruct_desc)a->data;
345    switch(op)
[5c3bc3]346    {
[06c0b3]347      case '.':
[5c3bc3]348      {
[06c0b3]349        if (a2->name!=NULL)
[5c3bc3]350        {
[06c0b3]351          BOOLEAN search_ring=FALSE;
352          newstruct_member nm=nt->member;
353          while ((nm!=NULL)&&(strcmp(nm->name,a2->name)!=0)) nm=nm->next;
354          if ((nm==NULL) && (strncmp(a2->name,"r_",2)==0))
[5e147a]355          {
[06c0b3]356            nm=nt->member;
357            while ((nm!=NULL)&&(strcmp(nm->name,a2->name+2)!=0)) nm=nm->next;
[4f08da]358            if ((nm!=NULL)&&(NeedShadowRing(nm->typ)))
[06c0b3]359              search_ring=TRUE;
360            else
361              nm=NULL;
[5e147a]362          }
[06c0b3]363          if (nm==NULL)
364          {
[56aaae]365            Werror("member %s not found", a2->name);
[06c0b3]366            return TRUE;
367          }
368          if (search_ring)
[5c3bc3]369          {
[83b708]370            ring r=(ring)al->m[nm->pos-1].data;
[06c0b3]371            res->rtyp=RING_CMD;
[354921]372            if (r==NULL)
373            {
[83b708]374              r=currRing;
375              if (r==NULL)
376                WerrorS("ring of this member is not set and no basering found");
[354921]377            }
[83b708]378            if (r!=NULL) res->data=rIncRefCnt(r);
[7ea6fa1]379            a1->CleanUp();
380            a2->CleanUp();
[06c0b3]381            return r==NULL;
382          }
[69d7df]383          else if (RingDependend(nm->typ)
[0de0509]384          || (al->m[nm->pos].RingDependend()))
[06c0b3]385          {
[2fb01f]386            if ((al->m[nm->pos].data==NULL)||(al->m[nm->pos-1].data==NULL))
[06c0b3]387            {
388              // NULL belongs to any ring
[0647c5]389              ring r=(ring)al->m[nm->pos-1].data;
390              if (r!=NULL)
[06c0b3]391              {
[1f91b9]392                rDecRefCnt(r);
[0647c5]393                al->m[nm->pos-1].data=NULL;
394                al->m[nm->pos-1].rtyp=DEF_CMD;
[06c0b3]395              }
396            }
[83aaa6]397            else if (al->m[nm->pos-1].data!=currRing)
[06c0b3]398            {
[1f952a]399              // object is not from currRing, so mark it for "write-only":
400              al->m[nm->pos].flag|=Sy_bit(FLAG_OTHER_RING);
[06c0b3]401              //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
[83aaa6]402            }
[1f952a]403            else
[5c3bc3]404            {
[1f952a]405              // object is from currRing, so mark it for "read-write":
406              al->m[nm->pos].flag &= ~Sy_bit(FLAG_OTHER_RING);
[0647c5]407
[5c3bc3]408            }
[2c5e69]409            al->m[nm->pos].flag|=Sy_bit(FLAG_RING);
[5c3bc3]410          }
[0de0509]411          else if ((nm->typ==DEF_CMD)||(nm->typ==LIST_CMD))
412          {
[089afd]413            if(al->m[nm->pos-1].data!=NULL)
[0de0509]414            {
[089afd]415              ring old=(ring)al->m[nm->pos-1].data;
[1f91b9]416              rDecRefCnt(old);
[0de0509]417            }
[089afd]418            al->m[nm->pos-1].data=(void*)currRing;
[1f91b9]419            if (currRing!=NULL) rIncRefCnt(currRing);
[0de0509]420          }
[06c0b3]421          Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
422          r->start = nm->pos+1;
423          memcpy(res,a1,sizeof(sleftv));
[95e3732]424          a1->Init();
[06c0b3]425          if (res->e==NULL) res->e=r;
426          else
[5e147a]427          {
[06c0b3]428            Subexpr sh=res->e;
429            while (sh->next != NULL) sh=sh->next;
430            sh->next=r;
[5e147a]431          }
[95e3732]432          //a1->CleanUp();// see Init() above
[7ea6fa1]433          a2->CleanUp();
[06c0b3]434          return FALSE;
[5c3bc3]435        }
436        else
437        {
[06c0b3]438          WerrorS("name expected");
439          return TRUE;
[5c3bc3]440        }
441      }
442    }
443  }
[06c0b3]444  else
445  {
446    a=getBlackboxStuff(a2->Typ());
447    nt=(newstruct_desc)a->data;
448    al=(lists)a2->Data();
449  }
450  newstruct_proc p=nt->procs;
[2262ab]451  while((p!=NULL) && ( (p->t!=op) || (p->args!=2) )) p=p->next;
[06c0b3]452  if (p!=NULL)
453  {
454    sleftv tmp;
455    tmp.Copy(a1);
456    tmp.next=(leftv)omAlloc0(sizeof(sleftv));
457    tmp.next->Copy(a2);
458    idrec hh;
[95e3732]459    hh.Init();
[06c0b3]460    hh.id=Tok2Cmdname(p->t);
461    hh.typ=PROC_CMD;
462    hh.data.pinf=p->p;
[5701b2]463    BOOLEAN sl=iiMake_proc(&hh,NULL,&tmp);
464    a1->CleanUp();
465    a2->CleanUp();
[5edb77]466    if (sl) return TRUE;
[06c0b3]467    else
468    {
[5701b2]469      memcpy(res,&iiRETURNEXPR,sizeof(sleftv));
[f92a39]470      iiRETURNEXPR.Init();
[06c0b3]471      return FALSE;
472    }
473  }
[5c3bc3]474  return blackboxDefaultOp2(op,res,a1,a2);
475}
[a2faa3]476
[5c3bc3]477// BOOLEAN opM(int op, leftv res, leftv args)
478BOOLEAN newstruct_OpM(int op, leftv res, leftv args)
479{
480  // interpreter: args->1. arg is newstruct
481  blackbox *a=getBlackboxStuff(args->Typ());
[06c0b3]482  newstruct_desc nt=(newstruct_desc)a->data;
[5c3bc3]483  switch(op)
484  {
485    case STRING_CMD:
486    {
487      res->data=(void *)a->blackbox_String(a,args->Data());
488      res->rtyp=STRING_CMD;
[7ea6fa1]489      args->CleanUp();
[5c3bc3]490      return FALSE;
491    }
492    default:
493      break;
494  }
[06c0b3]495  newstruct_proc p=nt->procs;
[8357e21]496
[2262ab]497  while((p!=NULL) &&( (p->t!=op) || (p->args!=4) )) p=p->next;
498
[06c0b3]499  if (p!=NULL)
500  {
501    idrec hh;
[95e3732]502    hh.Init();
[06c0b3]503    hh.id=Tok2Cmdname(p->t);
504    hh.typ=PROC_CMD;
505    hh.data.pinf=p->p;
[7ea6fa1]506    BOOLEAN sl=iiMake_proc(&hh,NULL,args);
507    args->CleanUp();
[5edb77]508    if (sl) return TRUE;
[06c0b3]509    else
510    {
[5701b2]511      memcpy(res,&iiRETURNEXPR,sizeof(sleftv));
[f92a39]512      iiRETURNEXPR.Init();
[06c0b3]513      return FALSE;
514    }
515  }
[97cc98]516  return blackboxDefaultOpM(op,res,args);
[06c0b3]517}
518
[2e4ec14]519void newstruct_destroy(blackbox */*b*/, void *d)
[5c3bc3]520{
521  if (d!=NULL)
522  {
523    lists n=(lists)d;
[06c0b3]524    lClean_newstruct(n);
[5c3bc3]525  }
526}
527
528void *newstruct_Init(blackbox *b)
529{
530  newstruct_desc n=(newstruct_desc)b->data;
531  lists l=(lists)omAlloc0Bin(slists_bin);
532  l->Init(n->size);
533  newstruct_member nm=n->member;
534  while (nm!=NULL)
535  {
536    l->m[nm->pos].rtyp=nm->typ;
[4f08da]537    if (NeedShadowRing(nm->typ))
[cb7abb]538    {
[56aaae]539      l->m[nm->pos-1].rtyp=RING_CMD;
[cb7abb]540      l->m[nm->pos-1].data=currRing; //idrecDataInit may create ringdep obj.
[1f91b9]541      if (currRing!=NULL) rIncRefCnt(currRing);
[cb7abb]542    }
[5c3bc3]543    l->m[nm->pos].data=idrecDataInit(nm->typ);
544    nm=nm->next;
545  }
546  return l;
547}
548
[2e4ec14]549BOOLEAN newstruct_CheckAssign(blackbox */*b*/, leftv L, leftv R)
[8357e21]550{
551  int lt=L->Typ();
552  int rt=R->Typ();
[096909f]553  if (iiTestConvert(rt,lt,dConvertTypes)==0)
[8357e21]554  {
[ab2a18]555    const char *rt1=Tok2Cmdname(rt);
556    const char *lt1=Tok2Cmdname(lt);
[75f460]557    if ((rt>0) && (lt>0)
[ab2a18]558    && ((strcmp(rt1,Tok2Cmdname(0))==0)||(strcmp(lt1,Tok2Cmdname(0))==0)))
559    {
560      Werror("can not assign %s(%d) to member of type %s(%d)",
561            rt1,rt,lt1,lt);
562    }
563    else
564    {
565      Werror("can not assign %s to member of type %s",rt1,lt1);
566    }
[8357e21]567    return TRUE;
568  }
569  return FALSE;
570}
571
572/* check internal structure:
573* BOOLEAN newstruct_Check(blackbox *b, void *d)
[5c3bc3]574{
575  newstruct_desc n=(newstruct_desc)b->data;
576  lists l=(lists)d;
577  newstruct_member nm=n->member;
578  while (nm!=NULL)
579  {
580    if ((l->m[nm->pos].rtyp!=nm->typ)
581    &&( nm->typ!=DEF_CMD))
582    {
583      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
584          Tok2Cmdname(nm->typ),nm->typ,
[5e147a]585          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
[5c3bc3]586      return TRUE;
587    }
588    nm=nm->next;
589  }
590  return FALSE;
591}
[8357e21]592*/
[a2faa3]593
[f84c3b]594BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
595{
596  newstruct_desc dd=(newstruct_desc)b->data;
[a088a12]597  sleftv l;
[95e3732]598  l.Init();
[a088a12]599  l.rtyp=STRING_CMD;
600  l.data=(void*)getBlackboxName(dd->id);
601  f->m->Write(f, &l);
[f84c3b]602  lists ll=(lists)d;
[97c955]603  int Ll=lSize(ll);
604  l.rtyp=INT_CMD;
605  l.data=(void*)(long)Ll;
[a088a12]606  f->m->Write(f, &l);
[97c955]607  // set all entries corresponding to "real" mebers to 1 in rings
608  char *rings=(char*)omAlloc0(Ll+1);
609  newstruct_member elem=dd->member;
610  while (elem!=NULL)
611  {
612    rings[elem->pos]='\1';
613    elem=elem->next;
614  }
615  int i;
616  BOOLEAN ring_changed=FALSE;
617  ring save_ring=currRing;
618  for(i=0;i<=Ll;i++)
619  {
620    if (rings[i]=='\0') // ring entry for pos i+1
621    {
622      if (ll->m[i].data!=NULL)
623      {
624        ring_changed=TRUE;
625        f->m->SetRing(f,(ring)ll->m[i].data,TRUE);
626      }
627    }
628    f->m->Write(f,&(ll->m[i]));
629  }
[7ea6fa1]630  omFreeSize(rings,Ll+1);
[df2357c]631  if (ring_changed && (save_ring!=NULL))
[97c955]632    f->m->SetRing(f,save_ring,FALSE);
[386458]633  return FALSE;
[f84c3b]634}
635
[266ddd]636BOOLEAN newstruct_deserialize(blackbox **, void **d, si_link f)
[f84c3b]637{
[266ddd]638  // newstruct is serialized as analog to a list,
[a088a12]639  // just read a list and take data,
640  // rtyp must be set correctly (to the blackbox id) by routine calling
641  // newstruct_deserialize
[97c955]642  leftv l=f->m->Read(f); // int: length of list
643  int Ll=(int)(long)(l->data);
[7ea6fa1]644  omFreeBin(l,sleftv_bin);
[97c955]645  lists L=(lists)omAllocBin(slists_bin);
646  L->Init(Ll+1);
647  for(int i=0;i<=Ll;i++)
648  {
649    l=f->m->Read(f);
650    memcpy(&(L->m[i]),l,sizeof(sleftv));
[7ea6fa1]651    omFreeBin(l,sleftv_bin);
[97c955]652  }
[a088a12]653  //newstruct_desc n=(newstruct_desc)b->data;
654  //TODO: check compatibility of list l->data with description in n
[97c955]655  *d=L;
[a088a12]656  return FALSE;
[f84c3b]657}
658
[06c0b3]659void newstruct_Print(blackbox *b,void *d)
660{
661  newstruct_desc dd=(newstruct_desc)b->data;
662  newstruct_proc p=dd->procs;
663  while((p!=NULL)&&(p->t!=PRINT_CMD))
664    p=p->next;
665  if (p!=NULL)
666  {
[5edb77]667    BOOLEAN sl;
[06c0b3]668    sleftv tmp;
[95e3732]669    tmp.Init();
[06c0b3]670    tmp.rtyp=dd->id;
671    tmp.data=(void*)newstruct_Copy(b,d);
672    idrec hh;
[95e3732]673    hh.Init();
[06c0b3]674    hh.id=Tok2Cmdname(p->t);
675    hh.typ=PROC_CMD;
676    hh.data.pinf=p->p;
677    sl=iiMake_proc(&hh,NULL,&tmp);
[0de0509]678    if (!sl)
679    {
680      if (iiRETURNEXPR.Typ()!=NONE) Warn("ignoring return value (%s)",Tok2Cmdname(iiRETURNEXPR.Typ()));
681      iiRETURNEXPR.CleanUp();
682    }
[f92a39]683    iiRETURNEXPR.Init();
[06c0b3]684  }
685  else
686    blackbox_default_Print(b,d);
687}
[5c3bc3]688void newstruct_setup(const char *n, newstruct_desc d )
689{
690  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
691  // all undefined entries will be set to default in setBlackboxStuff
[06c0b3]692  // the default Print is quite useful,
[5c3bc3]693  // all other are simply error messages
694  b->blackbox_destroy=newstruct_destroy;
695  b->blackbox_String=newstruct_String;
[06c0b3]696  b->blackbox_Print=newstruct_Print;//blackbox_default_Print;
[5c3bc3]697  b->blackbox_Init=newstruct_Init;
698  b->blackbox_Copy=newstruct_Copy;
699  b->blackbox_Assign=newstruct_Assign;
[0a64d50]700  b->blackbox_Op1=newstruct_Op1;
[5c3bc3]701  b->blackbox_Op2=newstruct_Op2;
[97cc98]702  //b->blackbox_Op3=blackboxDefaultOp3;
[5c3bc3]703  b->blackbox_OpM=newstruct_OpM;
[8357e21]704  b->blackbox_CheckAssign=newstruct_CheckAssign;
[f84c3b]705  b->blackbox_serialize=newstruct_serialize;
706  b->blackbox_deserialize=newstruct_deserialize;
[5c3bc3]707  b->data=d;
708  b->properties=1; // list_like
709  int rt=setBlackboxStuff(b,n);
[64cf44]710  d->id=rt;
[114346]711  //Print("create type %d (%s)\n",rt,n);
[5c3bc3]712}
713
[64cf44]714static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
[5c3bc3]715{
716  char *ss=omStrDup(s);
717  char *p=ss;
718  char *start;
719  int t;
720  char c;
721  newstruct_member elem;
[64cf44]722
[5c3bc3]723  idhdl save_ring=currRingHdl;
724  currRingHdl=(idhdl)1; // fake ring detection
725  loop
726  {
727    // read type:
[f09a99]728    while ((*p!='\0') && (*p<=' ')) p++;
[5c3bc3]729    start=p;
[f09a99]730    while (isalnum(*p)) p++;
[5c3bc3]731    *p='\0';
732    IsCmd(start,t);
733    if (t==0)
734    {
735      Werror("unknown type `%s`",start);
736      omFree(ss);
737      omFree(res);
738      currRingHdl=save_ring;
739      return NULL;
740    }
[f6b8d2e]741    if (t==QRING_CMD) t=RING_CMD;
[4f08da]742    else if (NeedShadowRing(t))
[5c3bc3]743      res->size++;    // one additional field for the ring (before the data)
744    //Print("found type %s at real-pos %d",start,res->size);
745    elem=(newstruct_member)omAlloc0(sizeof(*elem));
746    // read name:
747    p++;
[f09a99]748    while ((*p!='\0') && (*p<=' ')) p++;
[5c3bc3]749    start=p;
[f09a99]750    while (isalnum(*p)) p++;
[5c3bc3]751    c=*p;
752    *p='\0';
753    elem->typ=t;
754    elem->pos=res->size;
[f09a99]755    if ((*start=='\0') /*empty name*/||(isdigit(*start)))
[5c3bc3]756    {
[f09a99]757      WerrorS("illegal/empty name for element");
[4878eb]758      goto error_in_newstruct_def;
[5c3bc3]759    }
760    elem->name=omStrDup(start);
761    //Print(" name:%s\n",start);
762    elem->next=res->member;
763    res->member=elem;
764    res->size++;
765
766    // next ?
767    *p=c;
[f09a99]768    while ((*p!='\0') && (*p<=' ')) p++;
[eb5526e]769    if (*p!=',')
[4878eb]770    {
[eb5526e]771      if (*p!='\0')
772      {
773        Werror("unknown character in newstruct:>>%s<<",p);
774        goto error_in_newstruct_def;
775      }
776      break; // end-of-list
[4878eb]777    }
[5c3bc3]778    p++;
779  }
780  omFree(ss);
781  currRingHdl=save_ring;
[64cf44]782  //Print("new type with %d elements\n",res->size);
[69d7df]783  //newstructShow(res);
[5c3bc3]784  return res;
[4878eb]785error_in_newstruct_def:
786   omFree(elem);
787   omFree(ss);
788   omFree(res);
789   currRingHdl=save_ring;
790   return NULL;
[5c3bc3]791}
[eff324]792newstruct_desc newstructFromString(const char *s)
[64cf44]793{
794  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
795  res->size=0;
796
[eff324]797  return scanNewstructFromString(s,res);
[64cf44]798}
799newstruct_desc newstructChildFromString(const char *parent, const char *s)
[a2faa3]800{
[64cf44]801  // find parent:
802  int parent_id=0;
803  blackboxIsCmd(parent,parent_id);
804  if (parent_id<MAX_TOK)
805  {
806    Werror(">>%s< not found",parent);
807    return NULL;
808  }
809  blackbox *parent_bb=getBlackboxStuff(parent_id);
810  // check for the correct type:
811  if (parent_bb->blackbox_destroy!=newstruct_destroy)
812  {
813    Werror(">>%s< is not a user defined type",parent);
814    return NULL;
815  }
816  // setup for scanNewstructFromString:
817  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
818  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
819  res->size=parent_desc->size;
820  res->member=parent_desc->member;
821  res->parent=parent_desc;
822
823  return scanNewstructFromString(s,res);
[a2faa3]824}
[97c955]825
[06c0b3]826void newstructShow(newstruct_desc d)
827{
828  newstruct_member elem;
829  Print("id: %d\n",d->id);
830  elem=d->member;
831  while (elem!=NULL)
832  {
[56aaae]833    Print(">>%s<< at pos %d, type %d (%s)\n",elem->name,elem->pos,elem->typ,Tok2Cmdname(elem->typ));
[4f08da]834    if (NeedShadowRing(elem->typ))
[56aaae]835      Print(">>r_%s<< at pos %d, shadow ring\n",elem->name,elem->pos-1);
[06c0b3]836    elem=elem->next;
837  }
[0de0509]838  newstruct_proc p=d->procs;
839  while (p!=NULL)
840  {
841    Print("op:%d(%s) with %d args -> %s\n",p->t,iiTwoOps(p->t),p->args,p->p->procname);
842    p=p->next;
843  }
[06c0b3]844}
845
846BOOLEAN newstruct_set_proc(const char *bbname,const char *func, int args,procinfov pr)
847{
848  int id=0;
849  blackboxIsCmd(bbname,id);
[35c264]850  if (id<MAX_TOK)
851  {
852    Werror(">>%s<< is not a newstruct type",bbname);
853    return TRUE;
854  }
[06c0b3]855  blackbox *bb=getBlackboxStuff(id);
856  newstruct_desc desc=(newstruct_desc)bb->data;
857  newstruct_proc p=(newstruct_proc)omAlloc(sizeof(*p));
858  p->next=desc->procs; desc->procs=p;
[632c3a]859
860  idhdl save_ring=currRingHdl;
861  currRingHdl=(idhdl)1; // fake ring detection
862
[92a50b]863  int tt;
864  if(!(tt=IsCmd(func,p->t)))
[06c0b3]865  {
[92a50b]866    int t;
867    if((t=iiOpsTwoChar(func))!=0)
[06c0b3]868    {
869      p->t=t;
[92a50b]870      tt=CMD_2; /* ..,::, ==, <=, <>, >= !=i and +,-,*,/,%,.... */
871      if ((t==PLUSPLUS)
872      ||(t==MINUSMINUS)
873      ||(t=='='))
874        tt=CMD_1; /* ++,--,= */
[cec9b00]875      else if (t=='(') /* proc call */
876        tt=CMD_M;
[528499]877      else if (t=='-') /* unary and binary - */
878        tt=CMD_12;
[06c0b3]879    }
880    else
881    {
[92a50b]882      desc->procs=p->next;
883      omFreeSize(p,sizeof(*p));
[06c0b3]884      Werror(">>%s<< is not a kernel command",func);
[632c3a]885      currRingHdl = save_ring;
[06c0b3]886      return TRUE;
887    }
888  }
[92a50b]889  switch(tt)
890  {
891    // type conversions:
892    case BIGINTMAT_CMD:
893    case MATRIX_CMD:
894    case INTMAT_CMD:
895    case RING_CMD:
896    case RING_DECL:
897    case ROOT_DECL:
898    // operations:
899    case CMD_1:
[e734084]900      if(args!=1) { Warn("args must be 1 for %s in %s",func,my_yylinebuf);args=1;}
[92a50b]901      break;
902    case CMD_2:
903      if(args!=2) { Warn("args must be 2 in %s",my_yylinebuf);args=2;}
904      break;
905    case CMD_3:
906      if(args!=3) { Warn("args must be 3 in %s",my_yylinebuf);args=3;}
907      break;
908    case CMD_12:
909      if((args!=1)&&(args!=2)) { Werror("args must in 1 or 2 in %s",my_yylinebuf);}
910      break;
911    case CMD_13:
912      if((args!=1)&&(args!=3)) { Werror("args must in 1 or 3 in %s",my_yylinebuf);}
913      break;
914    case CMD_23:
915      if((args<2)||(args>3)) { Werror("args must in 2..3 in %s",my_yylinebuf);}
916      break;
917    case CMD_123:
918      if((args<1)||(args>3)) { Werror("args must in 1..3 in %s",my_yylinebuf);}
919      break;
[e734084]920    case RING_DECL_LIST:
921    case ROOT_DECL_LIST:
[92a50b]922    case CMD_M:
923      break;
924    default:
925      Werror("unknown token type %d in %s",tt,my_yylinebuf);
926      break;
927  }
928  currRingHdl = save_ring;
929  if (errorreported)
930  {
931    desc->procs=p->next;
932    omFreeSize(p,sizeof(*p));
933    return TRUE;
934  }
[06c0b3]935  p->args=args;
936  p->p=pr; pr->ref++;
[3169ca]937  pr->is_static=0;
[06c0b3]938  return FALSE;
939}
Note: See TracBrowser for help on using the repository browser.