source: git/Singular/links/asciiLink.cc @ fb1675

spielwiese
Last change on this file since fb1675 was fb1675, checked in by Hans Schoenemann <hannes@…>, 7 years ago
use include ".." for singular related .h, p8
  • Property mode set to 100644
File size: 13.0 KB
Line 
1/****************************************
2 * *  Computer Algebra System SINGULAR     *
3 * ****************************************/
4
5/*
6 * ABSTRACT: ascii links (standard)
7 */
8
9#include "kernel/mod2.h"
10#include "misc/options.h"
11#include "omalloc/omalloc.h"
12
13#include "Singular/tok.h"
14#include "Singular/subexpr.h"
15#include "Singular/ipshell.h"
16#include "Singular/ipid.h"
17#include "Singular/fevoices.h"
18#include "kernel/oswrapper/feread.h"
19#include "Singular/ipshell.h"
20#include "Singular/links/silink.h"
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27
28/* declarations */
29static BOOLEAN DumpAscii(FILE *fd, idhdl h,char ***list_of_libs);
30static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h,char ***list_of_libs);
31static const char* GetIdString(idhdl h);
32static int DumpRhs(FILE *fd, idhdl h);
33static BOOLEAN DumpQring(FILE *fd, idhdl h, const char *type_str);
34static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl);
35static BOOLEAN CollectLibs(char *name, char ***list_of_libs);
36//static BOOLEAN DumpLibs(FILE *fd, char ***list_of_libs);
37
38extern si_link_extension si_link_root;
39
40/* =============== ASCII ============================================= */
41BOOLEAN slOpenAscii(si_link l, short flag, leftv /*h*/)
42{
43  const char *mode;
44  if (flag & SI_LINK_OPEN)
45  {
46    if (l->mode[0] != '\0' && (strcmp(l->mode, "r") == 0))
47      flag = SI_LINK_READ;
48    else flag = SI_LINK_WRITE;
49  }
50
51  if (flag == SI_LINK_READ) mode = "r";
52  else if (strcmp(l->mode, "w") == 0) mode = "w";
53  else mode = "a";
54
55
56  if (l->name[0] == '\0')
57  {
58    // stdin or stdout
59    if (flag == SI_LINK_READ)
60    {
61      l->data = (void *) stdin;
62      mode = "r";
63    }
64    else
65    {
66      l->data = (void *) stdout;
67      mode = "a";
68    }
69  }
70  else
71  {
72    // normal ascii link to a file
73    FILE *outfile;
74    char *filename=l->name;
75
76    if(filename[0]=='>')
77    {
78      if (filename[1]=='>')
79      {
80        filename+=2;
81        mode = "a";
82      }
83      else
84      {
85        filename++;
86        mode="w";
87      }
88    }
89    outfile=myfopen(filename,mode);
90    if (outfile!=NULL)
91      l->data = (void *) outfile;
92    else
93      return TRUE;
94  }
95
96  omFree(l->mode);
97  l->mode = omStrDup(mode);
98  SI_LINK_SET_OPEN_P(l, flag);
99  return FALSE;
100}
101
102BOOLEAN slCloseAscii(si_link l)
103{
104  SI_LINK_SET_CLOSE_P(l);
105  if (l->name[0] != '\0')
106  {
107    return (fclose((FILE *)l->data)!=0);
108  }
109  return FALSE;
110}
111
112leftv slReadAscii2(si_link l, leftv pr)
113{
114  FILE * fp=(FILE *)l->data;
115  char * buf=NULL;
116  if (fp!=NULL && l->name[0] != '\0')
117  {
118    fseek(fp,0L,SEEK_END);
119    long len=ftell(fp);
120    fseek(fp,0L,SEEK_SET);
121    buf=(char *)omAlloc((int)len+1);
122    if (BVERBOSE(V_READING))
123      Print("//Reading %ld chars\n",len);
124    myfread( buf, len, 1, fp);
125    buf[len]='\0';
126  }
127  else
128  {
129    if (pr->Typ()==STRING_CMD)
130    {
131      buf=(char *)omAlloc(80);
132      fe_fgets_stdin((char *)pr->Data(),buf,80);
133    }
134    else
135    {
136      WerrorS("read(<link>,<string>) expected");
137      buf=omStrDup("");
138    }
139  }
140  leftv v=(leftv)omAlloc0Bin(sleftv_bin);
141  v->rtyp=STRING_CMD;
142  v->data=buf;
143  return v;
144}
145
146leftv slReadAscii(si_link l)
147{
148  sleftv tmp;
149  memset(&tmp,0,sizeof(sleftv));
150  tmp.rtyp=STRING_CMD;
151  tmp.data=(void*) "? ";
152  return slReadAscii2(l,&tmp);
153}
154
155BOOLEAN slWriteAscii(si_link l, leftv v)
156{
157  FILE *outfile=(FILE *)l->data;
158  BOOLEAN err=FALSE;
159  char *s;
160  while (v!=NULL)
161  {
162    switch(v->Typ())
163    {
164    case IDEAL_CMD:
165    case MODUL_CMD:
166    case MATRIX_CMD:
167      {
168        ideal I=(ideal)v->Data();
169        for(int i=0;i<IDELEMS(I);i++)
170        {
171          char *s=pString(I->m[i]);
172          fwrite(s,strlen(s),1,outfile);
173          omFree(s);
174          if (i<IDELEMS(I)-1) fwrite(",",1,1,outfile);
175        }
176        break;
177      }
178    default:
179      s = v->String();
180      // free v ??
181      if (s!=NULL)
182      {
183        fputs(s,outfile);
184        fputc('\n',outfile);
185        omFree((ADDRESS)s);
186      }
187      else
188      {
189        WerrorS("cannot convert to string");
190        err=TRUE;
191      }
192    }
193    v = v->next;
194  }
195  fflush(outfile);
196  return err;
197}
198
199const char* slStatusAscii(si_link l, const char* request)
200{
201  if (strcmp(request, "read") == 0)
202  {
203    if (SI_LINK_R_OPEN_P(l)) return "ready";
204    else return "not ready";
205  }
206  else if (strcmp(request, "write") == 0)
207  {
208    if (SI_LINK_W_OPEN_P(l)) return "ready";
209    else return "not ready";
210  }
211  else return "unknown status request";
212}
213
214/*------------------ Dumping in Ascii format -----------------------*/
215
216BOOLEAN slDumpAscii(si_link l)
217{
218  FILE *fd = (FILE *) l->data;
219  idhdl h = IDROOT, rh = currRingHdl;
220  char **list_of_libs=NULL;
221  BOOLEAN status = DumpAscii(fd, h, &list_of_libs);
222
223  if (! status ) status = DumpAsciiMaps(fd, h, NULL);
224
225  if (currRingHdl != rh) rSetHdl(rh);
226  fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
227  char **p=list_of_libs;
228  if (p!=NULL)
229  {
230    while((*p!=NULL) && (*p!=(char*)1))
231    {
232      fprintf(fd,"load(\"%s\",\"try\");\n",*p);
233      p++;
234    }
235    omFree(list_of_libs);
236  }
237  fputs("RETURN();\n",fd);
238  fflush(fd);
239
240  return status;
241}
242
243// we do that recursively, to dump ids in the the order in which they
244// were actually defined
245static BOOLEAN DumpAscii(FILE *fd, idhdl h, char ***list_of_libs)
246{
247  if (h == NULL) return FALSE;
248
249  if (DumpAscii(fd, IDNEXT(h),list_of_libs)) return TRUE;
250
251  // need to set the ring before writing it, otherwise we get in
252  // trouble with minpoly
253  if (IDTYP(h) == RING_CMD)
254    rSetHdl(h);
255
256  if (DumpAsciiIdhdl(fd, h,list_of_libs)) return TRUE;
257
258  if (IDTYP(h) == RING_CMD)
259    return DumpAscii(fd, IDRING(h)->idroot,list_of_libs);
260  else
261    return FALSE;
262}
263
264static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl)
265{
266  if (h == NULL) return FALSE;
267  if (DumpAsciiMaps(fd, IDNEXT(h), rhdl)) return TRUE;
268
269  if (IDTYP(h) == RING_CMD)
270    return DumpAsciiMaps(fd, IDRING(h)->idroot, h);
271  else if (IDTYP(h) == MAP_CMD)
272  {
273    char *rhs;
274    rSetHdl(rhdl);
275    rhs = h->String();
276
277    if (fprintf(fd, "setring %s;\n", IDID(rhdl)) == EOF) return TRUE;
278    if (fprintf(fd, "%s %s = %s, %s;\n", Tok2Cmdname(MAP_CMD), IDID(h),
279                IDMAP(h)->preimage, rhs) == EOF)
280    {
281      omFree(rhs);
282      return TRUE;
283    }
284    else
285    {
286      omFree(rhs);
287      return FALSE;
288    }
289  }
290  else return FALSE;
291}
292
293static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h, char ***list_of_libs)
294{
295  const char *type_str = GetIdString(h);
296  int type_id = IDTYP(h);
297
298  if (type_id == PACKAGE_CMD)
299  {
300    if (strcmp(IDID(h),"Top")==0) return FALSE; // do not dump "Top"
301    if (IDPACKAGE(h)->language==LANG_SINGULAR) return FALSE;
302  }
303  if (type_id == CRING_CMD)
304  {
305    // do not dump the default CRINGs:
306    if (strcmp(IDID(h),"QQ")==0) return FALSE;
307    if (strcmp(IDID(h),"ZZ")==0) return FALSE;
308    if (strcmp(IDID(h),"AE")==0) return FALSE;
309    if (strcmp(IDID(h),"QAE")==0) return FALSE;
310    if (strcmp(IDID(h),"flint_poly_Q")==0) return FALSE;
311  }
312
313  // we do not throw an error if a wrong type was attempted to be dumped
314  if (type_str == NULL)
315    return FALSE;
316
317  // handle qrings separately
318  if ((type_id == RING_CMD)&&(IDRING(h)->qideal!=NULL))
319    return DumpQring(fd, h, type_str);
320
321  // C-proc not to be dumped
322  if ((type_id == PROC_CMD) && (IDPROC(h)->language == LANG_C))
323    return FALSE;
324
325  // handle libraries
326  if ((type_id == PROC_CMD)
327  && (IDPROC(h)->language == LANG_SINGULAR)
328  && (IDPROC(h)->libname!=NULL))
329    return CollectLibs(IDPROC(h)->libname,list_of_libs);
330
331  // put type and name
332  if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF)
333    return TRUE;
334  // for matricies, append the dimension
335  if (type_id == MATRIX_CMD)
336  {
337    ideal id = IDIDEAL(h);
338    if (fprintf(fd, "[%d][%d]", id->nrows, id->ncols)== EOF) return TRUE;
339  }
340  else if (type_id == INTMAT_CMD)
341  {
342    if (fprintf(fd, "[%d][%d]", IDINTVEC(h)->rows(), IDINTVEC(h)->cols())
343        == EOF) return TRUE;
344  }
345
346  if (type_id == PACKAGE_CMD)
347  {
348    return (fputs(";\n",fd) == EOF);
349  }
350
351  // write the equal sign
352  if (fputs(" = ",fd) == EOF) return TRUE;
353
354  // and the right hand side
355  if (DumpRhs(fd, h) == EOF) return TRUE;
356
357  // semicolon und tschuess
358  if (fputs(";\n",fd) == EOF) return TRUE;
359
360  return FALSE;
361}
362
363static const char* GetIdString(idhdl h)
364{
365  int type = IDTYP(h);
366
367  switch(type)
368  {
369    case LIST_CMD:
370    {
371      lists l = IDLIST(h);
372      int i, nl = l->nr + 1;
373
374      for (i=0; i<nl; i++)
375        if (GetIdString((idhdl) &(l->m[i])) == NULL) return NULL;
376    }
377    case CRING_CMD:
378    #ifdef SINGULAR_4_2
379    case CNUMBER_CMD:
380    case CMATRIX_CMD:
381    #endif
382    case BIGINT_CMD:
383    case PACKAGE_CMD:
384    case INT_CMD:
385    case INTVEC_CMD:
386    case INTMAT_CMD:
387    case STRING_CMD:
388    case RING_CMD:
389    case QRING_CMD:
390    case PROC_CMD:
391    case NUMBER_CMD:
392    case POLY_CMD:
393    case IDEAL_CMD:
394    case VECTOR_CMD:
395    case MODUL_CMD:
396    case MATRIX_CMD:
397      return Tok2Cmdname(type);
398
399    case MAP_CMD:
400    case LINK_CMD:
401      return NULL;
402
403    default:
404      Warn("Error dump data of type %s", Tok2Cmdname(IDTYP(h)));
405       return NULL;
406  }
407}
408
409static BOOLEAN DumpQring(FILE *fd, idhdl h, const char *type_str)
410{
411  char *ring_str = h->String();
412  if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str)
413              == EOF) return TRUE;
414  if (fprintf(fd, "%s temp_ideal = %s;\n", Tok2Cmdname(IDEAL_CMD),
415              iiStringMatrix((matrix) IDRING(h)->qideal, 1, currRing, n_GetChar(currRing->cf)))
416      == EOF) return TRUE;
417  if (fputs("attrib(temp_ideal, \"isSB\", 1);\n",fd) == EOF) return TRUE;
418  if (fprintf(fd, "%s %s = temp_ideal;\n", type_str, IDID(h)) == EOF)
419    return TRUE;
420  if (fputs("kill temp_ring;\n",fd) == EOF) return TRUE;
421  else
422  {
423    omFree(ring_str);
424    return FALSE;
425  }
426}
427
428static BOOLEAN CollectLibs(char *name, char *** list_of_libs)
429{
430  if (*list_of_libs==NULL)
431  {
432    #define MAX_LIBS 256
433    (*list_of_libs)=(char**)omalloc0(MAX_LIBS*sizeof(char**));
434    (*list_of_libs)[0]=name;
435    (*list_of_libs)[MAX_LIBS-1]=(char*)1;
436    return FALSE;
437  }
438  else
439  {
440    char **p=*list_of_libs;
441    while (((*p)!=NULL)&&((*p!=(char*)1)))
442    {
443      if (strcmp((*p),name)==0) return FALSE;
444      p++;
445    }
446    if (*p==(char*)1)
447    {
448      WerrorS("too many libs");
449      return TRUE;
450    }
451    else
452    {
453      *p=name;
454    }
455  }
456  return FALSE;
457}
458
459
460static int DumpRhs(FILE *fd, idhdl h)
461{
462  int type_id = IDTYP(h);
463
464  if (type_id == LIST_CMD)
465  {
466    lists l = IDLIST(h);
467    int i, nl = l->nr;
468
469    fputs("list(",fd);
470
471    for (i=0; i<nl; i++)
472    {
473      if (DumpRhs(fd, (idhdl) &(l->m[i])) == EOF) return EOF;
474      fputs(",",fd);
475    }
476    if (nl > 0)
477    {
478      if (DumpRhs(fd, (idhdl) &(l->m[nl])) == EOF) return EOF;
479    }
480    fputs(")",fd);
481  }
482  else  if (type_id == STRING_CMD)
483  {
484    char *pstr = IDSTRING(h);
485    fputc('"', fd);
486    while (*pstr != '\0')
487    {
488      if (*pstr == '"' || *pstr == '\\')  fputc('\\', fd);
489      fputc(*pstr, fd);
490      pstr++;
491    }
492    fputc('"', fd);
493  }
494  else  if (type_id == PROC_CMD)
495  {
496    procinfov pi = IDPROC(h);
497    if (pi->language == LANG_SINGULAR)
498    {
499      /* pi-Libname==NULL */
500      char *pstr = pi->data.s.body;
501      fputc('"', fd);
502      while (*pstr != '\0')
503      {
504        if (*pstr == '"' || *pstr == '\\') fputc('\\', fd);
505        fputc(*pstr, fd);
506        pstr++;
507      }
508      fputc('"', fd);
509    }
510    else fputs("(null)", fd);
511  }
512  else
513  {
514    char *rhs = h->String();
515
516    if (rhs == NULL) return EOF;
517
518    BOOLEAN need_klammer=FALSE;
519    if (type_id == INTVEC_CMD) { fputs("intvec(",fd);need_klammer=TRUE; }
520    else if (type_id == IDEAL_CMD) { fputs("ideal(",fd);need_klammer=TRUE; }
521    else if (type_id == MODUL_CMD) { fputs("module(",fd);need_klammer=TRUE; }
522    else if (type_id == BIGINT_CMD) { fputs("bigint(",fd);need_klammer=TRUE; }
523
524    if (fputs(rhs,fd) == EOF) return EOF;
525    omFree(rhs);
526
527    if ((type_id == RING_CMD) &&
528        IDRING(h)->cf->type==n_algExt)
529    {
530      StringSetS("");
531      p_Write(IDRING(h)->cf->extRing->qideal->m[0],IDRING(h)->cf->extRing);
532      rhs = StringEndS();
533      if (fprintf(fd, "; minpoly = %s", rhs) == EOF) { omFree(rhs); return EOF;}
534      omFree(rhs);
535    }
536    else if (need_klammer) fputc(')',fd);
537  }
538  return 1;
539}
540
541BOOLEAN slGetDumpAscii(si_link l)
542{
543  if (l->name[0] == '\0')
544  {
545    WerrorS("getdump: Can not get dump from stdin");
546    return TRUE;
547  }
548  else
549  {
550    BOOLEAN status = newFile(l->name);
551    if (status)
552      return TRUE;
553
554    int old_echo=si_echo;
555    si_echo=0;
556
557    status=yyparse();
558
559    si_echo=old_echo;
560
561    if (status)
562      return TRUE;
563    else
564    {
565      // lets reset the file pointer to the end to reflect that
566      // we are finished with reading
567      FILE *f = (FILE *) l->data;
568      fseek(f, 0L, SEEK_END);
569      return FALSE;
570    }
571  }
572}
573
574
575void slStandardInit()
576{
577  si_link_extension s;
578  si_link_root=(si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
579  si_link_root->Open=slOpenAscii;
580  si_link_root->Close=slCloseAscii;
581  si_link_root->Kill=NULL;
582  si_link_root->Read=slReadAscii;
583  si_link_root->Read2=slReadAscii2;
584  si_link_root->Write=slWriteAscii;
585  si_link_root->Dump=slDumpAscii;
586  si_link_root->GetDump=slGetDumpAscii;
587  si_link_root->Status=slStatusAscii;
588  si_link_root->type="ASCII";
589  s = si_link_root;
590  s->next = NULL;
591}
Note: See TracBrowser for help on using the repository browser.