source: git/Singular/silink.cc @ 63be42

spielwiese
Last change on this file since 63be42 was 42e60f, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: use return value of Eval in slRead git-svn-id: file:///usr/local/Singular/svn/trunk@2444 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 16.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: silink.cc,v 1.22 1998-08-06 08:52:57 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)
162    res = l->m->Open(l, flag);
163  else
164    res = TRUE;
165
166  if (res)
167    Werror("open: Error for link of type: %s, mode: %s, name: %s",
168           l->m->type, l->mode, l->name);
169  return res;
170}
171
172BOOLEAN slClose(si_link l)
173{
174  BOOLEAN res;
175
176  if(! SI_LINK_OPEN_P(l))
177    return FALSE;
178  else if (l->m->Close != NULL)
179    res = l->m->Close(l);
180  else
181    res = TRUE;
182
183  if (res)
184    Werror("close: Error for link of type: %s, mode: %s, name: %s",
185           l->m->type, l->mode, l->name);
186  return res;
187}
188
189leftv slRead(si_link l, leftv a)
190{
191  leftv v = NULL;
192  if( ! SI_LINK_R_OPEN_P(l)) // open r ?
193  {
194    if (slOpen(l, SI_LINK_READ)) return NULL;
195  }
196
197  if (SI_LINK_R_OPEN_P(l))
198  { // open r
199    if (a==NULL)
200    {
201      if (l->m->Read != NULL) v = l->m->Read(l);
202    }
203    else
204    {
205      if (l->m->Read2 != NULL) v = l->m->Read2(l,a);
206    }
207  }
208  else
209  {
210    Werror("read: Error to open link of type %s, mode: %s, name: %s for reading",
211           l->m->type, l->mode, l->name);
212    return NULL;
213  }
214
215  // here comes the eval:
216  if (v != NULL)
217  {
218    if (v->Eval() && !errorreported)
219      WerrorS("eval: failed");
220  }
221  else
222    Werror("read: Error for link of type %s, mode: %s, name: %s",
223           l->m->type, l->mode, l->name);
224  return v;
225}
226
227BOOLEAN slWrite(si_link l, leftv v)
228{
229  BOOLEAN res;
230
231  if(! SI_LINK_W_OPEN_P(l)) // open w ?
232  {
233    if (slOpen(l, SI_LINK_WRITE)) return TRUE;
234  }
235
236  if(SI_LINK_W_OPEN_P(l))
237  { // now open w
238    if (l->m->Write != NULL)
239      res = l->m->Write(l,v);
240    else
241      res = TRUE;
242
243    if (res)
244      Werror("write: Error for link of type %s, mode: %s, name: %s",
245             l->m->type, l->mode, l->name);
246    return res;
247  }
248  else
249  {
250    Werror("write: Error to open link of type %s, mode: %s, name: %s for writing",
251           l->m->type, l->mode, l->name);
252    return TRUE;
253  }
254}
255
256BOOLEAN slDump(si_link l)
257{
258  BOOLEAN res;
259
260  if(! SI_LINK_W_OPEN_P(l)) // open w ?
261  {
262    if (slOpen(l, SI_LINK_WRITE)) return TRUE;
263  }
264
265  if(SI_LINK_W_OPEN_P(l))
266  { // now open w
267    if (l->m->Dump != NULL)
268      res = l->m->Dump(l);
269    else
270      res = TRUE;
271
272    if (res)
273      Werror("dump: Error for link of type %s, mode: %s, name: %s",
274             l->m->type, l->mode, l->name);
275    return res;
276  }
277  else
278  {
279    Werror("dump: Error to open link of type %s, mode: %s, name: %s for writing",
280           l->m->type, l->mode, l->name);
281    return TRUE;
282  }
283}
284
285BOOLEAN slGetDump(si_link l)
286{
287  BOOLEAN res;
288
289  if(! SI_LINK_R_OPEN_P(l)) // open r ?
290  {
291    if (slOpen(l, SI_LINK_READ)) return TRUE;
292  }
293
294  if(SI_LINK_R_OPEN_P(l))
295  { // now open r
296    if (l->m->GetDump != NULL)
297      res = l->m->GetDump(l);
298    else
299      res = TRUE;
300
301    if (res)
302      Werror("getdump: Error for link of type %s, mode: %s, name: %s",
303             l->m->type, l->mode, l->name);
304    return res;
305  }
306  else
307  {
308    Werror("dump: Error open link of type %s, mode: %s, name: %s for reading",
309           l->m->type, l->mode, l->name);
310    return TRUE;
311  }
312}
313
314
315/* =============== ASCII ============================================= */
316BOOLEAN slOpenAscii(si_link l, short flag)
317{
318  char *mode;
319  if (flag & SI_LINK_OPEN)
320  {
321    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
322      flag = SI_LINK_READ;
323    else flag = SI_LINK_WRITE;
324  }
325
326  if (flag == SI_LINK_READ) mode = "r";
327  else if (strcmp(l->mode, "w") == 0) mode = "w";
328  else mode = "a";
329
330
331  if (l->name[0] == '\0')
332  {
333    // stdin or stdout
334    if (flag == SI_LINK_READ)
335    {
336      l->data = (void *) stdin;
337      mode = "r";
338    }
339    else
340    {
341      l->data = (void *) stdout;
342      mode = "a";
343    }
344  }
345  else
346  {
347    // normal ascii link to a file
348    FILE *outfile;
349    char *filename=l->name;
350
351    if(filename[0]=='>')
352    {
353      if (filename[1]=='>')
354      {
355        filename+=2;
356        mode = "a";
357      }
358      else
359      {
360        filename++;
361        mode="w";
362      }
363    }
364    outfile=myfopen(filename,mode);
365    if (outfile!=NULL)
366      l->data = (void *) outfile;
367    else
368      return TRUE;
369  }
370
371  FreeL(l->mode);
372  l->mode = mstrdup(mode);
373  SI_LINK_SET_OPEN_P(l, flag);
374  return FALSE;
375}
376
377BOOLEAN slCloseAscii(si_link l)
378{
379  SI_LINK_SET_CLOSE_P(l);
380  if (l->name[0] != '\0')
381  {
382    return (fclose((FILE *)l->data)!=0);
383  }
384  return FALSE;
385}
386
387leftv slReadAscii(si_link l)
388{
389  FILE * fp=(FILE *)l->data;
390  char * buf=NULL;
391  if (fp!=NULL && l->name[0] != '\0')
392  {
393    fseek(fp,0L,SEEK_END);
394    long len=ftell(fp);
395    fseek(fp,0L,SEEK_SET);
396    buf=(char *)AllocL((int)len+1);
397    if (BVERBOSE(V_READING))
398      Print("//Reading %d chars\n",len);
399    myfread( buf, len, 1, fp);
400    buf[len]='\0';
401  }
402  else
403  {
404  #ifdef HAVE_TCL
405    if(tclmode)
406    {
407      WerrorS("reading from STDIN in TCL-mode not implemented");
408      buf=mstrdup("");
409    }
410    else
411  #endif
412    {
413      PrintS("? "); mflush();
414      buf=(char *)AllocL(80);
415      fe_fgets_stdin(buf,80);
416    }
417  }
418  leftv v=(leftv)Alloc0(sizeof(sleftv));
419  v->rtyp=STRING_CMD;
420  v->data=buf;
421  return v;
422}
423BOOLEAN slWriteAscii(si_link l, leftv v)
424{
425  FILE *outfile=(FILE *)l->data;
426  BOOLEAN err=FALSE;
427  char *s;
428  while (v!=NULL)
429  {
430    s = v->String();
431    // free v ??
432    if (s!=NULL)
433    {
434      fprintf(outfile,"%s\n",s);
435      FreeL((ADDRESS)s);
436    }
437    else
438    {
439      Werror("cannot convert to string");
440      err=TRUE;
441    }
442    v = v->next;
443  }
444  fflush(outfile);
445  return err;
446}
447
448char* slStatusAscii(si_link l, char* request)
449{
450  if (strcmp(request, "read") == 0)
451  {
452    if (SI_LINK_R_OPEN_P(l)) return "ready";
453    else return "not ready";
454  }
455  else if (strcmp(request, "write") == 0)
456  {
457    if (SI_LINK_W_OPEN_P(l)) return "ready";
458    else return "not ready";
459  }
460  else return "unknown status request";
461}
462
463/*------------------ Dumping in Ascii format -----------------------*/
464
465BOOLEAN slDumpAscii(si_link l)
466{
467  FILE *fd = (FILE *) l->data;
468  idhdl h = IDROOT, rh = currRingHdl;
469  BOOLEAN status = DumpAscii(fd, h);
470
471  if (! status ) status = DumpAsciiMaps(fd, h, NULL);
472
473  if (currRingHdl != rh) rSetHdl(rh, TRUE);
474  fprintf(fd, "RETURN();\n");
475  fflush(fd);
476
477  return status;
478}
479
480// we do that recursively, to dump ids in the the order in which they
481// were actually defined
482static BOOLEAN DumpAscii(FILE *fd, idhdl h)
483{
484  if (h == NULL) return FALSE;
485
486  if (DumpAscii(fd, IDNEXT(h))) return TRUE;
487
488  // need to set the ring before writing it, otherwise we get in
489  // trouble with minpoly
490  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
491    rSetHdl(h, TRUE);
492
493  if (DumpAsciiIdhdl(fd, h)) return TRUE;
494
495  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
496    return DumpAscii(fd, IDRING(h)->idroot);
497  else
498    return FALSE;
499}
500
501static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl)
502{
503  if (h == NULL) return FALSE;
504  if (DumpAsciiMaps(fd, IDNEXT(h), rhdl)) return TRUE;
505
506  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
507    return DumpAsciiMaps(fd, IDRING(h)->idroot, h);
508  else if (IDTYP(h) == MAP_CMD)
509  {
510    char *rhs;
511    rSetHdl(rhdl, TRUE);
512    rhs = ((leftv) h)->String();
513
514    if (fprintf(fd, "setring %s;\n", IDID(rhdl)) == EOF) return TRUE;
515    if (fprintf(fd, "%s %s = %s, %s;\n", Tok2Cmdname(MAP_CMD), IDID(h),
516                IDMAP(h)->preimage, rhs) == EOF)
517    {
518      FreeL(rhs);
519      return TRUE;
520    }
521    else
522    {
523      FreeL(rhs);
524      return FALSE;
525    }
526  }
527  else return FALSE;
528}
529
530static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h)
531{
532  char *type_str = GetIdString(h);
533  idtyp type_id = IDTYP(h);
534
535  // we do not throw an error if a wrong type was attempted to be dumped
536  if (type_str == NULL) return FALSE;
537
538  // handle qrings separately
539  if (type_id == QRING_CMD) return DumpQring(fd, h, type_str);
540
541  // do not dump LIB string
542  if (type_id == STRING_CMD && strcmp("LIB", IDID(h)) == 0)
543  {
544    return FALSE;
545  }
546
547  // put type and name
548  if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF) return TRUE;
549
550  // for matricies, append the dimension
551  if (type_id == MATRIX_CMD)
552  {
553    ideal id = IDIDEAL(h);
554    if (fprintf(fd, "[%d][%d]", id->nrows, id->ncols)== EOF) return TRUE;
555  }
556  else if (type_id == INTMAT_CMD)
557  {
558    if (fprintf(fd, "[%d][%d]", IDINTVEC(h)->rows(), IDINTVEC(h)->cols())
559        == EOF) return TRUE;
560  }
561  // write the equal sign
562  if (fprintf(fd, " = ") == EOF) return TRUE;
563
564  // and the right hand side
565  if (DumpRhs(fd, h) == EOF) return TRUE;
566
567  // semicolon und tschuess
568  if (fprintf(fd, ";\n") == EOF) return TRUE;
569
570  return FALSE;
571}
572
573static char* GetIdString(idhdl h)
574{
575  idtyp type = IDTYP(h);
576
577  switch(type)
578  {
579      case LIST_CMD:
580      {
581        lists l = IDLIST(h);
582        int i, nl = l->nr + 1;
583        char *name;
584
585        for (i=0; i<nl; i++)
586          if (GetIdString((idhdl) &(l->m[i])) == NULL) return NULL;
587      }
588      case INT_CMD:
589      case INTVEC_CMD:
590      case INTMAT_CMD:
591      case STRING_CMD:
592      case RING_CMD:
593      case QRING_CMD:
594      case PROC_CMD:
595      case NUMBER_CMD:
596      case POLY_CMD:
597      case IDEAL_CMD:
598      case VECTOR_CMD:
599      case MODUL_CMD:
600      case MATRIX_CMD:
601        return Tok2Cmdname(type);
602
603      case MAP_CMD:
604      case LINK_CMD:
605        return NULL;
606
607      default:
608       Warn("Error dump data of type %s", Tok2Cmdname(IDTYP(h)));
609       return NULL;
610  }
611}
612
613static BOOLEAN DumpQring(FILE *fd, idhdl h, char *type_str)
614{
615  char *ring_str = ((leftv) h)->String();
616  if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str)
617              == EOF) return TRUE;
618  if (fprintf(fd, "%s temp_ideal = %s;\n", Tok2Cmdname(IDEAL_CMD),
619              iiStringMatrix((matrix) IDRING(h)->qideal, 1))
620      == EOF) return TRUE;
621  if (fprintf(fd, "attrib(temp_ideal, \"isSB\", 1);\n") == EOF) return TRUE;
622  if (fprintf(fd, "%s %s = temp_ideal;\n", type_str, IDID(h)) == EOF)
623    return TRUE;
624  if (fprintf(fd, "kill temp_ring;\n") == EOF) return TRUE;
625  else
626  {
627    FreeL(ring_str);
628    return FALSE;
629  }
630}
631
632
633static int DumpRhs(FILE *fd, idhdl h)
634{
635  idtyp type_id = IDTYP(h);
636
637  if (type_id == LIST_CMD)
638  {
639    lists l = IDLIST(h);
640    int i, nl = l->nr;
641
642    fprintf(fd, "list(");
643
644    for (i=0; i<nl; i++)
645    {
646      if (DumpRhs(fd, (idhdl) &(l->m[i])) == EOF) return EOF;
647      fprintf(fd, ",");
648    }
649    if (nl > 0)
650    {
651      if (DumpRhs(fd, (idhdl) &(l->m[nl])) == EOF) return EOF;
652    }
653    fprintf(fd, ")");
654  }
655  else  if (type_id == STRING_CMD)
656  {
657    char *pstr = IDSTRING(h), c;
658    fputc('"', fd);
659    while (*pstr != '\0')
660    {
661      if (*pstr == '"' || *pstr == '\\')  fputc('\\', fd);
662      fputc(*pstr, fd);
663      pstr++;
664    }
665    fputc('"', fd);
666  }
667  else  if (type_id == PROC_CMD)
668  {
669    procinfov pi = IDPROC(h);
670    if (pi->language == LANG_SINGULAR) {
671      if( pi->data.s.body==NULL) iiGetLibProcBuffer(pi);
672      char *pstr = pi->data.s.body, c;
673      fputc('"', fd);
674      while (*pstr != '\0') {
675        if (*pstr == '"' || *pstr == '\\') fputc('\\', fd);
676        fputc(*pstr, fd);
677        pstr++;
678      }
679      fputc('"', fd);
680    } else fputs("(null)", fd);
681  }
682  else
683  {
684    char *rhs = ((leftv) h)->String();
685
686    if (rhs == NULL) return EOF;
687
688    if (type_id == INTVEC_CMD) fprintf(fd, "intvec(");
689
690    if (fprintf(fd, "%s", rhs) == EOF) return EOF;
691    FreeL(rhs);
692
693    if ((type_id == RING_CMD || type_id == QRING_CMD) &&
694        IDRING(h)->minpoly != NULL)
695    {
696      StringSetS("");
697      nWrite(IDRING(h)->minpoly);
698      rhs = StringAppend("");
699      if (fprintf(fd, "; minpoly = %s", rhs) == EOF) return EOF;
700    }
701    else if (type_id == INTVEC_CMD) fprintf(fd, ")");
702  }
703  return 1;
704}
705
706BOOLEAN slGetDumpAscii(si_link l)
707{
708  if (l->name[0] == '\0')
709  {
710    Werror("getdump: Can not get dump from stdin");
711    return TRUE;
712  }
713  else
714  {
715    BOOLEAN status = newFile(l->name);
716    if (status)
717      return TRUE;
718
719    int old_echo=si_echo;
720    si_echo=0;
721
722    status=yyparse();
723
724    si_echo=old_echo;
725
726    if (status)
727      return TRUE;
728    else
729    {
730      // lets reset the file pointer to the end to reflect that
731      // we are finished with reading
732      FILE *f = (FILE *) l->data;
733      fseek(f, 0L, SEEK_END);
734      return FALSE;
735    }
736  }
737}
738
739
740/*------------Initialization at Start-up time------------------------*/
741
742#ifdef HAVE_DBM
743#include "sing_dbm.h"
744#endif
745
746#ifdef HAVE_MPSR
747#include "sing_mp.h"
748#endif
749
750void slStandardInit()
751{
752  si_link_extension s;
753  si_link_root=(si_link_extension)Alloc0(sizeof(*si_link_root));
754  si_link_root->Open=slOpenAscii;
755  si_link_root->Close=slCloseAscii;
756  si_link_root->Read=slReadAscii;
757  si_link_root->Write=slWriteAscii;
758  si_link_root->Dump=slDumpAscii;
759  si_link_root->GetDump=slGetDumpAscii;
760  si_link_root->Status=slStatusAscii;
761  si_link_root->type="ASCII";
762  s = si_link_root;
763#ifdef HAVE_DBM
764#ifndef HAVE_MODULE_DBM
765  s->next = (si_link_extension)Alloc0(sizeof(*si_link_root));
766  s = s->next;
767  slInitDBMExtension(s);
768#endif
769#endif
770#ifdef HAVE_MPSR
771  s->next = (si_link_extension)Alloc0(sizeof(*si_link_root));
772  s = s->next;
773  slInitMPFileExtension(s);
774  s->next = (si_link_extension)Alloc0(sizeof(*si_link_root));
775  s = s->next;
776  slInitMPTcpExtension(s);
777#endif
778}
Note: See TracBrowser for help on using the repository browser.