source: git/Singular/newstruct.cc @ ecf019

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