source: git/Singular/newstruct.cc @ c0d292

jengelh-datetimespielwiese
Last change on this file since c0d292 was c0d292, checked in by Alexander Dreyer <alexander.dreyer@…>, 11 years ago
fix: removed done todo
  • Property mode set to 100644
File size: 17.1 KB
Line 
1#include <ctype.h>
2
3#include "config.h"
4#include <kernel/mod2.h>
5#include <Singular/ipid.h>
6#include <Singular/blackbox.h>
7#include <Singular/lists.h>
8#include <Singular/ipid.h>
9#include <Singular/ipshell.h>
10#include <Singular/newstruct.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    lists l=(lists)d;
53    newstruct_member a=ad->member;
54    StringSetS("");
55    loop
56    {
57      StringAppendS(a->name);
58      char *tmp=omStrDup(StringAppendS("="));
59      if ((!RingDependend(a->typ))
60      || ((l->m[a->pos-1].data==(void *)currRing)
61         && (currRing!=NULL)))
62      {
63        if (l->m[a->pos].rtyp==LIST_CMD)
64        {
65          StringAppendS("<list>");
66        }
67        else
68        {
69          StringSetS("");
70          char *tmp2=omStrDup(l->m[a->pos].String());
71          StringSetS(tmp);
72          if ((strlen(tmp2)>80)||(strchr(tmp2,'\n')!=NULL))
73          {
74            StringAppend("<%s>",Tok2Cmdname(l->m[a->pos].rtyp));
75          }
76          else StringAppendS(tmp2);
77          omFree(tmp2);
78        }
79      }
80      else StringAppendS("??");
81      omFree(tmp);
82      if (a->next==NULL) break;
83      StringAppendS("\n");
84      if(errorreported) break;
85      a=a->next;
86    }
87    return omStrDup(StringAppendS(""));
88  }
89}
90lists lCopy_newstruct(lists L)
91{
92  lists N=(lists)omAlloc0Bin(slists_bin);
93  int n=L->nr;
94  ring save_ring=currRing;
95  N->Init(n+1);
96  for(;n>=0;n--)
97  {
98    if (RingDependend(L->m[n].rtyp))
99    {
100      assume((L->m[n-1].rtyp==RING_CMD) || (L->m[n-1].data==NULL));
101      if(L->m[n-1].data!=NULL)
102      {
103        if (L->m[n-1].data!=(void*)currRing)
104          rChangeCurrRing((ring)(L->m[n-1].data));
105        N->m[n].Copy(&L->m[n]);
106      }
107      else
108      {
109        N->m[n].rtyp=L->m[n].rtyp;
110        N->m[n].data=idrecDataInit(L->m[n].rtyp);
111      }
112    }
113    else if(L->m[n].rtyp==LIST_CMD)
114    {
115      N->m[n].rtyp=L->m[n].rtyp;
116      N->m[n].data=(void *)lCopy((lists)(L->m[n].data));
117    }
118    else if(L->m[n].rtyp>MAX_TOK)
119    {
120      N->m[n].rtyp=L->m[n].rtyp;
121      blackbox *b=getBlackboxStuff(N->m[n].rtyp);
122      N->m[n].data=(void *)b->blackbox_Copy(b,L->m[n].data);
123    }
124    else
125      N->m[n].Copy(&L->m[n]);
126  }
127  if (currRing!=save_ring) rChangeCurrRing(save_ring);
128  return N;
129}
130void * newstruct_Copy(blackbox*, void *d)
131{
132  lists n1=(lists)d;
133  return (void*)lCopy_newstruct(n1);
134}
135
136BOOLEAN newstruct_Assign(leftv l, leftv r)
137{
138  if (r->Typ()>MAX_TOK)
139  {
140    blackbox *rr=getBlackboxStuff(r->Typ());
141    if (l->Typ()!=r->Typ())
142    {
143      newstruct_desc rrn=(newstruct_desc)rr->data;
144
145      if (!rrn)
146      {
147        Werror("custom type %s(%d) cannot be assigned to newstruct %s(%d)",
148               Tok2Cmdname(r->Typ()), r->Typ(), Tok2Cmdname(l->Typ()), l->Typ());
149        return TRUE;
150      }
151
152      newstruct_desc rrp=rrn->parent;
153      while ((rrp!=NULL)&&(rrp->id!=l->Typ())) rrp=rrp->parent;
154      if (rrp!=NULL)
155      {
156        if (l->rtyp==IDHDL)
157        {
158          IDTYP((idhdl)l->data)=r->Typ();
159        }
160        else
161        {
162          l->rtyp=r->Typ();
163        }
164      }
165      else                      // unrelated types - look for custom conversion
166      {
167        sleftv tmp;
168        BOOLEAN newstruct_Op1(int, leftv, leftv);  // forward declaration
169        if (! newstruct_Op1(l->Typ(), &tmp, r))  return newstruct_Assign(l, &tmp);
170      }
171    }
172    if (l->Typ()==r->Typ())
173    {
174      if (l->Data()!=NULL)
175      {
176        lists n1=(lists)l->Data();
177        n1->Clean(); n1=NULL;
178      }
179      lists n2=(lists)r->Data();
180      n2=lCopy_newstruct(n2);
181      if (l->rtyp==IDHDL)
182      {
183        IDDATA((idhdl)l->data)=(char *)n2;
184      }
185      else
186      {
187        l->data=(void *)n2;
188      }
189      return FALSE;
190    }
191  }
192
193  else if(l->Typ() > MAX_TOK)
194  {
195    blackbox *ll=getBlackboxStuff(l->Typ());
196    newstruct_desc nt=(newstruct_desc)ll->data;
197    newstruct_proc p=nt->procs;
198
199    while( (p!=NULL) && ((p->t!='=')||(p->args!=1)) ) p=p->next;
200
201    if (p!=NULL)
202    {
203      idrec hh;
204      memset(&hh,0,sizeof(hh));
205      hh.id=Tok2Cmdname(p->t);
206      hh.typ=PROC_CMD;
207      hh.data.pinf=p->p;
208      sleftv tmp;
209      memset(&tmp,0,sizeof(sleftv));
210      tmp.Copy(r);
211      leftv sl = iiMake_proc(&hh, NULL, &tmp);
212      if (sl != NULL)
213      {
214        if (sl->Typ()==l->Typ()) return newstruct_Assign(l, sl);
215        else sl->CleanUp();
216      }
217    }
218  }
219  Werror("assign %s(%d) = %s(%d)",
220        Tok2Cmdname(l->Typ()),l->Typ(),Tok2Cmdname(r->Typ()),r->Typ());
221  return TRUE;
222}
223
224BOOLEAN newstruct_Op1(int op, leftv res, leftv arg)
225{
226  // interpreter: arg is newstruct
227  blackbox *a=getBlackboxStuff(arg->Typ());
228  newstruct_desc nt=(newstruct_desc)a->data;
229  newstruct_proc p=nt->procs;
230
231  while((p!=NULL) &&( (p->t!=op) || (p->args!=1) )) p=p->next;
232
233  if (p!=NULL)
234  {
235    leftv sl;
236    sleftv tmp;
237    memset(&tmp,0,sizeof(sleftv));
238    tmp.Copy(arg);
239    idrec hh;
240    memset(&hh,0,sizeof(hh));
241    hh.id=Tok2Cmdname(p->t);
242    hh.typ=PROC_CMD;
243    hh.data.pinf=p->p;
244    sl=iiMake_proc(&hh,NULL,&tmp);
245    if (sl==NULL) return TRUE;
246    else
247    {
248      res->Copy(sl);
249      return FALSE;
250    }
251  }
252  return blackboxDefaultOp1(op,res,arg);
253}
254
255
256
257BOOLEAN newstruct_Op2(int op, leftv res, leftv a1, leftv a2)
258{
259  // interpreter: a1 or a2 is newstruct
260  blackbox *a=getBlackboxStuff(a1->Typ());
261  newstruct_desc nt;
262  lists al=(lists)a1->Data();
263  if (a!=NULL)
264  {
265    nt=(newstruct_desc)a->data;
266    switch(op)
267    {
268      case '.':
269      {
270        if (a2->name!=NULL)
271        {
272          BOOLEAN search_ring=FALSE;
273          newstruct_member nm=nt->member;
274          while ((nm!=NULL)&&(strcmp(nm->name,a2->name)!=0)) nm=nm->next;
275          if ((nm==NULL) && (strncmp(a2->name,"r_",2)==0))
276          {
277            nm=nt->member;
278            while ((nm!=NULL)&&(strcmp(nm->name,a2->name+2)!=0)) nm=nm->next;
279            if ((nm!=NULL)&&(RingDependend(nm->typ)))
280              search_ring=TRUE;
281            else
282              nm=NULL;
283          }
284          if (nm==NULL)
285          {
286            Werror("member %s nor found", a2->name);
287            return TRUE;
288          }
289          if (search_ring)
290          {
291            ring r;
292            res->rtyp=RING_CMD;
293            res->data=al->m[nm->pos-1].data;
294            r=(ring)res->data;
295            if (r==NULL) { res->data=(void *)currRing; r=currRing; }
296            if (r!=NULL) r->ref++;
297            else Werror("ring of this member is not set and no basering found");
298            return r==NULL;
299          }
300          else if (RingDependend(nm->typ))
301          {
302            if (al->m[nm->pos].data==NULL)
303            {
304              // NULL belongs to any ring
305              ring r=(ring)al->m[nm->pos-1].data;
306              if (r!=NULL)
307              {
308                r->ref--;
309                al->m[nm->pos-1].data=NULL;
310                al->m[nm->pos-1].rtyp=DEF_CMD;
311              }
312            }
313            else
314            {
315              //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
316              if ((al->m[nm->pos-1].data!=(void *)currRing)
317              &&(al->m[nm->pos-1].data!=(void*)0L))
318              {
319                Werror("different ring %lx(data) - %lx(basering)",
320                  (long unsigned)(al->m[nm->pos-1].data),(long unsigned)currRing);
321                return TRUE;
322              }
323            }
324            if ((currRing!=NULL)&&(al->m[nm->pos-1].data==NULL))
325            {
326              // remember the ring, if not already set
327              al->m[nm->pos-1].data=(void *)currRing;
328              al->m[nm->pos-1].rtyp=RING_CMD;
329              currRing->ref++;
330            }
331          }
332          Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
333          r->start = nm->pos+1;
334          memcpy(res,a1,sizeof(sleftv));
335          memset(a1,0,sizeof(sleftv));
336          if (res->e==NULL) res->e=r;
337          else
338          {
339            Subexpr sh=res->e;
340            while (sh->next != NULL) sh=sh->next;
341            sh->next=r;
342          }
343          return FALSE;
344        }
345        else
346        {
347          WerrorS("name expected");
348          return TRUE;
349        }
350      }
351    }
352  }
353  else
354  {
355    a=getBlackboxStuff(a2->Typ());
356    nt=(newstruct_desc)a->data;
357    al=(lists)a2->Data();
358  }
359  newstruct_proc p=nt->procs;
360  while((p!=NULL) && ( (p->t!=op) || (p->args!=2) )) p=p->next;
361  if (p!=NULL)
362  {
363    leftv sl;
364    sleftv tmp;
365    memset(&tmp,0,sizeof(sleftv));
366    tmp.Copy(a1);
367    tmp.next=(leftv)omAlloc0(sizeof(sleftv));
368    tmp.next->Copy(a2);
369    idrec hh;
370    memset(&hh,0,sizeof(hh));
371    hh.id=Tok2Cmdname(p->t);
372    hh.typ=PROC_CMD;
373    hh.data.pinf=p->p;
374    sl=iiMake_proc(&hh,NULL,&tmp);
375    if (sl==NULL) return TRUE;
376    else
377    {
378      res->Copy(sl);
379      return FALSE;
380    }
381  }
382  return blackboxDefaultOp2(op,res,a1,a2);
383}
384
385// BOOLEAN opM(int op, leftv res, leftv args)
386BOOLEAN newstruct_OpM(int op, leftv res, leftv args)
387{
388  // interpreter: args->1. arg is newstruct
389  blackbox *a=getBlackboxStuff(args->Typ());
390  newstruct_desc nt=(newstruct_desc)a->data;
391  switch(op)
392  {
393    case STRING_CMD:
394    {
395      res->data=(void *)a->blackbox_String(a,args->Data());
396      res->rtyp=STRING_CMD;
397      return FALSE;
398    }
399    default:
400      break;
401  }
402  newstruct_proc p=nt->procs;
403 
404  while((p!=NULL) &&( (p->t!=op) || (p->args!=4) )) p=p->next;
405
406  if (p!=NULL)
407  {
408    leftv sl;
409    sleftv tmp;
410    memset(&tmp,0,sizeof(sleftv));
411    tmp.Copy(args);
412    idrec hh;
413    memset(&hh,0,sizeof(hh));
414    hh.id=Tok2Cmdname(p->t);
415    hh.typ=PROC_CMD;
416    hh.data.pinf=p->p;
417    sl=iiMake_proc(&hh,NULL,&tmp);
418    if (sl==NULL) return TRUE;
419    else
420    {
421      res->Copy(sl);
422      return FALSE;
423    }
424  }
425  return blackbox_default_OpM(op,res,args);
426}
427
428void lClean_newstruct(lists l)
429{
430  if (l->nr>=0)
431  {
432    int i;
433    ring r=NULL;
434    for(i=l->nr;i>=0;i--)
435    {
436      if ((i>0) && (l->m[i-1].rtyp==RING_CMD))
437        r=(ring)(l->m[i-1].data);
438      else
439        r=NULL;
440      l->m[i].CleanUp(r);
441    }
442    omFreeSize((ADDRESS)l->m, (l->nr+1)*sizeof(sleftv));
443    l->nr=-1;
444  }
445  omFreeBin((ADDRESS)l,slists_bin);
446}
447
448void newstruct_destroy(blackbox *b, void *d)
449{
450  if (d!=NULL)
451  {
452    lists n=(lists)d;
453    lClean_newstruct(n);
454  }
455}
456
457void *newstruct_Init(blackbox *b)
458{
459  newstruct_desc n=(newstruct_desc)b->data;
460  lists l=(lists)omAlloc0Bin(slists_bin);
461  l->Init(n->size);
462  newstruct_member nm=n->member;
463  while (nm!=NULL)
464  {
465    l->m[nm->pos].rtyp=nm->typ;
466    l->m[nm->pos].data=idrecDataInit(nm->typ);
467    nm=nm->next;
468  }
469  return l;
470}
471
472BOOLEAN newstruct_Check(blackbox *b, void *d)
473{
474  newstruct_desc n=(newstruct_desc)b->data;
475  lists l=(lists)d;
476  newstruct_member nm=n->member;
477  while (nm!=NULL)
478  {
479    if ((l->m[nm->pos].rtyp!=nm->typ)
480    &&( nm->typ!=DEF_CMD))
481    {
482      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
483          Tok2Cmdname(nm->typ),nm->typ,
484          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
485      return TRUE;
486    }
487    nm=nm->next;
488  }
489  return FALSE;
490}
491
492BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
493{
494  newstruct_desc dd=(newstruct_desc)b->data;
495  sleftv l;
496  memset(&l,0,sizeof(l));
497  l.rtyp=STRING_CMD;
498  l.data=(void*)getBlackboxName(dd->id);
499  f->m->Write(f, &l);
500  lists ll=(lists)d;
501  memset(&l,0,sizeof(l));
502  l.rtyp=LIST_CMD;
503  l.data=ll;
504  f->m->Write(f, &l);
505  return FALSE;
506}
507
508BOOLEAN newstruct_deserialize(blackbox **b, void **d, si_link f)
509{
510  // newstruct is serialiazed as a list,
511  // just read a list and take data,
512  // rtyp must be set correctly (to the blackbox id) by routine calling
513  // newstruct_deserialize
514  leftv l=f->m->Read(f);
515  //newstruct_desc n=(newstruct_desc)b->data;
516  //TODO: check compatibility of list l->data with description in n
517  *d=l->data;
518  return FALSE;
519}
520
521void newstruct_Print(blackbox *b,void *d)
522{
523  newstruct_desc dd=(newstruct_desc)b->data;
524  newstruct_proc p=dd->procs;
525  while((p!=NULL)&&(p->t!=PRINT_CMD))
526    p=p->next;
527  if (p!=NULL)
528  {
529    leftv sl;
530    sleftv tmp;
531    memset(&tmp,0,sizeof(tmp));
532    tmp.rtyp=dd->id;
533    tmp.data=(void*)newstruct_Copy(b,d);
534    idrec hh;
535    memset(&hh,0,sizeof(hh));
536    hh.id=Tok2Cmdname(p->t);
537    hh.typ=PROC_CMD;
538    hh.data.pinf=p->p;
539    sl=iiMake_proc(&hh,NULL,&tmp);
540  }
541  else
542    blackbox_default_Print(b,d);
543}
544void newstruct_setup(const char *n, newstruct_desc d )
545{
546  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
547  // all undefined entries will be set to default in setBlackboxStuff
548  // the default Print is quite useful,
549  // all other are simply error messages
550  b->blackbox_destroy=newstruct_destroy;
551  b->blackbox_String=newstruct_String;
552  b->blackbox_Print=newstruct_Print;//blackbox_default_Print;
553  b->blackbox_Init=newstruct_Init;
554  b->blackbox_Copy=newstruct_Copy;
555  b->blackbox_Assign=newstruct_Assign;
556  b->blackbox_Op1=newstruct_Op1;
557  b->blackbox_Op2=newstruct_Op2;
558  //b->blackbox_Op3=blackbox_default_Op3;
559  b->blackbox_OpM=newstruct_OpM;
560  b->blackbox_Check=newstruct_Check;
561  b->blackbox_serialize=newstruct_serialize;
562  b->blackbox_deserialize=newstruct_deserialize;
563  b->data=d;
564  b->properties=1; // list_like
565  int rt=setBlackboxStuff(b,n);
566  d->id=rt;
567  //Print("create type %d (%s)\n",rt,n);
568}
569
570static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
571{
572  char *ss=omStrDup(s);
573  char *p=ss;
574  char *start;
575  int t;
576  char c;
577  newstruct_member elem;
578
579  idhdl save_ring=currRingHdl;
580  currRingHdl=(idhdl)1; // fake ring detection
581  loop
582  {
583    // read type:
584    while (*p==' ') p++;
585    start=p;
586    while (isalpha(*p)) p++;
587    *p='\0';
588    IsCmd(start,t);
589    if (t==0)
590    {
591      Werror("unknown type `%s`",start);
592      omFree(ss);
593      omFree(res);
594      currRingHdl=save_ring;
595      return NULL;
596    }
597    if (RingDependend(t))
598      res->size++;    // one additional field for the ring (before the data)
599    //Print("found type %s at real-pos %d",start,res->size);
600    elem=(newstruct_member)omAlloc0(sizeof(*elem));
601    // read name:
602    p++;
603    while (*p==' ') p++;
604    start=p;
605    while (isalpha(*p)) p++;
606    c=*p;
607    *p='\0';
608    elem->typ=t;
609    elem->pos=res->size;
610    if (*start=='\0') /*empty name*/
611    {
612      WerrorS("empty name for element");
613      goto error_in_newstruct_def;
614    }
615    elem->name=omStrDup(start);
616    //Print(" name:%s\n",start);
617    elem->next=res->member;
618    res->member=elem;
619    res->size++;
620
621    // next ?
622    *p=c;
623    while (*p==' ') p++;
624    if (*p!=',')
625    {
626      if (*p!='\0')
627      {
628        Werror("unknown character in newstruct:>>%s<<",p);
629        goto error_in_newstruct_def;
630      }
631      break; // end-of-list
632    }
633    p++;
634  }
635  omFree(ss);
636  currRingHdl=save_ring;
637  //Print("new type with %d elements\n",res->size);
638  return res;
639error_in_newstruct_def:
640   omFree(elem);
641   omFree(ss);
642   omFree(res);
643   currRingHdl=save_ring;
644   return NULL;
645}
646newstruct_desc newstructFromString(const char *s)
647{
648  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
649  res->size=0;
650
651  return scanNewstructFromString(s,res);
652}
653newstruct_desc newstructChildFromString(const char *parent, const char *s)
654{
655  // find parent:
656  int parent_id=0;
657  blackboxIsCmd(parent,parent_id);
658  if (parent_id<MAX_TOK)
659  {
660    Werror(">>%s< not found",parent);
661    return NULL;
662  }
663  blackbox *parent_bb=getBlackboxStuff(parent_id);
664  // check for the correct type:
665  if (parent_bb->blackbox_destroy!=newstruct_destroy)
666  {
667    Werror(">>%s< is not a user defined type",parent);
668    return NULL;
669  }
670  // setup for scanNewstructFromString:
671  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
672  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
673  res->size=parent_desc->size;
674  res->member=parent_desc->member;
675  res->parent=parent_desc;
676
677  return scanNewstructFromString(s,res);
678}
679void newstructShow(newstruct_desc d)
680{
681  newstruct_member elem;
682  Print("id: %d\n",d->id);
683  elem=d->member;
684  while (elem!=NULL)
685  {
686    Print(">>%s<< at pos %d, type %d\n",elem->name,elem->pos,elem->typ);
687    elem=elem->next;
688  }
689}
690
691BOOLEAN newstruct_set_proc(const char *bbname,const char *func, int args,procinfov pr)
692{
693  int id=0;
694  blackboxIsCmd(bbname,id);
695  blackbox *bb=getBlackboxStuff(id);
696  newstruct_desc desc=(newstruct_desc)bb->data;
697  newstruct_proc p=(newstruct_proc)omAlloc(sizeof(*p));
698  p->next=desc->procs; desc->procs=p;
699
700  idhdl save_ring=currRingHdl;
701  currRingHdl=(idhdl)1; // fake ring detection
702
703  if(!IsCmd(func,p->t))
704  {
705    int t=0;
706    if (func[1]=='\0') p->t=func[0];
707    else if((t=iiOpsTwoChar(func))!=0)
708    {
709      p->t=t;
710    }
711    else
712    {
713      Werror(">>%s<< is not a kernel command",func);
714      currRingHdl = save_ring;
715      return TRUE;
716    }
717  }
718  p->args=args;
719  p->p=pr; pr->ref++;
720  currRingHdl = save_ring;
721  return FALSE;
722}
Note: See TracBrowser for help on using the repository browser.