source: git/Singular/newstruct.cc @ f5b40a

spielwiese
Last change on this file since f5b40a was f5b40a, checked in by Hans Schoenemann <hannes@…>, 12 years ago
use kernel/mod2.h everythere
  • Property mode set to 100644
File size: 11.8 KB
Line 
1#include <ctype.h>
2
3#include <kernel/mod2.h>
4#include <Singular/ipid.h>
5#include <Singular/blackbox.h>
6#include <Singular/lists.h>
7#include <Singular/ipid.h>
8#include <Singular/ipshell.h>
9#include <Singular/newstruct.h>
10
11struct newstruct_member_s;
12typedef struct newstruct_member_s *newstruct_member;
13struct  newstruct_member_s
14{
15  newstruct_member next;
16  char *         name;
17  int            typ;
18  int            pos;
19};
20
21struct newstruct_desc_s
22{
23  newstruct_member member;
24  newstruct_desc   parent;
25  int            size; // number of mebers +1
26  int            id;   // the type id assigned to this bb
27};
28
29
30char * newstruct_String(blackbox *b, void *d)
31{
32  if (d==NULL) return omStrDup("oo");
33  else
34  {
35    newstruct_desc ad=(newstruct_desc)(b->data);
36    lists l=(lists)d;
37    newstruct_member a=ad->member;
38    StringSetS("");
39    loop
40    {
41      StringAppendS(a->name);
42      char *tmp=omStrDup(StringAppendS("="));
43      if ((!RingDependend(a->typ))
44      || ((l->m[a->pos-1].data==(void *)currRing)
45         && (currRing!=NULL)))
46      {
47        if (l->m[a->pos].rtyp==LIST_CMD)
48        {
49          StringAppendS("<list>");
50        }
51        else
52        {
53          StringSetS("");
54          char *tmp2=omStrDup(l->m[a->pos].String());
55          StringSetS(tmp);
56          if ((strlen(tmp2)>80)||(strchr(tmp2,'\n')!=NULL))
57          {
58            StringAppend("<%s>",Tok2Cmdname(l->m[a->pos].rtyp));
59          }
60          else StringAppendS(tmp2);
61          omFree(tmp2);
62        }
63      }
64      else StringAppendS("??");
65      omFree(tmp);
66      if (a->next==NULL) break;
67      StringAppendS("\n");
68      if(errorreported) break;
69      a=a->next;
70    }
71    return omStrDup(StringAppendS(""));
72  }
73}
74lists lCopy_newstruct(lists L)
75{
76  lists N=(lists)omAlloc0Bin(slists_bin);
77  int n=L->nr;
78  ring save_ring=currRing;
79  N->Init(n+1);
80  for(;n>=0;n--)
81  {
82    if (RingDependend(L->m[n].rtyp))
83    {
84      assume((L->m[n-1].rtyp==RING_CMD) || (L->m[n-1].data==NULL));
85      if(L->m[n-1].data!=NULL)
86      {
87        if (L->m[n-1].data!=(void*)currRing)
88          rChangeCurrRing((ring)(L->m[n-1].data));
89        N->m[n].Copy(&L->m[n]);
90      }
91      else
92      {
93        N->m[n].rtyp=L->m[n].rtyp;
94        N->m[n].data=idrecDataInit(L->m[n].rtyp);
95      }
96    }
97    else if((L->m[n].rtyp>MAX_TOK)||(L->m[n].rtyp==LIST_CMD))
98    {
99      N->m[n].rtyp=L->m[n].rtyp;
100      N->m[n].data=(void *)lCopy_newstruct((lists)(L->m[n].data));
101    }
102    else
103      N->m[n].Copy(&L->m[n]);
104  }
105  if (currRing!=save_ring) rChangeCurrRing(save_ring);
106  return N;
107}
108void * newstruct_Copy(blackbox*b, void *d)
109{
110  lists n1=(lists)d;
111  return (void*)lCopy_newstruct(n1);
112}
113
114BOOLEAN newstruct_Assign(leftv l, leftv r)
115{
116  blackbox *ll=getBlackboxStuff(l->Typ());
117  if (r->Typ()>MAX_TOK)
118  {
119    blackbox *rr=getBlackboxStuff(r->Typ());
120    if (l->Typ()!=r->Typ())
121    {
122      newstruct_desc rrn=(newstruct_desc)rr->data;
123      newstruct_desc rrp=rrn->parent;
124      while ((rrp!=NULL)&&(rrp->id!=l->Typ())) rrp=rrp->parent;
125      if (rrp!=NULL)
126      {
127        if (l->rtyp==IDHDL)
128        {
129          IDTYP((idhdl)l->data)=r->Typ();
130        }
131        else
132        {
133          l->rtyp=r->Typ();
134        }
135      }
136    }
137    if (l->Typ()==r->Typ())
138    {
139      if (l->Data()!=NULL)
140      {
141        lists n1=(lists)l->Data();
142        n1->Clean(); n1=NULL;
143      }
144      lists n2=(lists)r->Data();
145      n2=lCopy_newstruct(n2);
146      if (l->rtyp==IDHDL)
147      {
148        IDDATA((idhdl)l->data)=(char *)n2;
149      }
150      else
151      {
152        l->data=(void *)n2;
153      }
154      return FALSE;
155    }
156  }
157  Werror("assign %s(%d) = %s(%d)",
158        Tok2Cmdname(l->Typ()),l->Typ(),Tok2Cmdname(r->Typ()),r->Typ());
159  return TRUE;
160}
161
162BOOLEAN newstruct_Op2(int op, leftv res, leftv a1, leftv a2)
163{
164  // interpreter: a1 is newstruct
165  blackbox *a=getBlackboxStuff(a1->Typ());
166  newstruct_desc nt=(newstruct_desc)a->data;
167  lists al=(lists)a1->Data();
168  switch(op)
169  {
170    case '.':
171    {
172      if (a2->name!=NULL)
173      {
174        BOOLEAN search_ring=FALSE;
175        newstruct_member nm=nt->member;
176        while ((nm!=NULL)&&(strcmp(nm->name,a2->name)!=0)) nm=nm->next;
177        if ((nm==NULL) && (strncmp(a2->name,"r_",2)==0))
178        {
179          nm=nt->member;
180          while ((nm!=NULL)&&(strcmp(nm->name,a2->name+2)!=0)) nm=nm->next;
181          if ((nm!=NULL)&&(RingDependend(nm->typ)))
182            search_ring=TRUE;
183          else
184            nm=NULL;
185        }
186        if (nm==NULL)
187        {
188          Werror("member %s nor found", a2->name);
189          return TRUE;
190        }
191        if (search_ring)
192        {
193          ring r;
194          res->rtyp=RING_CMD;
195          res->data=al->m[nm->pos-1].data;
196          r=(ring)res->data;
197          if (r==NULL) { res->data=(void *)currRing; r=currRing; }
198          if (r!=NULL) r->ref++;
199          else Werror("ring of this member is not set and no basering found");
200          return r==NULL;
201        }
202        else if (RingDependend(nm->typ))
203        {
204          if (al->m[nm->pos].data==NULL)
205          {
206            // NULL belongs to any ring
207            ring r=(ring)al->m[nm->pos-1].data;
208            if (r!=NULL)
209            {
210              r->ref--;
211              al->m[nm->pos-1].data=NULL;
212              al->m[nm->pos-1].rtyp=DEF_CMD;
213            }
214          }
215          else
216          {
217            //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
218            if ((al->m[nm->pos-1].data!=(void *)currRing)
219            &&(al->m[nm->pos-1].data!=(void*)0L))
220            {
221              Werror("different ring %lx(data) - %lx(basering)",
222                (long unsigned)(al->m[nm->pos-1].data),(long unsigned)currRing);
223              return TRUE;
224            }
225          }
226          if ((currRing!=NULL)&&(al->m[nm->pos-1].data==NULL))
227          {
228            // remember the ring, if not already set
229            al->m[nm->pos-1].data=(void *)currRing;
230            al->m[nm->pos-1].rtyp=RING_CMD;
231            currRing->ref++;
232          }
233        }
234        Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
235        r->start = nm->pos+1;
236        memcpy(res,a1,sizeof(sleftv));
237        memset(a1,0,sizeof(sleftv));
238        if (res->e==NULL) res->e=r;
239        else
240        {
241          Subexpr sh=res->e;
242          while (sh->next != NULL) sh=sh->next;
243          sh->next=r;
244        }
245        return FALSE;
246      }
247      else
248      {
249        WerrorS("name expected");
250        return TRUE;
251      }
252    }
253  }
254  return blackboxDefaultOp2(op,res,a1,a2);
255}
256
257// BOOLEAN opM(int op, leftv res, leftv args)
258BOOLEAN newstruct_OpM(int op, leftv res, leftv args)
259{
260  // interpreter: args->1. arg is newstruct
261  blackbox *a=getBlackboxStuff(args->Typ());
262  switch(op)
263  {
264    case STRING_CMD:
265    {
266      res->data=(void *)a->blackbox_String(a,args->Data());
267      res->rtyp=STRING_CMD;
268      return FALSE;
269    }
270    default:
271      return blackbox_default_OpM(op,res,args);
272      break;
273  }
274  return TRUE;
275}
276
277void newstruct_destroy(blackbox *b, void *d)
278{
279  if (d!=NULL)
280  {
281    lists n=(lists)d;
282    n->Clean();
283  }
284}
285
286void *newstruct_Init(blackbox *b)
287{
288  newstruct_desc n=(newstruct_desc)b->data;
289  lists l=(lists)omAlloc0Bin(slists_bin);
290  l->Init(n->size);
291  newstruct_member nm=n->member;
292  while (nm!=NULL)
293  {
294    l->m[nm->pos].rtyp=nm->typ;
295    l->m[nm->pos].data=idrecDataInit(nm->typ);
296    nm=nm->next;
297  }
298  return l;
299}
300
301BOOLEAN newstruct_Check(blackbox *b, void *d)
302{
303  newstruct_desc n=(newstruct_desc)b->data;
304  lists l=(lists)d;
305  newstruct_member nm=n->member;
306  while (nm!=NULL)
307  {
308    if ((l->m[nm->pos].rtyp!=nm->typ)
309    &&( nm->typ!=DEF_CMD))
310    {
311      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
312          Tok2Cmdname(nm->typ),nm->typ,
313          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
314      return TRUE;
315    }
316    nm=nm->next;
317  }
318  return FALSE;
319}
320
321BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
322{
323  newstruct_desc dd=(newstruct_desc)b->data;
324  sleftv l;
325  memset(&l,0,sizeof(l));
326  l.rtyp=STRING_CMD;
327  l.data=(void*)getBlackboxName(dd->id);
328  f->m->Write(f, &l);
329  lists ll=(lists)d;
330  memset(&l,0,sizeof(l));
331  l.rtyp=LIST_CMD;
332  l.data=ll;
333  f->m->Write(f, &l);
334  return FALSE;
335}
336
337BOOLEAN newstruct_deserialize(blackbox **b, void **d, si_link f)
338{
339  // newstruct is serialiazed as a list,
340  // just read a list and take data,
341  // rtyp must be set correctly (to the blackbox id) by routine calling
342  // newstruct_deserialize
343  leftv l=f->m->Read(f);
344  //newstruct_desc n=(newstruct_desc)b->data;
345  //TODO: check compatibility of list l->data with description in n
346  *d=l->data;
347  return FALSE;
348}
349
350void newstruct_setup(const char *n, newstruct_desc d )
351{
352  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
353  // all undefined entries will be set to default in setBlackboxStuff
354  // the default Print is quite usefule,
355  // all other are simply error messages
356  b->blackbox_destroy=newstruct_destroy;
357  b->blackbox_String=newstruct_String;
358  //b->blackbox_Print=blackbox_default_Print;
359  b->blackbox_Init=newstruct_Init;
360  b->blackbox_Copy=newstruct_Copy;
361  b->blackbox_Assign=newstruct_Assign;
362  //b->blackbox_Op1=blackboxDefaultOp1;
363  b->blackbox_Op2=newstruct_Op2;
364  //b->blackbox_Op3=blackbox_default_Op3;
365  b->blackbox_OpM=newstruct_OpM;
366  b->blackbox_Check=newstruct_Check;
367  b->blackbox_serialize=newstruct_serialize;
368  b->blackbox_deserialize=newstruct_deserialize;
369  b->data=d;
370  b->properties=1; // list_like
371  int rt=setBlackboxStuff(b,n);
372  d->id=rt;
373  //Print("create type %d (%s)\n",rt,n);
374}
375
376static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
377{
378  char *ss=omStrDup(s);
379  char *p=ss;
380  char *start;
381  int t;
382  char c;
383  newstruct_member elem;
384
385  idhdl save_ring=currRingHdl;
386  currRingHdl=(idhdl)1; // fake ring detection
387  loop
388  {
389    // read type:
390    while (*p==' ') p++;
391    start=p;
392    while (isalpha(*p)) p++;
393    *p='\0';
394    IsCmd(start,t);
395    if (t==0)
396    {
397      Werror("unknown type `%s`",start);
398      omFree(ss);
399      omFree(res);
400      currRingHdl=save_ring;
401      return NULL;
402    }
403    if (RingDependend(t))
404      res->size++;    // one additional field for the ring (before the data)
405    //Print("found type %s at real-pos %d",start,res->size);
406    elem=(newstruct_member)omAlloc0(sizeof(*elem));
407    // read name:
408    p++;
409    while (*p==' ') p++;
410    start=p;
411    while (isalpha(*p)) p++;
412    c=*p;
413    *p='\0';
414    elem->typ=t;
415    elem->pos=res->size;
416    if (*start=='\0') /*empty name*/
417    {
418      WerrorS("empty name for element");
419      goto error_in_newstruct_def;
420    }
421    elem->name=omStrDup(start);
422    //Print(" name:%s\n",start);
423    elem->next=res->member;
424    res->member=elem;
425    res->size++;
426
427    // next ?
428    *p=c;
429    while (*p==' ') p++;
430    if (*p!=',')
431    {
432      if (*p!='\0')
433      {
434        Werror("unknown character in newstruct:>>%s<<",p);
435        goto error_in_newstruct_def;
436      }
437      break; // end-of-list
438    }
439    p++;
440  }
441  omFree(ss);
442  currRingHdl=save_ring;
443  //Print("new type with %d elements\n",res->size);
444  return res;
445error_in_newstruct_def:
446   omFree(elem);
447   omFree(ss);
448   omFree(res);
449   currRingHdl=save_ring;
450   return NULL;
451}
452newstruct_desc newstructFromString(const char *s)
453{
454  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
455  res->size=0;
456
457  return scanNewstructFromString(s,res);
458}
459newstruct_desc newstructChildFromString(const char *parent, const char *s)
460{
461  // find parent:
462  int parent_id=0;
463  blackboxIsCmd(parent,parent_id);
464  if (parent_id<MAX_TOK)
465  {
466    Werror(">>%s< not found",parent);
467    return NULL;
468  }
469  blackbox *parent_bb=getBlackboxStuff(parent_id);
470  // check for the correct type:
471  if (parent_bb->blackbox_destroy!=newstruct_destroy)
472  {
473    Werror(">>%s< is not a user defined type",parent);
474    return NULL;
475  }
476  // setup for scanNewstructFromString:
477  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
478  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
479  res->size=parent_desc->size;
480  res->member=parent_desc->member;
481  res->parent=parent_desc;
482
483  return scanNewstructFromString(s,res);
484}
Note: See TracBrowser for help on using the repository browser.