source: git/Singular/newstruct.cc @ f0f0003

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