source: git/Singular/newstruct.cc @ 5476e83

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