source: git/Singular/newstruct.cc @ d770e6

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