source: git/Singular/silink.cc @ 97454d

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