source: git/Singular/newstruct.cc @ 0a64d50

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