source: git/Singular/newstruct.cc @ 528499

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