source: git/Singular/subexpr.cc @ b9e18a3

spielwiese
Last change on this file since b9e18a3 was b9e18a3, checked in by Hans Schönemann <hannes@…>, 14 years ago
tr 223 and off-by-1 in ring construction git-svn-id: file:///usr/local/Singular/svn/trunk@12743 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 36.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: handling of leftv
6*/
7/* $Id$ */
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <ctype.h>
13#include <unistd.h>
14
15#include "mod2.h"
16#include "intvec.h"
17#include "tok.h"
18#include "options.h"
19#include "ipid.h"
20#include "intvec.h"
21#include <omalloc.h>
22#include "febase.h"
23#include "polys.h"
24#include "ideals.h"
25#include "maps.h"
26#include "matpol.h"
27#include "kstd1.h"
28#include "timer.h"
29#include "ring.h"
30#include "ffields.h"
31#include "numbers.h"
32#include "longrat.h"
33#include "ipshell.h"
34#include "lists.h"
35#include "attrib.h"
36#include "silink.h"
37#include "syz.h"
38#include "attrib.h"
39#include "subexpr.h"
40
41
42omBin sSubexpr_bin = omGetSpecBin(sizeof(sSubexpr));
43omBin sleftv_bin = omGetSpecBin(sizeof(sleftv));
44omBin procinfo_bin = omGetSpecBin(sizeof(procinfo));
45omBin libstack_bin = omGetSpecBin(sizeof(libstack));
46static omBin size_two_bin = omGetSpecBin(2);
47
48sleftv     sLastPrinted;
49const char sNoName[]="_";
50#ifdef SIQ
51BOOLEAN siq=FALSE;
52#endif
53
54int sleftv::listLength()
55{
56  int n = 1;
57  leftv sl = next;
58  while (sl!=NULL)
59  {
60    n++;
61    sl=sl->next;
62  }
63  return n;
64}
65
66void sleftv::Print(leftv store, int spaces)
67{
68  int  t=Typ();
69  if (errorreported) return;
70#ifdef SIQ
71  if (rtyp==COMMAND)
72  {
73    command c=(command)data;
74    char ch[2];
75    ch[0]=c->op;ch[1]='\0';
76    const char *s=ch;
77    if (c->op>127) s=iiTwoOps(c->op);
78    ::Print("##command %d(%s), %d args\n",
79      c->op, s, c->argc);
80    if (c->argc>0)
81      c->arg1.Print(NULL,spaces+2);
82    if(c->argc<4)
83    {
84      if (c->argc>1)
85        c->arg2.Print(NULL,spaces+2);
86      if (c->argc>2)
87        c->arg3.Print(NULL,spaces+2);
88    }
89    PrintS("##end");
90  }
91  else
92#endif
93  {
94    const char *n=Name();
95    char *s;
96    void *d=Data();
97    if (errorreported)
98      return;
99    if ((store!=NULL)&&(store!=this))
100      store->CleanUp();
101
102    switch (t /*=Typ()*/)
103      {
104        case UNKNOWN:
105        case DEF_CMD:
106        case PACKAGE_CMD:
107          PrintNSpaces(spaces);
108          PrintS("`");PrintS(n);PrintS("`");
109          break;
110        case NONE:
111          return;
112        case INTVEC_CMD:
113        case INTMAT_CMD:
114          ((intvec *)d)->show(t,spaces);
115          break;
116        case RING_CMD:
117        case QRING_CMD:
118          PrintNSpaces(spaces);
119          rWrite((ring)d);
120          break;
121        case MATRIX_CMD:
122          iiWriteMatrix((matrix)d,n,2,spaces);
123          break;
124        case MODUL_CMD:
125        case IDEAL_CMD:
126          if ((TEST_V_QRING)  &&(currQuotient!=NULL))
127          {
128            jjNormalizeQRingId(this);
129            d=Data();
130          }
131          // no break:
132        case MAP_CMD:
133          iiWriteMatrix((matrix)d,n,1,spaces);
134          break;
135        case POLY_CMD:
136        case VECTOR_CMD:
137          if ((TEST_V_QRING)  &&(currQuotient!=NULL))
138          {
139            jjNormalizeQRingP(this);
140            d=Data();
141          }
142          PrintNSpaces(spaces);
143          pWrite0((poly)d);
144          break;
145        case RESOLUTION_CMD:
146          syPrint((syStrategy)d);
147          break;
148        case STRING_CMD:
149          PrintNSpaces(spaces);
150          PrintS((char *)d);
151          break;
152       case INT_CMD:
153          PrintNSpaces(spaces);
154          ::Print("%d",(int)(long)d);
155          break;
156       case PROC_CMD:
157         {
158           procinfov pi=(procinfov)d;
159
160           PrintNSpaces(spaces);
161           PrintS("// libname  : ");
162           PrintS(piProcinfo(pi, "libname"));
163           PrintLn();
164
165           PrintNSpaces(spaces);
166           PrintS("// procname : ");
167           PrintS(piProcinfo(pi, "procname"));
168           PrintLn();
169
170           PrintNSpaces(spaces);
171           PrintS("// type     : ");
172           PrintS(piProcinfo(pi, "type"));
173           //           ::Print("%-*.*s// ref      : %s",spaces,spaces," ",
174           //   piProcinfo(pi, "ref"));
175           break;
176         }
177       case POINTER_CMD:
178         { package pack = (package)d;
179         PrintNSpaces(spaces);
180         PrintS("// PointerTest\n");
181         PrintNSpaces(spaces);
182         ::Print("// %s\n",IDID(pack->idroot));
183         //::Print(((char *)(pack->idroot)->data), spaces);
184         break;
185         }
186       case LINK_CMD:
187          {
188            si_link l=(si_link)d;
189            PrintNSpaces(spaces);
190            ::Print("// type : %s\n", slStatus(l, "type"));
191            PrintNSpaces(spaces);
192            ::Print("// mode : %s\n", slStatus(l, "mode"));
193            PrintNSpaces(spaces);
194            ::Print("// name : %s\n", slStatus(l, "name"));
195            PrintNSpaces(spaces);
196            ::Print("// open : %s\n", slStatus(l, "open"));
197            PrintNSpaces(spaces);
198            ::Print("// read : %s\n", slStatus(l, "read"));
199            PrintNSpaces(spaces);
200            ::Print("// write: %s", slStatus(l, "write"));
201          break;
202          }
203        case NUMBER_CMD:
204        case BIGINT_CMD:
205          s=String(d);
206          if (s==NULL) return;
207          PrintNSpaces(spaces);
208          PrintS(s);
209          omFree((ADDRESS)s);
210          break;
211        case LIST_CMD:
212        {
213          lists l=(lists)d;
214          if (l->nr<0)
215          {
216             PrintNSpaces(spaces);
217             PrintS("empty list\n");
218          }
219          else
220          {
221            int i=0;
222            for (;i<=l->nr;i++)
223            {
224              if (l->m[i].rtyp!=DEF_CMD)
225              {
226                PrintNSpaces(spaces);
227                ::Print("[%d]:\n",i+1);
228                l->m[i].Print(NULL,spaces+3);
229              }
230            }
231          }
232          break;
233        }
234#ifdef TEST
235        default:
236          ::Print("Print:unknown type %s(%d)", Tok2Cmdname(t),t);
237#endif
238      } /* end switch: (Typ()) */
239  }
240  if (next!=NULL)
241  {
242    if (t==COMMAND) PrintLn();
243    else if (t!=LIST_CMD) PrintS(" ");
244    next->Print(NULL,spaces);
245  }
246  else if (t!=LIST_CMD)
247  {
248    PrintLn();
249  }
250#ifdef SIQ
251  if (rtyp!=COMMAND)
252#endif
253  {
254    if ((store!=NULL)
255    && (store!=this)
256    && (t/*Typ()*/!=LINK_CMD)
257    && (t/*Typ()*/!=RING_CMD)
258    && (t/*Typ()*/!=QRING_CMD)
259    && (t/*Typ()*/!=POINTER_CMD)
260    && (t/*Typ()*/!=PACKAGE_CMD)
261    && (t/*Typ()*/!=PROC_CMD)
262    && (t/*Typ()*/!=DEF_CMD)
263    )
264    {
265      store->rtyp=t/*Typ()*/;
266      store->data=CopyD();
267      if((e!=NULL)||(attribute!=NULL))
268      {
269        store->attribute=CopyA();
270      }
271      if (e==NULL)
272      {
273        store->flag=flag;
274      }
275      //else
276      //{
277      //}
278    }
279  }
280}
281
282void sleftv::CleanUp(ring r)
283{
284  if ((name!=NULL) && (name!=sNoName) && (rtyp!=IDHDL))
285  {
286    //::Print("free %x (%s)\n",name,name);
287    omFree((ADDRESS)name);
288  }
289  //name=NULL;
290  //flag=0;
291  if (data!=NULL)
292  {
293    switch (rtyp)
294    {
295      case INTVEC_CMD:
296      case INTMAT_CMD:
297        delete (intvec *)data;
298        break;
299      case MAP_CMD:
300        omFree((ADDRESS)((map)data)->preimage);
301        ((map)data)->preimage=NULL;
302        // no break: kill the image as an ideal
303      case MATRIX_CMD:
304      case MODUL_CMD:
305      case IDEAL_CMD:
306        if ((((long)data) & 3)==0)
307        {
308          if(r!=NULL) id_Delete((ideal *)(&data),r);
309        }
310        break;
311      case STRING_CMD:
312        omFree((ADDRESS)data);
313        break;
314      case POLY_CMD:
315      case VECTOR_CMD:
316        if (r!=NULL) p_Delete((poly *)(&data),r);
317        break;
318      case NUMBER_CMD:
319        if (r!=NULL) n_Delete((number *)(&data),r);
320        break;
321      case BIGINT_CMD:
322        nlDelete((number *)(&data),r);
323        break;
324      case LIST_CMD:
325        ((lists)data)->Clean(r); // may contain ring-dep data
326        break;
327      case QRING_CMD:
328      case RING_CMD:
329        rKill((ring)data);
330        break;
331      case PROC_CMD:
332        piKill((procinfov)data);
333        break;
334      case LINK_CMD:
335        slKill((si_link)data);
336        break;
337      case COMMAND:
338      {
339        command cmd=(command)data;
340        if (cmd->arg1.rtyp!=0) cmd->arg1.CleanUp();
341        if (cmd->arg2.rtyp!=0) cmd->arg2.CleanUp();
342        if (cmd->arg3.rtyp!=0) cmd->arg3.CleanUp();
343        omFreeBin((ADDRESS)data, sip_command_bin);
344        break;
345      }
346      case RESOLUTION_CMD:
347        if (r!=NULL) syKillComputation((syStrategy)data,r);
348        break;
349#ifdef TEST
350      // the following types do not take memory
351      // or are not copied
352      case IDHDL:
353      case PACKAGE_CMD:
354      case ANY_TYPE:
355      case VECHO:
356      case VPAGELENGTH:
357      case VPRINTLEVEL:
358      case VCOLMAX:
359      case VTIMER:
360#ifdef HAVE_RTIMER
361      case VRTIMER:
362#endif
363      case VOICE:
364      case VMAXDEG:
365      case VMAXMULT:
366      case TRACE:
367      case VSHORTOUT:
368      case VNOETHER:
369      case VMINPOLY:
370      case LIB_CMD:
371      case 0:
372      case INT_CMD:
373        break;
374      default:
375        ::Print("CleanUp: unknown type %d\n",rtyp);  /* DEBUG */
376#endif
377    } /* end switch: (rtyp) */
378    //data=NULL; // will be done by Init() at the end
379  }
380  if (attribute!=NULL)
381  {
382    switch (rtyp)
383    {
384      case POINTER_CMD:
385      case PACKAGE_CMD:
386      case IDHDL:
387      case ANY_TYPE:
388      case VECHO:
389      case VPAGELENGTH:
390      case VPRINTLEVEL:
391      case VCOLMAX:
392      case VTIMER:
393#ifdef HAVE_RTIMER
394      case VRTIMER:
395#endif
396      case VOICE:
397      case VMAXDEG:
398      case VMAXMULT:
399      case TRACE:
400      case VSHORTOUT:
401      case VNOETHER:
402      case VMINPOLY:
403      case LIB_CMD:
404      case 0:
405        //attribute=NULL; // will be done by Init() at the end
406        break;
407      default:
408      {
409        attr t;
410        while (attribute!=NULL)
411        {
412          t=attribute->next;
413          attribute->kill(currRing);
414          attribute=t;
415        }
416      }
417    }
418  }
419  Subexpr h;
420  while (e!=NULL)
421  {
422    h=e->next;
423    omFreeBin((ADDRESS)e, sSubexpr_bin);
424    e=h;
425  }
426  //rtyp=NONE; // will be done by Init() at the end
427  if (next!=NULL)
428  {
429    leftv tmp_n;
430    do
431    {
432      tmp_n=next->next;
433      //next->name=NULL;
434      next->next=NULL;
435      next->CleanUp(r);
436      omFreeBin((ADDRESS)next, sleftv_bin);
437      next=tmp_n;
438    } while (next!=NULL);
439  }
440  Init();
441}
442
443BOOLEAN sleftv::RingDependend()
444{
445  int rt=Typ();
446  if(::RingDependend(rt) && (rt!=QRING_CMD))
447    return TRUE;
448  if (rt==LIST_CMD)
449    return lRingDependend((lists)Data());
450  return FALSE;
451}
452
453static inline void * s_internalCopy(const int t,  void *d)
454{
455  switch (t)
456  {
457    case INTVEC_CMD:
458    case INTMAT_CMD:
459      return (void *)ivCopy((intvec *)d);
460    case MATRIX_CMD:
461      return (void *)mpCopy((matrix)d);
462    case IDEAL_CMD:
463    case MODUL_CMD:
464      return  (void *)idCopy((ideal)d);
465    case STRING_CMD:
466        return (void *)omStrDup((char *)d);
467    case POINTER_CMD:
468      return d;
469    case PACKAGE_CMD:
470      return  (void *)paCopy((package) d);
471    case PROC_CMD:
472      return  (void *)piCopy((procinfov) d);
473    case POLY_CMD:
474    case VECTOR_CMD:
475      return  (void *)pCopy((poly)d);
476    case INT_CMD:
477      return  d;
478    case NUMBER_CMD:
479      return  (void *)nCopy((number)d);
480    case BIGINT_CMD:
481      return  (void *)nlCopy((number)d);
482    case MAP_CMD:
483      return  (void *)maCopy((map)d);
484    case LIST_CMD:
485      return  (void *)lCopy((lists)d);
486    case LINK_CMD:
487      return (void *)slCopy((si_link) d);
488    case RING_CMD:
489    case QRING_CMD:
490      {
491        ring r=(ring)d;
492        r->ref++;
493        return d;
494      }
495    case RESOLUTION_CMD:
496      return (void*)syCopy((syStrategy)d);
497#ifdef TEST
498    case DEF_CMD:
499    case NONE:
500      break; /* error recovery: do nothing */
501    //case COMMAND:
502    default:
503      Warn("s_internalCopy: cannot copy type %s(%d)",
504            Tok2Cmdname(t),t);
505#endif
506  }
507  return NULL;
508}
509
510
511
512void * slInternalCopy(leftv source, const int t, void *d, Subexpr e)
513{
514  if (t==STRING_CMD)
515  {
516      if ((e==NULL)
517      || (source->rtyp==LIST_CMD)
518      || ((source->rtyp==IDHDL)&&(IDTYP((idhdl)source->data)==LIST_CMD)))
519        return (void *)omStrDup((char *)d);
520      else if (e->next==NULL)
521      {
522        char *s=(char*)omAllocBin(size_two_bin);
523        s[0]=*(char *)d;
524        s[1]='\0';
525        return s;
526      }
527      #ifdef TEST
528      else
529      {
530        Werror("not impl. string-op in `%s`",my_yylinebuf);
531        return NULL;
532      }
533      #endif
534  }
535  return s_internalCopy(t,d);
536}
537
538void sleftv::Copy(leftv source)
539{
540  Init();
541  rtyp=source->Typ();
542  void *d=source->Data();
543  if(!errorreported)
544  {
545    data=s_internalCopy(rtyp,d);
546    if ((source->attribute!=NULL)||(source->e!=NULL))
547      attribute=source->CopyA();
548    if(source->e==NULL)
549    {
550      flag=source->flag;
551    }
552    //else
553    //{
554    //}
555    if (source->next!=NULL)
556    {
557      next=(leftv)omAllocBin(sleftv_bin);
558      next->Copy(source->next);
559    }
560  }
561}
562
563void * sleftv::CopyD(int t)
564{
565  if ((rtyp!=IDHDL)&&(e==NULL))
566  {
567    if (iiCheckRing(t)) return NULL;
568    void *x=data;
569    if (rtyp==VNOETHER) x=(void *)pCopy(ppNoether);
570    else if (rtyp==LIB_CMD)
571      x=(void *)omStrDup((char *)Data());
572    else if ((rtyp==VMINPOLY)&& (currRing->minpoly!=NULL)&&(!rField_is_GF()))
573      x=(void *)nCopy(currRing->minpoly);
574    data=NULL;
575    return x;
576  }
577  void *d=Data(); // will also do a iiCheckRing
578  if ((!errorreported) && (d!=NULL)) return slInternalCopy(this,t,d,e);
579  return NULL;
580}
581
582//void * sleftv::CopyD()
583//{
584  //if ((rtyp!=IDHDL)&&(e==NULL)
585  //&&(rtyp!=VNOETHER)&&(rtyp!=LIB_CMD)&&(rtyp!=VMINPOLY))
586  //{
587  //  void *x=data;
588  //  data=NULL;
589  //  return x;
590  //}
591//  return CopyD(Typ());
592//}
593
594attr sleftv::CopyA()
595{
596  attr *a=Attribute();
597  if ((a!=NULL) && (*a!=NULL))
598    return (*a)->Copy();
599  return NULL;
600}
601
602char *  sleftv::String(void *d, BOOLEAN typed, int dim)
603{
604#ifdef SIQ
605  if (rtyp==COMMAND)
606  {
607    ::Print("##command %d\n",((command)data)->op);
608    if (((command)data)->arg1.rtyp!=0)
609      ((command)data)->arg1.Print(NULL,2);
610    if (((command)data)->arg2.rtyp!=0)
611      ((command)data)->arg2.Print(NULL,2);
612    if (((command)data)->arg3.rtyp==0)
613      ((command)data)->arg3.Print(NULL,2);
614    PrintS("##end\n");
615    return omStrDup("");
616  }
617#endif
618  if (d==NULL) d=Data();
619  if (!errorreported)
620  {
621    char *s;
622    const char *n;
623    if (name!=NULL) n=name;
624    else n=sNoName;
625    int t=Typ();
626    switch (t /*Typ()*/)
627    {
628        case INT_CMD:
629          if (typed)
630          {
631            s=(char *)omAlloc(MAX_INT_LEN+7);
632            sprintf(s,"int(%d)",(int)(long)d);
633          }
634          else
635          {
636            s=(char *)omAlloc(MAX_INT_LEN+2);
637            sprintf(s,"%d",(int)(long)d);
638          }
639          return s;
640
641        case STRING_CMD:
642          if (d == NULL)
643          {
644            if (typed) return omStrDup("\"\"");
645            return omStrDup("");
646          }
647          if (typed)
648          {
649            s = (char*) omAlloc(strlen((char*) d) + 3);
650            sprintf(s,"\"%s\"", (char*) d);
651            return s;
652          }
653          else
654          {
655            return omStrDup((char*)d);
656          }
657
658        case POLY_CMD:
659        case VECTOR_CMD:
660          if (typed)
661          {
662            char* ps = pString((poly) d);
663            s = (char*) omAlloc(strlen(ps) + 10);
664            sprintf(s,"%s(%s)", (t /*Typ()*/ == POLY_CMD ? "poly" : "vector"), ps);
665            return s;
666          }
667          else
668            return omStrDup(pString((poly)d));
669
670        case NUMBER_CMD:
671          StringSetS((char*) (typed ? "number(" : ""));
672          if ((rtyp==IDHDL)&&(IDTYP((idhdl)data)==NUMBER_CMD))
673          {
674            nWrite(IDNUMBER((idhdl)data));
675          }
676          else if (rtyp==NUMBER_CMD)
677          {
678            number n=(number)data;
679            nWrite(n);
680            data=(char *)n;
681          }
682          else if((rtyp==VMINPOLY)&&(rField_is_GF()))
683          {
684            nfShowMipo();
685          }
686          else
687          {
688            number n=nCopy((number)d);
689            nWrite(n);
690            nDelete(&n);
691          }
692          s = StringAppendS((char*) (typed ? ")" : ""));
693          return omStrDup(s);
694
695        case BIGINT_CMD:
696          {
697          StringSetS((char*) (typed ? "bigint(" : ""));
698          number nl=(number)d;
699          nlWrite(nl,NULL);
700          s = StringAppendS((char*) (typed ? ")" : ""));
701          return omStrDup(s);
702          }
703
704        case MATRIX_CMD:
705          s= iiStringMatrix((matrix)d,dim);
706          if (typed)
707          {
708            char* ns = (char*) omAlloc(strlen(s) + 40);
709            sprintf(ns, "matrix(ideal(%s),%d,%d)", s,
710                    ((ideal) d)->nrows, ((ideal) d)->ncols);
711            omCheckAddr(ns);
712            return ns;
713          }
714          else
715          {
716            return omStrDup(s);
717          }
718
719        case MODUL_CMD:
720        case IDEAL_CMD:
721        case MAP_CMD:
722          s= iiStringMatrix((matrix)d,dim);
723          if (typed)
724          {
725            char* ns = (char*) omAlloc(strlen(s) + 10);
726            sprintf(ns, "%s(%s)", (t/*Typ()*/==MODUL_CMD ? "module" : "ideal"), s);
727            omCheckAddr(ns);
728            return ns;
729          }
730          return omStrDup(s);
731
732        case INTVEC_CMD:
733        case INTMAT_CMD:
734        {
735          intvec *v=(intvec *)d;
736          s = v->String(dim);
737          if (typed)
738          {
739            char* ns;
740            if (t/*Typ()*/ == INTMAT_CMD)
741            {
742              ns = (char*) omAlloc(strlen(s) + 40);
743              sprintf(ns, "intmat(intvec(%s),%d,%d)", s, v->rows(), v->cols());
744            }
745            else
746            {
747              ns = (char*) omAlloc(strlen(s) + 10);
748              sprintf(ns, "intvec(%s)", s);
749            }
750            omCheckAddr(ns);
751            omFree(s);
752            return ns;
753          }
754          else
755            return s;
756        }
757
758        case RING_CMD:
759        case QRING_CMD:
760          s  = rString((ring)d);
761
762          if (typed)
763          {
764            char* ns;
765            if (t/*Typ()*/ == QRING_CMD)
766            {
767              char* id = iiStringMatrix((matrix) ((ring) d)->qideal, dim);
768              ns = (char*) omAlloc(strlen(s) + strlen(id) + 20);
769              sprintf(ns, "\"%s\";%sideal(%s)", s,(dim == 2 ? "\n" : " "), id);
770            }
771            else
772            {
773              ns = (char*) omAlloc(strlen(s) + 4);
774              sprintf(ns, "\"%s\"", s);
775            }
776            omFree(s);
777            omCheckAddr(ns);
778            return ns;
779          }
780          return s;
781
782        case RESOLUTION_CMD:
783        {
784          lists l = syConvRes((syStrategy)d);
785          s = lString(l, typed, dim);
786          l->Clean();
787          return s;
788        }
789
790        case PROC_CMD:
791        {
792          procinfo* pi = (procinfo*) d;
793          if((pi->language == LANG_SINGULAR) && (pi->data.s.body!=NULL))
794            s = (pi->data.s.body);
795          else
796            s = (char *)"";
797          if (typed)
798          {
799            char* ns = (char*) omAlloc(strlen(s) + 4);
800            sprintf(ns, "\"%s\"", s);
801            omCheckAddr(ns);
802            return ns;
803          }
804          return omStrDup(s);
805        }
806
807        case LINK_CMD:
808          s = slString((si_link) d);
809          if (typed)
810          {
811            char* ns = (char*) omAlloc(strlen(s) + 10);
812            sprintf(ns, "link(\"%s\")", s);
813            omFree(s);
814            omCheckAddr(ns);
815            return ns;
816          }
817          return s;
818
819        case LIST_CMD:
820          return lString((lists) d, typed, dim);
821    } /* end switch: (Typ()) */
822  }
823  return omStrDup("");
824}
825
826
827int  sleftv::Typ()
828{
829  if (e==NULL)
830  {
831    switch (rtyp)
832    {
833      case IDHDL:
834        return IDTYP((idhdl)data);
835      case VECHO:
836      case VPAGELENGTH:
837      case VPRINTLEVEL:
838      case VCOLMAX:
839      case VTIMER:
840#ifdef HAVE_RTIMER
841      case VRTIMER:
842#endif
843      case VOICE:
844      case VMAXDEG:
845      case VMAXMULT:
846      case TRACE:
847      case VSHORTOUT:
848        return INT_CMD;
849      case LIB_CMD:
850        return STRING_CMD;
851      case VMINPOLY:
852        return NUMBER_CMD;
853      case VNOETHER:
854        return POLY_CMD;
855      //case COMMAND:
856      //  return COMMAND;
857      default:
858        return rtyp;
859    }
860  }
861  int r=0;
862  int t=rtyp;
863  if (t==IDHDL) t=IDTYP((idhdl)data);
864  switch (t)
865  {
866    case INTVEC_CMD:
867    case INTMAT_CMD:
868      r=INT_CMD;
869      break;
870    case IDEAL_CMD:
871    case MATRIX_CMD:
872    case MAP_CMD:
873      r=POLY_CMD;
874      break;
875    case MODUL_CMD:
876      r=VECTOR_CMD;
877      break;
878    case STRING_CMD:
879      r=STRING_CMD;
880      break;
881    case LIST_CMD:
882    {
883      lists l;
884      if (rtyp==IDHDL) l=IDLIST((idhdl)data);
885      else             l=(lists)data;
886      if ((0<e->start)&&(e->start<=l->nr+1))
887      {
888        Subexpr tmp=l->m[e->start-1].e;
889        l->m[e->start-1].e=e->next;
890        r=l->m[e->start-1].Typ();
891        e->next=l->m[e->start-1].e;
892        l->m[e->start-1].e=tmp;
893      }
894      else
895      {
896        //Warn("out of range: %d not in 1..%d",e->start,l->nr+1);
897        r=NONE;
898      }
899      break;
900    }
901    default:
902      Werror("cannot index type %d",t);
903  }
904  return r;
905}
906
907int  sleftv::LTyp()
908{
909  lists l=NULL;
910  int r;
911  if (rtyp==LIST_CMD)
912    l=(lists)data;
913  else if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)==LIST_CMD))
914    l=IDLIST((idhdl)data);
915  else
916    return Typ();
917  //if (l!=NULL)
918  {
919    if ((e!=NULL) && (e->next!=NULL))
920    {
921      if ((0<e->start)&&(e->start<=l->nr+1))
922      {
923        l->m[e->start-1].e=e->next;
924        r=l->m[e->start-1].LTyp();
925        l->m[e->start-1].e=NULL;
926      }
927      else
928      {
929        //Warn("out of range: %d not in 1..%d",e->start,l->nr+1);
930        r=NONE;
931      }
932      return r;
933    }
934    return LIST_CMD;
935  }
936  return Typ();
937}
938
939void sleftv::SetData(void* what)
940{
941  if (rtyp == IDHDL)
942  {
943    IDDATA((idhdl)data) = (char *)what;
944  }
945  else
946  {
947    data = what;
948  }
949}
950
951void * sleftv::Data()
952{
953  if ((rtyp!=IDHDL) && iiCheckRing(rtyp))
954     return NULL;
955  if (e==NULL)
956  {
957    switch (rtyp)
958    {
959      case VECHO:      return (void *)si_echo;
960      case VPAGELENGTH:return (void *)pagelength;
961      case VPRINTLEVEL:return (void *)printlevel;
962      case VCOLMAX:    return (void *)colmax;
963      case VTIMER:     return (void *)getTimer();
964#ifdef HAVE_RTIMER
965      case VRTIMER:    return (void *)getRTimer();
966#endif
967      case VOICE:      return (void *)(myynest+1);
968      case VMAXDEG:    return (void *)Kstd1_deg;
969      case VMAXMULT:   return (void *)Kstd1_mu;
970      case TRACE:      return (void *)traceit;
971      case VSHORTOUT:  return (void *)(currRing != NULL ? currRing->ShortOut : 0);
972      case VMINPOLY:   if (currRing != NULL &&
973                           (currRing->minpoly!=NULL)&&(!rField_is_GF()))
974                       /* Q(a), Fp(a), but not GF(q) */
975                         return (void *)currRing->minpoly;
976                       else
977                         return (void *)nNULL;
978      case VNOETHER:   return (void *) ppNoether;
979      case LIB_CMD:    {
980                         return (void *)sNoName;
981                       }
982      case IDHDL:
983        return IDDATA((idhdl)data);
984      case POINTER_CMD:
985        return IDDATA((idhdl)data);
986      case COMMAND:
987        //return NULL;
988      default:
989        return data;
990    }
991  }
992  /* e != NULL : */
993  int t=rtyp;
994  void *d=data;
995  if (t==IDHDL)
996  {
997    t=((idhdl)data)->typ;
998    d=IDDATA((idhdl)data);
999  }
1000  if (iiCheckRing(t))
1001    return NULL;
1002  char *r=NULL;
1003  int index=e->start;
1004  switch (t)
1005  {
1006    case INTVEC_CMD:
1007    {
1008      intvec *iv=(intvec *)d;
1009      if ((index<1)||(index>iv->length()))
1010      {
1011        if (!errorreported)
1012          Werror("wrong range[%d] in intvec(%d)",index,iv->length());
1013      }
1014      else
1015        r=(char *)((*iv)[index-1]);
1016      break;
1017    }
1018    case INTMAT_CMD:
1019    {
1020      intvec *iv=(intvec *)d;
1021      if ((index<1)
1022         ||(index>iv->rows())
1023         ||(e->next->start<1)
1024         ||(e->next->start>iv->cols()))
1025      {
1026        if (!errorreported)
1027        Werror("wrong range[%d,%d] in intmat(%dx%d)",index,e->next->start,
1028                                                     iv->rows(),iv->cols());
1029      }
1030      else
1031        r=(char *)(IMATELEM((*iv),index,e->next->start));
1032      break;
1033    }
1034    case IDEAL_CMD:
1035    case MODUL_CMD:
1036    case MAP_CMD:
1037    {
1038      ideal I=(ideal)d;
1039      if ((index<1)||(index>IDELEMS(I)))
1040      {
1041        if (!errorreported)
1042          Werror("wrong range[%d] in ideal/module(%d)",index,IDELEMS(I));
1043      }
1044      else
1045        r=(char *)I->m[index-1];
1046      break;
1047    }
1048    case STRING_CMD:
1049    {
1050      // this was a memory leak
1051      // we evalute it, cleanup and replace this leftv by it's evalutated form
1052      // the evalutated form will be build in tmp
1053      sleftv tmp;
1054      tmp.Init();
1055      tmp.rtyp=STRING_CMD;
1056      r=(char *)omAllocBin(size_two_bin);
1057      if ((index>0)&& (index<=(int)strlen((char *)d)))
1058      {
1059        r[0]=*(((char *)d)+index-1);
1060        r[1]='\0';
1061      }
1062      else
1063      {
1064        r[0]='\0';
1065      }
1066      tmp.data=r;
1067      if ((rtyp==IDHDL)||(rtyp==STRING_CMD))
1068      {
1069        tmp.next=next; next=NULL;
1070        //if (rtyp==STRING_CMD) { omFree((ADDRESS)data); }
1071        //data=NULL;
1072        d=NULL;
1073        CleanUp();
1074        memcpy(this,&tmp,sizeof(tmp));
1075      }
1076      // and, remember, r is also the result...
1077      else
1078      {
1079        // ???
1080        // here we still have a memory leak...
1081        // example: list L="123","456";
1082        // L[1][2];
1083        // therefore, it should never happen:
1084        assume(0);
1085        // but if it happens: here is the temporary fix:
1086        // omMarkAsStaticAddr(r);
1087      }
1088      break;
1089    }
1090    case MATRIX_CMD:
1091    {
1092      if ((index<1)
1093         ||(index>MATROWS((matrix)d))
1094         ||(e->next->start<1)
1095         ||(e->next->start>MATCOLS((matrix)d)))
1096      {
1097        if (!errorreported)
1098          Werror("wrong range[%d,%d] in intmat(%dx%d)",
1099                  index,e->next->start,
1100                  MATROWS((matrix)d),MATCOLS((matrix)d));
1101      }
1102      else
1103        r=(char *)MATELEM((matrix)d,index,e->next->start);
1104      break;
1105    }
1106    case LIST_CMD:
1107    {
1108      lists l=(lists)d;
1109      if ((0<index)&&(index<=l->nr+1))
1110      {
1111        if ((e->next!=NULL)
1112        && (l->m[index-1].rtyp==STRING_CMD))
1113        // string[..].Data() modifies sleftv, so let's do it ourself
1114        {
1115          char *dd=(char *)l->m[index-1].data;
1116          int j=e->next->start-1;
1117          r=(char *)omAllocBin(size_two_bin);
1118          if ((j>=0) && (j<(int)strlen(dd)))
1119          {
1120            r[0]=*(dd+j);
1121            r[1]='\0';
1122          }
1123          else
1124          {
1125            r[0]='\0';
1126          }
1127        }
1128        else
1129        {
1130          Subexpr tmp=l->m[index-1].e;
1131          l->m[index-1].e=e->next;
1132          r=(char *)l->m[index-1].Data();
1133          e->next=l->m[index-1].e;
1134          l->m[index-1].e=tmp;
1135        }
1136      }
1137      else //if (!errorreported)
1138        Werror("wrong range[%d] in list(%d)",index,l->nr+1);
1139      break;
1140    }
1141#ifdef TEST
1142    default:
1143      Werror("cannot index type %s(%d)",Tok2Cmdname(t),t);
1144#endif
1145  }
1146  return r;
1147}
1148
1149attr * sleftv::Attribute()
1150{
1151  if (e==NULL) return &attribute;
1152  if ((rtyp==LIST_CMD)
1153  ||((rtyp==IDHDL)&&(IDTYP((idhdl)data)==LIST_CMD)))
1154  {
1155    leftv v=LData();
1156    return &(v->attribute);
1157  }
1158  return NULL;
1159}
1160
1161leftv sleftv::LData()
1162{
1163  if (e!=NULL)
1164  {
1165    lists l=NULL;
1166
1167    if (rtyp==LIST_CMD)
1168      l=(lists)data;
1169    if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)==LIST_CMD))
1170      l=IDLIST((idhdl)data);
1171    if (l!=NULL)
1172    {
1173      if ((0>=e->start)||(e->start>l->nr+1))
1174        return NULL;
1175      if (e->next!=NULL)
1176      {
1177        l->m[e->start-1].e=e->next;
1178        leftv r=l->m[e->start-1].LData();
1179        l->m[e->start-1].e=NULL;
1180        return r;
1181      }
1182      return &(l->m[e->start-1]);
1183    }
1184  }
1185  return this;
1186}
1187
1188leftv sleftv::LHdl()
1189{
1190  if (e!=NULL)
1191  {
1192    lists l=NULL;
1193
1194    if (rtyp==LIST_CMD)
1195      l=(lists)data;
1196    if ((rtyp==IDHDL)&& (IDTYP((idhdl)data)==LIST_CMD))
1197      l=IDLIST((idhdl)data);
1198    if (l!=NULL)
1199    {
1200      if ((0>=e->start)||(e->start>l->nr+1))
1201        return NULL;
1202      if (e->next!=NULL)
1203      {
1204        l->m[e->start-1].e=e->next;
1205        leftv r=l->m[e->start-1].LHdl();
1206        l->m[e->start-1].e=NULL;
1207        return r;
1208      }
1209      return &(l->m[e->start-1]);
1210    }
1211  }
1212  return this;
1213}
1214
1215BOOLEAN assumeStdFlag(leftv h)
1216{
1217  if ((h->e!=NULL)&&(h->LTyp()==LIST_CMD))
1218  {
1219    return assumeStdFlag(h->LData());
1220  }
1221  if (!hasFlag(h,FLAG_STD))
1222  {
1223    if (!TEST_VERB_NSB)
1224      Warn("%s is no standard basis",h->Name());
1225    return FALSE;
1226  }
1227  return TRUE;
1228}
1229
1230/*2
1231* transforms a name (as an string created by omAlloc or omStrDup)
1232* into an expression (sleftv), deletes the string
1233* utility for grammar and iparith
1234*/
1235void syMake(leftv v,const char * id, idhdl packhdl)
1236{
1237  /* resolv an identifier: (to DEF_CMD, if siq>0)
1238  * 1) reserved id: done by scanner
1239  * 2) `basering` / 'Current`
1240  * 3) existing identifier, local
1241  * 4) ringvar, local ring
1242  * 5) existing identifier, global
1243  * 6) monom (resp. number), local ring: consisting of:
1244  * 6') ringvar, global ring
1245  * 6'') monom (resp. number), local ring
1246  * 7) monom (resp. number), non-local ring
1247  * 8) basering
1248  * 9) `_`
1249  * 10) everything else is of type 0
1250  */
1251#ifdef TEST
1252  if ((*id<' ')||(*id>(char)126))
1253  {
1254    Print("wrong id :%s:\n",id);
1255  }
1256#endif
1257  v->Init();
1258  if(packhdl != NULL)
1259  {
1260  //  Print("setting req_packhdl to %s\n",IDID(packhdl));
1261    v->req_packhdl = IDPACKAGE(packhdl);
1262  }
1263  else v->req_packhdl = currPack;
1264//  if (v->req_packhdl!=basePack)
1265//    Print("search %s in %s\n",id,v->req_packhdl->libname);
1266  idhdl h=NULL;
1267#ifdef SIQ
1268  if (siq<=0)
1269#endif
1270  {
1271    if (!isdigit(id[0]))
1272    {
1273      if (strcmp(id,"basering")==0)
1274      {
1275        if (currRingHdl!=NULL)
1276        {
1277          if (id!=IDID(currRingHdl)) omFree((ADDRESS)id);
1278          h=currRingHdl;
1279          goto id_found;
1280        }
1281        else
1282        {
1283          v->name = id;
1284          return; /* undefined */
1285        }
1286      }
1287      else if (strcmp(id,"Current")==0)
1288      {
1289        if (currPackHdl!=NULL)
1290        {
1291          omFree((ADDRESS)id);
1292          h=currPackHdl;
1293          goto id_found;
1294        }
1295        else
1296        {
1297          v->name = id;
1298          return; /* undefined */
1299        }
1300      }
1301      if(v->req_packhdl!=currPack)
1302      {
1303        h=v->req_packhdl->idroot->get(id,myynest);
1304      }
1305      else
1306      h=ggetid(id);
1307      /* 3) existing identifier, local */
1308      if ((h!=NULL) && (IDLEV(h)==myynest))
1309      {
1310        if (id!=IDID(h)) omFree((ADDRESS)id);
1311        goto id_found;
1312      }
1313    }
1314    /* 4. local ring: ringvar */
1315    if ((currRingHdl!=NULL) && (IDLEV(currRingHdl)==myynest)
1316    && (!yyInRingConstruction))
1317    {
1318      int vnr;
1319      if ((vnr=rIsRingVar(id))>=0)
1320      {
1321        poly p=pOne();
1322        pSetExp(p,vnr+1,1);
1323        pSetm(p);
1324        v->data = (void *)p;
1325        v->name = id;
1326        v->rtyp = POLY_CMD;
1327        return;
1328      }
1329    }
1330    /* 5. existing identifier, global */
1331    if (h!=NULL)
1332    {
1333      if (id!=IDID(h)) omFree((ADDRESS)id);
1334      goto id_found;
1335    }
1336    /* 6. local ring: number/poly */
1337    if ((currRingHdl!=NULL) && (IDLEV(currRingHdl)==myynest))
1338    {
1339      BOOLEAN ok=FALSE;
1340      poly p = (!yyInRingConstruction) ? pmInit(id,ok) : (poly)NULL;
1341      if (ok)
1342      {
1343        if (p==NULL)
1344        {
1345          v->data = (void *)nInit(0);
1346          v->rtyp = NUMBER_CMD;
1347          #ifdef HAVE_PLURAL
1348          // in this case we may have monomials equal to 0 in p_Read
1349          v->name = id;
1350          #else
1351          omFree((ADDRESS)id);
1352          #endif
1353        }
1354        else
1355        if (pIsConstant(p))
1356        {
1357          v->data = pGetCoeff(p);
1358          pGetCoeff(p)=NULL;
1359          pLmFree(p);
1360          v->rtyp = NUMBER_CMD;
1361          v->name = id;
1362        }
1363        else
1364        {
1365          v->data = p;
1366          v->rtyp = POLY_CMD;
1367          v->name = id;
1368        }
1369        return;
1370      }
1371    }
1372    /* 7. non-local ring: number/poly */
1373    {
1374      BOOLEAN ok=FALSE;
1375      poly p = ((currRing!=NULL)     /* ring required */
1376               && (currRingHdl!=NULL)
1377               && (!yyInRingConstruction) /* not in decl */
1378               && (IDLEV(currRingHdl)!=myynest)) /* already in case 4/6 */
1379                     ? pmInit(id,ok) : (poly)NULL;
1380      if (ok)
1381      {
1382        if (p==NULL)
1383        {
1384          v->data = (void *)nInit(0);
1385          v->rtyp = NUMBER_CMD;
1386          #ifdef HAVE_PLURAL
1387          // in this case we may have monomials equal to 0 in p_Read
1388          v->name = id;
1389          #else
1390          omFree((ADDRESS)id);
1391          #endif
1392        }
1393        else
1394        if (pIsConstant(p))
1395        {
1396          v->data = pGetCoeff(p);
1397          pGetCoeff(p)=NULL;
1398          pLmFree(p);
1399          v->rtyp = NUMBER_CMD;
1400          v->name = id;
1401        }
1402        else
1403        {
1404          v->data = p;
1405          v->rtyp = POLY_CMD;
1406          v->name = id;
1407        }
1408        return;
1409      }
1410    }
1411    /* 8. basering ? */
1412    if ((myynest>1)&&(currRingHdl!=NULL))
1413    {
1414      if (strcmp(id,IDID(currRingHdl))==0)
1415      {
1416        if (IDID(currRingHdl)!=id) omFree((ADDRESS)id);
1417        h=currRingHdl;
1418        goto id_found;
1419      }
1420    }
1421    if((v->req_packhdl!=basePack) && (v->req_packhdl==currPack))
1422    {
1423      h=basePack->idroot->get(id,myynest);
1424      if (h!=NULL)
1425      {
1426        if (id!=IDID(h)) omFree((ADDRESS)id);
1427        v->req_packhdl=basePack;
1428        goto id_found;
1429      }
1430    }
1431  }
1432#ifdef SIQ
1433  else
1434    v->rtyp=DEF_CMD;
1435#endif
1436  /* 9: _ */
1437  if (strcmp(id,"_")==0)
1438  {
1439    omFree((ADDRESS)id);
1440    v->Copy(&sLastPrinted);
1441  }
1442  else
1443  {
1444    /* 10: everything else */
1445    /* v->rtyp = UNKNOWN;*/
1446    v->name = id;
1447  }
1448  return;
1449id_found: // we have an id (in h) found, to set the data in from h
1450  v->rtyp = IDHDL;
1451  v->data = (char *)h;
1452  v->flag = IDFLAG(h);
1453  v->name = IDID(h);
1454  v->attribute=IDATTR(h);
1455}
1456
1457int sleftv::Eval()
1458{
1459  BOOLEAN nok=FALSE;
1460  leftv nn=next;
1461  next=NULL;
1462  if(rtyp==IDHDL)
1463  {
1464    int t=Typ();
1465    if (t!=PROC_CMD)
1466    {
1467      void *d=CopyD(t);
1468      data=d;
1469      rtyp=t;
1470      name=NULL;
1471      e=NULL;
1472    }
1473  }
1474  else if (rtyp==COMMAND)
1475  {
1476    command d=(command)data;
1477    if(d->op==PROC_CMD) //assume d->argc==2
1478    {
1479      char *what=(char *)(d->arg1.Data());
1480      idhdl h=ggetid(what);
1481      if((h!=NULL)&&(IDTYP(h)==PROC_CMD))
1482      {
1483        nok=d->arg2.Eval();
1484        if(!nok)
1485        {
1486          leftv r=iiMake_proc(h,req_packhdl,&d->arg2);
1487          if (r!=NULL)
1488            memcpy(this,r,sizeof(sleftv));
1489          else
1490            nok=TRUE;
1491        }
1492      }
1493      else nok=TRUE;
1494    }
1495    else if (d->op=='=') //assume d->argc==2
1496    {
1497      if ((d->arg1.rtyp!=IDHDL)&&(d->arg1.rtyp!=DEF_CMD))
1498      {
1499        nok=d->arg1.Eval();
1500      }
1501      if (!nok)
1502      {
1503        const char *n=d->arg1.name;
1504        nok=(n == NULL) || d->arg2.Eval();
1505        if (!nok)
1506        {
1507          int save_typ=d->arg1.rtyp;
1508          omCheckAddr((ADDRESS)n);
1509          if (d->arg1.rtyp!=IDHDL)
1510          syMake(&d->arg1,n);
1511          omCheckAddr((ADDRESS)d->arg1.name);
1512          if (d->arg1.rtyp==IDHDL)
1513          {
1514            n=omStrDup(IDID((idhdl)d->arg1.data));
1515            killhdl((idhdl)d->arg1.data);
1516            d->arg1.Init();
1517            //d->arg1.data=NULL;
1518            d->arg1.name=n;
1519          }
1520          d->arg1.rtyp=DEF_CMD;
1521          sleftv t;
1522          if(save_typ!=PROC_CMD) save_typ=d->arg2.rtyp;
1523          if (::RingDependend(d->arg2.rtyp))
1524            nok=iiDeclCommand(&t,&d->arg1,0,save_typ,&currRing->idroot);
1525          else
1526            nok=iiDeclCommand(&t,&d->arg1,0,save_typ,&IDROOT);
1527          memcpy(&d->arg1,&t,sizeof(sleftv));
1528          omCheckAddr((ADDRESS)d->arg1.name);
1529          nok=nok||iiAssign(&d->arg1,&d->arg2);
1530          omCheckIf(d->arg1.name != NULL,  // OB: ????
1531                    omCheckAddr((ADDRESS)d->arg1.name));
1532          if (!nok)
1533          {
1534            memset(&d->arg1,0,sizeof(sleftv));
1535            this->CleanUp();
1536            rtyp=NONE;
1537          }
1538        }
1539      }
1540      else nok=TRUE;
1541    }
1542    else if (d->argc==1)
1543    {
1544      nok=d->arg1.Eval();
1545      nok=nok||iiExprArith1(this,&d->arg1,d->op);
1546    }
1547    else if(d->argc==2)
1548    {
1549      nok=d->arg1.Eval();
1550      nok=nok||d->arg2.Eval();
1551      nok=nok||iiExprArith2(this,&d->arg1,d->op,&d->arg2);
1552    }
1553    else if(d->argc==3)
1554    {
1555      nok=d->arg1.Eval();
1556      nok=nok||d->arg2.Eval();
1557      nok=nok||d->arg3.Eval();
1558      nok=nok||iiExprArith3(this,d->op,&d->arg1,&d->arg2,&d->arg3);
1559    }
1560    else if(d->argc!=0)
1561    {
1562      nok=d->arg1.Eval();
1563      nok=nok||iiExprArithM(this,&d->arg1,d->op);
1564    }
1565    else // d->argc == 0
1566    {
1567      nok = iiExprArithM(this, NULL, d->op);
1568    }
1569  }
1570  else if (((rtyp==0)||(rtyp==DEF_CMD))
1571    &&(name!=NULL))
1572  {
1573     syMake(this,name);
1574  }
1575#ifdef MDEBUG
1576  switch(Typ())
1577  {
1578    case NUMBER_CMD:
1579#ifdef LDEBUG
1580      nTest((number)Data());
1581#endif
1582      break;
1583    case BIGINT_CMD:
1584#ifdef LDEBUG
1585      nlTest((number)Data());
1586#endif
1587      break;
1588    case POLY_CMD:
1589      pTest((poly)Data());
1590      break;
1591    case IDEAL_CMD:
1592    case MODUL_CMD:
1593    case MATRIX_CMD:
1594      {
1595        ideal id=(ideal)Data();
1596        omCheckAddrSize(id,sizeof(*id));
1597        int i=id->ncols*id->nrows-1;
1598        for(;i>=0;i--) pTest(id->m[i]);
1599      }
1600      break;
1601  }
1602#endif
1603  if (nn!=NULL) nok=nok||nn->Eval();
1604  next=nn;
1605  return nok;
1606}
1607
1608const char *iiSleftv2name(leftv v)
1609{
1610  return(v->name);
1611}
1612
1613void * sattr::CopyA()
1614{
1615  omCheckAddrSize(this,sizeof(sattr));
1616  return s_internalCopy(atyp,data);
1617}
1618
Note: See TracBrowser for help on using the repository browser.