source: git/Singular/newstruct.cc @ 4878eb

spielwiese
Last change on this file since 4878eb was 4878eb, checked in by Hans Schoenemann <hannes@…>, 13 years ago
better error handling for newstruct member names git-svn-id: file:///usr/local/Singular/svn/trunk@13914 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 10.1 KB
Line 
1#include <ctype.h>
2
3#include <Singular/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          StringAppendS(tmp2);
57          omFree(tmp2);
58        }
59      }
60      else StringAppendS("??");
61      omFree(tmp);
62      if (a->next==NULL) break;
63      StringAppendS("\n");
64      if(errorreported) break;
65      a=a->next;
66    }
67    return omStrDup(StringAppendS(""));
68  }
69}
70lists lCopy_newstruct(lists L)
71{
72  lists N=(lists)omAlloc0Bin(slists_bin);
73  int n=L->nr;
74  ring save_ring=currRing;
75  N->Init(n+1);
76  for(;n>=0;n--)
77  {
78    if (RingDependend(L->m[n].rtyp))
79    {
80      assume((L->m[n-1].rtyp==RING_CMD) || (L->m[n-1].data==NULL));
81      if(L->m[n-1].data!=NULL)
82      {
83        if (L->m[n-1].data!=(void*)currRing)
84          rChangeCurrRing((ring)(L->m[n-1].data));
85        N->m[n].Copy(&L->m[n]);
86      }
87      else
88      {
89        N->m[n].rtyp=L->m[n].rtyp;
90        N->m[n].data=idrecDataInit(L->m[n].rtyp);
91      }
92    }
93    else if((L->m[n].rtyp>MAX_TOK)||(L->m[n].rtyp==LIST_CMD))
94    {
95      N->m[n].rtyp=L->m[n].rtyp;
96      N->m[n].data=(void *)lCopy_newstruct((lists)(L->m[n].data));
97    }
98    else
99      N->m[n].Copy(&L->m[n]);
100  }
101  if (currRing!=save_ring) rChangeCurrRing(save_ring);
102  return N;
103}
104void * newstruct_Copy(blackbox*b, void *d)
105{
106  lists n1=(lists)d;
107  return (void*)lCopy_newstruct(n1);
108}
109
110BOOLEAN newstruct_Assign(leftv l, leftv r)
111{
112  blackbox *ll=getBlackboxStuff(l->Typ());
113  if (r->Typ()>MAX_TOK)
114  {
115    blackbox *rr=getBlackboxStuff(r->Typ());
116    if (l->Typ()!=r->Typ())
117    {
118      newstruct_desc rrn=(newstruct_desc)rr->data;
119      newstruct_desc rrp=rrn->parent;
120      while ((rrp!=NULL)&&(rrp->id!=l->Typ())) rrp=rrp->parent;
121      if (rrp!=NULL)
122      {
123        if (l->rtyp==IDHDL)
124        {
125          IDTYP((idhdl)l->data)=r->Typ();
126        }
127        else
128        {
129          l->rtyp=r->Typ();
130        }
131      }
132    }
133    if (l->Typ()==r->Typ())
134    {
135      if (l->Data()!=NULL)
136      {
137        lists n1=(lists)l->Data();
138        n1->Clean(); n1=NULL;
139      }
140      lists n2=(lists)r->Data();
141      n2=lCopy_newstruct(n2);
142      if (l->rtyp==IDHDL)
143      {
144        IDDATA((idhdl)l->data)=(char *)n2;
145      }
146      else
147      {
148        l->data=(void *)n2;
149      }
150      return FALSE;
151    }
152  }
153  Werror("assign %s(%d) = %s(%d)",
154        Tok2Cmdname(l->Typ()),l->Typ(),Tok2Cmdname(r->Typ()),r->Typ());
155  return TRUE;
156}
157
158BOOLEAN newstruct_Op2(int op, leftv res, leftv a1, leftv a2)
159{
160  // interpreter: a1 is newstruct
161  blackbox *a=getBlackboxStuff(a1->Typ());
162  newstruct_desc nt=(newstruct_desc)a->data;
163  lists al=(lists)a1->Data();
164  switch(op)
165  {
166    case '.':
167    {
168      if (a2->name!=NULL)
169      {
170        newstruct_member nm=nt->member;
171        while ((nm!=NULL)&&(strcmp(nm->name,a2->name)!=0)) nm=nm->next;
172        if (nm==NULL)
173        {
174          Werror("member %s nor found");
175          return TRUE;
176        }
177        if (RingDependend(nm->typ))
178        {
179          if (al->m[nm->pos].data==NULL)
180          {
181            // NULL belongs to any ring
182            ring r=(ring)al->m[nm->pos-1].data;
183            if (r!=NULL)
184            {
185              r->ref--;
186              al->m[nm->pos-1].data=NULL;
187              al->m[nm->pos-1].rtyp=DEF_CMD;
188            }
189          }
190          else
191          {
192            //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
193            if ((al->m[nm->pos-1].data!=(void *)currRing)
194            &&(al->m[nm->pos-1].data!=(void*)0L))
195            {
196              Werror("different ring %lx(data) - %lx(basering)",
197                (long unsigned)(al->m[nm->pos-1].data),(long unsigned)currRing);
198              return TRUE;
199            }
200          }
201          if ((currRing!=NULL)&&(al->m[nm->pos-1].data==NULL))
202          {
203            // remember the ring, if not already set
204            al->m[nm->pos-1].data=(void *)currRing;
205            al->m[nm->pos-1].rtyp=RING_CMD;
206            currRing->ref++;
207          }
208        }
209        Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
210        r->start = nm->pos+1;
211        memcpy(res,a1,sizeof(sleftv));
212        memset(a1,0,sizeof(sleftv));
213        if (res->e==NULL) res->e=r;
214        else
215        {
216          Subexpr sh=res->e;
217          while (sh->next != NULL) sh=sh->next;
218          sh->next=r;
219        }
220        return FALSE;
221      }
222      else
223      {
224        WerrorS("name expected");
225        return TRUE;
226      }
227    }
228  }
229  return blackboxDefaultOp2(op,res,a1,a2);
230}
231
232// BOOLEAN opM(int op, leftv res, leftv args)
233BOOLEAN newstruct_OpM(int op, leftv res, leftv args)
234{
235  // interpreter: args->1. arg is newstruct
236  blackbox *a=getBlackboxStuff(args->Typ());
237  switch(op)
238  {
239    case STRING_CMD:
240    {
241      res->data=(void *)a->blackbox_String(a,args->Data());
242      res->rtyp=STRING_CMD;
243      return FALSE;
244    }
245    default:
246      Werror("op %d not implemented for type %d",op,args->Typ());
247      break;
248  }
249  return TRUE;
250}
251
252void newstruct_destroy(blackbox *b, void *d)
253{
254  if (d!=NULL)
255  {
256    lists n=(lists)d;
257    n->Clean();
258  }
259}
260
261void *newstruct_Init(blackbox *b)
262{
263  newstruct_desc n=(newstruct_desc)b->data;
264  lists l=(lists)omAlloc0Bin(slists_bin);
265  l->Init(n->size);
266  newstruct_member nm=n->member;
267  while (nm!=NULL)
268  {
269    l->m[nm->pos].rtyp=nm->typ;
270    l->m[nm->pos].data=idrecDataInit(nm->typ);
271    nm=nm->next;
272  }
273  return l;
274}
275
276BOOLEAN newstruct_Check(blackbox *b, void *d)
277{
278  newstruct_desc n=(newstruct_desc)b->data;
279  lists l=(lists)d;
280  newstruct_member nm=n->member;
281  while (nm!=NULL)
282  {
283    if ((l->m[nm->pos].rtyp!=nm->typ)
284    &&( nm->typ!=DEF_CMD))
285    {
286      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
287          Tok2Cmdname(nm->typ),nm->typ,
288          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
289      return TRUE;
290    }
291    nm=nm->next;
292  }
293  return FALSE;
294}
295
296void newstruct_setup(const char *n, newstruct_desc d )
297{
298  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
299  // all undefined entries will be set to default in setBlackboxStuff
300  // the default Print is quite usefule,
301  // all other are simply error messages
302  b->blackbox_destroy=newstruct_destroy;
303  b->blackbox_String=newstruct_String;
304  //b->blackbox_Print=blackbox_default_Print;
305  b->blackbox_Init=newstruct_Init;
306  b->blackbox_Copy=newstruct_Copy;
307  b->blackbox_Assign=newstruct_Assign;
308  //b->blackbox_Op1=blackboxDefaultOp1;
309  b->blackbox_Op2=newstruct_Op2;
310  //b->blackbox_Op3=blackbox_default_Op3;
311  b->blackbox_OpM=newstruct_OpM;
312  b->blackbox_Check=newstruct_Check;
313  b->data=d;
314  b->properties=1; // list_like
315  int rt=setBlackboxStuff(b,n);
316  d->id=rt;
317  //Print("create type %d (%s)\n",rt,n);
318}
319
320static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
321{
322  char *ss=omStrDup(s);
323  char *p=ss;
324  char *start;
325  int t;
326  char c;
327  newstruct_member elem;
328
329  idhdl save_ring=currRingHdl;
330  currRingHdl=(idhdl)1; // fake ring detection
331  loop
332  {
333    // read type:
334    while (*p==' ') p++;
335    start=p;
336    while (isalpha(*p)) p++;
337    *p='\0';
338    IsCmd(start,t);
339    if (t==0)
340    {
341      Werror("unknown type `%s`",start);
342      omFree(ss);
343      omFree(res);
344      currRingHdl=save_ring;
345      return NULL;
346    }
347    if (RingDependend(t))
348      res->size++;    // one additional field for the ring (before the data)
349    //Print("found type %s at real-pos %d",start,res->size);
350    elem=(newstruct_member)omAlloc0(sizeof(*elem));
351    // read name:
352    p++;
353    while (*p==' ') p++;
354    start=p;
355    while (isalpha(*p)) p++;
356    c=*p;
357    *p='\0';
358    elem->typ=t;
359    elem->pos=res->size;
360    if (*start=='\0') /*empty name*/
361    {
362      WerrorS("empty name for element");
363      goto error_in_newstruct_def;
364    }
365    elem->name=omStrDup(start);
366    //Print(" name:%s\n",start);
367    elem->next=res->member;
368    res->member=elem;
369    res->size++;
370
371    // next ?
372    *p=c;
373    while (*p==' ') p++;
374    if (*p!=',') break;
375    if (*p!='\0')
376    {
377      Werror("unknown character in newstruct:>>%s<<",p);
378      goto error_in_newstruct_def;
379    }
380    p++;
381  }
382  omFree(ss);
383  currRingHdl=save_ring;
384  //Print("new type with %d elements\n",res->size);
385  return res;
386error_in_newstruct_def:
387   omFree(elem);
388   omFree(ss);
389   omFree(res);
390   currRingHdl=save_ring;
391   return NULL;
392}
393newstruct_desc newstructFromString(const char *s)
394{
395  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
396  res->size=0;
397
398  return scanNewstructFromString(s,res);
399}
400newstruct_desc newstructChildFromString(const char *parent, const char *s)
401{
402  // find parent:
403  int parent_id=0;
404  blackboxIsCmd(parent,parent_id);
405  if (parent_id<MAX_TOK)
406  {
407    Werror(">>%s< not found",parent);
408    return NULL;
409  }
410  blackbox *parent_bb=getBlackboxStuff(parent_id);
411  // check for the correct type:
412  if (parent_bb->blackbox_destroy!=newstruct_destroy)
413  {
414    Werror(">>%s< is not a user defined type",parent);
415    return NULL;
416  }
417  // setup for scanNewstructFromString:
418  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
419  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
420  res->size=parent_desc->size;
421  res->member=parent_desc->member;
422  res->parent=parent_desc;
423
424  return scanNewstructFromString(s,res);
425}
Note: See TracBrowser for help on using the repository browser.