source: git/Singular/links/ssiLink.cc @ a3f0fea

spielwiese
Last change on this file since a3f0fea was a3f0fea, checked in by Reimer Behrends <behrends@…>, 5 years ago
Modify variable declarions for pSingular.
  • Property mode set to 100644
File size: 55.8 KB
Line 
1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    ssiLink.h
6 *  Purpose: declaration of sl_link routines for ssi
7 ***************************************************************/
8#define TRANSEXT_PRIVATES 1 /* allow access to transext internals */
9
10#include "kernel/mod2.h"
11
12#include "misc/intvec.h"
13#include "misc/options.h"
14
15#include "reporter/si_signals.h"
16#include "reporter/s_buff.h"
17
18#include "coeffs/bigintmat.h"
19#include "coeffs/longrat.h"
20
21#include "polys/monomials/ring.h"
22#include "polys/monomials/p_polys.h"
23#include "polys/ext_fields/transext.h"
24#include "polys/simpleideals.h"
25#include "polys/matpol.h"
26
27#include "kernel/oswrapper/timer.h"
28#include "kernel/oswrapper/feread.h"
29#include "kernel/oswrapper/rlimit.h"
30
31#include "Singular/tok.h"
32#include "Singular/ipid.h"
33#include "Singular/ipshell.h"
34#include "Singular/subexpr.h"
35#include "Singular/links/silink.h"
36#include "Singular/cntrlc.h"
37#include "Singular/lists.h"
38#include "Singular/blackbox.h"
39#include "Singular/links/ssiLink.h"
40
41#ifdef HAVE_SIMPLEIPC
42#include "Singular/links/simpleipc.h"
43#endif
44
45#include <errno.h>
46#include <sys/types.h>          /* for portability */
47#include <ctype.h>   /*for isdigit*/
48#include <netdb.h>
49#include <netinet/in.h> /* for htons etc.*/
50
51#define SSI_VERSION 12
52// 5->6: changed newstruct representation
53// 6->7: attributes
54// 7->8: qring
55// 8->9: module: added rank
56// 9->10: tokens in grammar.h/tok.h reorganized
57// 10->11: extended ring descr. for named coeffs (not in used until 4.1)
58// 11->12: add rank to ideal/module, add smatrix
59
60VAR link_list ssiToBeClosed=NULL;
61VAR volatile BOOLEAN ssiToBeClosed_inactive=TRUE;
62
63// forward declarations:
64void ssiWritePoly_R(const ssiInfo *d, int typ, poly p, const ring r);
65void ssiWriteIdeal_R(const ssiInfo *d, int typ,const ideal I, const ring r);
66poly ssiReadPoly_R(const ssiInfo *D, const ring r);
67ideal ssiReadIdeal_R(const ssiInfo *d,const ring r);
68
69// the helper functions:
70BOOLEAN ssiSetCurrRing(const ring r) /* returned: not accepted */
71{
72  //  if (currRing!=NULL)
73  //  Print("need to change the ring, currRing:%s, switch to: ssiRing%d\n",IDID(currRingHdl),nr);
74  //  else
75  //  Print("no ring, switch to ssiRing%d\n",nr);
76  if (!rEqual(r,currRing,1))
77  {
78    char name[20];
79    int nr=0;
80    idhdl h=NULL;
81    loop
82    {
83      sprintf(name,"ssiRing%d",nr); nr++;
84      h=IDROOT->get(name, 0);
85      if (h==NULL)
86      {
87        h=enterid(name,0,RING_CMD,&IDROOT,FALSE);
88        IDRING(h)=r;
89        r->ref++;
90        break;
91      }
92      else if ((IDTYP(h)==RING_CMD)
93      && (rEqual(r,IDRING(h),1)))
94        break;
95    }
96    rSetHdl(h);
97    return FALSE;
98  }
99  else
100  {
101    rKill(r);
102    return TRUE;
103  }
104}
105// the implementation of the functions:
106void ssiWriteInt(const ssiInfo *d,const int i)
107{
108  fprintf(d->f_write,"%d ",i);
109  //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
110}
111
112void ssiWriteString(const ssiInfo *d,const char *s)
113{
114  fprintf(d->f_write,"%d %s ",(int)strlen(s),s);
115  //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
116}
117
118void ssiWriteBigInt(const ssiInfo *d, const number n)
119{
120 n_WriteFd(n,d,coeffs_BIGINT);
121}
122
123void ssiWriteNumber_CF(const ssiInfo *d, const number n, const coeffs cf)
124{
125  // syntax is as follows:
126  // case 1 Z/p:   3 <int>
127  // case 2 Q:     3 4 <int>
128  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
129  //        or     3 1  dto.
130  //        or     3 3 <mpz_t nominator>
131  //        or     3 5 <mpz_t raw nom.> <mpz_t raw denom.>
132  //        or     3 6 <mpz_t raw nom.> <mpz_t raw denom.>
133  //        or     3 8 <mpz_t raw nom.>
134  if (getCoeffType(cf)==n_transExt)
135  {
136    fraction f=(fraction)n;
137    ssiWritePoly_R(d,POLY_CMD,NUM(f),cf->extRing);
138    ssiWritePoly_R(d,POLY_CMD,DEN(f),cf->extRing);
139  }
140  else if (getCoeffType(cf)==n_algExt)
141  {
142    ssiWritePoly_R(d,POLY_CMD,(poly)n,cf->extRing);
143  }
144  else if (cf->cfWriteFd!=NULL)
145  {
146    n_WriteFd(n,d,cf);
147  }
148  else WerrorS("coeff field not implemented");
149}
150
151void ssiWriteNumber(const ssiInfo *d, const number n)
152{
153  ssiWriteNumber_CF(d,n,d->r->cf);
154}
155
156void ssiWriteRing_R(ssiInfo *d,const ring r)
157{
158  /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
159  /* ch=-1: transext, coeff ring follows */
160  /* ch=-2: algext, coeff ring and minpoly follows */
161  /* ch=-3: cf name follows */
162  if (r!=NULL)
163  {
164    if (rField_is_Q(r) || rField_is_Zp(r))
165      fprintf(d->f_write,"%d %d ",n_GetChar(r->cf),r->N);
166    else if (rFieldType(r)==n_transExt)
167      fprintf(d->f_write,"-1 %d ",r->N);
168    else if (rFieldType(r)==n_algExt)
169      fprintf(d->f_write,"-2 %d ",r->N);
170    else /*dummy*/
171    {
172      fprintf(d->f_write,"-3 %d ",r->N);
173      ssiWriteString(d,nCoeffName(r->cf));
174    }
175
176    int i;
177    for(i=0;i<r->N;i++)
178    {
179      fprintf(d->f_write,"%d %s ",(int)strlen(r->names[i]),r->names[i]);
180    }
181    /* number of orderings:*/
182    i=0;
183    // remember dummy ring: everything 0:
184    if (r->order!=NULL) while (r->order[i]!=0) i++;
185    fprintf(d->f_write,"%d ",i);
186    /* each ordering block: */
187    i=0;
188    if (r->order!=NULL) while(r->order[i]!=0)
189    {
190      fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
191      switch(r->order[i])
192      {
193        case ringorder_a:
194        case ringorder_wp:
195        case ringorder_Wp:
196        case ringorder_ws:
197        case ringorder_Ws:
198        case ringorder_aa:
199        {
200          int ii;
201          for(ii=r->block0[i];ii<=r->block1[i];ii++)
202            fprintf(d->f_write,"%d ",r->wvhdl[i][ii-r->block0[i]]);
203        }
204        break;
205
206        case ringorder_a64:
207        case ringorder_M:
208        case ringorder_L:
209        case ringorder_IS:
210          Werror("ring oder not implemented for ssi:%d",r->order[i]);
211          break;
212
213        default: break;
214      }
215      i++;
216    }
217    if ((rFieldType(r)==n_transExt)
218    || (rFieldType(r)==n_algExt))
219    {
220      ssiWriteRing_R(d,r->cf->extRing); /* includes alg.ext if rFieldType(r)==n_algExt */
221    }
222    /* Q-ideal :*/
223    if (r->qideal!=NULL)
224    {
225      ssiWriteIdeal_R(d,IDEAL_CMD,r->qideal,r);
226    }
227    else
228    {
229      fputs("0 ",d->f_write/*ideal with 0 entries */);
230    }
231  }
232  else /* dummy ring r==NULL*/
233  {
234    fputs("0 0 0 0 "/*,r->ch,r->N, blocks, q-ideal*/,d->f_write);
235  }
236}
237
238void ssiWriteRing(ssiInfo *d,const ring r)
239{
240  /* 5 <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <extRing> <Q-ideal> */
241  /* ch=-1: transext, coeff ring follows */
242  /* ch=-2: algext, coeff ring and minpoly follows */
243  /* ch=-3: cf name follows */
244  if ((r==NULL)||(r->cf==NULL))
245  {
246    WerrorS("undefined ring");
247    return;
248  }
249  if (r==currRing) // see recursive calls for transExt/algExt
250  {
251    if (d->r!=NULL) rKill(d->r);
252    d->r=r;
253  }
254  if (r!=NULL)
255  {
256    /*d->*/r->ref++;
257  }
258  ssiWriteRing_R(d,r);
259}
260void ssiWritePoly_R(const ssiInfo *d, int /*typ*/, poly p, const ring r)
261{
262  fprintf(d->f_write,"%d ",pLength(p));//number of terms
263
264  while(p!=NULL)
265  {
266    ssiWriteNumber_CF(d,pGetCoeff(p),r->cf);
267    //nWrite(fich,pGetCoeff(p));
268    fprintf(d->f_write,"%ld ",p_GetComp(p,r));//component
269
270    for(int j=1;j<=rVar(r);j++)
271    {
272      fprintf(d->f_write,"%ld ",p_GetExp(p,j,r ));//x^j
273    }
274    pIter(p);
275  }
276}
277
278void ssiWritePoly(const ssiInfo *d, int typ, poly p)
279{
280  ssiWritePoly_R(d,typ,p,d->r);
281}
282
283void ssiWriteIdeal_R(const ssiInfo *d, int typ,const ideal I, const ring R)
284{
285   // syntax: 7 # of elements <poly 1> <poly2>.....(ideal,module,smatrix)
286   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....(matrix)
287   // syntax
288   matrix M=(matrix)I;
289   int mn;
290   if (typ==MATRIX_CMD)
291   {
292     mn=MATROWS(M)*MATCOLS(M);
293     fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
294   }
295   else
296   {
297     mn=IDELEMS(I);
298     fprintf(d->f_write,"%d ",IDELEMS(I));
299   }
300
301   int i;
302   int tt;
303   if ((typ==MODUL_CMD)||(typ==SMATRIX_CMD))
304     tt=VECTOR_CMD;
305   else
306     tt=POLY_CMD;
307
308   for(i=0;i<mn;i++)
309   {
310     ssiWritePoly_R(d,tt,I->m[i],R);
311   }
312}
313void ssiWriteIdeal(const ssiInfo *d, int typ,const ideal I)
314{
315  ssiWriteIdeal_R(d,typ,I,d->r);
316}
317
318void ssiWriteCommand(si_link l, command D)
319{
320  ssiInfo *d=(ssiInfo*)l->data;
321  // syntax: <num ops> <operation> <op1> <op2> ....
322  fprintf(d->f_write,"%d %d ",D->argc,D->op);
323  if (D->argc >0) ssiWrite(l, &(D->arg1));
324  if (D->argc < 4)
325  {
326    if (D->argc >1) ssiWrite(l, &(D->arg2));
327    if (D->argc >2) ssiWrite(l, &(D->arg3));
328  }
329}
330
331void ssiWriteProc(const ssiInfo *d,procinfov p)
332{
333  if (p->data.s.body==NULL)
334    iiGetLibProcBuffer(p);
335  if (p->data.s.body!=NULL)
336    ssiWriteString(d,p->data.s.body);
337  else
338    ssiWriteString(d,"");
339}
340
341void ssiWriteList(si_link l,lists dd)
342{
343  ssiInfo *d=(ssiInfo*)l->data;
344  int Ll=dd->nr;
345  fprintf(d->f_write,"%d ",Ll+1);
346  int i;
347  for(i=0;i<=Ll;i++)
348  {
349    ssiWrite(l,&(dd->m[i]));
350  }
351}
352void ssiWriteIntvec(const ssiInfo *d,intvec * v)
353{
354  fprintf(d->f_write,"%d ",v->length());
355  int i;
356  for(i=0;i<v->length();i++)
357  {
358    fprintf(d->f_write,"%d ",(*v)[i]);
359  }
360}
361void ssiWriteIntmat(const ssiInfo *d,intvec * v)
362{
363  fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
364  int i;
365  for(i=0;i<v->length();i++)
366  {
367    fprintf(d->f_write,"%d ",(*v)[i]);
368  }
369}
370
371void ssiWriteBigintmat(const ssiInfo *d,bigintmat * v)
372{
373  fprintf(d->f_write,"%d %d ",v->rows(),v->cols());
374  int i;
375  for(i=0;i<v->length();i++)
376  {
377    ssiWriteBigInt(d,(*v)[i]);
378  }
379}
380
381char *ssiReadString(const ssiInfo *d)
382{
383  char *buf;
384  int l;
385  l=s_readint(d->f_read);
386  buf=(char*)omAlloc0(l+1);
387  int throwaway =s_getc(d->f_read); /* skip ' '*/
388  throwaway=s_readbytes(buf,l,d->f_read);
389  //if (throwaway!=l) printf("want %d, got %d bytes\n",l,throwaway);
390  buf[l]='\0';
391  return buf;
392}
393
394int ssiReadInt(s_buff fich)
395{
396  return s_readint(fich);
397}
398
399number ssiReadNumber_CF(const ssiInfo *d, const coeffs cf)
400{
401  if (cf->cfReadFd!=NULL)
402  {
403     return n_ReadFd(d,cf);
404  }
405  else if (getCoeffType(cf) == n_transExt)
406  {
407    // poly poly
408    fraction f=(fraction)n_Init(1,cf);
409    p_Delete(&NUM(f),cf->extRing);
410    NUM(f)=ssiReadPoly_R(d,cf->extRing);
411    DEN(f)=ssiReadPoly_R(d,cf->extRing);
412    return (number)f;
413  }
414  else if (getCoeffType(cf) == n_algExt)
415  {
416    // poly
417    return (number)ssiReadPoly_R(d,cf->extRing);
418  }
419  else WerrorS("coeffs not implemented in ssiReadNumber");
420  return NULL;
421}
422
423number ssiReadBigInt(const ssiInfo *d)
424{
425  number n=ssiReadNumber_CF(d,coeffs_BIGINT);
426  if ((SR_HDL(n) & SR_INT)==0)
427  {
428    if (n->s!=3) Werror("invalid sub type in bigint:%d",n->s);
429  }
430  return n;
431}
432
433number ssiReadNumber(const ssiInfo *d)
434{
435  if (currRing==NULL) ssiSetCurrRing(d->r);
436  return ssiReadNumber_CF(d,d->r->cf);
437}
438
439ring ssiReadRing(const ssiInfo *d)
440{
441/* syntax is <ch> <N> <l1> <v1> ...<lN> <vN> <number of orderings> <ord1> <block0_1> <block1_1> .... <Q-ideal> */
442  int ch, N,i;
443  char **names;
444  ch=s_readint(d->f_read);
445  N=s_readint(d->f_read);
446  coeffs cf=NULL;
447  if (ch==-3)
448  {
449    char *cf_name=ssiReadString(d);
450    cf=nFindCoeffByName(cf_name);
451    if (cf==NULL)
452    {
453      Werror("cannot find cf:%s",cf_name);
454      omFree(cf_name);
455      return NULL;
456    }
457  }
458  if (N!=0)
459  {
460    names=(char**)omAlloc(N*sizeof(char*));
461    for(i=0;i<N;i++)
462    {
463      names[i]=ssiReadString(d);
464    }
465  }
466  // read the orderings:
467  int num_ord; // number of orderings
468  num_ord=s_readint(d->f_read);
469  rRingOrder_t *ord=(rRingOrder_t *)omAlloc0((num_ord+1)*sizeof(rRingOrder_t));
470  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
471  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
472  int **wvhdl=(int**)omAlloc0((num_ord+1)*sizeof(int*));
473  for(i=0;i<num_ord;i++)
474  {
475    ord[i]=(rRingOrder_t)s_readint(d->f_read);
476    block0[i]=s_readint(d->f_read);
477    block1[i]=s_readint(d->f_read);
478    switch(ord[i])
479    {
480      case ringorder_a:
481      case ringorder_wp:
482      case ringorder_Wp:
483      case ringorder_ws:
484      case ringorder_Ws:
485      case ringorder_aa:
486      {
487        wvhdl[i]=(int*)omAlloc((block1[i]-block0[i]+1)*sizeof(int));
488        int ii;
489        for(ii=block0[i];ii<=block1[i];ii++)
490          wvhdl[i][ii-block0[i]]=s_readint(d->f_read);
491      }
492      break;
493
494      case ringorder_a64:
495      case ringorder_M:
496      case ringorder_L:
497      case ringorder_IS:
498        Werror("ring oder not implemented for ssi:%d",ord[i]);
499        break;
500
501      default: break;
502    }
503  }
504  if (N==0)
505  {
506    omFree(ord);
507    omFree(block0);
508    omFree(block1);
509    omFree(wvhdl);
510    return NULL;
511  }
512  else
513  {
514    ring r=NULL;
515    if (ch>=0) /* Q, Z/p */
516      r=rDefault(ch,N,names,num_ord,ord,block0,block1,wvhdl);
517    else if (ch==-1) /* trans ext. */
518    {
519      TransExtInfo T;
520      T.r=ssiReadRing(d);
521      if (T.r==NULL) return NULL;
522      cf=nInitChar(n_transExt,&T);
523      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
524    }
525    else if (ch==-2) /* alg ext. */
526    {
527      TransExtInfo T;
528      T.r=ssiReadRing(d); /* includes qideal */
529      if (T.r==NULL) return NULL;
530      cf=nInitChar(n_algExt,&T);
531      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
532    }
533    else if (ch==-3)
534    {
535      r=rDefault(cf,N,names,num_ord,ord,block0,block1,wvhdl);
536    }
537    else
538    {
539      Werror("ssi: read unknown coeffs type (%d)",ch);
540      for(i=0;i<N;i++)
541      {
542        omFree(names[i]);
543      }
544      omFreeSize(names,N*sizeof(char*));
545      return NULL;
546    }
547    ideal q=ssiReadIdeal_R(d,r);
548    if (IDELEMS(q)==0) omFreeBin(q,sip_sideal_bin);
549    else r->qideal=q;
550    for(i=0;i<N;i++)
551    {
552      omFree(names[i]);
553    }
554    omFreeSize(names,N*sizeof(char*));
555    return r;
556  }
557}
558
559poly ssiReadPoly_R(const ssiInfo *D, const ring r)
560{
561// < # of terms> < term1> < .....
562  int n,i,l;
563  n=ssiReadInt(D->f_read); // # of terms
564  //Print("poly: terms:%d\n",n);
565  poly p;
566  poly ret=NULL;
567  poly prev=NULL;
568  for(l=0;l<n;l++) // read n terms
569  {
570// coef,comp.exp1,..exp N
571    p=p_Init(r,r->PolyBin);
572    pSetCoeff0(p,ssiReadNumber_CF(D,r->cf));
573    int d;
574    d=s_readint(D->f_read);
575    p_SetComp(p,d,r);
576    for(i=1;i<=rVar(r);i++)
577    {
578      d=s_readint(D->f_read);
579      p_SetExp(p,i,d,r);
580    }
581    p_Setm(p,r);
582    p_Test(p,r);
583    if (ret==NULL) ret=p;
584    else           pNext(prev)=p;
585    prev=p;
586 }
587 return ret;
588}
589
590poly ssiReadPoly(const ssiInfo *D)
591{
592  if (currRing==NULL) ssiSetCurrRing(D->r);
593  return ssiReadPoly_R(D,D->r);
594}
595
596ideal ssiReadIdeal_R(const ssiInfo *d,const ring r)
597{
598// < # of terms> < term1> < .....
599  int n,i;
600  ideal I;
601  n=s_readint(d->f_read);
602  I=idInit(n,1); // will be fixed later for module/smatrix
603  for(i=0;i<IDELEMS(I);i++) // read n terms
604  {
605    I->m [i]=ssiReadPoly_R(d,r);
606  }
607  return I;
608}
609
610ideal ssiReadIdeal(const ssiInfo *d)
611{
612  if (currRing==NULL) ssiSetCurrRing(d->r);
613  return ssiReadIdeal_R(d,d->r);
614}
615
616matrix ssiReadMatrix(const ssiInfo *d)
617{
618  int n,m;
619  m=s_readint(d->f_read);
620  n=s_readint(d->f_read);
621  matrix M=mpNew(m,n);
622  poly p;
623  for(int i=1;i<=MATROWS(M);i++)
624    for(int j=1;j<=MATCOLS(M);j++)
625    {
626      p=ssiReadPoly(d);
627      MATELEM(M,i,j)=p;
628    }
629  return M;
630}
631
632command ssiReadCommand(si_link l)
633{
634  ssiInfo *d=(ssiInfo*)l->data;
635  // syntax: <num ops> <operation> <op1> <op2> ....
636  command D=(command)omAlloc0(sizeof(*D));
637  int argc,op;
638  argc=s_readint(d->f_read);
639  op=s_readint(d->f_read);
640  D->argc=argc; D->op=op;
641  leftv v;
642  if (argc >0)
643  {
644    v=ssiRead1(l);
645    memcpy(&(D->arg1),v,sizeof(*v));
646    omFreeBin(v,sleftv_bin);
647  }
648  if (argc <4)
649  {
650    if (D->argc >1)
651    {
652      v=ssiRead1(l);
653      memcpy(&(D->arg2),v,sizeof(*v));
654      omFreeBin(v,sleftv_bin);
655    }
656    if (D->argc >2)
657    {
658      v=ssiRead1(l);
659      memcpy(&(D->arg3),v,sizeof(*v));
660      omFreeBin(v,sleftv_bin);
661    }
662  }
663  else
664  {
665    leftv prev=&(D->arg1);
666    argc--;
667    while(argc >0)
668    {
669      v=ssiRead1(l);
670      prev->next=v;
671      prev=v;
672      argc--;
673    }
674  }
675  return D;
676}
677
678procinfov ssiReadProc(const ssiInfo *d)
679{
680  char *s=ssiReadString(d);
681  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
682  p->language=LANG_SINGULAR;
683  p->libname=omStrDup("");
684  p->procname=omStrDup("");
685  p->data.s.body=s;
686  return p;
687}
688lists ssiReadList(si_link l)
689{
690  ssiInfo *d=(ssiInfo*)l->data;
691  int nr;
692  nr=s_readint(d->f_read);
693  lists L=(lists)omAlloc0Bin(slists_bin);
694  L->Init(nr);
695
696  int i;
697  leftv v;
698  for(i=0;i<=L->nr;i++)
699  {
700    v=ssiRead1(l);
701    memcpy(&(L->m[i]),v,sizeof(*v));
702    omFreeBin(v,sleftv_bin);
703  }
704  return L;
705}
706intvec* ssiReadIntvec(const ssiInfo *d)
707{
708  int nr;
709  nr=s_readint(d->f_read);
710  intvec *v=new intvec(nr);
711  for(int i=0;i<nr;i++)
712  {
713    (*v)[i]=s_readint(d->f_read);
714  }
715  return v;
716}
717intvec* ssiReadIntmat(const ssiInfo *d)
718{
719  int r,c;
720  r=s_readint(d->f_read);
721  c=s_readint(d->f_read);
722  intvec *v=new intvec(r,c,0);
723  for(int i=0;i<r*c;i++)
724  {
725    (*v)[i]=s_readint(d->f_read);
726  }
727  return v;
728}
729bigintmat* ssiReadBigintmat(const ssiInfo *d)
730{
731  int r,c;
732  r=s_readint(d->f_read);
733  c=s_readint(d->f_read);
734  bigintmat *v=new bigintmat(r,c,coeffs_BIGINT);
735  for(int i=0;i<r*c;i++)
736  {
737    (*v)[i]=ssiReadBigInt(d);
738  }
739  return v;
740}
741
742void ssiReadBlackbox(leftv res, si_link l)
743{
744  ssiInfo *d=(ssiInfo*)l->data;
745  int throwaway=s_readint(d->f_read);
746  char *name=ssiReadString(d);
747  int tok;
748  blackboxIsCmd(name,tok);
749  if (tok>MAX_TOK)
750  {
751    blackbox *b=getBlackboxStuff(tok);
752    res->rtyp=tok;
753    b->blackbox_deserialize(&b,&(res->data),l);
754  }
755  else
756  {
757    Werror("blackbox %s not found",name);
758  }
759  omFree(name);
760}
761
762void ssiReadAttrib(leftv res, si_link l)
763{
764  ssiInfo *d=(ssiInfo*)l->data;
765  BITSET fl=(BITSET)s_readint(d->f_read);
766  int nr_of_attr=s_readint(d->f_read);
767  if (nr_of_attr>0)
768  {
769    for(int i=1;i<nr_of_attr;i++)
770    {
771    }
772  }
773  leftv tmp=ssiRead1(l);
774  memcpy(res,tmp,sizeof(sleftv));
775  memset(tmp,0,sizeof(sleftv));
776  omFreeBin(tmp,sleftv_bin);
777  if (nr_of_attr>0)
778  {
779  }
780  res->flag=fl;
781}
782//**************************************************************************/
783
784BOOLEAN ssiOpen(si_link l, short flag, leftv u)
785{
786  if (l!=NULL)
787  {
788    const char *mode;
789    ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
790    if (flag & SI_LINK_OPEN)
791    {
792      if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
793        flag = SI_LINK_READ;
794      else flag = SI_LINK_WRITE;
795    }
796
797    if (flag == SI_LINK_READ) mode = "r";
798    else if (strcmp(l->mode, "w") == 0) mode = "w";
799    else if (strcmp(l->mode, "fork") == 0) mode = "fork";
800    else if (strcmp(l->mode, "tcp") == 0) mode = "tcp";
801    else if (strcmp(l->mode, "connect") == 0) mode = "connect";
802    else mode = "a";
803
804
805    SI_LINK_SET_OPEN_P(l, flag);
806    if(l->data!=NULL) omFreeSize(l->data,sizeof(ssiInfo));
807    l->data=d;
808    omFree(l->mode);
809    l->mode = omStrDup(mode);
810
811    if (l->name[0] == '\0')
812    {
813      if (strcmp(mode,"fork")==0)
814      {
815        link_list n=(link_list)omAlloc(sizeof(link_struct));
816        n->u=u;
817        n->l=l;
818        n->next=(void *)ssiToBeClosed;
819        ssiToBeClosed=n;
820
821        int pc[2];
822        int cp[2];
823        pipe(pc);
824        pipe(cp);
825        pid_t pid = fork();
826        if (pid == -1 && errno == EAGAIN)   // RLIMIT_NPROC too low?
827        {
828          raise_rlimit_nproc();
829          pid = fork();
830        }
831        if (pid == -1)
832        {
833          WerrorS("could not fork");
834        }
835        if (pid==0) /*fork: child*/
836        {
837          /* block SIGINT */
838          sigset_t sigint;
839          sigemptyset(&sigint);
840          sigaddset(&sigint, SIGINT);
841          sigprocmask(SIG_BLOCK, &sigint, NULL);
842
843          link_list hh=(link_list)ssiToBeClosed->next;
844          /* we know: l is the first entry in ssiToBeClosed-list */
845          while(hh!=NULL)
846          {
847            SI_LINK_SET_CLOSE_P(hh->l);
848            ssiInfo *dd=(ssiInfo*)hh->l->data;
849            s_close(dd->f_read);
850            fclose(dd->f_write);
851            if (dd->r!=NULL) rKill(dd->r);
852            omFreeSize((ADDRESS)dd,(sizeof *dd));
853            hh->l->data=NULL;
854            link_list nn=(link_list)hh->next;
855            omFree(hh);
856            hh=nn;
857          }
858          ssiToBeClosed->next=NULL;
859#ifdef HAVE_SIMPLEIPC
860          memset(sem_acquired, 0, SIPC_MAX_SEMAPHORES*sizeof(sem_acquired[0]));
861#endif   // HAVE_SIMPLEIPC
862          si_close(pc[1]); si_close(cp[0]);
863          d->f_write=fdopen(cp[1],"w");
864          d->f_read=s_open(pc[0]);
865          d->fd_read=pc[0];
866          d->fd_write=cp[1];
867          //d->r=currRing;
868          //if (d->r!=NULL) d->r->ref++;
869          l->data=d;
870          omFree(l->mode);
871          l->mode = omStrDup(mode);
872          singular_in_batchmode=TRUE;
873          SI_LINK_SET_RW_OPEN_P(l);
874          //myynest=0;
875          fe_fgets_stdin=fe_fgets_dummy;
876          if ((u!=NULL)&&(u->rtyp==IDHDL))
877          {
878            idhdl h=(idhdl)u->data;
879            h->lev=0;
880          }
881          loop
882          {
883            if (!SI_LINK_OPEN_P(l)) m2_end(0);
884            if(d->f_read->is_eof) m2_end(0);
885            leftv h=ssiRead1(l); /*contains an exit.... */
886            if (feErrors != NULL && *feErrors != '\0')
887            {
888              // handle errors:
889              PrintS(feErrors); /* currently quite simple */
890              *feErrors = '\0';
891            }
892            ssiWrite(l,h);
893            h->CleanUp();
894            omFreeBin(h, sleftv_bin);
895          }
896          /* never reached*/
897        }
898        else if (pid>0) /*fork: parent*/
899        {
900          d->pid=pid;
901          si_close(pc[0]); si_close(cp[1]);
902          d->f_write=fdopen(pc[1],"w");
903          d->f_read=s_open(cp[0]);
904          d->fd_read=cp[0];
905          d->fd_write=pc[1];
906          SI_LINK_SET_RW_OPEN_P(l);
907          d->send_quit_at_exit=1;
908          //d->r=currRing;
909          //if (d->r!=NULL) d->r->ref++;
910        }
911        else
912        {
913          Werror("fork failed (%d)",errno);
914          l->data=NULL;
915          omFree(d);
916          return TRUE;
917        }
918      }
919      // ---------------------------------------------------------------------
920      else if (strcmp(mode,"tcp")==0)
921      {
922        int sockfd, newsockfd, portno, clilen;
923        struct sockaddr_in serv_addr, cli_addr;
924        sockfd = socket(AF_INET, SOCK_STREAM, 0);
925        if(sockfd < 0)
926        {
927          WerrorS("ERROR opening socket");
928          l->data=NULL;
929          omFree(d);
930          return TRUE;
931        }
932        memset((char *) &serv_addr,0, sizeof(serv_addr));
933        portno = 1025;
934        serv_addr.sin_family = AF_INET;
935        serv_addr.sin_addr.s_addr = INADDR_ANY;
936        do
937        {
938          portno++;
939          serv_addr.sin_port = htons(portno);
940          if(portno > 50000)
941          {
942            WerrorS("ERROR on binding (no free port available?)");
943            l->data=NULL;
944            omFree(d);
945            return TRUE;
946          }
947        }
948        while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
949        Print("waiting on port %d\n", portno);mflush();
950        listen(sockfd,1);
951        newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
952        if(newsockfd < 0)
953        {
954          WerrorS("ERROR on accept");
955          l->data=NULL;
956          omFree(d);
957          return TRUE;
958        }
959        PrintS("client accepted\n");
960        d->fd_read = newsockfd;
961        d->fd_write = newsockfd;
962        d->f_read = s_open(newsockfd);
963        d->f_write = fdopen(newsockfd, "w");
964        SI_LINK_SET_RW_OPEN_P(l);
965        si_close(sockfd);
966      }
967      // no ssi-Link on stdin or stdout
968      else
969      {
970        Werror("invalid mode >>%s<< for ssi",mode);
971        l->data=NULL;
972        omFree(d);
973        return TRUE;
974      }
975    }
976    // =========================================================================
977    else /*l->name=NULL*/
978    {
979      // tcp mode
980      if(strcmp(mode,"tcp")==0)
981      {
982        int sockfd, newsockfd, portno, clilen;
983        struct sockaddr_in serv_addr, cli_addr;
984        sockfd = socket(AF_INET, SOCK_STREAM, 0);
985        if(sockfd < 0)
986        {
987          WerrorS("ERROR opening socket");
988          l->data=NULL;
989          omFree(d);
990          return TRUE;
991        }
992        memset((char *) &serv_addr,0, sizeof(serv_addr));
993        portno = 1025;
994        serv_addr.sin_family = AF_INET;
995        serv_addr.sin_addr.s_addr = INADDR_ANY;
996        do
997        {
998          portno++;
999          serv_addr.sin_port = htons(portno);
1000          if(portno > 50000)
1001          {
1002            WerrorS("ERROR on binding (no free port available?)");
1003            l->data=NULL;
1004            return TRUE;
1005          }
1006        }
1007        while(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0);
1008        //Print("waiting on port %d\n", portno);mflush();
1009        listen(sockfd,1);
1010        char* cli_host = (char*)omAlloc(256);
1011        char* path = (char*)omAlloc(1024);
1012        int r = si_sscanf(l->name,"%255[^:]:%s",cli_host,path);
1013        if(r == 0)
1014        {
1015          WerrorS("ERROR: no host specified");
1016          l->data=NULL;
1017          omFree(d);
1018          omFree(path);
1019          omFree(cli_host);
1020          return TRUE;
1021        }
1022        else if(r == 1)
1023        {
1024          WarnS("program not specified, using /usr/local/bin/Singular");
1025          Warn("in line >>%s<<",my_yylinebuf);
1026          strcpy(path,"/usr/local/bin/Singular");
1027        }
1028        char* ssh_command = (char*)omAlloc(256);
1029        char* ser_host = (char*)omAlloc(64);
1030        gethostname(ser_host,64);
1031        sprintf(ssh_command,"ssh %s %s -q --batch --link=ssi --MPhost=%s --MPport=%d &",cli_host,path,ser_host,portno);
1032        //Print("client on %s started:%s\n",cli_host,path);
1033        omFree(path);
1034        omFree(cli_host);
1035        if (TEST_OPT_PROT) { Print("running >>%s<<\n",ssh_command); }
1036        system(ssh_command);
1037        omFree(ssh_command);
1038        omFree(ser_host);
1039        clilen = sizeof(cli_addr);
1040        newsockfd = si_accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
1041        if(newsockfd < 0)
1042        {
1043          WerrorS("ERROR on accept");
1044          l->data=NULL;
1045          omFree(d);
1046          return TRUE;
1047        }
1048        //PrintS("client accepted\n");
1049        d->fd_read = newsockfd;
1050        d->fd_write = newsockfd;
1051        d->f_read = s_open(newsockfd);
1052        d->f_write = fdopen(newsockfd, "w");
1053        si_close(sockfd);
1054        SI_LINK_SET_RW_OPEN_P(l);
1055        d->send_quit_at_exit=1;
1056        link_list newlink=(link_list)omAlloc(sizeof(link_struct));
1057        newlink->u=u;
1058        newlink->l=l;
1059        newlink->next=(void *)ssiToBeClosed;
1060        ssiToBeClosed=newlink;
1061        fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
1062      }
1063      // ----------------------------------------------------------------------
1064      else if(strcmp(mode,"connect")==0)
1065      {
1066        char* host = (char*)omAlloc(256);
1067        int sockfd, portno;
1068        struct sockaddr_in serv_addr;
1069        struct hostent *server;
1070
1071        si_sscanf(l->name,"%255[^:]:%d",host,&portno);
1072        //Print("connect to host %s, port %d\n",host,portno);mflush();
1073        if (portno!=0)
1074        {
1075          sockfd = socket(AF_INET, SOCK_STREAM, 0);
1076          if (sockfd < 0) { WerrorS("ERROR opening socket"); return TRUE; }
1077          server = gethostbyname(host);
1078          if (server == NULL) {  WerrorS("ERROR, no such host");  return TRUE; }
1079          memset((char *) &serv_addr, 0, sizeof(serv_addr));
1080          serv_addr.sin_family = AF_INET;
1081          memcpy((char *)&serv_addr.sin_addr.s_addr,
1082                (char *)server->h_addr,
1083                server->h_length);
1084          serv_addr.sin_port = htons(portno);
1085          if (si_connect(sockfd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
1086          { Werror("ERROR connecting(errno=%d)",errno); return TRUE; }
1087          //PrintS("connected\n");mflush();
1088          d->f_read=s_open(sockfd);
1089          d->fd_read=sockfd;
1090          d->f_write=fdopen(sockfd,"w");
1091          d->fd_write=sockfd;
1092          SI_LINK_SET_RW_OPEN_P(l);
1093          omFree(host);
1094        }
1095        else
1096        {
1097          l->data=NULL;
1098          omFree(d);
1099          return TRUE;
1100        }
1101      }
1102      // ======================================================================
1103      else
1104      {
1105        // normal link to a file
1106        FILE *outfile;
1107        char *filename=l->name;
1108
1109        if(filename[0]=='>')
1110        {
1111          if (filename[1]=='>')
1112          {
1113            filename+=2;
1114            mode = "a";
1115          }
1116          else
1117          {
1118            filename++;
1119            mode="w";
1120          }
1121        }
1122        outfile=myfopen(filename,mode);
1123        if (outfile!=NULL)
1124        {
1125          if (strcmp(l->mode,"r")==0)
1126          {
1127            fclose(outfile);
1128            d->f_read=s_open_by_name(filename);
1129          }
1130          else
1131          {
1132            d->f_write = outfile;
1133            fprintf(d->f_write,"98 %d %d %u %u\n",SSI_VERSION,MAX_TOK,si_opt_1,si_opt_2);
1134          }
1135        }
1136        else
1137        {
1138          omFree(d);
1139          l->data=NULL;
1140          return TRUE;
1141        }
1142      }
1143    }
1144  }
1145
1146  return FALSE;
1147}
1148
1149//**************************************************************************/
1150BOOLEAN ssiPrepClose(si_link l)
1151{
1152  if (l!=NULL)
1153  {
1154    SI_LINK_SET_CLOSE_P(l);
1155    ssiInfo *d = (ssiInfo *)l->data;
1156    if (d!=NULL)
1157    {
1158      if (d->send_quit_at_exit)
1159      {
1160        fputs("99\n",d->f_write);
1161        fflush(d->f_write);
1162      }
1163      d->quit_sent=1;
1164    }
1165  }
1166  return FALSE;
1167}
1168
1169BOOLEAN ssiClose(si_link l)
1170{
1171  if (l!=NULL)
1172  {
1173    SI_LINK_SET_CLOSE_P(l);
1174    ssiInfo *d = (ssiInfo *)l->data;
1175    if (d!=NULL)
1176    {
1177      // send quit signal
1178      if ((d->send_quit_at_exit)
1179      && (d->quit_sent==0))
1180      {
1181        fputs("99\n",d->f_write);
1182        fflush(d->f_write);
1183      }
1184      // clean ring
1185      if (d->r!=NULL) rKill(d->r);
1186      // did the child to stop ?
1187      si_waitpid(d->pid,NULL,WNOHANG);
1188      if ((d->pid!=0)
1189      && (kill(d->pid,0)==0)) // child is still running
1190      {
1191        struct timespec t;
1192        t.tv_sec=0;
1193        t.tv_nsec=100000000; // <=100 ms
1194        struct timespec rem;
1195        int r;
1196        loop
1197        {
1198          // wait till signal or time rem:
1199          r = nanosleep(&t, &rem);
1200          t = rem;
1201          // child finished:
1202          if (si_waitpid(d->pid,NULL,WNOHANG) != 0) break;
1203          // other signal, waited s>= 100 ms:
1204          if ((r==0) || (errno != EINTR)) break;
1205        }
1206        if (kill(d->pid,0) == 0) // pid still exists
1207        {
1208          kill(d->pid,15);
1209          t.tv_sec=5; // <=5s
1210          t.tv_nsec=0;
1211          loop
1212          {
1213            // wait till signal or time rem:
1214            r = nanosleep(&t, &rem);
1215            t = rem;
1216            // child finished:
1217            if (si_waitpid(d->pid,NULL,WNOHANG) != 0) break;
1218            // other signal, waited s>=  5 s:
1219            if ((r==0) || (errno != EINTR)) break;
1220          }
1221          if (kill(d->pid,0) == 0)
1222          {
1223            kill(d->pid,9); // just to be sure
1224            si_waitpid(d->pid,NULL,0);
1225          }
1226        }
1227      }
1228      if (d->f_read!=NULL) { s_close(d->f_read);d->f_read=NULL;}
1229      if (d->f_write!=NULL) { fclose(d->f_write); d->f_write=NULL; }
1230      if ((strcmp(l->mode,"tcp")==0)
1231      || (strcmp(l->mode,"fork")==0))
1232      {
1233        link_list hh=ssiToBeClosed;
1234        if (hh!=NULL)
1235        {
1236          if (hh->l==l)
1237          {
1238             ssiToBeClosed=(link_list)hh->next;
1239             omFreeSize(hh,sizeof(link_struct));
1240          }
1241          else while(hh->next!=NULL)
1242          {
1243            link_list hhh=(link_list)hh->next;
1244            if (hhh->l==l)
1245            {
1246              hh->next=hhh->next;
1247              omFreeSize(hhh,sizeof(link_struct));
1248              break;
1249            }
1250            else
1251              hh=(link_list)hh->next;
1252          }
1253        }
1254      }
1255      omFreeSize((ADDRESS)d,(sizeof *d));
1256    }
1257    l->data=NULL;
1258  }
1259  return FALSE;
1260}
1261
1262//**************************************************************************/
1263leftv ssiRead1(si_link l)
1264{
1265  ssiInfo *d = (ssiInfo *)l->data;
1266  leftv res=(leftv)omAlloc0Bin(sleftv_bin);
1267  int t=0;
1268  t=s_readint(d->f_read);
1269  //Print("got type %d\n",t);
1270  switch(t)
1271  {
1272    case 1:res->rtyp=INT_CMD;
1273           res->data=(char *)(long)ssiReadInt(d->f_read);
1274           break;
1275    case 2:res->rtyp=STRING_CMD;
1276           res->data=(char *)ssiReadString(d);
1277           break;
1278    case 3:res->rtyp=NUMBER_CMD;
1279           res->data=(char *)ssiReadNumber(d);
1280           break;
1281    case 4:res->rtyp=BIGINT_CMD;
1282           res->data=(char *)ssiReadBigInt(d);
1283           break;
1284    case 15:
1285    case 5:{
1286             d->r=ssiReadRing(d);
1287             if (d->r==NULL) return NULL;
1288             res->data=(char*)d->r;
1289             res->rtyp=RING_CMD;
1290             if (t==15) // setring
1291             {
1292               if(ssiSetCurrRing(d->r)) { d->r=currRing; d->r->ref++; }
1293               omFreeBin(res,sleftv_bin);
1294               return ssiRead1(l);
1295             }
1296           }
1297           break;
1298    case 6:res->rtyp=POLY_CMD;
1299           if (d->r==NULL) goto no_ring;
1300           res->data=(char*)ssiReadPoly(d);
1301           break;
1302    case 7:res->rtyp=IDEAL_CMD;
1303           if (d->r==NULL) goto no_ring;
1304           res->data=(char*)ssiReadIdeal(d);
1305           break;
1306    case 8:res->rtyp=MATRIX_CMD;
1307           if (d->r==NULL) goto no_ring;
1308           res->data=(char*)ssiReadMatrix(d);
1309           break;
1310    case 9:res->rtyp=VECTOR_CMD;
1311           if (d->r==NULL) goto no_ring;
1312           res->data=(char*)ssiReadPoly(d);
1313           break;
1314    case 10:
1315    case 22:if (t==22) res->rtyp=SMATRIX_CMD;
1316           else        res->rtyp=MODUL_CMD;
1317           if (d->r==NULL) goto no_ring;
1318           {
1319             int rk=s_readint(d->f_read);
1320             ideal M=ssiReadIdeal(d);
1321             M->rank=rk;
1322             res->data=(char*)M;
1323           }
1324           break;
1325    case 11:
1326           {
1327             res->rtyp=COMMAND;
1328             res->data=ssiReadCommand(l);
1329             int nok=res->Eval();
1330             if (nok) WerrorS("error in eval");
1331             break;
1332           }
1333    case 12: /*DEF_CMD*/
1334           {
1335             res->rtyp=0;
1336             res->name=(char *)ssiReadString(d);
1337             int nok=res->Eval();
1338             if (nok) WerrorS("error in name lookup");
1339             break;
1340           }
1341    case 13: res->rtyp=PROC_CMD;
1342             res->data=ssiReadProc(d);
1343             break;
1344    case 14: res->rtyp=LIST_CMD;
1345             res->data=ssiReadList(l);
1346             break;
1347    case 16: res->rtyp=NONE; res->data=NULL;
1348             break;
1349    case 17: res->rtyp=INTVEC_CMD;
1350             res->data=ssiReadIntvec(d);
1351             break;
1352    case 18: res->rtyp=INTMAT_CMD;
1353             res->data=ssiReadIntmat(d);
1354             break;
1355    case 19: res->rtyp=BIGINTMAT_CMD;
1356             res->data=ssiReadBigintmat(d);
1357             break;
1358    case 20: ssiReadBlackbox(res,l);
1359             break;
1360    case 21: ssiReadAttrib(res,l);
1361             break;
1362    // ------------
1363    case 98: // version
1364             {
1365                int n98_v,n98_m;
1366                BITSET n98_o1,n98_o2;
1367                n98_v=s_readint(d->f_read);
1368                n98_m=s_readint(d->f_read);
1369                n98_o1=s_readint(d->f_read);
1370                n98_o2=s_readint(d->f_read);
1371                if ((n98_v!=SSI_VERSION) ||(n98_m!=MAX_TOK))
1372                {
1373                  Print("incompatible versions of ssi: %d/%d vs %d/%d\n",
1374                                  SSI_VERSION,MAX_TOK,n98_v,n98_m);
1375                }
1376                #ifndef SING_NDEBUG
1377                if (TEST_OPT_DEBUG)
1378                  Print("// opening ssi-%d, MAX_TOK=%d\n",n98_v,n98_m);
1379                #endif
1380                si_opt_1=n98_o1;
1381                si_opt_2=n98_o2;
1382                omFreeBin(res,sleftv_bin);
1383                return ssiRead1(l);
1384             }
1385    case 99: omFreeBin(res,sleftv_bin); ssiClose(l); m2_end(0);
1386    case 0: if (s_iseof(d->f_read))
1387            {
1388              ssiClose(l);
1389            }
1390            res->rtyp=DEF_CMD;
1391            break;
1392    default: Werror("not implemented (t:%d)",t);
1393             omFreeBin(res,sleftv_bin);
1394             res=NULL;
1395             break;
1396  }
1397  // if currRing is required for the result, but lost
1398  // define "ssiRing%d" as currRing:
1399  if ((d->r!=NULL)
1400  && (currRing!=d->r)
1401  && (res->RingDependend()))
1402  {
1403    if(ssiSetCurrRing(d->r)) { d->r=currRing; d->r->ref++; }
1404  }
1405  return res;
1406no_ring: WerrorS("no ring");
1407  omFreeBin(res,sleftv_bin);
1408  return NULL;
1409}
1410//**************************************************************************/
1411BOOLEAN ssiSetRing(si_link l, ring r, BOOLEAN send)
1412{
1413  if(SI_LINK_W_OPEN_P(l)==0)
1414     if (slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL)) return TRUE;
1415  ssiInfo *d = (ssiInfo *)l->data;
1416  if (d->r!=r)
1417  {
1418    if (send)
1419    {
1420      fputs("15 ",d->f_write);
1421      ssiWriteRing(d,r);
1422    }
1423    d->r=r;
1424  }
1425  if (currRing!=r) rChangeCurrRing(r);
1426  return FALSE;
1427}
1428//**************************************************************************/
1429
1430BOOLEAN ssiWrite(si_link l, leftv data)
1431{
1432  if(SI_LINK_W_OPEN_P(l)==0)
1433     if (slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE,NULL)) return TRUE;
1434  ssiInfo *d = (ssiInfo *)l->data;
1435  d->level++;
1436  //FILE *fich=d->f;
1437  while (data!=NULL)
1438  {
1439    int tt=data->Typ();
1440    void *dd=data->Data();
1441    attr *aa=data->Attribute();
1442    BOOLEAN with_attr=FALSE;
1443    if ((aa!=NULL) && ((*aa)!=NULL))
1444    {
1445      attr a=*aa;
1446      int n=0;
1447      while(a!=NULL) { n++; a=a->next;}
1448      fprintf(d->f_write,"21 %d %d ",data->flag,n);
1449    }
1450    else if (data->flag!=0)
1451    {
1452      fprintf(d->f_write,"21 %d 0 ",data->flag);
1453    }
1454    if ((dd==NULL) && (data->name!=NULL) && (tt==0)) tt=DEF_CMD;
1455      // return pure undefined names as def
1456
1457    switch(tt /*data->Typ()*/)
1458    {
1459          case 0: /*error*/
1460          case NONE/* nothing*/:fputs("16 ",d->f_write);
1461                          break;
1462          case STRING_CMD: fputs("2 ",d->f_write);
1463                           ssiWriteString(d,(char *)dd);
1464                           break;
1465          case INT_CMD: fputs("1 ",d->f_write);
1466                        ssiWriteInt(d,(int)(long)dd);
1467                        break;
1468          case BIGINT_CMD:fputs("4 ",d->f_write);
1469                        ssiWriteBigInt(d,(number)dd);
1470                        break;
1471          case NUMBER_CMD:
1472                          if (d->r!=currRing)
1473                          {
1474                            fputs("15 ",d->f_write);
1475                            ssiWriteRing(d,currRing);
1476                            if (d->level<=1) fputc('\n',d->f_write);
1477                          }
1478                          fputs("3 ",d->f_write);
1479                          ssiWriteNumber(d,(number)dd);
1480                        break;
1481          case RING_CMD:fputs("5 ",d->f_write);
1482                        ssiWriteRing(d,(ring)dd);
1483                        break;
1484          case BUCKET_CMD:
1485                        {
1486                          sBucket_pt b=(sBucket_pt)dd;
1487                          if (d->r!=sBucketGetRing(b))
1488                          {
1489                            fputs("15 ",d->f_write);
1490                            ssiWriteRing(d,sBucketGetRing(b));
1491                            if (d->level<=1) fputc('\n',d->f_write);
1492                          }
1493                          fputs("6 ",d->f_write);
1494                          ssiWritePoly(d,tt,sBucketPeek(b));
1495                          break;
1496                        }
1497          case POLY_CMD:
1498          case VECTOR_CMD:
1499                        if (d->r!=currRing)
1500                        {
1501                          fputs("15 ",d->f_write);
1502                          ssiWriteRing(d,currRing);
1503                          if (d->level<=1) fputc('\n',d->f_write);
1504                        }
1505                        if(tt==POLY_CMD) fputs("6 ",d->f_write);
1506                        else             fputs("9 ",d->f_write);
1507                        ssiWritePoly(d,tt,(poly)dd);
1508                        break;
1509          case IDEAL_CMD:
1510          case MODUL_CMD:
1511          case MATRIX_CMD:
1512          case SMATRIX_CMD:
1513                        if (d->r!=currRing)
1514                        {
1515                          fputs("15 ",d->f_write);
1516                          ssiWriteRing(d,currRing);
1517                          if (d->level<=1) fputc('\n',d->f_write);
1518                        }
1519                        if(tt==IDEAL_CMD)       fputs("7 ",d->f_write);
1520                        else if(tt==MATRIX_CMD) fputs("8 ",d->f_write);
1521                        else if(tt==SMATRIX_CMD) fputs("22 ",d->f_write);
1522                        else
1523                        {
1524                          ideal M=(ideal)dd;
1525                          fprintf(d->f_write,"10 %d ",(int)M->rank);
1526                        }
1527                        ssiWriteIdeal(d,tt,(ideal)dd);
1528                        break;
1529          case COMMAND:
1530                   fputs("11 ",d->f_write);
1531                   ssiWriteCommand(l,(command)dd);
1532                   break;
1533          case DEF_CMD: /* not evaluated stuff in quotes */
1534                   fputs("12 ",d->f_write);
1535                   ssiWriteString(d,data->Name());
1536                   break;
1537          case PROC_CMD:
1538                   fputs("13 ",d->f_write);
1539                   ssiWriteProc(d,(procinfov)dd);
1540                   break;
1541          case LIST_CMD:
1542                   fputs("14 ",d->f_write);
1543                   ssiWriteList(l,(lists)dd);
1544                   break;
1545          case INTVEC_CMD:
1546                   fputs("17 ",d->f_write);
1547                   ssiWriteIntvec(d,(intvec *)dd);
1548                   break;
1549          case INTMAT_CMD:
1550                   fputs("18 ",d->f_write);
1551                   ssiWriteIntmat(d,(intvec *)dd);
1552                   break;
1553          case BIGINTMAT_CMD:
1554                   fputs("19 ",d->f_write);
1555                   ssiWriteBigintmat(d,(bigintmat *)dd);
1556                   break;
1557          default:
1558            if (tt>MAX_TOK)
1559            {
1560              blackbox *b=getBlackboxStuff(tt);
1561              fputs("20 ",d->f_write);
1562              b->blackbox_serialize(b,dd,l);
1563            }
1564            else
1565            {
1566              Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
1567              d->level=0;
1568              return TRUE;
1569            }
1570            break;
1571    }
1572    if (d->level<=1) { fputc('\n',d->f_write); fflush(d->f_write); }
1573    data=data->next;
1574  }
1575  d->level--;
1576  return FALSE;
1577}
1578
1579BOOLEAN ssiGetDump(si_link l);
1580BOOLEAN ssiDump(si_link l);
1581
1582si_link_extension slInitSsiExtension(si_link_extension s)
1583{
1584  s->Open=ssiOpen;
1585  s->Close=ssiClose;
1586  s->Kill=ssiClose;
1587  s->Read=ssiRead1;
1588  s->Read2=(slRead2Proc)NULL;
1589  s->Write=ssiWrite;
1590  s->Dump=ssiDump;
1591  s->GetDump=ssiGetDump;
1592
1593  s->Status=slStatusSsi;
1594  s->SetRing=ssiSetRing;
1595  s->type="ssi";
1596  return s;
1597}
1598
1599const char* slStatusSsi(si_link l, const char* request)
1600{
1601  ssiInfo *d=(ssiInfo*)l->data;
1602  if (d==NULL) return "not open";
1603  if (((strcmp(l->mode,"fork")==0)
1604  ||(strcmp(l->mode,"tcp")==0)
1605  ||(strcmp(l->mode,"connect")==0))
1606  && (strcmp(request, "read") == 0))
1607  {
1608    fd_set  mask;
1609    struct timeval wt;
1610    if (s_isready(d->f_read)) return "ready";
1611    loop
1612    {
1613      /* Don't block. Return socket status immediately. */
1614      wt.tv_sec  = 0;
1615      wt.tv_usec = 0;
1616
1617      FD_ZERO(&mask);
1618      FD_SET(d->fd_read, &mask);
1619      //Print("test fd %d\n",d->fd_read);
1620    /* check with select: chars waiting: no -> not ready */
1621      switch (si_select(d->fd_read+1, &mask, NULL, NULL, &wt))
1622      {
1623        case 0: /* not ready */ return "not ready";
1624        case -1: /*error*/      return "error";
1625        case 1: /*ready ? */    break;
1626      }
1627    /* yes: read 1 char*/
1628    /* if \n, check again with select else ungetc(c), ready*/
1629      int c=s_getc(d->f_read);
1630      //Print("try c=%d\n",c);
1631      if (c== -1) return "eof"; /* eof or error */
1632      else if (isdigit(c))
1633      { s_ungetc(c,d->f_read); return "ready"; }
1634      else if (c>' ')
1635      {
1636        Werror("unknown char in ssiLink(%d)",c);
1637        return "error";
1638      }
1639      /* else: next char */
1640    }
1641  }
1642  else if (strcmp(request, "read") == 0)
1643  {
1644    if (SI_LINK_R_OPEN_P(l) && (!s_iseof(d->f_read)) && (s_isready(d->f_read))) return "ready";
1645    else return "not ready";
1646  }
1647  else if (strcmp(request, "write") == 0)
1648  {
1649    if (SI_LINK_W_OPEN_P(l)) return "ready";
1650    else return "not ready";
1651  }
1652  else return "unknown status request";
1653}
1654
1655int slStatusSsiL(lists L, int timeout)
1656{
1657// input: L: a list with links of type
1658//           ssi-connect, ssi-fork, ssi-tcp, MPtcp-fork or MPtcp-launch.
1659//           Note: Not every entry in L must be set.
1660//        timeout: timeout for select in micro-seconds
1661//           or -1 for infinity
1662//           or 0 for polling
1663// returns: ERROR (via Werror): L has wrong elements or link not open
1664//           -2: select returns an error
1665//           -1: the read state of all links is eof
1666//           0:  timeout (or polling): none ready,
1667//           i>0: (at least) L[i] is ready
1668  si_link l;
1669  ssiInfo *d;
1670  int d_fd;
1671  fd_set  mask, fdmask;
1672  FD_ZERO(&fdmask);
1673  FD_ZERO(&mask);
1674  int max_fd=0; /* 1 + max fd in fd_set */
1675
1676  /* timeout */
1677  struct timeval wt;
1678  struct timeval *wt_ptr=&wt;
1679  int startingtime = getRTimer()/TIMER_RESOLUTION;  // in seconds
1680  if (timeout== -1)
1681  {
1682    wt_ptr=NULL;
1683  }
1684  else
1685  {
1686    wt.tv_sec  = timeout / 1000000;
1687    wt.tv_usec = timeout % 1000000;
1688  }
1689
1690  /* auxiliary variables */
1691  int i;
1692  int j;
1693  int k;
1694  int s;
1695  char fdmaskempty;
1696
1697  /* check the links and fill in fdmask */
1698  /* check ssi links for ungetc_buf */
1699  for(i=L->nr; i>=0; i--)
1700  {
1701    if (L->m[i].Typ()!=DEF_CMD)
1702    {
1703      if (L->m[i].Typ()!=LINK_CMD)
1704      { WerrorS("all elements must be of type link"); return -2;}
1705      l=(si_link)L->m[i].Data();
1706      if(SI_LINK_OPEN_P(l)==0)
1707      { WerrorS("all links must be open"); return -2;}
1708      if (((strcmp(l->m->type,"ssi")!=0) && (strcmp(l->m->type,"MPtcp")!=0))
1709      || ((strcmp(l->mode,"fork")!=0) && (strcmp(l->mode,"tcp")!=0)
1710        && (strcmp(l->mode,"launch")!=0) && (strcmp(l->mode,"connect")!=0)))
1711      {
1712        WerrorS("all links must be of type ssi:fork, ssi:tcp, ssi:connect");
1713        return -2;
1714      }
1715      if (strcmp(l->m->type,"ssi")==0)
1716      {
1717        d=(ssiInfo*)l->data;
1718        d_fd=d->fd_read;
1719        if (!s_isready(d->f_read))
1720        {
1721          FD_SET(d_fd, &fdmask);
1722          if (d_fd > max_fd) max_fd=d_fd;
1723        }
1724        else
1725          return i+1;
1726      }
1727      else
1728      {
1729        Werror("wrong link type >>%s<<",l->m->type);
1730        return -2;
1731      }
1732    }
1733  }
1734  max_fd++;
1735
1736do_select:
1737  /* copy fdmask to mask */
1738  FD_ZERO(&mask);
1739  for(k = 0; k < max_fd; k++)
1740  {
1741    if(FD_ISSET(k, &fdmask))
1742    {
1743      FD_SET(k, &mask);
1744    }
1745  }
1746
1747  /* check with select: chars waiting: no -> not ready */
1748  s = si_select(max_fd, &mask, NULL, NULL, wt_ptr);
1749  if (s==-1)
1750  {
1751    WerrorS("error in select call");
1752    return -2; /*error*/
1753  }
1754  if (s==0)
1755  {
1756    return 0; /*poll: not ready */
1757  }
1758  else /* s>0, at least one ready  (the number of fd which are ready is s)*/
1759  {
1760    j=0;
1761    while (j<=max_fd) { if (FD_ISSET(j,&mask)) break; j++; }
1762    for(i=L->nr; i>=0; i--)
1763    {
1764      if (L->m[i].rtyp==LINK_CMD)
1765      {
1766        l=(si_link)L->m[i].Data();
1767        if (strcmp(l->m->type,"ssi")==0)
1768        {
1769          d=(ssiInfo*)l->data;
1770          d_fd=d->fd_read;
1771          if(j==d_fd) break;
1772        }
1773        else
1774        {
1775          Werror("wrong link type >>%s<<",l->m->type);
1776          return -2;
1777        }
1778      }
1779    }
1780    // only ssi links:
1781    loop
1782    {
1783      /* yes: read 1 char*/
1784      /* if \n, check again with select else ungetc(c), ready*/
1785      /* setting: d: current ssiInfo, j current fd, i current entry in L*/
1786      int c=s_getc(d->f_read);
1787      //Print("try c=%d\n",c);
1788      if (c== -1) /* eof */
1789      {
1790        FD_CLR(j,&fdmask);
1791        fdmaskempty = 1;
1792        for(k = 0; k < max_fd; k++)
1793        {
1794          if(FD_ISSET(k, &fdmask))
1795          {
1796            fdmaskempty = 0;
1797            break;
1798          }
1799        }
1800        if(fdmaskempty)
1801        {
1802          return -1;
1803        }
1804        if(timeout != -1)
1805        {
1806          timeout = si_max(0,
1807             timeout - 1000000*(getRTimer()/TIMER_RESOLUTION - startingtime));
1808          wt.tv_sec  = timeout / 1000000;
1809          wt.tv_usec = (timeout % 1000000);
1810        }
1811        goto do_select;
1812      }
1813
1814      else if (isdigit(c))
1815      { s_ungetc(c,d->f_read); return i+1; }
1816      else if (c>' ')
1817      {
1818        Werror("unknown char in ssiLink(%d)",c);
1819        return -2;
1820      }
1821      /* else: next char */
1822      goto do_select;
1823    }
1824  }
1825}
1826
1827int ssiBatch(const char *host, const char * port)
1828/* return 0 on success, >0 else*/
1829{
1830  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
1831  char *buf=(char*)omAlloc(256);
1832  sprintf(buf,"ssi:connect %s:%s",host,port);
1833  slInit(l, buf);
1834  omFreeSize(buf,256);
1835  if (slOpen(l,SI_LINK_OPEN,NULL)) return 1;
1836  SI_LINK_SET_RW_OPEN_P(l);
1837
1838  idhdl id = enterid("link_ll", 0, LINK_CMD, &IDROOT, FALSE);
1839  IDLINK(id) = l;
1840
1841  loop
1842  {
1843    leftv h=ssiRead1(l); /*contains an exit.... */
1844    if (feErrors != NULL && *feErrors != '\0')
1845    {
1846      // handle errors:
1847      PrintS(feErrors); /* currently quite simple */
1848      *feErrors = '\0';
1849    }
1850    ssiWrite(l,h);
1851    h->CleanUp();
1852    omFreeBin(h, sleftv_bin);
1853  }
1854  /* never reached*/
1855  exit(0);
1856}
1857
1858STATIC_VAR int ssiReserved_P=0;
1859STATIC_VAR int ssiReserved_sockfd;
1860STATIC_VAR struct sockaddr_in ssiResverd_serv_addr;
1861STATIC_VAR int  ssiReserved_Clients;
1862int ssiReservePort(int clients)
1863{
1864  if (ssiReserved_P!=0)
1865  {
1866    WerrorS("ERROR already a reverved port requested");
1867    return 0;
1868  }
1869  int portno;
1870  ssiReserved_sockfd = socket(AF_INET, SOCK_STREAM, 0);
1871  if(ssiReserved_sockfd < 0)
1872  {
1873    WerrorS("ERROR opening socket");
1874    return 0;
1875  }
1876  memset((char *) &ssiResverd_serv_addr,0, sizeof(ssiResverd_serv_addr));
1877  portno = 1025;
1878  ssiResverd_serv_addr.sin_family = AF_INET;
1879  ssiResverd_serv_addr.sin_addr.s_addr = INADDR_ANY;
1880  do
1881  {
1882    portno++;
1883    ssiResverd_serv_addr.sin_port = htons(portno);
1884    if(portno > 50000)
1885    {
1886      WerrorS("ERROR on binding (no free port available?)");
1887      return 0;
1888    }
1889  }
1890  while(bind(ssiReserved_sockfd, (struct sockaddr *) &ssiResverd_serv_addr, sizeof(ssiResverd_serv_addr)) < 0);
1891  ssiReserved_P=portno;
1892  listen(ssiReserved_sockfd,clients);
1893  ssiReserved_Clients=clients;
1894  return portno;
1895}
1896
1897EXTERN_VAR si_link_extension si_link_root;
1898si_link ssiCommandLink()
1899{
1900  if (ssiReserved_P==0)
1901  {
1902    WerrorS("ERROR no reverved port requested");
1903    return NULL;
1904  }
1905  struct sockaddr_in cli_addr;
1906  int clilen = sizeof(cli_addr);
1907  int newsockfd = si_accept(ssiReserved_sockfd, (struct sockaddr *) &cli_addr, (socklen_t *)&clilen);
1908  if(newsockfd < 0)
1909  {
1910    Werror("ERROR on accept (errno=%d)",errno);
1911    return NULL;
1912  }
1913  si_link l=(si_link) omAlloc0Bin(sip_link_bin);
1914  si_link_extension s = si_link_root;
1915  si_link_extension prev = s;
1916  while (strcmp(s->type, "ssi") != 0)
1917  {
1918    if (s->next == NULL)
1919    {
1920      prev = s;
1921      s = NULL;
1922      break;
1923    }
1924    else
1925    {
1926      s = s->next;
1927    }
1928  }
1929  if (s != NULL)
1930    l->m = s;
1931  else
1932  {
1933    si_link_extension ns = (si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
1934    prev->next=slInitSsiExtension(ns);
1935    l->m = prev->next;
1936  }
1937  l->name=omStrDup("");
1938  l->mode=omStrDup("tcp");
1939  l->ref=1;
1940  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
1941  l->data=d;
1942  d->fd_read = newsockfd;
1943  d->fd_write = newsockfd;
1944  d->f_read = s_open(newsockfd);
1945  d->f_write = fdopen(newsockfd, "w");
1946  SI_LINK_SET_RW_OPEN_P(l);
1947  ssiReserved_Clients--;
1948  if (ssiReserved_Clients<=0)
1949  {
1950    ssiReserved_P=0;
1951    si_close(ssiReserved_sockfd);
1952  }
1953  return l;
1954}
1955/*---------------------------------------------------------------------*/
1956/**
1957 * @brief additional default signal handler
1958
1959  // some newer Linux version cannot have SIG_IGN for SIGCHLD,
1960  // so use this nice routine here:
1961  //  SuSe 9.x reports -1 always
1962  //  Redhat 9.x/FC x reports sometimes -1
1963  // see also: hpux_system
1964  // also needed by getrusage (timer etc.)
1965
1966 @param[in] sig
1967**/
1968/*---------------------------------------------------------------------*/
1969void sig_chld_hdl(int)
1970{
1971  pid_t kidpid;
1972  int status;
1973
1974  loop
1975  {
1976    kidpid = si_waitpid(-1, &status, WNOHANG);
1977    if (kidpid==-1)
1978    {
1979      /* continue on interruption (EINTR): */
1980      if (errno == EINTR) continue;
1981      /* break on anything else (EINVAL or ECHILD according to manpage): */
1982      break;
1983    }
1984    else if (kidpid==0) break; /* no more children to process, so break */
1985
1986    //printf("Child %ld terminated\n", kidpid);
1987    link_list hh=ssiToBeClosed;
1988    while((hh!=NULL)&&(ssiToBeClosed_inactive))
1989    {
1990      if((hh->l!=NULL) && (hh->l->m->Open==ssiOpen))
1991      {
1992        ssiInfo *d = (ssiInfo *)hh->l->data;
1993        if(d->pid==kidpid)
1994        {
1995          if(ssiToBeClosed_inactive)
1996          {
1997            ssiToBeClosed_inactive=FALSE;
1998            slClose(hh->l);
1999            ssiToBeClosed_inactive=TRUE;
2000            break;
2001          }
2002          else break;
2003        }
2004        else hh=(link_list)hh->next;
2005      }
2006      else hh=(link_list)hh->next;
2007    }
2008  }
2009}
2010
2011static BOOLEAN DumpSsiIdhdl(si_link l, idhdl h)
2012{
2013  int type_id = IDTYP(h);
2014
2015  // C-proc not to be dumped, also LIB-proc not
2016  if (type_id == PROC_CMD)
2017  {
2018    if (IDPROC(h)->language == LANG_C) return FALSE;
2019    if (IDPROC(h)->libname != NULL) return FALSE;
2020  }
2021  // do not dump links
2022  if (type_id == LINK_CMD) return FALSE;
2023
2024  // do not dump ssi internal rings: ssiRing*
2025  if ((type_id == RING_CMD) && (strncmp(IDID(h),"ssiRing",7)==0))
2026    return FALSE;
2027
2028  // do not dump default cring:
2029  if (type_id == CRING_CMD)
2030  {
2031    if (strcmp(IDID(h),"ZZ")==0) return FALSE;
2032    if (strcmp(IDID(h),"QQ")==0) return FALSE;
2033    #ifdef SINGULAR_4_2
2034    if (strcmp(IDID(h),"AE")==0) return FALSE;
2035    if (strcmp(IDID(h),"QAE")==0) return FALSE;
2036    #endif
2037  }
2038
2039  command D=(command)omAlloc0(sizeof(*D));
2040  sleftv tmp;
2041  memset(&tmp,0,sizeof(tmp));
2042  tmp.rtyp=COMMAND;
2043  tmp.data=D;
2044
2045  if (type_id == PACKAGE_CMD)
2046  {
2047    // do not dump Top, Standard
2048    if ((strcmp(IDID(h), "Top") == 0)
2049    || (strcmp(IDID(h), "Standard") == 0))
2050    {
2051      omFreeSize(D,sizeof(*D));
2052      return FALSE;
2053    }
2054    package p=(package)IDDATA(h);
2055    // dump Singular-packages as LIB("...");
2056    if (p->language==LANG_SINGULAR)
2057    {
2058      D->op=LOAD_CMD;
2059      D->argc=2;
2060      D->arg1.rtyp=STRING_CMD;
2061      D->arg1.data=p->libname;
2062      D->arg2.rtyp=STRING_CMD;
2063      D->arg2.data=(char*)"with";
2064      ssiWrite(l,&tmp);
2065      omFreeSize(D,sizeof(*D));
2066      return FALSE;
2067    }
2068    // dump Singular-packages as load("...");
2069    else if (p->language==LANG_C)
2070    {
2071      D->op=LOAD_CMD;
2072      D->argc=1;
2073      D->arg1.rtyp=STRING_CMD;
2074      D->arg1.data=p->libname;
2075      ssiWrite(l,&tmp);
2076      omFreeSize(D,sizeof(*D));
2077      return FALSE;
2078    }
2079  }
2080
2081  // put type and name
2082  //Print("generic dump:%s,%s\n",IDID(h),Tok2Cmdname(IDTYP(h)));
2083  D->op='=';
2084  D->argc=2;
2085  D->arg1.rtyp=DEF_CMD;
2086  D->arg1.name=IDID(h);
2087  D->arg2.rtyp=IDTYP(h);
2088  D->arg2.data=IDDATA(h);
2089  ssiWrite(l,&tmp);
2090  omFreeSize(D,sizeof(*D));
2091  return FALSE;
2092}
2093static BOOLEAN ssiDumpIter(si_link l, idhdl h)
2094{
2095  if (h == NULL) return FALSE;
2096
2097  if (ssiDumpIter(l, IDNEXT(h))) return TRUE;
2098
2099  // need to set the ring before writing it, otherwise we get in
2100  // trouble with minpoly
2101  if (IDTYP(h) == RING_CMD)
2102    rSetHdl(h);
2103
2104  if (DumpSsiIdhdl(l, h)) return TRUE;
2105
2106  // do not dump ssi internal rings: ssiRing*
2107  // but dump objects of all other rings
2108  if ((IDTYP(h) == RING_CMD)
2109  && (strncmp(IDID(h),"ssiRing",7)!=0))
2110    return ssiDumpIter(l, IDRING(h)->idroot);
2111  else
2112    return FALSE;
2113}
2114BOOLEAN ssiDump(si_link l)
2115{
2116  idhdl h = IDROOT, rh = currRingHdl;
2117  BOOLEAN status = ssiDumpIter(l, h);
2118
2119  //if (! status ) status = DumpAsciiMaps(fd, h, NULL);
2120
2121  if (currRingHdl != rh) rSetHdl(rh);
2122  //fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
2123
2124  return status;
2125}
2126BOOLEAN ssiGetDump(si_link l)
2127{
2128  ssiInfo *d=(ssiInfo*)l->data;
2129  loop
2130  {
2131    if (!SI_LINK_OPEN_P(l)) break;
2132    if (s_iseof(d->f_read)) break;
2133    leftv h=ssiRead1(l); /*contains an exit.... */
2134    if (feErrors != NULL && *feErrors != '\0')
2135    {
2136      // handle errors:
2137      PrintS(feErrors); /* currently quite simple */
2138      return TRUE;
2139      *feErrors = '\0';
2140    }
2141    h->CleanUp();
2142    omFreeBin(h, sleftv_bin);
2143  }
2144  return FALSE;
2145}
2146// ----------------------------------------------------------------
2147// format
2148// 1 int %d
2149// 2 string <len> %s
2150// 3 number
2151// 4 bigint 4 %d or 3 <mpz_t>
2152// 5 ring
2153// 6 poly
2154// 7 ideal
2155// 8 matrix
2156// 9 vector
2157// 10 module
2158// 11 command
2159// 12 def <len> %s
2160// 13 proc <len> %s
2161// 14 list %d <elem1> ....
2162// 15 setring .......
2163// 16 nothing
2164// 17 intvec <len> ...
2165// 18 intmat
2166// 19 bigintmat <r> <c> ...
2167// 20 blackbox <name> 1 <len> ...
2168// 21 attrib <bit-attrib> <len> <a-name1> <val1>... <data>
2169// 22 smatrix
2170//
2171// 98: verify version: <ssi-version> <MAX_TOK> <OPT1> <OPT2>
2172// 99: quit Singular
Note: See TracBrowser for help on using the repository browser.