source: git/Singular/links/asciiLink.cc @ 9f7665

spielwiese
Last change on this file since 9f7665 was 9f7665, checked in by Oleksandr Motsak <motsak@…>, 10 years ago
Removed HAVE_CONFIG guards fix: fixed the inclusion of configure-generated *config.h's
  • Property mode set to 100644
File size: 10.9 KB
Line 
1/****************************************
2 * *  Computer Algebra System SINGULAR     *
3 * ****************************************/
4
5/*
6 * ABSTRACT: ascii links (standard)
7 */
8
9#include <stdio.h>
10#include <string.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <unistd.h>
14
15
16
17
18#include <kernel/mod2.h>
19#include <Singular/tok.h>
20#include <misc/options.h>
21#include <omalloc/omalloc.h>
22#include <kernel/febase.h>
23#include <Singular/subexpr.h>
24#include <Singular/ipshell.h>
25#include <Singular/ipid.h>
26#include <Singular/links/silink.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    s = v->String();
161    // free v ??
162    if (s!=NULL)
163    {
164      fprintf(outfile,"%s\n",s);
165      omFree((ADDRESS)s);
166    }
167    else
168    {
169      Werror("cannot convert to string");
170      err=TRUE;
171    }
172    v = v->next;
173  }
174  fflush(outfile);
175  return err;
176}
177
178const char* slStatusAscii(si_link l, const char* request)
179{
180  if (strcmp(request, "read") == 0)
181  {
182    if (SI_LINK_R_OPEN_P(l)) return "ready";
183    else return "not ready";
184  }
185  else if (strcmp(request, "write") == 0)
186  {
187    if (SI_LINK_W_OPEN_P(l)) return "ready";
188    else return "not ready";
189  }
190  else return "unknown status request";
191}
192
193/*------------------ Dumping in Ascii format -----------------------*/
194
195BOOLEAN slDumpAscii(si_link l)
196{
197  FILE *fd = (FILE *) l->data;
198  idhdl h = IDROOT, rh = currRingHdl;
199  BOOLEAN status = DumpAscii(fd, h);
200
201  if (! status ) status = DumpAsciiMaps(fd, h, NULL);
202
203  if (currRingHdl != rh) rSetHdl(rh);
204  fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
205  fprintf(fd, "RETURN();\n");
206  fflush(fd);
207
208  return status;
209}
210
211// we do that recursively, to dump ids in the the order in which they
212// were actually defined
213static BOOLEAN DumpAscii(FILE *fd, idhdl h)
214{
215  if (h == NULL) return FALSE;
216
217  if (DumpAscii(fd, IDNEXT(h))) return TRUE;
218
219  // need to set the ring before writing it, otherwise we get in
220  // trouble with minpoly
221  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
222    rSetHdl(h);
223
224  if (DumpAsciiIdhdl(fd, h)) return TRUE;
225
226  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
227    return DumpAscii(fd, IDRING(h)->idroot);
228  else
229    return FALSE;
230}
231
232static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl)
233{
234  if (h == NULL) return FALSE;
235  if (DumpAsciiMaps(fd, IDNEXT(h), rhdl)) return TRUE;
236
237  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
238    return DumpAsciiMaps(fd, IDRING(h)->idroot, h);
239  else if (IDTYP(h) == MAP_CMD)
240  {
241    char *rhs;
242    rSetHdl(rhdl);
243    rhs = h->String();
244
245    if (fprintf(fd, "setring %s;\n", IDID(rhdl)) == EOF) return TRUE;
246    if (fprintf(fd, "%s %s = %s, %s;\n", Tok2Cmdname(MAP_CMD), IDID(h),
247                IDMAP(h)->preimage, rhs) == EOF)
248    {
249      omFree(rhs);
250      return TRUE;
251    }
252    else
253    {
254      omFree(rhs);
255      return FALSE;
256    }
257  }
258  else return FALSE;
259}
260
261static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h)
262{
263  const char *type_str = GetIdString(h);
264  int type_id = IDTYP(h);
265
266  if ((type_id == PACKAGE_CMD) &&(strcmp(IDID(h), "Top") == 0))
267    return FALSE;
268
269  // we do not throw an error if a wrong type was attempted to be dumped
270  if (type_str == NULL)
271    return FALSE;
272
273  // handle qrings separately
274  if (type_id == QRING_CMD)
275    return DumpQring(fd, h, type_str);
276
277  // C-proc not to be dumped
278  if ((type_id == PROC_CMD) && (IDPROC(h)->language == LANG_C))
279    return FALSE;
280
281  // put type and name
282  if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF)
283    return TRUE;
284  // for matricies, append the dimension
285  if (type_id == MATRIX_CMD)
286  {
287    ideal id = IDIDEAL(h);
288    if (fprintf(fd, "[%d][%d]", id->nrows, id->ncols)== EOF) return TRUE;
289  }
290  else if (type_id == INTMAT_CMD)
291  {
292    if (fprintf(fd, "[%d][%d]", IDINTVEC(h)->rows(), IDINTVEC(h)->cols())
293        == EOF) return TRUE;
294  }
295
296  if (type_id == PACKAGE_CMD)
297  {
298    return (fprintf(fd, ";\n") == EOF);
299  }
300
301  // write the equal sign
302  if (fprintf(fd, " = ") == EOF) return TRUE;
303
304  // and the right hand side
305  if (DumpRhs(fd, h) == EOF) return TRUE;
306
307  // semicolon und tschuess
308  if (fprintf(fd, ";\n") == EOF) return TRUE;
309
310  return FALSE;
311}
312
313static const char* GetIdString(idhdl h)
314{
315  int type = IDTYP(h);
316
317  switch(type)
318  {
319      case LIST_CMD:
320      {
321        lists l = IDLIST(h);
322        int i, nl = l->nr + 1;
323
324        for (i=0; i<nl; i++)
325          if (GetIdString((idhdl) &(l->m[i])) == NULL) return NULL;
326      }
327      case PACKAGE_CMD:
328      case INT_CMD:
329      case INTVEC_CMD:
330      case INTMAT_CMD:
331      case STRING_CMD:
332      case RING_CMD:
333      case QRING_CMD:
334      case PROC_CMD:
335      case NUMBER_CMD:
336      case POLY_CMD:
337      case IDEAL_CMD:
338      case VECTOR_CMD:
339      case MODUL_CMD:
340      case MATRIX_CMD:
341        return Tok2Cmdname(type);
342
343      case MAP_CMD:
344      case LINK_CMD:
345        return NULL;
346
347      default:
348       Warn("Error dump data of type %s", Tok2Cmdname(IDTYP(h)));
349       return NULL;
350  }
351}
352
353static BOOLEAN DumpQring(FILE *fd, idhdl h, const char *type_str)
354{
355  char *ring_str = h->String();
356  if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str)
357              == EOF) return TRUE;
358  if (fprintf(fd, "%s temp_ideal = %s;\n", Tok2Cmdname(IDEAL_CMD),
359              iiStringMatrix((matrix) IDRING(h)->qideal, 1, currRing, n_GetChar(currRing->cf)))
360      == EOF) return TRUE;
361  if (fprintf(fd, "attrib(temp_ideal, \"isSB\", 1);\n") == EOF) return TRUE;
362  if (fprintf(fd, "%s %s = temp_ideal;\n", type_str, IDID(h)) == EOF)
363    return TRUE;
364  if (fprintf(fd, "kill temp_ring;\n") == EOF) return TRUE;
365  else
366  {
367    omFree(ring_str);
368    return FALSE;
369  }
370}
371
372
373static int DumpRhs(FILE *fd, idhdl h)
374{
375  int type_id = IDTYP(h);
376
377  if (type_id == LIST_CMD)
378  {
379    lists l = IDLIST(h);
380    int i, nl = l->nr;
381
382    fprintf(fd, "list(");
383
384    for (i=0; i<nl; i++)
385    {
386      if (DumpRhs(fd, (idhdl) &(l->m[i])) == EOF) return EOF;
387      fprintf(fd, ",");
388    }
389    if (nl > 0)
390    {
391      if (DumpRhs(fd, (idhdl) &(l->m[nl])) == EOF) return EOF;
392    }
393    fprintf(fd, ")");
394  }
395  else  if (type_id == STRING_CMD)
396  {
397    char *pstr = IDSTRING(h);
398    fputc('"', fd);
399    while (*pstr != '\0')
400    {
401      if (*pstr == '"' || *pstr == '\\')  fputc('\\', fd);
402      fputc(*pstr, fd);
403      pstr++;
404    }
405    fputc('"', fd);
406  }
407  else  if (type_id == PROC_CMD)
408  {
409    procinfov pi = IDPROC(h);
410    if (pi->language == LANG_SINGULAR)
411    {
412      if( pi->data.s.body==NULL) iiGetLibProcBuffer(pi);
413      char *pstr = pi->data.s.body;
414      fputc('"', fd);
415      while (*pstr != '\0')
416      {
417        if (*pstr == '"' || *pstr == '\\') fputc('\\', fd);
418        fputc(*pstr, fd);
419        pstr++;
420      }
421      fputc('"', fd);
422    }
423    else fputs("(null)", fd);
424  }
425  else
426  {
427    char *rhs = h->String();
428
429    if (rhs == NULL) return EOF;
430
431    BOOLEAN need_klammer=FALSE;
432    if (type_id == INTVEC_CMD) { fprintf(fd, "intvec(");need_klammer=TRUE; }
433    else if (type_id == IDEAL_CMD) { fprintf(fd, "ideal(");need_klammer=TRUE; }
434    else if (type_id == MODUL_CMD) { fprintf(fd, "module(");need_klammer=TRUE; }
435
436    if (fprintf(fd, "%s", rhs) == EOF) return EOF;
437    omFree(rhs);
438
439    if ((type_id == RING_CMD || type_id == QRING_CMD) &&
440        IDRING(h)->cf->type==n_algExt)
441    {
442      StringSetS("");
443      p_Write(IDRING(h)->cf->extRing->qideal->m[0],IDRING(h)->cf->extRing);
444      rhs = StringEndS();
445      if (fprintf(fd, "; minpoly = %s", rhs) == EOF) { omFree(rhs); return EOF;}
446      omFree(rhs);
447    }
448    else if (need_klammer) fprintf(fd, ")");
449  }
450  return 1;
451}
452
453BOOLEAN slGetDumpAscii(si_link l)
454{
455  if (l->name[0] == '\0')
456  {
457    Werror("getdump: Can not get dump from stdin");
458    return TRUE;
459  }
460  else
461  {
462    BOOLEAN status = newFile(l->name);
463    if (status)
464      return TRUE;
465
466    int old_echo=si_echo;
467    si_echo=0;
468
469    status=yyparse();
470
471    si_echo=old_echo;
472
473    if (status)
474      return TRUE;
475    else
476    {
477      // lets reset the file pointer to the end to reflect that
478      // we are finished with reading
479      FILE *f = (FILE *) l->data;
480      fseek(f, 0L, SEEK_END);
481      return FALSE;
482    }
483  }
484}
485
486
487void slStandardInit()
488{
489  si_link_extension s;
490  si_link_root=(si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
491  si_link_root->Open=slOpenAscii;
492  si_link_root->Close=slCloseAscii;
493  si_link_root->Kill=NULL;
494  si_link_root->Read=slReadAscii;
495  si_link_root->Read2=slReadAscii2;
496  si_link_root->Write=slWriteAscii;
497  si_link_root->Dump=slDumpAscii;
498  si_link_root->GetDump=slGetDumpAscii;
499  si_link_root->Status=slStatusAscii;
500  si_link_root->type="ASCII";
501  s = si_link_root;
502  s->next = NULL;
503}
Note: See TracBrowser for help on using the repository browser.