source: git/Singular/newstruct.cc @ 06c0b3

jengelh-datetimespielwiese
Last change on this file since 06c0b3 was 06c0b3, checked in by Hans Schoenemann <hannes@…>, 11 years ago
fix: newstruct changes fropm master
  • Property mode set to 100644
File size: 15.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
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  while((p!=NULL) &&(p->t=op)&&(p->args!=4)) p=p->next;
326  if (p!=NULL)
327  {
328    leftv sl;
329    sleftv tmp;
330    memset(&tmp,0,sizeof(sleftv));
331    tmp.Copy(args);
332    idrec hh;
333    memset(&hh,0,sizeof(hh));
334    hh.id=Tok2Cmdname(p->t);
335    hh.typ=PROC_CMD;
336    hh.data.pinf=p->p;
337    sl=iiMake_proc(&hh,NULL,&tmp);
338    if (sl==NULL) return TRUE;
339    else
340    {
341      res->Copy(sl);
342      return FALSE;
343    }
344  }
345  return blackbox_default_OpM(op,res,args);
346}
347
348void lClean_newstruct(lists l)
349{
350  if (l->nr>=0)
351  {
352    int i;
353    ring r=NULL;
354    for(i=l->nr;i>=0;i--)
355    {
356      if ((i>0) && (l->m[i-1].rtyp==RING_CMD))
357        r=(ring)(l->m[i-1].data);
358      else
359        r=NULL;
360      l->m[i].CleanUp(r);
361    }
362    omFreeSize((ADDRESS)l->m, (l->nr+1)*sizeof(sleftv));
363    l->nr=-1;
364  }
365  omFreeBin((ADDRESS)l,slists_bin);
366}
367
368void newstruct_destroy(blackbox *b, void *d)
369{
370  if (d!=NULL)
371  {
372    lists n=(lists)d;
373    lClean_newstruct(n);
374  }
375}
376
377void *newstruct_Init(blackbox *b)
378{
379  newstruct_desc n=(newstruct_desc)b->data;
380  lists l=(lists)omAlloc0Bin(slists_bin);
381  l->Init(n->size);
382  newstruct_member nm=n->member;
383  while (nm!=NULL)
384  {
385    l->m[nm->pos].rtyp=nm->typ;
386    l->m[nm->pos].data=idrecDataInit(nm->typ);
387    nm=nm->next;
388  }
389  return l;
390}
391
392BOOLEAN newstruct_Check(blackbox *b, void *d)
393{
394  newstruct_desc n=(newstruct_desc)b->data;
395  lists l=(lists)d;
396  newstruct_member nm=n->member;
397  while (nm!=NULL)
398  {
399    if ((l->m[nm->pos].rtyp!=nm->typ)
400    &&( nm->typ!=DEF_CMD))
401    {
402      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
403          Tok2Cmdname(nm->typ),nm->typ,
404          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
405      return TRUE;
406    }
407    nm=nm->next;
408  }
409  return FALSE;
410}
411
412BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
413{
414  newstruct_desc dd=(newstruct_desc)b->data;
415  sleftv l;
416  memset(&l,0,sizeof(l));
417  l.rtyp=STRING_CMD;
418  l.data=(void*)getBlackboxName(dd->id);
419  f->m->Write(f, &l);
420  lists ll=(lists)d;
421  memset(&l,0,sizeof(l));
422  l.rtyp=LIST_CMD;
423  l.data=ll;
424  f->m->Write(f, &l);
425  return FALSE;
426}
427
428BOOLEAN newstruct_deserialize(blackbox **b, void **d, si_link f)
429{
430  // newstruct is serialiazed as a list,
431  // just read a list and take data,
432  // rtyp must be set correctly (to the blackbox id) by routine calling
433  // newstruct_deserialize
434  leftv l=f->m->Read(f);
435  //newstruct_desc n=(newstruct_desc)b->data;
436  //TODO: check compatibility of list l->data with description in n
437  *d=l->data;
438  return FALSE;
439}
440
441void newstruct_Print(blackbox *b,void *d)
442{
443  newstruct_desc dd=(newstruct_desc)b->data;
444  newstruct_proc p=dd->procs;
445  while((p!=NULL)&&(p->t!=PRINT_CMD))
446    p=p->next;
447  if (p!=NULL)
448  {
449    leftv sl;
450    sleftv tmp;
451    memset(&tmp,0,sizeof(tmp));
452    tmp.rtyp=dd->id;
453    tmp.data=(void*)newstruct_Copy(b,d);
454    idrec hh;
455    memset(&hh,0,sizeof(hh));
456    hh.id=Tok2Cmdname(p->t);
457    hh.typ=PROC_CMD;
458    hh.data.pinf=p->p;
459    sl=iiMake_proc(&hh,NULL,&tmp);
460  }
461  else
462    blackbox_default_Print(b,d);
463}
464void newstruct_setup(const char *n, newstruct_desc d )
465{
466  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
467  // all undefined entries will be set to default in setBlackboxStuff
468  // the default Print is quite useful,
469  // all other are simply error messages
470  b->blackbox_destroy=newstruct_destroy;
471  b->blackbox_String=newstruct_String;
472  b->blackbox_Print=newstruct_Print;//blackbox_default_Print;
473  b->blackbox_Init=newstruct_Init;
474  b->blackbox_Copy=newstruct_Copy;
475  b->blackbox_Assign=newstruct_Assign;
476  //b->blackbox_Op1=blackboxDefaultOp1;
477  b->blackbox_Op2=newstruct_Op2;
478  //b->blackbox_Op3=blackbox_default_Op3;
479  b->blackbox_OpM=newstruct_OpM;
480  b->blackbox_Check=newstruct_Check;
481  b->blackbox_serialize=newstruct_serialize;
482  b->blackbox_deserialize=newstruct_deserialize;
483  b->data=d;
484  b->properties=1; // list_like
485  int rt=setBlackboxStuff(b,n);
486  d->id=rt;
487  //Print("create type %d (%s)\n",rt,n);
488}
489
490static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
491{
492  char *ss=omStrDup(s);
493  char *p=ss;
494  char *start;
495  int t;
496  char c;
497  newstruct_member elem;
498
499  idhdl save_ring=currRingHdl;
500  currRingHdl=(idhdl)1; // fake ring detection
501  loop
502  {
503    // read type:
504    while (*p==' ') p++;
505    start=p;
506    while (isalpha(*p)) p++;
507    *p='\0';
508    IsCmd(start,t);
509    if (t==0)
510    {
511      Werror("unknown type `%s`",start);
512      omFree(ss);
513      omFree(res);
514      currRingHdl=save_ring;
515      return NULL;
516    }
517    if (RingDependend(t))
518      res->size++;    // one additional field for the ring (before the data)
519    //Print("found type %s at real-pos %d",start,res->size);
520    elem=(newstruct_member)omAlloc0(sizeof(*elem));
521    // read name:
522    p++;
523    while (*p==' ') p++;
524    start=p;
525    while (isalpha(*p)) p++;
526    c=*p;
527    *p='\0';
528    elem->typ=t;
529    elem->pos=res->size;
530    if (*start=='\0') /*empty name*/
531    {
532      WerrorS("empty name for element");
533      goto error_in_newstruct_def;
534    }
535    elem->name=omStrDup(start);
536    //Print(" name:%s\n",start);
537    elem->next=res->member;
538    res->member=elem;
539    res->size++;
540
541    // next ?
542    *p=c;
543    while (*p==' ') p++;
544    if (*p!=',')
545    {
546      if (*p!='\0')
547      {
548        Werror("unknown character in newstruct:>>%s<<",p);
549        goto error_in_newstruct_def;
550      }
551      break; // end-of-list
552    }
553    p++;
554  }
555  omFree(ss);
556  currRingHdl=save_ring;
557  //Print("new type with %d elements\n",res->size);
558  return res;
559error_in_newstruct_def:
560   omFree(elem);
561   omFree(ss);
562   omFree(res);
563   currRingHdl=save_ring;
564   return NULL;
565}
566newstruct_desc newstructFromString(const char *s)
567{
568  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
569  res->size=0;
570
571  return scanNewstructFromString(s,res);
572}
573newstruct_desc newstructChildFromString(const char *parent, const char *s)
574{
575  // find parent:
576  int parent_id=0;
577  blackboxIsCmd(parent,parent_id);
578  if (parent_id<MAX_TOK)
579  {
580    Werror(">>%s< not found",parent);
581    return NULL;
582  }
583  blackbox *parent_bb=getBlackboxStuff(parent_id);
584  // check for the correct type:
585  if (parent_bb->blackbox_destroy!=newstruct_destroy)
586  {
587    Werror(">>%s< is not a user defined type",parent);
588    return NULL;
589  }
590  // setup for scanNewstructFromString:
591  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
592  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
593  res->size=parent_desc->size;
594  res->member=parent_desc->member;
595  res->parent=parent_desc;
596
597  return scanNewstructFromString(s,res);
598}
599void newstructShow(newstruct_desc d)
600{
601  newstruct_member elem;
602  Print("id: %d\n",d->id);
603  elem=d->member;
604  while (elem!=NULL)
605  {
606    Print(">>%s<< at pos %d, type %d\n",elem->name,elem->pos,elem->typ);
607    elem=elem->next;
608  }
609}
610
611BOOLEAN newstruct_set_proc(const char *bbname,const char *func, int args,procinfov pr)
612{
613  int id=0;
614  blackboxIsCmd(bbname,id);
615  blackbox *bb=getBlackboxStuff(id);
616  newstruct_desc desc=(newstruct_desc)bb->data;
617  newstruct_proc p=(newstruct_proc)omAlloc(sizeof(*p));
618  p->next=desc->procs; desc->procs=p;
619  if(!IsCmd(func,p->t))
620  {
621    int t=0;
622    if (func[1]=='\0') p->t=func[0];
623    else if((t=iiOpsTwoChar(func))!=0)
624    {
625      p->t=t;
626    }
627    else
628    {
629      Werror(">>%s<< is not a kernel command",func);
630      return TRUE;
631    }
632  }
633  p->args=args;
634  p->p=pr; pr->ref++;
635  return FALSE;
636}
Note: See TracBrowser for help on using the repository browser.