source: git/Singular/ssiLink.cc @ 6c2364

spielwiese
Last change on this file since 6c2364 was 6c2364, checked in by Hans Schoenemann <hannes@…>, 14 years ago
ssi: status simplified git-svn-id: file:///usr/local/Singular/svn/trunk@13093 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 20.9 KB
Line 
1/****************************************
2 * Computer Algebra System SINGULAR     *
3 ****************************************/
4/***************************************************************
5 * File:    ssiLink.h
6 *  Purpose: declaration of sl_link routines for ssi
7 *  Version: $Id$
8 ***************************************************************/
9#include <stdio.h>
10#include <fcntl.h>
11#include <errno.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <signal.h>
15#include <sys/select.h>
16#include <ctype.h>   /*for isdigit*/
17
18
19#include "mod2.h"
20
21#include "tok.h"
22#include "ipid.h"
23#include <omalloc.h>
24#include <kernel/ring.h>
25#include <kernel/matpol.h>
26#include <kernel/ideals.h>
27#include <kernel/polys.h>
28#include <kernel/longrat.h>
29#include <kernel/ideals.h>
30#include "subexpr.h"
31#include "silink.h"
32#include "lists.h"
33#include "ssiLink.h"
34
35typedef struct
36{
37  FILE *f_read;
38  FILE *f_write;
39  ring r;
40  pid_t pid; /* only valid for fork/tcp mode*/
41  int fd_read,fd_write; /* only valid for fork/tcp mode*/
42  char level;
43} ssiInfo;
44
45// the helper functions:
46void ssiSetCurrRing(const ring r)
47{
48  if (!rEqual(r,currRing,1))
49  {
50    char name[20];
51    int nr=0;
52    do
53    { sprintf(name,"ssiRing%d",nr); nr++; }
54    while(IDROOT->get(name, 0)!=NULL);
55    idhdl h=enterid(omStrDup(name),0,RING_CMD,&IDROOT,FALSE);
56    IDRING(h)=r;
57    r->ref++;
58    rSetHdl(h);
59  }
60}
61// the implementation of the functions:
62void ssiWriteInt(ssiInfo *d,const int i)
63{
64  fprintf(d->f_write,"%d ",i);
65  //if (d->f_debug!=NULL) fprintf(d->f_debug,"int: %d ",i);
66}
67
68void ssiWriteString(ssiInfo *d,const char *s)
69{
70  fprintf(d->f_write,"%d %s ",strlen(s),s);
71  //if (d->f_debug!=NULL) fprintf(d->f_debug,"stringi: %d \"%s\" ",strlen(s),s);
72}
73
74
75void ssiWriteBigInt(const ssiInfo *d, const number n)
76{
77  // syntax is as follows:
78  // case 2 Q:     3 4 <int>
79  //        or     3 3 <mpz_t nominator>
80  if(SR_HDL(n) & SR_INT)
81  {
82    fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
83    //if (d->f_debug!=NULL) fprintf(d->f_debug,"bigint: short \"%ld\" ",SR_TO_INT(n));
84  }
85  else if (n->s==3)
86  {
87    gmp_fprintf(d->f_write,"3 %Zd ",n->z);
88    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"bigint: gmp \"%Zd\" ",n->z);
89  }
90  else Werror("illiegal bigint");
91}
92
93void ssiWriteNumber(const ssiInfo *d, const number n)
94{
95  // syntax is as follows:
96  // case 1 Z/p:   3 <int>
97  // case 2 Q:     3 4 <int>
98  //        or     3 0 <mpz_t nominator> <mpz_t denominator>
99  //        or     3 1  dto.
100  //        or     3 3 <mpz_t nominator>
101  if(rField_is_Zp(d->r))
102  {
103    fprintf(d->f_write,"%d ",(int)(long)n);
104    //if (d->f_debug!=NULL) fprintf(d->f_debug,"number: \"%ld\" ",(int)(long)n);
105  }
106  else if (rField_is_Q(d->r))
107  {
108    if(SR_HDL(n) & SR_INT)
109    {
110      fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
111      //if (d->f_debug!=NULL) fprintf(d->f_debug,"number: short \"%ld\" ",SR_TO_INT(n));
112    }
113    else if (n->s<2)
114    {
115      gmp_fprintf(d->f_write,"%d %Zd %Zd ",n->s,n->z,n->n);
116      //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
117    }
118    else /*n->s==3*/
119    {
120      gmp_fprintf(d->f_write,"3 %Zd ",n->z);
121      //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
122    }
123  }
124  else WerrorS("coeff field not implemented");
125}
126
127void ssiWriteRing(ssiInfo *d,const ring r)
128{
129  /* 5 <ch> <N> <l1> <s1>....<ln> <sN> */
130  if (d->r!=NULL) rKill(d->r);
131  d->r=r;
132  d->r->ref++;
133  fprintf(d->f_write,"%d %d ",r->ch,r->N);
134
135  int i;
136  for(i=0;i<r->N;i++)
137  {
138    fprintf(d->f_write,"%d %s ",strlen(r->names[i]),r->names[i]);
139  }
140  /* number of orderings:*/
141  i=0;
142  while (r->order[i]!=0) i++;
143  fprintf(d->f_write,"%d ",i);
144  /* each ordering block: */
145  i=0;
146  while(r->order[i]!=0)
147  {
148    fprintf(d->f_write,"%d %d %d ",r->order[i],r->block0[i], r->block1[i]);
149    i++;
150  }
151}
152
153void ssiWritePoly(ssiInfo *d, int typ, poly p)
154{
155  fprintf(d->f_write,"%d ",pLength(p));//number of terms
156  int i;
157
158  while(p!=NULL)
159  {
160    ssiWriteNumber(d,pGetCoeff(p));
161    //nWrite(fich,pGetCoeff(p));
162    fprintf(d->f_write,"%ld ",p_GetComp(p,d->r));//component
163
164    for(int j=1;j<=rVar(d->r);j++)
165    {
166      fprintf(d->f_write,"%ld ",p_GetExp(p,j,d->r ));//x^j
167    }
168    pIter(p);
169  }
170}
171
172void ssiWriteIdeal(ssiInfo *d, int typ,ideal I)
173{
174   // syntax: 7 # of elements <poly 1> <poly2>.....
175   // syntax: 8 <rows> <cols> <poly 1> <poly2>.....
176   matrix M=(matrix)I;
177   if (typ==MATRIX_CMD)
178        fprintf(d->f_write,"%d %d ", MATROWS(M),MATCOLS(M));
179   else
180     fprintf(d->f_write,"%d ",IDELEMS(I));
181
182   int i;
183   int tt;
184   if (typ==MODUL_CMD) tt=VECTOR_CMD;
185   else                tt=POLY_CMD;
186
187   for(i=0;i<IDELEMS(I);i++)
188   {
189     ssiWritePoly(d,tt,I->m[i]);
190   }
191}
192void ssiWriteCommand(si_link l, command D)
193{
194  ssiInfo *d=(ssiInfo*)l->data;
195  // syntax: <num ops> <operation> <op1> <op2> ....
196  fprintf(d->f_write,"%d %d ",D->argc,D->op);
197  if (D->argc >0) ssiWrite(l, &(D->arg1));
198  if (D->argc < 4)
199  {
200    if (D->argc >1) ssiWrite(l, &(D->arg2));
201    if (D->argc >2) ssiWrite(l, &(D->arg3));
202  }
203}
204
205void ssiWriteProc(ssiInfo *d,procinfov p)
206{
207  ssiWriteString(d,p->data.s.body);
208}
209
210void ssiWriteList(si_link l,lists dd)
211{
212  ssiInfo *d=(ssiInfo*)l->data;
213  fprintf(d->f_write,"%d ",dd->nr+1);
214  int i;
215  for(i=0;i<=dd->nr;i++)
216  {
217    ssiWrite(l,&(dd->m[i]));
218  }
219}
220
221char *ssiReadString(ssiInfo *d)
222{
223  char *buf;
224  int l;
225  fscanf(d->f_read,"%d ",&l);
226  buf=(char*)omAlloc(l+1);
227  fread(buf,1,l,d->f_read);
228  buf[l]='\0';
229  return buf;
230}
231
232int ssiReadInt(FILE *fich)
233{
234  int d;
235  fscanf(fich,"%d",&d);
236  return d;
237}
238
239number ssiReadBigInt(ssiInfo *d)
240{
241   int sub_type=-1;
242   fscanf(d->f_read,"%d",&sub_type);
243   switch(sub_type)
244   {
245   case 3:
246     {// read int or mpz_t or mpz_t, mpz_t
247       number n=nlRInit(0);
248       gmp_fscanf(d->f_read,"%Zd",n->z);
249       n->s=sub_type;
250       return n;
251     }
252   case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
253   default: Werror("error in reading number: invalid subtype %d",sub_type);
254            return NULL;
255   }
256}
257
258number ssiReadNumber(ssiInfo *d)
259{
260  if (rField_is_Q(d->r))
261  {
262     int sub_type=-1;
263     fscanf(d->f_read,"%d",&sub_type);
264     switch(sub_type)
265     {
266     case 0:
267     case 1:
268       {// read int or mpz_t or mpz_t, mpz_t
269        number n=nlRInit(0);
270        mpz_init(n->n);
271        gmp_fscanf(d->f_read,"%Zd %Zd",n->z,n->n);
272        n->s=sub_type;
273        return n;
274       }
275
276     case 3:
277       {// read int or mpz_t or mpz_t, mpz_t
278         number n=nlRInit(0);
279         gmp_fscanf(d->f_read,"%Zd",n->z);
280         n->s=sub_type;
281         return n;
282       }
283     case 4: { int dd; fscanf(d->f_read,"%d",&dd); return INT_TO_SR(dd); }
284     default: Werror("error in reading number: invalid subtype %d",sub_type);
285              return NULL;
286     }
287  }
288  else if (rField_is_Zp(d->r))
289  {
290    // read int
291    int dd;
292    fscanf(d->f_read,"%d",&dd);
293    return (number)dd;
294  }
295  else Werror("coeffs not implemented");
296  return NULL;
297}
298
299ring ssiReadRing(ssiInfo *d)
300{
301/* syntax is <ch> <N> <l1> <s1> ....<lN> <sN> */
302  int ch, N,i,l;
303  char **names;
304  fscanf(d->f_read,"%d %d ",&ch,&N);
305  names=(char**)omAlloc(N*sizeof(char*));
306  for(i=0;i<N;i++)
307  {
308    names[i]=ssiReadString(d);
309  }
310  // read the orderings:
311  int num_ord; // number of orderings
312  fscanf(d->f_read,"%d",&num_ord);
313  int *ord=(int *)omAlloc0((num_ord+1)*sizeof(int));
314  int *block0=(int *)omAlloc0((num_ord+1)*sizeof(int));
315  int *block1=(int *)omAlloc0((num_ord+1)*sizeof(int));
316  for(i=0;i<num_ord;i++)
317  {
318     fscanf(d->f_read,"%d %d %d",&ord[i],&block0[i],&block1[i]);
319  }
320  return rDefault(ch,N,names,num_ord,ord,block0,block1);
321}
322
323poly ssiReadPoly(ssiInfo *D)
324{
325// < # of terms> < term1> < .....
326  int n,i,l;
327  n=ssiReadInt(D->f_read);
328  //Print("poly: terms:%d\n",n);
329  poly p;
330  int j;
331  j=0;
332  poly ret=NULL;
333  poly prev=NULL;
334  for(l=0;l<n;l++) // read n terms
335  {
336// coef,comp.exp1,..exp N
337    p=p_Init(D->r);
338    pGetCoeff(p)=ssiReadNumber(D);
339    int d;
340    fscanf(D->f_read,"%d",&d);
341    p_SetComp(p,d,D->r);
342    for(i=1;i<=rVar(D->r);i++)
343    {
344      fscanf(D->f_read,"%d",&d);
345      p_SetExp(p,i,d,D->r);
346    }
347    p_Setm(p,D->r);
348    p_Test(p,D->r);
349    if (ret==NULL) ret=p;
350    else           pNext(prev)=p;
351    prev=p;
352 }
353 return ret;
354}
355
356ideal ssiReadIdeal(ssiInfo *d)
357{
358  int n,i;
359  ideal I;
360  fscanf(d->f_read,"%d",&n);
361  I=idInit(n,1);
362  for(i=0;i<IDELEMS(I);i++) // read n terms
363  {
364    I->m [i]=ssiReadPoly(d);
365  }
366  return I;
367}
368
369matrix ssiReadMatrix(ssiInfo *d)
370{
371  int n,m,i,j;
372  fscanf(d->f_read,"%d %d",&m,&n);
373  matrix M=mpNew(m,n);
374  poly p;
375  for(int i=1;i<=MATROWS(M);i++)
376    for(int j=1;j<=MATCOLS(M);j++)
377    {
378      p=ssiReadPoly(d);
379      MATELEM(M,i,j)=p;
380    }
381  return M;
382}
383
384command ssiReadCommand(si_link l)
385{
386  ssiInfo *d=(ssiInfo*)l->data;
387  // syntax: <num ops> <operation> <op1> <op2> ....
388  command D=(command)omAlloc0(sizeof(*D));
389  int argc,op;
390  fscanf(d->f_read,"%d %d",&argc,&op);
391  D->argc=argc; D->op=op;
392  leftv v;
393  if (argc >0)
394  {
395    v=ssiRead1(l);
396    memcpy(&(D->arg1),v,sizeof(*v));
397    omFreeBin(v,sleftv_bin);
398  }
399  if (argc <4)
400  {
401    if (D->argc >1)
402    {
403      v=ssiRead1(l);
404      memcpy(&(D->arg2),v,sizeof(*v));
405      omFreeBin(v,sleftv_bin);
406    }
407    if (D->argc >2)
408    {
409      v=ssiRead1(l);
410      memcpy(&(D->arg3),v,sizeof(*v));
411      omFreeBin(v,sleftv_bin);
412    }
413  }
414  else
415  {
416    leftv prev=&(D->arg1);
417    argc--;
418    while(argc >0)
419    {
420      v=ssiRead1(l);
421      prev->next=v;
422      prev=v;
423      argc--;
424    }
425  }
426  return D;
427}
428
429procinfov ssiReadProc(ssiInfo *d)
430{
431  char *s=ssiReadString(d);
432  procinfov p=(procinfov)omAlloc0Bin(procinfo_bin);
433  p->language=LANG_SINGULAR;
434  p->libname=omStrDup("");
435  p->procname=omStrDup("");
436  p->data.s.body=s;
437  return p;
438}
439lists ssiReadList(si_link l)
440{
441  ssiInfo *d=(ssiInfo*)l->data;
442  int nr;
443  fscanf(d->f_read,"%d",&nr);
444  lists L=(lists)omAlloc(sizeof(*L));
445  L->Init(nr);
446
447  int i;
448  leftv v;
449  for(i=0;i<nr;i++)
450  {
451    v=ssiRead1(l);
452    memcpy(&(L->m[i]),v,sizeof(*v));
453    omFreeBin(v,sleftv_bin);
454  }
455  return L;
456}
457
458//**************************************************************************/
459BOOLEAN ssiOpen(si_link l, short flag)
460{
461  const char *mode;
462  ssiInfo *d=(ssiInfo*)omAlloc0(sizeof(ssiInfo));
463  if (flag & SI_LINK_OPEN)
464  {
465    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
466      flag = SI_LINK_READ;
467    else flag = SI_LINK_WRITE;
468  }
469
470  if (flag == SI_LINK_READ) mode = "r";
471  else if (strcmp(l->mode, "w") == 0) mode = "w";
472  else if (strcmp(l->mode, "fork") == 0) mode = "fork";
473  else mode = "a";
474
475
476  if (l->name[0] == '\0')
477  {
478    if (strcmp(mode,"fork")==0)
479    {
480      int pc[2];
481      int cp[2];
482      pipe(pc);
483      pipe(cp);
484      pid_t pid=fork();
485      if (pid==0) /*child*/
486      {
487        close(pc[1]); close(cp[0]);
488        d->f_read=fdopen(pc[0],"r");
489        d->fd_read=pc[0];
490        d->f_write=fdopen(cp[1],"w");
491        d->fd_write=cp[1];
492        l->data=d;
493        omFree(l->mode);
494        l->mode = omStrDup(mode);
495        SI_LINK_SET_OPEN_P(l, flag);
496        myynest=0;
497        fe_fgets_stdin=fe_fgets_dummy;
498        loop
499        {
500          leftv h=ssiRead1(l); /*contains an exit.... */
501          if (feErrors != NULL && *feErrors != '\0')
502          {
503            // handle errors:
504            PrintS(feErrors); /* currently quite simple */
505            *feErrors = '\0';
506          }
507          ssiWrite(l,h);
508          h->CleanUp();
509          omFreeBin(h, sleftv_bin);
510        }
511        /* never reached*/
512      }
513      else if (pid>0)
514      {
515        d->pid=pid;
516        close(pc[0]); close(cp[1]);
517        d->f_read=fdopen(cp[0],"r");
518        d->fd_read=cp[0];
519        d->f_write=fdopen(pc[1],"w");
520        d->fd_write=pc[1];
521        l->flags|=SI_LINK_READ|SI_LINK_WRITE;
522      }
523      else
524      {
525        Werror("fork failed (%d)",errno);
526      }
527    }
528    // stdin or stdout
529    else if (flag == SI_LINK_READ)
530    {
531      d->f_read = stdin;
532      mode = "r";
533    }
534    else
535    {
536      d->f_write = stdout;
537      mode = "a";
538    }
539  }
540  else
541  {
542    // normal ascii link to a file
543    FILE *outfile;
544    char *filename=l->name;
545
546    if(filename[0]=='>')
547    {
548      if (filename[1]=='>')
549      {
550        filename+=2;
551        mode = "a";
552      }
553      else
554      {
555        filename++;
556        mode="w";
557      }
558    }
559    outfile=myfopen(filename,mode);
560    if (outfile!=NULL)
561    {
562      if (strcmp(l->mode,"r")==0) d->f_read = outfile;
563      else d->f_write = outfile;
564    }
565    else
566    {
567      omFree(d);
568      return TRUE;
569    }
570  }
571  l->data=d;
572
573  omFree(l->mode);
574  l->mode = omStrDup(mode);
575  SI_LINK_SET_OPEN_P(l, flag);
576  return FALSE;
577}
578
579//**************************************************************************/
580LINKAGE BOOLEAN ssiClose(si_link l)
581{
582  ssiInfo *d = (ssiInfo *)l->data;
583  if (d!=NULL)
584  {
585    if (d->pid!=0) { fprintf(d->f_write,"99\n");fflush(d->f_write); }
586    if (d->f_read!=NULL) fclose(d->f_read);
587    if (d->f_write!=NULL) fclose(d->f_write);
588    if (d->r!=NULL) rKill(d->r);
589    if (d->pid!=0) { kill(d->pid,15); kill(d->pid,9); }
590    omFreeSize((ADDRESS)d,(sizeof *d));
591  }
592  l->data=NULL;
593  SI_LINK_SET_CLOSE_P(l);
594  return FALSE;
595}
596
597//**************************************************************************/
598LINKAGE leftv ssiRead1(si_link l)
599{
600  ssiInfo *d = (ssiInfo *)l->data;
601  leftv res=(leftv)omAlloc0(sizeof(sleftv));
602  int t=0;
603  fscanf(d->f_read,"%d",&t);
604  //Print("got type %d\n",t);
605  switch(t)
606  {
607    case 1:res->rtyp=INT_CMD;
608           res->data=(char *)ssiReadInt(d->f_read);
609           break;
610    case 2:res->rtyp=STRING_CMD;
611           res->data=(char *)ssiReadString(d);
612           break;
613    case 3:res->rtyp=NUMBER_CMD;
614           res->data=(char *)ssiReadNumber(d);
615           break;
616    case 4:res->rtyp=BIGINT_CMD;
617           res->data=(char *)ssiReadBigInt(d);
618           break;
619    case 15:
620    case 5:{
621             d->r=ssiReadRing(d);
622             d->r->ref++;
623             res->rtyp=RING_CMD;
624             res->data=(char*)d->r;
625             // we are in the top-level, so set the basering to d->r:
626             ssiSetCurrRing(d->r);
627             if (t==15) return ssiRead1(l);
628           }
629           break;
630    case 6:res->rtyp=POLY_CMD;
631           if (d->r==NULL) goto no_ring;
632           res->data=(char*)ssiReadPoly(d);
633           break;
634    case 7:res->rtyp=IDEAL_CMD;
635           if (d->r==NULL) goto no_ring;
636           res->data=(char*)ssiReadIdeal(d);
637           break;
638    case 8:res->rtyp=MATRIX_CMD;
639           if (d->r==NULL) goto no_ring;
640           res->data=(char*)ssiReadMatrix(d);
641           break;
642    case 9:res->rtyp=VECTOR_CMD;
643           if (d->r==NULL) goto no_ring;
644           res->data=(char*)ssiReadPoly(d);
645           break;
646    case 10:res->rtyp=MODUL_CMD;
647           if (d->r==NULL) goto no_ring;
648           res->data=(char*)ssiReadIdeal(d);
649           break;
650    case 11:
651           {
652             res->rtyp=COMMAND;
653             res->data=ssiReadCommand(l);
654             int nok=res->Eval();
655             if (nok) WerrorS("error in eval");
656             break;
657           }
658    case 12: /*DEF_CMD*/
659           {
660             res->rtyp=0;
661             res->name=(char *)ssiReadString(d);
662             int nok=res->Eval();
663             if (nok) WerrorS("error in name lookup");
664             break;
665           }
666    case 13: res->rtyp=PROC_CMD;
667             res->data=ssiReadProc(d);
668             break;
669    case 14: res->rtyp=LIST_CMD;
670             res->data=ssiReadList(l);
671             break;
672    case 99: ssiClose(l); exit(0);
673    case 0: if (feof(d->f_read))
674            {
675              ssiClose(l);
676              res->rtyp=DEF_CMD;
677              break;
678            }
679    default: WerrorS("not implemented");
680             omFreeSize(res,sizeof(sleftv));
681             res=NULL;
682             break;
683  }
684  return res;
685no_ring: WerrorS("no ring");
686  return NULL;
687}
688//**************************************************************************/
689LINKAGE BOOLEAN ssiWrite(si_link l, leftv data)
690{
691  if(!SI_LINK_W_OPEN_P(l)) slOpen(l,SI_LINK_OPEN|SI_LINK_WRITE);
692  ssiInfo *d = (ssiInfo *)l->data;
693  d->level++;
694  //FILE *fich=d->f;
695  while (data!=NULL)
696  {
697    int tt=data->Typ();
698    void *dd=data->Data();
699
700    switch(tt /*data->Typ()*/)
701    {
702          case STRING_CMD: fprintf(d->f_write,"2 ");
703                           ssiWriteString(d,(char *)dd);
704                           break;
705          case INT_CMD: fprintf(d->f_write,"1 ");
706                        ssiWriteInt(d,(int)(long)dd);
707                        break;
708          case BIGINT_CMD:fprintf(d->f_write,"4 ");
709                        ssiWriteBigInt(d,(number)dd);
710                        break;
711          case NUMBER_CMD:
712                          if (d->r!=currRing)
713                          {
714                            fprintf(d->f_write,"15 ");
715                            ssiWriteRing(d,currRing);
716                            if (d->level<=1) fprintf(d->f_write,"\n");
717                          }
718                          fprintf(d->f_write,"3 ");
719                          ssiWriteNumber(d,(number)dd);
720                        break;
721          case RING_CMD:fprintf(d->f_write,"5 ");
722                        ssiWriteRing(d,(ring)dd);
723                        break;
724          case POLY_CMD:
725          case VECTOR_CMD:
726                        if (d->r!=currRing)
727                        {
728                          fprintf(d->f_write,"15 ");
729                          ssiWriteRing(d,currRing);
730                          if (d->level<=1) fprintf(d->f_write,"\n");
731                        }
732                        if(tt==POLY_CMD) fprintf(d->f_write,"6 ");
733                        else             fprintf(d->f_write,"9 ");
734                        ssiWritePoly(d,tt,(poly)dd);
735                        break;
736          case IDEAL_CMD:
737          case MODUL_CMD:
738          case MATRIX_CMD:
739                        if (d->r!=currRing)
740                        {
741                          fprintf(d->f_write,"15 ");
742                          ssiWriteRing(d,currRing);
743                          if (d->level<=1) fprintf(d->f_write,"\n");
744                        }
745                        if(tt==IDEAL_CMD)       fprintf(d->f_write,"7 ");
746                        else if(tt==MATRIX_CMD) fprintf(d->f_write,"8 ");
747                        else                    fprintf(d->f_write,"10 ");
748                        ssiWriteIdeal(d,tt,(ideal)dd);
749                        break;
750          case COMMAND:
751                   fprintf(d->f_write,"11 ");
752                   ssiWriteCommand(l,(command)dd);
753                   break;
754          case DEF_CMD: /* not evaluated stuff in quotes */
755                   fprintf(d->f_write,"12 ");
756                   ssiWriteString(d,data->Name());
757                   break;
758          case PROC_CMD:
759                   fprintf(d->f_write,"13 ");
760                   ssiWriteProc(d,(procinfov)dd);
761                   break;
762          case LIST_CMD:
763                   fprintf(d->f_write,"14 ");
764                   ssiWriteList(l,(lists)dd);
765                   break;
766          default: Werror("not implemented (t:%d, rtyp:%d)",tt, data->rtyp);
767                   d->level=0;
768                   return TRUE;
769    }
770    if (d->level<=1) { fprintf(d->f_write,"\n"); fflush(d->f_write); }
771    data=data->next;
772  }
773  d->level--;
774  return FALSE;
775}
776
777si_link_extension slInitSsiExtension(si_link_extension s)
778{
779  s->Open=(slOpenProc)ssiOpen;
780  s->Close=(slCloseProc)ssiClose;
781  s->Kill=(slKillProc)ssiClose;
782  s->Read=(slReadProc)ssiRead1;
783  s->Read2=(slRead2Proc)NULL;
784  s->Write=(slWriteProc)ssiWrite;
785
786  s->Status=slStatusSsi;
787  s->type="ssi";
788  return s;
789}
790const char* slStatusSsi(si_link l, const char* request)
791{
792  ssiInfo *d=(ssiInfo*)l->data;
793  if (d==NULL) return "not open";
794  if ((strcmp(l->mode,"fork")==0) && (strcmp(request, "read") == 0))
795  {
796    fd_set  mask, fdmask;
797    struct timeval wt;
798    loop
799    {
800      /* Don't block. Return socket status immediately. */
801      wt.tv_sec  = 0;
802      wt.tv_usec = 0;
803
804      FD_ZERO(&mask);
805      FD_SET(d->fd_read, &mask);
806      //Print("test fd %d\n",d->fd_read);
807    /* check with select: chars waiting: no -> not ready */
808      switch (select(d->fd_read+1, &mask, NULL, NULL, &wt))
809      {
810        case 0: /* not ready */ return "not ready";
811        case -1: /*error*/      return "error";
812        case 1: /*ready ? */    break;
813      }
814    /* yes: read 1 char*/
815    /* if \n, check again with select else ungetc(c), ready*/
816      int c=fgetc(d->f_read);
817      //Print("try c=%d\n",c);
818      if (c== -1) return "eof";
819      else if (isdigit(c))
820      { ungetc(c,d->f_read); return "ready"; }
821      else if ((c!=' ') && (c!='\n'))
822      {
823        Werror("unknown char in ssiLink(%d)",c);
824        return "error";
825      }
826      /* else: next char */
827    }
828  }
829  else if (strcmp(request, "read") == 0)
830  {
831    if (SI_LINK_R_OPEN_P(l) && (!feof(d->f_read))) return "ready";
832    else return "not ready";
833  }
834  else if (strcmp(request, "write") == 0)
835  {
836    if (SI_LINK_W_OPEN_P(l)) return "ready";
837    else return "not ready";
838  }
839  else return "unknown status request";
840}
841
842// ----------------------------------------------------------------
843// format
844// 1 int %d
845// 2 string <len> %s
846// 3 number
847// 4 bigint 4 %d or 3 <mpz_t>
848// 5 ring
849// 6 poly
850// 7 ideal
851// 8 matrix
852// 9 vector
853// 10 module
854// 11 command
855// 12 def <len> %s
856// 13 proc <len> %s
857// 14 list %d <elem1> ....
858// 15 setring .......
859//
Note: See TracBrowser for help on using the repository browser.