source: git/Singular/newstruct.cc @ 2262ab

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