source: git/Singular/newstruct.cc @ f24b9c

spielwiese
Last change on this file since f24b9c was 97c955, checked in by Hans Schoenemann <hannes@…>, 10 years ago
fix: ring dep. stuff in newstruct: send/receive via links (ssi:6) from master
  • Property mode set to 100644
File size: 20.5 KB
Line 
1#include <ctype.h>
2
3#ifdef HAVE_CONFIG_H
4#include "singularconfig.h"
5#endif /* HAVE_CONFIG_H */
6#include <kernel/mod2.h>
7#include <Singular/ipid.h>
8#include <Singular/blackbox.h>
9#include <Singular/lists.h>
10#include <Singular/ipid.h>
11#include <Singular/ipshell.h>
12#include <Singular/newstruct.h>
13
14struct newstruct_member_s;
15typedef struct newstruct_member_s *newstruct_member;
16struct  newstruct_member_s
17{
18  newstruct_member next;
19  char *         name;
20  int            typ;
21  int            pos;
22};
23
24struct newstruct_proc_s;
25typedef struct newstruct_proc_a *newstruct_proc;
26struct  newstruct_proc_a
27{
28  newstruct_proc next;
29  int            t; /*tok id */
30  int            args; /* number of args */
31  procinfov      p;
32};
33
34struct newstruct_desc_s
35{
36  newstruct_member member;
37  newstruct_desc   parent;
38  newstruct_proc   procs;
39  int            size; // number of mebers +1
40  int            id;   // the type id assigned to this bb
41};
42
43int newstruct_desc_size()
44{
45  return sizeof(newstruct_desc_s);
46}
47
48char * newstruct_String(blackbox *b, void *d)
49{
50  if (d==NULL) return omStrDup("oo");
51  else
52  {
53    newstruct_desc ad=(newstruct_desc)(b->data);
54
55    newstruct_proc p=ad->procs;
56    while((p!=NULL)&&(p->t!=STRING_CMD))
57      p=p->next;
58
59    if (p!=NULL)
60    {
61      BOOLEAN sl;
62      sleftv tmp;
63      memset(&tmp,0,sizeof(tmp));
64      tmp.rtyp=ad->id;
65      void * newstruct_Copy(blackbox*, void *); //forward declaration
66      tmp.data=(void*)newstruct_Copy(b,d);
67      idrec hh;
68      memset(&hh,0,sizeof(hh));
69      hh.id=Tok2Cmdname(p->t);
70      hh.typ=PROC_CMD;
71      hh.data.pinf=p->p;
72      sl=iiMake_proc(&hh,NULL,&tmp);
73
74      if ((!sl)&& (iiRETURNEXPR.Typ() == STRING_CMD))
75      {
76        char *res = omStrDup((char*)iiRETURNEXPR.CopyD());
77        iiRETURNEXPR.CleanUp();
78        iiRETURNEXPR.Init();
79        return res;
80      }
81      iiRETURNEXPR.CleanUp();
82      iiRETURNEXPR.Init();
83    }
84
85    lists l=(lists)d;
86    newstruct_member a=ad->member;
87    StringSetS("");
88    loop
89    {
90      StringAppendS(a->name);
91      StringAppendS("=");
92      if ((!RingDependend(a->typ))
93      || ((l->m[a->pos-1].data==(void *)currRing)
94         && (currRing!=NULL)))
95      {
96        if (l->m[a->pos].rtyp==LIST_CMD)
97        {
98          StringAppendS("<list>");
99        }
100        else
101        {
102          char *tmp2=omStrDup(l->m[a->pos].String());
103          if ((strlen(tmp2)>80)||(strchr(tmp2,'\n')!=NULL))
104          {
105            StringAppendS("<");
106            StringAppendS(Tok2Cmdname(l->m[a->pos].rtyp));
107            StringAppendS(">");
108          }
109          else StringAppendS(tmp2);
110          omFree(tmp2);
111        }
112      }
113      else StringAppendS("??");
114      if (a->next==NULL) break;
115      StringAppendS("\n");
116      if(errorreported) break;
117      a=a->next;
118    }
119    return StringEndS();
120  }
121}
122lists lCopy_newstruct(lists L)
123{
124  lists N=(lists)omAlloc0Bin(slists_bin);
125  int n=L->nr;
126  ring save_ring=currRing;
127  N->Init(n+1);
128  for(;n>=0;n--)
129  {
130    if (RingDependend(L->m[n].rtyp)
131    ||((L->m[n].rtyp==LIST_CMD)&&lRingDependend((lists)L->m[n].data)))
132    {
133      assume((L->m[n-1].rtyp==RING_CMD) || (L->m[n-1].data==NULL));
134      if(L->m[n-1].data!=NULL)
135      {
136        if (L->m[n-1].data!=(void*)currRing)
137          rChangeCurrRing((ring)(L->m[n-1].data));
138        N->m[n].Copy(&L->m[n]);
139      }
140      else
141      {
142        N->m[n].rtyp=L->m[n].rtyp;
143        N->m[n].data=idrecDataInit(L->m[n].rtyp);
144      }
145    }
146    else if(L->m[n].rtyp==LIST_CMD)
147    {
148      N->m[n].rtyp=L->m[n].rtyp;
149      N->m[n].data=(void *)lCopy((lists)(L->m[n].data));
150    }
151    else if(L->m[n].rtyp>MAX_TOK)
152    {
153      N->m[n].rtyp=L->m[n].rtyp;
154      blackbox *b=getBlackboxStuff(N->m[n].rtyp);
155      N->m[n].data=(void *)b->blackbox_Copy(b,L->m[n].data);
156    }
157    else
158      N->m[n].Copy(&L->m[n]);
159  }
160  if (currRing!=save_ring) rChangeCurrRing(save_ring);
161  return N;
162}
163void * newstruct_Copy(blackbox*, void *d)
164{
165  lists n1=(lists)d;
166  return (void*)lCopy_newstruct(n1);
167}
168
169// Used by newstruct_Assign for overloaded '='
170BOOLEAN newstruct_equal(int op, leftv l, leftv r)
171{
172  blackbox *ll=getBlackboxStuff(op);
173  assume(ll->data != NULL);
174  newstruct_desc nt=(newstruct_desc)ll->data;
175  newstruct_proc p=nt->procs;
176
177  while( (p!=NULL) && ((p->t!='=')||(p->args!=1)) ) p=p->next;
178
179  if (p!=NULL)
180  {
181    BOOLEAN sl;
182    idrec hh;
183    memset(&hh,0,sizeof(hh));
184    hh.id=Tok2Cmdname(p->t);
185    hh.typ=PROC_CMD;
186    hh.data.pinf=p->p;
187    sleftv tmp;
188    memset(&tmp,0,sizeof(sleftv));
189    tmp.Copy(r);
190    sl = iiMake_proc(&hh, NULL, &tmp);
191    if (!sl)
192    {
193      if (iiRETURNEXPR.Typ() == op)
194      {
195        l->Copy(&iiRETURNEXPR);
196        iiRETURNEXPR.Init();
197        return FALSE;
198      }
199      iiRETURNEXPR.CleanUp();
200      iiRETURNEXPR.Init();
201    }
202  }
203  return TRUE;
204}
205
206void lClean_newstruct(lists l)
207{
208  if (l->nr>=0)
209  {
210    int i;
211    ring r=NULL;
212    for(i=l->nr;i>=0;i--)
213    {
214      if ((i>0) && (l->m[i-1].rtyp==RING_CMD))
215        r=(ring)(l->m[i-1].data);
216      else
217        r=NULL;
218      l->m[i].CleanUp(r);
219    }
220    omFreeSize((ADDRESS)l->m, (l->nr+1)*sizeof(sleftv));
221    l->nr=-1;
222  }
223  omFreeBin((ADDRESS)l,slists_bin);
224}
225
226BOOLEAN newstruct_Assign(leftv l, leftv r)
227{
228  if (r->Typ()>MAX_TOK)
229  {
230    blackbox *rr=getBlackboxStuff(r->Typ());
231    if (l->Typ()!=r->Typ())
232    {
233      newstruct_desc rrn=(newstruct_desc)rr->data;
234
235      if (!rrn)
236      {
237        Werror("custom type %s(%d) cannot be assigned to newstruct %s(%d)",
238               Tok2Cmdname(r->Typ()), r->Typ(), Tok2Cmdname(l->Typ()), l->Typ());
239        return TRUE;
240      }
241
242      newstruct_desc rrp=rrn->parent;
243      while ((rrp!=NULL)&&(rrp->id!=l->Typ())) rrp=rrp->parent;
244      if (rrp!=NULL)
245      {
246        if (l->rtyp==IDHDL)
247        {
248          IDTYP((idhdl)l->data)=r->Typ();
249        }
250        else
251        {
252          l->rtyp=r->Typ();
253        }
254      }
255      else                      // unrelated types - look for custom conversion
256      {
257        sleftv tmp;
258        BOOLEAN newstruct_Op1(int, leftv, leftv);  // forward declaration
259        if (! newstruct_Op1(l->Typ(), &tmp, r))  return newstruct_Assign(l, &tmp);
260      }
261    }
262    if (l->Typ()==r->Typ())
263    {
264      if (l->Data()!=NULL)
265      {
266        lists n1=(lists)l->Data();
267        lClean_newstruct(n1);
268      }
269      lists n2=(lists)r->Data();
270      n2=lCopy_newstruct(n2);
271      if (l->rtyp==IDHDL)
272      {
273        IDDATA((idhdl)l->data)=(char *)n2;
274      }
275      else
276      {
277        l->data=(void *)n2;
278      }
279      return FALSE;
280    }
281  }
282  else
283  {
284    assume(l->Typ() > MAX_TOK);
285    sleftv tmp;
286    if(!newstruct_equal(l->Typ(), &tmp, r)) return newstruct_Assign(l, &tmp);
287  }
288  Werror("assign %s(%d) = %s(%d)",
289        Tok2Cmdname(l->Typ()),l->Typ(),Tok2Cmdname(r->Typ()),r->Typ());
290  return TRUE;
291}
292
293BOOLEAN newstruct_Op1(int op, leftv res, leftv arg)
294{
295  // interpreter: arg is newstruct
296  blackbox *a=getBlackboxStuff(arg->Typ());
297  newstruct_desc nt=(newstruct_desc)a->data;
298  newstruct_proc p=nt->procs;
299
300  while((p!=NULL) &&( (p->t!=op) || (p->args!=1) )) p=p->next;
301
302  if (p!=NULL)
303  {
304    BOOLEAN sl;
305    sleftv tmp;
306    memset(&tmp,0,sizeof(sleftv));
307    tmp.Copy(arg);
308    idrec hh;
309    memset(&hh,0,sizeof(hh));
310    hh.id=Tok2Cmdname(p->t);
311    hh.typ=PROC_CMD;
312    hh.data.pinf=p->p;
313    sl=iiMake_proc(&hh,NULL,&tmp);
314    if (sl) return TRUE;
315    else
316    {
317      res->Copy(&iiRETURNEXPR);
318      iiRETURNEXPR.Init();
319      return FALSE;
320    }
321  }
322  return blackboxDefaultOp1(op,res,arg);
323}
324
325
326
327BOOLEAN newstruct_Op2(int op, leftv res, leftv a1, leftv a2)
328{
329  // interpreter: a1 or a2 is newstruct
330  blackbox *a=getBlackboxStuff(a1->Typ());
331  newstruct_desc nt;
332  lists al=(lists)a1->Data();
333  if (a!=NULL)
334  {
335    nt=(newstruct_desc)a->data;
336    switch(op)
337    {
338      case '.':
339      {
340        if (a2->name!=NULL)
341        {
342          BOOLEAN search_ring=FALSE;
343          newstruct_member nm=nt->member;
344          while ((nm!=NULL)&&(strcmp(nm->name,a2->name)!=0)) nm=nm->next;
345          if ((nm==NULL) && (strncmp(a2->name,"r_",2)==0))
346          {
347            nm=nt->member;
348            while ((nm!=NULL)&&(strcmp(nm->name,a2->name+2)!=0)) nm=nm->next;
349            if ((nm!=NULL)&&(RingDependend(nm->typ)))
350              search_ring=TRUE;
351            else
352              nm=NULL;
353          }
354          if (nm==NULL)
355          {
356            Werror("member %s not found", a2->name);
357            return TRUE;
358          }
359          if (search_ring)
360          {
361            ring r;
362            res->rtyp=RING_CMD;
363            res->data=al->m[nm->pos-1].data;
364            r=(ring)res->data;
365            if (r==NULL) { res->data=(void *)currRing; r=currRing; }
366            if (r!=NULL) r->ref++;
367            else Werror("ring of this member is not set and no basering found");
368            return r==NULL;
369          }
370          else if (RingDependend(nm->typ)
371          || (al->m[nm->pos].RingDependend()))
372          {
373            if (al->m[nm->pos].data==NULL)
374            {
375              // NULL belongs to any ring
376              ring r=(ring)al->m[nm->pos-1].data;
377              if (r!=NULL)
378              {
379                r->ref--;
380                al->m[nm->pos-1].data=NULL;
381                al->m[nm->pos-1].rtyp=DEF_CMD;
382              }
383            }
384            else
385            {
386              //Print("checking ring at pos %d for dat at pos %d\n",nm->pos-1,nm->pos);
387              if ((al->m[nm->pos-1].data!=(void *)currRing)
388              &&(al->m[nm->pos-1].data!=(void*)0L))
389              {
390                Werror("different ring %lx(data) - %lx(basering)",
391                  (long unsigned)(al->m[nm->pos-1].data),(long unsigned)currRing);
392                return TRUE;
393              }
394            }
395            if ((currRing!=NULL)&&(al->m[nm->pos-1].data==NULL))
396            {
397              // remember the ring, if not already set
398              al->m[nm->pos-1].data=(void *)currRing;
399              al->m[nm->pos-1].rtyp=RING_CMD;
400              currRing->ref++;
401            }
402          }
403          else if ((nm->typ==DEF_CMD)||(nm->typ==LIST_CMD))
404          {
405            if (al->m[nm->pos-1].data==NULL)
406            {
407              al->m[nm->pos-1].data=(void*)currRing;
408              if (currRing!=NULL) currRing->ref++;
409            }
410          }
411          Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
412          r->start = nm->pos+1;
413          memcpy(res,a1,sizeof(sleftv));
414          memset(a1,0,sizeof(sleftv));
415          if (res->e==NULL) res->e=r;
416          else
417          {
418            Subexpr sh=res->e;
419            while (sh->next != NULL) sh=sh->next;
420            sh->next=r;
421          }
422          return FALSE;
423        }
424        else
425        {
426          WerrorS("name expected");
427          return TRUE;
428        }
429      }
430    }
431  }
432  else
433  {
434    a=getBlackboxStuff(a2->Typ());
435    nt=(newstruct_desc)a->data;
436    al=(lists)a2->Data();
437  }
438  newstruct_proc p=nt->procs;
439  while((p!=NULL) && ( (p->t!=op) || (p->args!=2) )) p=p->next;
440  if (p!=NULL)
441  {
442    BOOLEAN sl;
443    sleftv tmp;
444    memset(&tmp,0,sizeof(sleftv));
445    tmp.Copy(a1);
446    tmp.next=(leftv)omAlloc0(sizeof(sleftv));
447    tmp.next->Copy(a2);
448    idrec hh;
449    memset(&hh,0,sizeof(hh));
450    hh.id=Tok2Cmdname(p->t);
451    hh.typ=PROC_CMD;
452    hh.data.pinf=p->p;
453    sl=iiMake_proc(&hh,NULL,&tmp);
454    if (sl) return TRUE;
455    else
456    {
457      res->Copy(&iiRETURNEXPR);
458      iiRETURNEXPR.Init();
459      return FALSE;
460    }
461  }
462  return blackboxDefaultOp2(op,res,a1,a2);
463}
464
465// BOOLEAN opM(int op, leftv res, leftv args)
466BOOLEAN newstruct_OpM(int op, leftv res, leftv args)
467{
468  // interpreter: args->1. arg is newstruct
469  blackbox *a=getBlackboxStuff(args->Typ());
470  newstruct_desc nt=(newstruct_desc)a->data;
471  switch(op)
472  {
473    case STRING_CMD:
474    {
475      res->data=(void *)a->blackbox_String(a,args->Data());
476      res->rtyp=STRING_CMD;
477      return FALSE;
478    }
479    default:
480      break;
481  }
482  newstruct_proc p=nt->procs;
483
484  while((p!=NULL) &&( (p->t!=op) || (p->args!=4) )) p=p->next;
485
486  if (p!=NULL)
487  {
488    BOOLEAN sl;
489    sleftv tmp;
490    memset(&tmp,0,sizeof(sleftv));
491    tmp.Copy(args);
492    idrec hh;
493    memset(&hh,0,sizeof(hh));
494    hh.id=Tok2Cmdname(p->t);
495    hh.typ=PROC_CMD;
496    hh.data.pinf=p->p;
497    sl=iiMake_proc(&hh,NULL,&tmp);
498    if (sl) return TRUE;
499    else
500    {
501      res->Copy(&iiRETURNEXPR);
502      iiRETURNEXPR.Init();
503      return FALSE;
504    }
505  }
506  return blackbox_default_OpM(op,res,args);
507}
508
509void newstruct_destroy(blackbox */*b*/, void *d)
510{
511  if (d!=NULL)
512  {
513    lists n=(lists)d;
514    lClean_newstruct(n);
515  }
516}
517
518void *newstruct_Init(blackbox *b)
519{
520  newstruct_desc n=(newstruct_desc)b->data;
521  lists l=(lists)omAlloc0Bin(slists_bin);
522  l->Init(n->size);
523  newstruct_member nm=n->member;
524  while (nm!=NULL)
525  {
526    l->m[nm->pos].rtyp=nm->typ;
527    if (RingDependend(nm->typ) ||(nm->typ==DEF_CMD)||(nm->typ==LIST_CMD))
528      l->m[nm->pos-1].rtyp=RING_CMD;
529    l->m[nm->pos].data=idrecDataInit(nm->typ);
530    nm=nm->next;
531  }
532  return l;
533}
534
535BOOLEAN newstruct_CheckAssign(blackbox */*b*/, leftv L, leftv R)
536{
537  int lt=L->Typ();
538  int rt=R->Typ();
539  if ((lt!=DEF_CMD)&&(lt!=rt))
540  {
541    Werror("can not assign %s(%d) to member of type %s(%d)",
542            Tok2Cmdname(rt),rt,
543            Tok2Cmdname(lt),lt);
544    return TRUE;
545  }
546  return FALSE;
547}
548
549/* check internal structure:
550* BOOLEAN newstruct_Check(blackbox *b, void *d)
551{
552  newstruct_desc n=(newstruct_desc)b->data;
553  lists l=(lists)d;
554  newstruct_member nm=n->member;
555  while (nm!=NULL)
556  {
557    if ((l->m[nm->pos].rtyp!=nm->typ)
558    &&( nm->typ!=DEF_CMD))
559    {
560      Werror("type change in member %s (%s(%d) -> %s(%d))",nm->name,
561          Tok2Cmdname(nm->typ),nm->typ,
562          Tok2Cmdname(l->m[nm->pos].rtyp),l->m[nm->pos].rtyp);
563      return TRUE;
564    }
565    nm=nm->next;
566  }
567  return FALSE;
568}
569*/
570
571BOOLEAN newstruct_serialize(blackbox *b, void *d, si_link f)
572{
573  newstruct_desc dd=(newstruct_desc)b->data;
574  sleftv l;
575  memset(&l,0,sizeof(l));
576  l.rtyp=STRING_CMD;
577  l.data=(void*)getBlackboxName(dd->id);
578  f->m->Write(f, &l);
579  lists ll=(lists)d;
580  int Ll=lSize(ll);
581  l.rtyp=INT_CMD;
582  l.data=(void*)(long)Ll;
583  f->m->Write(f, &l);
584  // set all entries corresponding to "real" mebers to 1 in rings
585  char *rings=(char*)omAlloc0(Ll+1);
586  newstruct_member elem=dd->member;
587  while (elem!=NULL)
588  {
589    rings[elem->pos]='\1';
590    elem=elem->next;
591  }
592  int i;
593  BOOLEAN ring_changed=FALSE;
594  ring save_ring=currRing;
595  for(i=0;i<=Ll;i++)
596  {
597    if (rings[i]=='\0') // ring entry for pos i+1
598    {
599      if (ll->m[i].data!=NULL)
600      {
601        ring_changed=TRUE;
602        f->m->SetRing(f,(ring)ll->m[i].data,TRUE);
603      }
604    }
605    f->m->Write(f,&(ll->m[i]));
606  }
607  if (ring_changed)
608    f->m->SetRing(f,save_ring,FALSE);
609}
610
611BOOLEAN newstruct_deserialize(blackbox **b, void **d, si_link f)
612{
613  // newstruct is serialiazed as analog to a list,
614  // just read a list and take data,
615  // rtyp must be set correctly (to the blackbox id) by routine calling
616  // newstruct_deserialize
617  leftv l=f->m->Read(f); // int: length of list
618  int Ll=(int)(long)(l->data);
619  omFree(l);
620  lists L=(lists)omAllocBin(slists_bin);
621  L->Init(Ll+1);
622  for(int i=0;i<=Ll;i++)
623  {
624    l=f->m->Read(f);
625    memcpy(&(L->m[i]),l,sizeof(sleftv));
626    omFree(l);
627  }
628  //newstruct_desc n=(newstruct_desc)b->data;
629  //TODO: check compatibility of list l->data with description in n
630  *d=L;
631  return FALSE;
632}
633
634void newstruct_Print(blackbox *b,void *d)
635{
636  newstruct_desc dd=(newstruct_desc)b->data;
637  newstruct_proc p=dd->procs;
638  while((p!=NULL)&&(p->t!=PRINT_CMD))
639    p=p->next;
640  if (p!=NULL)
641  {
642    BOOLEAN sl;
643    sleftv tmp;
644    memset(&tmp,0,sizeof(tmp));
645    tmp.rtyp=dd->id;
646    tmp.data=(void*)newstruct_Copy(b,d);
647    idrec hh;
648    memset(&hh,0,sizeof(hh));
649    hh.id=Tok2Cmdname(p->t);
650    hh.typ=PROC_CMD;
651    hh.data.pinf=p->p;
652    sl=iiMake_proc(&hh,NULL,&tmp);
653    if (!sl)
654    {
655      if (iiRETURNEXPR.Typ()!=NONE) Warn("ignoring return value (%s)",Tok2Cmdname(iiRETURNEXPR.Typ()));
656      iiRETURNEXPR.CleanUp();
657    }
658    iiRETURNEXPR.Init();
659  }
660  else
661    blackbox_default_Print(b,d);
662}
663void newstruct_setup(const char *n, newstruct_desc d )
664{
665  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
666  // all undefined entries will be set to default in setBlackboxStuff
667  // the default Print is quite useful,
668  // all other are simply error messages
669  b->blackbox_destroy=newstruct_destroy;
670  b->blackbox_String=newstruct_String;
671  b->blackbox_Print=newstruct_Print;//blackbox_default_Print;
672  b->blackbox_Init=newstruct_Init;
673  b->blackbox_Copy=newstruct_Copy;
674  b->blackbox_Assign=newstruct_Assign;
675  b->blackbox_Op1=newstruct_Op1;
676  b->blackbox_Op2=newstruct_Op2;
677  //b->blackbox_Op3=blackbox_default_Op3;
678  b->blackbox_OpM=newstruct_OpM;
679  b->blackbox_CheckAssign=newstruct_CheckAssign;
680  b->blackbox_serialize=newstruct_serialize;
681  b->blackbox_deserialize=newstruct_deserialize;
682  b->data=d;
683  b->properties=1; // list_like
684  int rt=setBlackboxStuff(b,n);
685  d->id=rt;
686  //Print("create type %d (%s)\n",rt,n);
687}
688
689static newstruct_desc scanNewstructFromString(const char *s, newstruct_desc res)
690{
691  char *ss=omStrDup(s);
692  char *p=ss;
693  char *start;
694  int t;
695  char c;
696  newstruct_member elem;
697
698  idhdl save_ring=currRingHdl;
699  currRingHdl=(idhdl)1; // fake ring detection
700  loop
701  {
702    // read type:
703    while (*p==' ') p++;
704    start=p;
705    while (isalpha(*p)) p++;
706    *p='\0';
707    IsCmd(start,t);
708    if (t==0)
709    {
710      Werror("unknown type `%s`",start);
711      omFree(ss);
712      omFree(res);
713      currRingHdl=save_ring;
714      return NULL;
715    }
716    if (RingDependend(t) || (t==DEF_CMD)||(t==LIST_CMD))
717      res->size++;    // one additional field for the ring (before the data)
718    //Print("found type %s at real-pos %d",start,res->size);
719    elem=(newstruct_member)omAlloc0(sizeof(*elem));
720    // read name:
721    p++;
722    while (*p==' ') p++;
723    start=p;
724    while (isalpha(*p)) p++;
725    c=*p;
726    *p='\0';
727    elem->typ=t;
728    elem->pos=res->size;
729    if (*start=='\0') /*empty name*/
730    {
731      WerrorS("empty name for element");
732      goto error_in_newstruct_def;
733    }
734    elem->name=omStrDup(start);
735    //Print(" name:%s\n",start);
736    elem->next=res->member;
737    res->member=elem;
738    res->size++;
739
740    // next ?
741    *p=c;
742    while (*p==' ') p++;
743    if (*p!=',')
744    {
745      if (*p!='\0')
746      {
747        Werror("unknown character in newstruct:>>%s<<",p);
748        goto error_in_newstruct_def;
749      }
750      break; // end-of-list
751    }
752    p++;
753  }
754  omFree(ss);
755  currRingHdl=save_ring;
756  //Print("new type with %d elements\n",res->size);
757  //newstructShow(res);
758  return res;
759error_in_newstruct_def:
760   omFree(elem);
761   omFree(ss);
762   omFree(res);
763   currRingHdl=save_ring;
764   return NULL;
765}
766newstruct_desc newstructFromString(const char *s)
767{
768  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
769  res->size=0;
770
771  return scanNewstructFromString(s,res);
772}
773newstruct_desc newstructChildFromString(const char *parent, const char *s)
774{
775  // find parent:
776  int parent_id=0;
777  blackboxIsCmd(parent,parent_id);
778  if (parent_id<MAX_TOK)
779  {
780    Werror(">>%s< not found",parent);
781    return NULL;
782  }
783  blackbox *parent_bb=getBlackboxStuff(parent_id);
784  // check for the correct type:
785  if (parent_bb->blackbox_destroy!=newstruct_destroy)
786  {
787    Werror(">>%s< is not a user defined type",parent);
788    return NULL;
789  }
790  // setup for scanNewstructFromString:
791  newstruct_desc res=(newstruct_desc)omAlloc0(sizeof(*res));
792  newstruct_desc parent_desc=(newstruct_desc)parent_bb->data;
793  res->size=parent_desc->size;
794  res->member=parent_desc->member;
795  res->parent=parent_desc;
796
797  return scanNewstructFromString(s,res);
798}
799
800void newstructShow(newstruct_desc d)
801{
802  newstruct_member elem;
803  Print("id: %d\n",d->id);
804  elem=d->member;
805  while (elem!=NULL)
806  {
807    Print(">>%s<< at pos %d, type %d (%s)\n",elem->name,elem->pos,elem->typ,Tok2Cmdname(elem->typ));
808    if (RingDependend(elem->typ)|| (elem->typ==DEF_CMD) ||(elem->typ==LIST_CMD))
809      Print(">>r_%s<< at pos %d, shadow ring\n",elem->name,elem->pos-1);
810    elem=elem->next;
811  }
812  newstruct_proc p=d->procs;
813  while (p!=NULL)
814  {
815    Print("op:%d(%s) with %d args -> %s\n",p->t,iiTwoOps(p->t),p->args,p->p->procname);
816    p=p->next;
817  }
818}
819
820BOOLEAN newstruct_set_proc(const char *bbname,const char *func, int args,procinfov pr)
821{
822  int id=0;
823  blackboxIsCmd(bbname,id);
824  if (id<MAX_TOK)
825  {
826    Werror(">>%s<< is not a newstruct type",bbname);
827    return TRUE;
828  }
829  blackbox *bb=getBlackboxStuff(id);
830  newstruct_desc desc=(newstruct_desc)bb->data;
831  newstruct_proc p=(newstruct_proc)omAlloc(sizeof(*p));
832  p->next=desc->procs; desc->procs=p;
833
834  idhdl save_ring=currRingHdl;
835  currRingHdl=(idhdl)1; // fake ring detection
836
837  if(!IsCmd(func,p->t))
838  {
839    int t=0;
840    if (func[1]=='\0') p->t=func[0];
841    else if((t=iiOpsTwoChar(func))!=0)
842    {
843      p->t=t;
844    }
845    else
846    {
847      Werror(">>%s<< is not a kernel command",func);
848      currRingHdl = save_ring;
849      return TRUE;
850    }
851  }
852  p->args=args;
853  p->p=pr; pr->ref++;
854  currRingHdl = save_ring;
855  return FALSE;
856}
Note: See TracBrowser for help on using the repository browser.