source: git/Singular/newstruct.cc @ 1f91b9

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