source: git/Singular/silink.cc @ 18dd47

spielwiese
Last change on this file since 18dd47 was c1945e, checked in by Hans Schönemann <hannes@…>, 27 years ago
* hannes: ascii links use feFopen instead of fopen git-svn-id: file:///usr/local/Singular/svn/trunk@207 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: silink.cc,v 1.11 1997-04-29 12:02:23 Singular Exp $ */
5
6/*
7* ABSTRACT: general interface to links
8*/
9
10#include <stdio.h>
11#include <string.h>
12#include "mod2.h"
13#include "tok.h"
14#include "mmemory.h"
15#include "febase.h"
16#include "subexpr.h"
17#include "ipid.h"
18#include "silink.h"
19#include "ipshell.h"
20#include "ring.h"
21#include "lists.h"
22#include "ideals.h"
23#include "numbers.h"
24#include "intvec.h"
25
26/* declarations */
27static BOOLEAN DumpAscii(FILE *fd, idhdl h);
28static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h);
29static char* GetIdString(idhdl h);
30static int DumpRhs(FILE *fd, idhdl h);
31static BOOLEAN DumpQring(FILE *fd, idhdl h, char *type_str);
32static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl);
33
34/* ====================================================================== */
35si_link_extension si_link_root=NULL;
36
37BOOLEAN slInit(si_link l, char *istr)
38{
39  char *type = NULL, *mode = NULL, *name = NULL;
40  int i = 0, j;
41 
42  // set mode and type
43  if (istr != NULL)
44  {
45    // find the first colon char in istr
46    i = 0;
47    while (istr[i] != ':' && istr[i] != '\0') i++;
48    if (istr[i] == ':')
49    {
50      // if found, set type
51      if (i > 0)
52      {
53        istr[i] = '\0';
54        type = mstrdup(istr);
55        istr[i] = ':';
56      }
57      // and check for mode
58      j = ++i;
59      while (istr[j] != ' ' && istr[j] != '\0') j++;
60      if (j > i)
61      {
62        mode = mstrdup(&(istr[i]));
63        mode[j - i] = '\0';
64      }
65      // and for the name
66      while (istr[j] == ' '&& istr[j] != '\0') j++;
67      if (istr[j] != '\0') name = mstrdup(&(istr[j]));
68    }
69    else // no colon find -- string is entire name
70    {
71      j=0;
72      while (istr[j] == ' '&& istr[j] != '\0') j++;
73      if (istr[j] != '\0') name = mstrdup(&(istr[j]));
74    }
75  }
76
77  // set the link extension
78  if (type != NULL)
79  {
80    si_link_extension s = si_link_root;
81   
82    while (s != NULL && (strcmp(s->type, type) != 0)) s = s->next;
83
84    if (s != NULL)
85      l->m = s;
86    else
87    {
88      Warn("Found unknown link type: %s", type);
89      Warn("Use default link type: %s", si_link_root->type);
90      l->m = si_link_root;
91    }
92    FreeL(type);
93  }
94  else
95    l->m = si_link_root;
96
97  l->name = (name != NULL ? name : mstrdup(""));
98  l->mode = (mode != NULL ? mode : mstrdup(""));
99  l->ref = 1;
100  return FALSE;
101}
102
103void slCleanUp(si_link l)
104{
105  (l->ref)--;
106  if (l->ref == 0)
107  {
108    if (SI_LINK_OPEN_P(l)) slClose(l);
109    FreeL((ADDRESS)l->name);
110    FreeL((ADDRESS)l->mode);
111    memset((void *) l, 0, sizeof(ip_link));
112  }
113}
114
115void slKill(si_link l)
116{
117  slCleanUp(l);
118  if (l->ref == 0)
119    Free((ADDRESS)l, sizeof(ip_link));
120}
121
122char* slStatus(si_link l, char *request)
123{
124  if (l == NULL) return "empty link";
125  else if (l->m == NULL) return "unknown link type";
126  else if (strcmp(request, "type") == 0) return l->m->type;
127  else if (strcmp(request, "mode") == 0) return l->mode;
128  else if (strcmp(request, "name") == 0) return l->name;
129  else if (strcmp(request, "open") == 0)
130  {
131    if (SI_LINK_OPEN_P(l)) return "yes";
132    else return "no";
133  }
134  else if (strcmp(request, "openread") == 0)
135  {
136    if (SI_LINK_R_OPEN_P(l)) return "yes";
137    else return "no";
138  }
139  else if (strcmp(request, "openwrite") == 0)
140  {
141    if (SI_LINK_W_OPEN_P(l)) return "yes";
142    else return "no";
143  }
144  else if (l->m->Status == NULL) return "unknown status request";
145  else return l->m->Status(l, request);
146}
147
148//--------------------------------------------------------------------------
149BOOLEAN slOpen(si_link l, short flag)
150{
151  BOOLEAN res;
152 
153  if (l->m == NULL) slInit(l, "");
154
155  if (SI_LINK_OPEN_P(l))
156  {
157    Warn("open: link of type: %s, mode: %s, name: %s is already open",
158         l->m->type, l->mode, l->name);
159    return FALSE;
160  }
161  else if (l->m->Open != NULL) res = l->m->Open(l, flag);
162  else res = TRUE;
163
164  if (res)
165    Werror("open: Error for link of type: %s, mode: %s, name: %s",
166           l->m->type, l->mode, l->name);
167  return res;
168}
169
170BOOLEAN slClose(si_link l)
171{
172  BOOLEAN res;
173
174  if(! SI_LINK_OPEN_P(l)) return FALSE;
175  else if (l->m->Close != NULL) return res = l->m->Close(l);
176  else res = TRUE;
177 
178  if (res)
179    Werror("close: Error for link of type: %s, mode: %s, name: %s",
180           l->m->type, l->mode, l->name);
181  return res;
182}
183
184leftv slRead(si_link l, leftv a)
185{
186  leftv v = NULL;
187  if( ! SI_LINK_R_OPEN_P(l)) // open r ?
188  {
189    if (slOpen(l, SI_LINK_READ)) return NULL;
190  }
191
192  if (SI_LINK_R_OPEN_P(l))
193  { // open r
194    if (a==NULL)
195    {
196      if (l->m->Read != NULL) v = l->m->Read(l);
197    }
198    else
199    {
200      if (l->m->Read2 != NULL) v = l->m->Read2(l,a);
201    }
202  }
203  else
204  {
205    Werror("read: Error to open link of type %s, mode: %s, name: %s for reading",
206           l->m->type, l->mode, l->name);
207    return NULL;
208  }
209 
210  // here comes the eval:
211  if (v != NULL) v->Eval();
212  else
213    Werror("read: Error for link of type %s, mode: %s, name: %s",
214           l->m->type, l->mode, l->name);
215  return v;
216}
217
218BOOLEAN slWrite(si_link l, leftv v)
219{
220  BOOLEAN res;
221 
222  if(! SI_LINK_W_OPEN_P(l)) // open w ?
223  {
224    if (slOpen(l, SI_LINK_WRITE)) return TRUE;
225  }
226
227  if(SI_LINK_W_OPEN_P(l))
228  { // now open w
229    if (l->m->Write != NULL) res = l->m->Write(l,v);
230    else res = TRUE;
231
232    if (res)
233      Werror("write: Error for link of type %s, mode: %s, name: %s",
234             l->m->type, l->mode, l->name);
235    return res;
236  }
237  else
238  {
239    Werror("write: Error to open link of type %s, mode: %s, name: %s for writing",
240           l->m->type, l->mode, l->name);
241    return TRUE;
242  }
243}
244
245BOOLEAN slDump(si_link l)
246{
247  BOOLEAN res;
248
249  if(! SI_LINK_W_OPEN_P(l)) // open w ?
250  {
251    if (slOpen(l, SI_LINK_WRITE)) return TRUE;
252  }
253
254  if(SI_LINK_W_OPEN_P(l))
255  { // now open w
256    if (l->m->Dump != NULL) res = l->m->Dump(l);
257    else res = TRUE;
258
259    if (res)
260      Werror("dump: Error for link of type %s, mode: %s, name: %s",
261             l->m->type, l->mode, l->name);
262    return res;
263  }
264  else
265  {
266    Werror("dump: Error to open link of type %s, mode: %s, name: %s for writing",
267           l->m->type, l->mode, l->name);
268    return TRUE;
269  }
270}
271
272BOOLEAN slGetDump(si_link l)
273{
274  BOOLEAN res;
275
276  if(! SI_LINK_R_OPEN_P(l)) // open r ?
277  {
278    if (slOpen(l, SI_LINK_READ)) return TRUE;
279  }
280
281  if(SI_LINK_R_OPEN_P(l))
282  { // now open r
283    if (l->m->GetDump != NULL) res = l->m->GetDump(l);
284    else res = TRUE;
285
286    if (res)
287      Werror("getdump: Error for link of type %s, mode: %s, name: %s",
288             l->m->type, l->mode, l->name);
289    return res;
290  }
291  else
292  {
293    Werror("dump: Error open link of type %s, mode: %s, name: %s for reading",
294           l->m->type, l->mode, l->name);
295    return TRUE;
296  }
297}
298
299
300/* =============== ASCII ============================================= */
301BOOLEAN slOpenAscii(si_link l, short flag)
302{
303  char *mode;
304  if (flag == SI_LINK_OPEN)
305  {
306    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
307      flag = SI_LINK_READ;
308    else flag = SI_LINK_WRITE;
309  }
310
311  if (flag == SI_LINK_READ) mode = "r";
312  else if (strcmp(l->mode, "w") == 0) mode = "w";
313  else mode = "a";
314   
315       
316  if (l->name[0] == '\0')
317  {
318    // stdin or stdout
319    if (flag == SI_LINK_READ)
320    {
321      l->data = (void *) stdin;
322      mode = "r";
323    }
324    else
325    {
326      l->data = (void *) stdout;
327      mode = "a";
328    }
329  }
330  else
331  {
332    // normal ascii link to a file
333    FILE *outfile;
334    char *filename=l->name;
335
336    if(filename[0]=='>')
337    {
338      if (filename[1]=='>')
339      {
340        filename+=2;
341        mode = "a";
342      }
343      else
344      {
345        filename++;
346        mode="w";
347      }
348    }
349    outfile=feFopen(filename,mode);
350    if (outfile!=NULL) l->data = (void *) outfile;
351    else return TRUE;
352  }
353
354  FreeL(l->mode);
355  l->mode = mstrdup(mode);
356  SI_LINK_SET_OPEN_P(l, flag);
357  return FALSE;
358}
359
360BOOLEAN slCloseAscii(si_link l)
361{
362  SI_LINK_SET_CLOSE_P(l);
363  if (l->name[0] != '\0')
364  {
365    return (fclose((FILE *)l->data)!=0);
366  }
367  return FALSE;
368}
369
370leftv slReadAscii(si_link l)
371{
372  FILE * fp=(FILE *)l->data;
373  char * buf=NULL;
374  if (fp!=NULL && l->name[0] != '\0')
375  {
376    fseek(fp,0L,SEEK_END);
377    long len=ftell(fp);
378    fseek(fp,0L,SEEK_SET);
379    buf=(char *)AllocL((int)len+1);
380    if (BVERBOSE(V_READING)) Print("//Reading %d chars\n",len);
381    fread( buf, len, 1, fp);
382    buf[len]='\0';
383  }
384  else
385  {
386    PrintS("? "); mflush();
387    buf=(char *)AllocL(80);
388    fe_fgets_stdin(buf,80);
389  }
390  leftv v=(leftv)Alloc0(sizeof(sleftv));
391  v->rtyp=STRING_CMD;
392  v->data=buf;
393  return v;
394}
395BOOLEAN slWriteAscii(si_link l, leftv v)
396{
397  FILE *outfile=(FILE *)l->data;
398  BOOLEAN err=FALSE;
399  char *s;
400  while (v!=NULL)
401  {
402    s = v->String();
403    // free v ??
404    if (s!=NULL)
405    {
406      fprintf(outfile,"%s\n",s);
407      FreeL((ADDRESS)s);
408    }
409    else
410    {
411      Werror("cannot convert to string");
412      err=TRUE;
413    }
414    v = v->next;
415  }
416  fflush(outfile);
417  return err;
418}
419
420char* slStatusAscii(si_link l, char* request)
421{
422  if (strcmp(request, "read") == 0)
423  {
424    if (SI_LINK_R_OPEN_P(l)) return "ready";
425    else return "not ready";
426  }
427  else if (strcmp(request, "write") == 0)
428  {
429    if (SI_LINK_W_OPEN_P(l)) return "ready";
430    else return "not ready";
431  }
432  else return "unknown status request";
433}
434
435/*------------------ Dumping in Ascii format -----------------------*/
436
437BOOLEAN slDumpAscii(si_link l)
438{
439  FILE *fd = (FILE *) l->data;
440  idhdl h = idroot, rh = currRingHdl;
441  BOOLEAN status = DumpAscii(fd, h);
442
443  if (! status ) status = DumpAsciiMaps(fd, h, NULL);
444
445  if (currRingHdl != rh) rSetHdl(rh, TRUE);
446  fflush(fd);
447 
448  return status;
449}
450
451// we do that recursively, to dump ids in the the order in which they
452// were actually defined
453static BOOLEAN DumpAscii(FILE *fd, idhdl h)
454{
455  if (h == NULL) return FALSE;
456
457  if (DumpAscii(fd, IDNEXT(h))) return TRUE;
458
459  // need to set the ring before writing it, otherwise we get in
460  // trouble with minpoly
461  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
462    rSetHdl(h, TRUE);
463
464  if (DumpAsciiIdhdl(fd, h)) return TRUE;
465
466  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
467    return DumpAscii(fd, IDRING(h)->idroot);
468  else
469    return FALSE;
470}
471
472static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl)
473{
474  if (h == NULL) return FALSE;
475  if (DumpAsciiMaps(fd, IDNEXT(h), rhdl)) return TRUE;
476
477  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
478    return DumpAsciiMaps(fd, IDRING(h)->idroot, h);
479  else if (IDTYP(h) == MAP_CMD)
480  {
481    char *rhs;
482    rSetHdl(rhdl, TRUE);
483    rhs = ((leftv) h)->String();
484   
485    if (fprintf(fd, "setring %s;\n", IDID(rhdl)) == EOF) return TRUE;
486    if (fprintf(fd, "%s %s = %s, %s;\n", Tok2Cmdname(MAP_CMD), IDID(h),
487                IDMAP(h)->preimage, rhs) == EOF)
488    {
489      FreeL(rhs);
490      return TRUE;
491    }
492    else
493    {
494      FreeL(rhs);
495      return FALSE;
496    }
497  }
498  else return FALSE;
499}
500 
501static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h)
502{
503  char *type_str = GetIdString(h);
504  idtyp type_id = IDTYP(h);
505
506  // we do not throw an error if a wrong type was attempted to be dumped
507  if (type_str == NULL) return FALSE;
508
509  // handle qrings separately
510  if (type_id == QRING_CMD) return DumpQring(fd, h, type_str);
511 
512  if (type_id == STRING_CMD && strcmp("LIB", IDID(h)) == 0)
513  {
514    if (fprintf(fd, "LIB \"%s\";\n", IDSTRING(h)) == EOF) return TRUE;
515    else return FALSE;
516  }
517                                     
518  // put type and name
519  if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF) return TRUE;
520
521  // for matricies, append the dimension
522  if (type_id == MATRIX_CMD)
523  {
524    ideal id = IDIDEAL(h);
525    if (fprintf(fd, "[%d][%d]", id->nrows, id->ncols)== EOF) return TRUE;
526  }
527  else if (type_id == INTMAT_CMD)
528  {
529    if (fprintf(fd, "[%d][%d]", IDINTVEC(h)->rows(), IDINTVEC(h)->cols())
530        == EOF) return TRUE;
531  }
532  // write the equal sign
533  if (fprintf(fd, " = ") == EOF) return TRUE;
534
535  // and the right hand side
536  if (DumpRhs(fd, h) == EOF) return TRUE;
537 
538  // semicolon und tschuess
539  if (fprintf(fd, ";\n") == EOF) return TRUE;
540
541  return FALSE;
542}
543
544static char* GetIdString(idhdl h)
545{
546  idtyp type = IDTYP(h);
547 
548  switch(type)
549  {
550      case LIST_CMD:
551      {
552        lists l = IDLIST(h);
553        int i, nl = l->nr + 1;
554        char *name;
555
556        for (i=0; i<nl; i++)
557          if (GetIdString((idhdl) &(l->m[i])) == NULL) return NULL;
558      }
559      case INT_CMD:
560      case INTVEC_CMD:
561      case INTMAT_CMD:
562      case STRING_CMD:
563      case RING_CMD:
564      case QRING_CMD:
565      case PROC_CMD:
566      case NUMBER_CMD:
567      case POLY_CMD:
568      case IDEAL_CMD:
569      case VECTOR_CMD:
570      case MODUL_CMD:
571      case MATRIX_CMD:
572        return Tok2Cmdname(type);
573       
574      case MAP_CMD:
575      case LINK_CMD:
576        return NULL;
577
578      default:
579       Warn("Error dump data of type %s", Tok2Cmdname(IDTYP(h)));
580       return NULL;
581  }
582}
583
584static BOOLEAN DumpQring(FILE *fd, idhdl h, char *type_str)
585{
586  char *ring_str = ((leftv) h)->String();
587  if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str)
588              == EOF) return TRUE;
589  if (fprintf(fd, "%s temp_ideal = %s;\n", Tok2Cmdname(IDEAL_CMD),
590              iiStringMatrix((matrix) IDRING(h)->qideal, 1))
591      == EOF) return TRUE;
592  if (fprintf(fd, "attrib(temp_ideal, \"isSB\", 1);\n") == EOF) return TRUE;
593  if (fprintf(fd, "%s %s = temp_ideal;\n", type_str, IDID(h)) == EOF)
594    return TRUE;
595  if (fprintf(fd, "kill temp_ring;\n") == EOF) return TRUE;
596  else
597  {
598    FreeL(ring_str);
599    return FALSE;
600  }
601}
602
603 
604static int DumpRhs(FILE *fd, idhdl h)
605{
606  idtyp type_id = IDTYP(h);
607
608  if (type_id == LIST_CMD)
609  {
610    lists l = IDLIST(h);
611    int i, nl = l->nr;
612
613    fprintf(fd, "list(");
614   
615    for (i=0; i<nl; i++)
616    {
617      if (DumpRhs(fd, (idhdl) &(l->m[i])) == EOF) return EOF;
618      fprintf(fd, ",");
619    }
620    if (nl > 0)
621    {
622      if (DumpRhs(fd, (idhdl) &(l->m[nl])) == EOF) return EOF;
623    }
624    fprintf(fd, ")");
625  }
626  else  if (type_id == PROC_CMD || type_id == STRING_CMD)
627  {
628    char *pstr = IDSTRING(h), c;
629    fputc('"', fd);
630    while (*pstr != '\0')
631    {
632      if (*pstr == '"') fputc('\\', fd);
633      fputc(*pstr, fd);
634      pstr++;
635    }
636    fputc('"', fd);
637  }
638  else
639  {
640    char *rhs = ((leftv) h)->String();
641
642    if (rhs == NULL) return EOF;
643
644    if (type_id == INTVEC_CMD) fprintf(fd, "intvec(");
645
646    if (fprintf(fd, "%s", rhs) == EOF) return EOF;
647    FreeL(rhs);
648
649    if ((type_id == RING_CMD || type_id == QRING_CMD) &&
650        IDRING(h)->minpoly != NULL)
651    {
652      StringSetS("");
653      nWrite(IDRING(h)->minpoly);
654      rhs = StringAppend("");
655      if (fprintf(fd, "; minpoly = %s", rhs) == EOF) return EOF;
656    }
657    else if (type_id == INTVEC_CMD) fprintf(fd, ")");
658  }
659  return 1;
660}
661   
662BOOLEAN slGetDumpAscii(si_link l)
663{
664  if (l->name[0] == '\0')
665  {
666    Werror("getdump: Can not get dump from stdin");
667    return TRUE;
668  }
669  else
670  {
671    BOOLEAN status = iiPStart(NULL, l->name, NULL);
672
673    if (status)
674      return TRUE;
675    else
676    {
677      // lets reset the file pointer to the end to reflect that
678      // we are finished with reading
679      FILE *f = (FILE *) l->data;
680      fseek(f, 0L, SEEK_END);
681      return FALSE;
682    }
683  }
684}
685     
686 
687/*------------Initialization at Start-up time------------------------*/
688
689#ifdef HAVE_DBM
690#include "sing_dbm.h"
691#endif
692
693#ifdef HAVE_MPSR
694#include "sing_mp.h"
695#endif 
696
697void slStandardInit()
698{
699  si_link_extension s;
700  si_link_root=(si_link_extension)Alloc0(sizeof(*si_link_root));
701  si_link_root->Open=slOpenAscii;
702  si_link_root->Close=slCloseAscii;
703  si_link_root->Read=slReadAscii;
704  si_link_root->Write=slWriteAscii;
705  si_link_root->Dump=slDumpAscii;
706  si_link_root->GetDump=slGetDumpAscii;
707  si_link_root->Status=slStatusAscii;
708  si_link_root->type="Ascii";
709  s = si_link_root;
710#ifdef HAVE_DBM
711#ifndef HAVE_MODULE_DBM
712  s->next = (si_link_extension)Alloc0(sizeof(*si_link_root));
713  s = s->next;
714  slInitDBMExtension(s);
715#endif
716#endif
717#ifdef HAVE_MPSR
718  s->next = (si_link_extension)Alloc0(sizeof(*si_link_root));
719  s = s->next;
720  slInitMPFileExtension(s);
721  s->next = (si_link_extension)Alloc0(sizeof(*si_link_root));
722  s = s->next;
723  slInitMPTcpExtension(s);
724#endif 
725}
Note: See TracBrowser for help on using the repository browser.