source: git/Singular/newstruct.cc @ cb461b

spielwiese
Last change on this file since cb461b was cab909, checked in by Hans Schoenemann <hannes@…>, 3 years ago
Revert "reset flag in lCopy_newstruct" This reverts commit 62dcd6d3be9fcd6a94650637217e78b4857b8a64.
  • Property mode set to 100644
File size: 22.7 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=(ring)al->m[nm->pos-1].data;
371            res->rtyp=RING_CMD;
372            if (r==NULL)
373            {
374              r=currRing;
375              if (r==NULL)
376                WerrorS("ring of this member is not set and no basering found");
377            }
378            if (r!=NULL) res->data=rIncRefCnt(r);
379            a1->CleanUp();
380            a2->CleanUp();
381            return r==NULL;
382          }
383          else if (RingDependend(nm->typ)
384          || (al->m[nm->pos].RingDependend()))
385          {
386            if ((al->m[nm->pos].data==NULL)||(al->m[nm->pos-1].data==NULL))
387            {
388              // NULL belongs to any ring
389              ring r=(ring)al->m[nm->pos-1].data;
390              if (r!=NULL)
391              {
392                rDecRefCnt(r);
393                al->m[nm->pos-1].data=NULL;
394                al->m[nm->pos-1].rtyp=DEF_CMD;
395              }
396            }
397            else if (al->m[nm->pos-1].data!=currRing)
398            {
399              // object is not from currRing, so mark it for "write-only":
400              al->m[nm->pos].flag|=Sy_bit(FLAG_OTHER_RING);
401              //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
402            }
403            else
404            {
405              // object is from currRing, so mark it for "read-write":
406              al->m[nm->pos].flag &= ~Sy_bit(FLAG_OTHER_RING);
407
408            }
409            al->m[nm->pos].flag|=Sy_bit(FLAG_RING);
410          }
411          else if ((nm->typ==DEF_CMD)||(nm->typ==LIST_CMD))
412          {
413            if(al->m[nm->pos-1].data!=NULL)
414            {
415              ring old=(ring)al->m[nm->pos-1].data;
416              rDecRefCnt(old);
417            }
418            al->m[nm->pos-1].data=(void*)currRing;
419            if (currRing!=NULL) rIncRefCnt(currRing);
420          }
421          Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
422          r->start = nm->pos+1;
423          memcpy(res,a1,sizeof(sleftv));
424          a1->Init();
425          if (res->e==NULL) res->e=r;
426          else
427          {
428            Subexpr sh=res->e;
429            while (sh->next != NULL) sh=sh->next;
430            sh->next=r;
431          }
432          //a1->CleanUp();// see Init() above
433          a2->CleanUp();
434          return FALSE;
435        }
436        else
437        {
438          WerrorS("name expected");
439          return TRUE;
440        }
441      }
442    }
443  }
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;
451  while((p!=NULL) && ( (p->t!=op) || (p->args!=2) )) p=p->next;
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;
459    hh.Init();
460    hh.id=Tok2Cmdname(p->t);
461    hh.typ=PROC_CMD;
462    hh.data.pinf=p->p;
463    BOOLEAN sl=iiMake_proc(&hh,NULL,&tmp);
464    a1->CleanUp();
465    a2->CleanUp();
466    if (sl) return TRUE;
467    else
468    {
469      memcpy(res,&iiRETURNEXPR,sizeof(sleftv));
470      iiRETURNEXPR.Init();
471      return FALSE;
472    }
473  }
474  return blackboxDefaultOp2(op,res,a1,a2);
475}
476
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());
482  newstruct_desc nt=(newstruct_desc)a->data;
483  switch(op)
484  {
485    case STRING_CMD:
486    {
487      res->data=(void *)a->blackbox_String(a,args->Data());
488      res->rtyp=STRING_CMD;
489      args->CleanUp();
490      return FALSE;
491    }
492    default:
493      break;
494  }
495  newstruct_proc p=nt->procs;
496
497  while((p!=NULL) &&( (p->t!=op) || (p->args!=4) )) p=p->next;
498
499  if (p!=NULL)
500  {
501    idrec hh;
502    hh.Init();
503    hh.id=Tok2Cmdname(p->t);
504    hh.typ=PROC_CMD;
505    hh.data.pinf=p->p;
506    BOOLEAN sl=iiMake_proc(&hh,NULL,args);
507    args->CleanUp();
508    if (sl) return TRUE;
509    else
510    {
511      memcpy(res,&iiRETURNEXPR,sizeof(sleftv));
512      iiRETURNEXPR.Init();
513      return FALSE;
514    }
515  }
516  return blackboxDefaultOpM(op,res,args);
517}
518
519void newstruct_destroy(blackbox */*b*/, void *d)
520{
521  if (d!=NULL)
522  {
523    lists n=(lists)d;
524    lClean_newstruct(n);
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;
537    if (NeedShadowRing(nm->typ))
538    {
539      l->m[nm->pos-1].rtyp=RING_CMD;
540      l->m[nm->pos-1].data=currRing; //idrecDataInit may create ringdep obj.
541      if (currRing!=NULL) rIncRefCnt(currRing);
542    }
543    l->m[nm->pos].data=idrecDataInit(nm->typ);
544    nm=nm->next;
545  }
546  return l;
547}
548
549BOOLEAN newstruct_CheckAssign(blackbox */*b*/, leftv L, leftv R)
550{
551  int lt=L->Typ();
552  int rt=R->Typ();
553  if (iiTestConvert(rt,lt,dConvertTypes)==0)
554  {
555    const char *rt1=Tok2Cmdname(rt);
556    const char *lt1=Tok2Cmdname(lt);
557    if ((rt>0) && (lt>0)
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    }
567    return TRUE;
568  }
569  return FALSE;
570}
571
572/* check internal structure:
573* BOOLEAN newstruct_Check(blackbox *b, void *d)
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,
585          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
586      return TRUE;
587    }
588    nm=nm->next;
589  }
590  return FALSE;
591}
592*/
593
594BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
595{
596  newstruct_desc dd=(newstruct_desc)b->data;
597  sleftv l;
598  l.Init();
599  l.rtyp=STRING_CMD;
600  l.data=(void*)getBlackboxName(dd->id);
601  f->m->Write(f, &l);
602  lists ll=(lists)d;
603  int Ll=lSize(ll);
604  l.rtyp=INT_CMD;
605  l.data=(void*)(long)Ll;
606  f->m->Write(f, &l);
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  }
630  omFreeSize(rings,Ll+1);
631  if (ring_changed && (save_ring!=NULL))
632    f->m->SetRing(f,save_ring,FALSE);
633  return FALSE;
634}
635
636BOOLEAN newstruct_deserialize(blackbox **, void **d, si_link f)
637{
638  // newstruct is serialized as analog to a list,
639  // just read a list and take data,
640  // rtyp must be set correctly (to the blackbox id) by routine calling
641  // newstruct_deserialize
642  leftv l=f->m->Read(f); // int: length of list
643  int Ll=(int)(long)(l->data);
644  omFreeBin(l,sleftv_bin);
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));
651    omFreeBin(l,sleftv_bin);
652  }
653  //newstruct_desc n=(newstruct_desc)b->data;
654  //TODO: check compatibility of list l->data with description in n
655  *d=L;
656  return FALSE;
657}
658
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  {
667    BOOLEAN sl;
668    sleftv tmp;
669    tmp.Init();
670    tmp.rtyp=dd->id;
671    tmp.data=(void*)newstruct_Copy(b,d);
672    idrec hh;
673    hh.Init();
674    hh.id=Tok2Cmdname(p->t);
675    hh.typ=PROC_CMD;
676    hh.data.pinf=p->p;
677    sl=iiMake_proc(&hh,NULL,&tmp);
678    if (!sl)
679    {
680      if (iiRETURNEXPR.Typ()!=NONE) Warn("ignoring return value (%s)",Tok2Cmdname(iiRETURNEXPR.Typ()));
681      iiRETURNEXPR.CleanUp();
682    }
683    iiRETURNEXPR.Init();
684  }
685  else
686    blackbox_default_Print(b,d);
687}
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
692  // the default Print is quite useful,
693  // all other are simply error messages
694  b->blackbox_destroy=newstruct_destroy;
695  b->blackbox_String=newstruct_String;
696  b->blackbox_Print=newstruct_Print;//blackbox_default_Print;
697  b->blackbox_Init=newstruct_Init;
698  b->blackbox_Copy=newstruct_Copy;
699  b->blackbox_Assign=newstruct_Assign;
700  b->blackbox_Op1=newstruct_Op1;
701  b->blackbox_Op2=newstruct_Op2;
702  //b->blackbox_Op3=blackboxDefaultOp3;
703  b->blackbox_OpM=newstruct_OpM;
704  b->blackbox_CheckAssign=newstruct_CheckAssign;
705  b->blackbox_serialize=newstruct_serialize;
706  b->blackbox_deserialize=newstruct_deserialize;
707  b->data=d;
708  b->properties=1; // list_like
709  int rt=setBlackboxStuff(b,n);
710  d->id=rt;
711  //Print("create type %d (%s)\n",rt,n);
712}
713
714static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
715{
716  char *ss=omStrDup(s);
717  char *p=ss;
718  char *start;
719  int t;
720  char c;
721  newstruct_member elem;
722
723  idhdl save_ring=currRingHdl;
724  currRingHdl=(idhdl)1; // fake ring detection
725  loop
726  {
727    // read type:
728    while ((*p!='\0') && (*p<=' ')) p++;
729    start=p;
730    while (isalnum(*p)) p++;
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    }
741    if (t==QRING_CMD) t=RING_CMD;
742    else if (NeedShadowRing(t))
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++;
748    while ((*p!='\0') && (*p<=' ')) p++;
749    start=p;
750    while (isalnum(*p)) p++;
751    c=*p;
752    *p='\0';
753    elem->typ=t;
754    elem->pos=res->size;
755    if ((*start=='\0') /*empty name*/||(isdigit(*start)))
756    {
757      WerrorS("illegal/empty name for element");
758      goto error_in_newstruct_def;
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;
768    while ((*p!='\0') && (*p<=' ')) p++;
769    if (*p!=',')
770    {
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
777    }
778    p++;
779  }
780  omFree(ss);
781  currRingHdl=save_ring;
782  //Print("new type with %d elements\n",res->size);
783  //newstructShow(res);
784  return res;
785error_in_newstruct_def:
786   omFree(elem);
787   omFree(ss);
788   omFree(res);
789   currRingHdl=save_ring;
790   return NULL;
791}
792newstruct_desc newstructFromString(const char *s)
793{
794  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
795  res->size=0;
796
797  return scanNewstructFromString(s,res);
798}
799newstruct_desc newstructChildFromString(const char *parent, const char *s)
800{
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);
824}
825
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  {
833    Print(">>%s<< at pos %d, type %d (%s)\n",elem->name,elem->pos,elem->typ,Tok2Cmdname(elem->typ));
834    if (NeedShadowRing(elem->typ))
835      Print(">>r_%s<< at pos %d, shadow ring\n",elem->name,elem->pos-1);
836    elem=elem->next;
837  }
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  }
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);
850  if (id<MAX_TOK)
851  {
852    Werror(">>%s<< is not a newstruct type",bbname);
853    return TRUE;
854  }
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;
859
860  idhdl save_ring=currRingHdl;
861  currRingHdl=(idhdl)1; // fake ring detection
862
863  int tt;
864  if(!(tt=IsCmd(func,p->t)))
865  {
866    int t;
867    if((t=iiOpsTwoChar(func))!=0)
868    {
869      p->t=t;
870      tt=CMD_2; /* ..,::, ==, <=, <>, >= !=i and +,-,*,/,%,.... */
871      if ((t==PLUSPLUS)
872      ||(t==MINUSMINUS)
873      ||(t=='='))
874        tt=CMD_1; /* ++,--,= */
875      else if (t=='(') /* proc call */
876        tt=CMD_M;
877      else if (t=='-') /* unary and binary - */
878        tt=CMD_12;
879    }
880    else
881    {
882      desc->procs=p->next;
883      omFreeSize(p,sizeof(*p));
884      Werror(">>%s<< is not a kernel command",func);
885      currRingHdl = save_ring;
886      return TRUE;
887    }
888  }
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:
900      if(args!=1) { Warn("args must be 1 for %s in %s",func,my_yylinebuf);args=1;}
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;
920    case RING_DECL_LIST:
921    case ROOT_DECL_LIST:
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  }
935  p->args=args;
936  p->p=pr; pr->ref++;
937  pr->is_static=0;
938  return FALSE;
939}
Note: See TracBrowser for help on using the repository browser.