source: git/Singular/links/ssiLink.cc @ 03ce7d6

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