source: git/Singular/newstruct.cc

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