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

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