source: git/Singular/links/asciiLink.cc @ 7b9b8e5

spielwiese
Last change on this file since 7b9b8e5 was 7b9b8e5, checked in by Hans Schoenemann <hannes@…>, 8 years ago
fix: Werror -> WerrorS if possible
  • Property mode set to 100644
File size: 12.7 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          fprintf(outfile,"%s",pString(I->m[i]));
172          if (i<IDELEMS(I)-1) fprintf(outfile,",");
173        }
174        break;
175      }
176    default:
177      s = v->String();
178      // free v ??
179      if (s!=NULL)
180      {
181        fprintf(outfile,"%s\n",s);
182        omFree((ADDRESS)s);
183      }
184      else
185      {
186        WerrorS("cannot convert to string");
187        err=TRUE;
188      }
189    }
190    v = v->next;
191  }
192  fflush(outfile);
193  return err;
194}
195
196const char* slStatusAscii(si_link l, const char* request)
197{
198  if (strcmp(request, "read") == 0)
199  {
200    if (SI_LINK_R_OPEN_P(l)) return "ready";
201    else return "not ready";
202  }
203  else if (strcmp(request, "write") == 0)
204  {
205    if (SI_LINK_W_OPEN_P(l)) return "ready";
206    else return "not ready";
207  }
208  else return "unknown status request";
209}
210
211/*------------------ Dumping in Ascii format -----------------------*/
212
213BOOLEAN slDumpAscii(si_link l)
214{
215  FILE *fd = (FILE *) l->data;
216  idhdl h = IDROOT, rh = currRingHdl;
217  char **list_of_libs=NULL;
218  BOOLEAN status = DumpAscii(fd, h, &list_of_libs);
219
220  if (! status ) status = DumpAsciiMaps(fd, h, NULL);
221
222  if (currRingHdl != rh) rSetHdl(rh);
223  fprintf(fd, "option(set, intvec(%d, %d));\n", si_opt_1, si_opt_2);
224  char **p=list_of_libs;
225  if (p!=NULL)
226  {
227    while((*p!=NULL) && (*p!=(char*)1))
228    {
229      fprintf(fd,"load(\"%s\",\"try\");\n",*p);
230      p++;
231    }
232    omFree(list_of_libs);
233  }
234  fprintf(fd, "RETURN();\n");
235  fflush(fd);
236
237  return status;
238}
239
240// we do that recursively, to dump ids in the the order in which they
241// were actually defined
242static BOOLEAN DumpAscii(FILE *fd, idhdl h, char ***list_of_libs)
243{
244  if (h == NULL) return FALSE;
245
246  if (DumpAscii(fd, IDNEXT(h),list_of_libs)) return TRUE;
247
248  // need to set the ring before writing it, otherwise we get in
249  // trouble with minpoly
250  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
251    rSetHdl(h);
252
253  if (DumpAsciiIdhdl(fd, h,list_of_libs)) return TRUE;
254
255  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
256    return DumpAscii(fd, IDRING(h)->idroot,list_of_libs);
257  else
258    return FALSE;
259}
260
261static BOOLEAN DumpAsciiMaps(FILE *fd, idhdl h, idhdl rhdl)
262{
263  if (h == NULL) return FALSE;
264  if (DumpAsciiMaps(fd, IDNEXT(h), rhdl)) return TRUE;
265
266  if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
267    return DumpAsciiMaps(fd, IDRING(h)->idroot, h);
268  else if (IDTYP(h) == MAP_CMD)
269  {
270    char *rhs;
271    rSetHdl(rhdl);
272    rhs = h->String();
273
274    if (fprintf(fd, "setring %s;\n", IDID(rhdl)) == EOF) return TRUE;
275    if (fprintf(fd, "%s %s = %s, %s;\n", Tok2Cmdname(MAP_CMD), IDID(h),
276                IDMAP(h)->preimage, rhs) == EOF)
277    {
278      omFree(rhs);
279      return TRUE;
280    }
281    else
282    {
283      omFree(rhs);
284      return FALSE;
285    }
286  }
287  else return FALSE;
288}
289
290static BOOLEAN DumpAsciiIdhdl(FILE *fd, idhdl h, char ***list_of_libs)
291{
292  const char *type_str = GetIdString(h);
293  int type_id = IDTYP(h);
294
295  if (type_id == PACKAGE_CMD)
296  {
297    if (strcmp(IDID(h),"Top")==0) return FALSE;
298    if (IDPACKAGE(h)->language==LANG_SINGULAR) return FALSE;
299  }
300
301  // we do not throw an error if a wrong type was attempted to be dumped
302  if (type_str == NULL)
303    return FALSE;
304
305  // handle qrings separately
306  if (type_id == QRING_CMD)
307    return DumpQring(fd, h, type_str);
308
309  // C-proc not to be dumped
310  if ((type_id == PROC_CMD) && (IDPROC(h)->language == LANG_C))
311    return FALSE;
312
313  // handle libraries
314  if ((type_id == PROC_CMD)
315  && (IDPROC(h)->language == LANG_SINGULAR)
316  && (IDPROC(h)->libname!=NULL))
317    return CollectLibs(IDPROC(h)->libname,list_of_libs);
318
319  // put type and name
320  if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF)
321    return TRUE;
322  // for matricies, append the dimension
323  if (type_id == MATRIX_CMD)
324  {
325    ideal id = IDIDEAL(h);
326    if (fprintf(fd, "[%d][%d]", id->nrows, id->ncols)== EOF) return TRUE;
327  }
328  else if (type_id == INTMAT_CMD)
329  {
330    if (fprintf(fd, "[%d][%d]", IDINTVEC(h)->rows(), IDINTVEC(h)->cols())
331        == EOF) return TRUE;
332  }
333
334  if (type_id == PACKAGE_CMD)
335  {
336    return (fprintf(fd, ";\n") == EOF);
337  }
338
339  // write the equal sign
340  if (fprintf(fd, " = ") == EOF) return TRUE;
341
342  // and the right hand side
343  if (DumpRhs(fd, h) == EOF) return TRUE;
344
345  // semicolon und tschuess
346  if (fprintf(fd, ";\n") == EOF) return TRUE;
347
348  return FALSE;
349}
350
351static const char* GetIdString(idhdl h)
352{
353  int type = IDTYP(h);
354
355  switch(type)
356  {
357    case LIST_CMD:
358    {
359      lists l = IDLIST(h);
360      int i, nl = l->nr + 1;
361
362      for (i=0; i<nl; i++)
363        if (GetIdString((idhdl) &(l->m[i])) == NULL) return NULL;
364    }
365    #ifdef SINGULAR_4_1
366    case CRING_CMD:
367    case CNUMBER_CMD:
368    case CMATRIX_CMD:
369    #endif
370    case BIGINT_CMD:
371    case PACKAGE_CMD:
372    case INT_CMD:
373    case INTVEC_CMD:
374    case INTMAT_CMD:
375    case STRING_CMD:
376    case RING_CMD:
377    case QRING_CMD:
378    case PROC_CMD:
379    case NUMBER_CMD:
380    case POLY_CMD:
381    case IDEAL_CMD:
382    case VECTOR_CMD:
383    case MODUL_CMD:
384    case MATRIX_CMD:
385      return Tok2Cmdname(type);
386
387    case MAP_CMD:
388    case LINK_CMD:
389      return NULL;
390
391    default:
392      Warn("Error dump data of type %s", Tok2Cmdname(IDTYP(h)));
393       return NULL;
394  }
395}
396
397static BOOLEAN DumpQring(FILE *fd, idhdl h, const char *type_str)
398{
399  char *ring_str = h->String();
400  if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str)
401              == EOF) return TRUE;
402  if (fprintf(fd, "%s temp_ideal = %s;\n", Tok2Cmdname(IDEAL_CMD),
403              iiStringMatrix((matrix) IDRING(h)->qideal, 1, currRing, n_GetChar(currRing->cf)))
404      == EOF) return TRUE;
405  if (fprintf(fd, "attrib(temp_ideal, \"isSB\", 1);\n") == EOF) return TRUE;
406  if (fprintf(fd, "%s %s = temp_ideal;\n", type_str, IDID(h)) == EOF)
407    return TRUE;
408  if (fprintf(fd, "kill temp_ring;\n") == EOF) return TRUE;
409  else
410  {
411    omFree(ring_str);
412    return FALSE;
413  }
414}
415
416static BOOLEAN CollectLibs(char *name, char *** list_of_libs)
417{
418  if (*list_of_libs==NULL)
419  {
420    #define MAX_LIBS 256
421    (*list_of_libs)=(char**)omalloc0(MAX_LIBS*sizeof(char**));
422    (*list_of_libs)[0]=name;
423    (*list_of_libs)[MAX_LIBS-1]=(char*)1;
424    return FALSE;
425  }
426  else
427  {
428    char **p=*list_of_libs;
429    while (((*p)!=NULL)&&((*p!=(char*)1)))
430    {
431      if (strcmp((*p),name)==0) return FALSE;
432      p++;
433    }
434    if (*p==(char*)1)
435    {
436      WerrorS("too many libs");
437      return TRUE;
438    }
439    else
440    {
441      *p=name;
442    }
443  }
444  return FALSE;
445}
446
447
448static int DumpRhs(FILE *fd, idhdl h)
449{
450  int type_id = IDTYP(h);
451
452  if (type_id == LIST_CMD)
453  {
454    lists l = IDLIST(h);
455    int i, nl = l->nr;
456
457    fprintf(fd, "list(");
458
459    for (i=0; i<nl; i++)
460    {
461      if (DumpRhs(fd, (idhdl) &(l->m[i])) == EOF) return EOF;
462      fprintf(fd, ",");
463    }
464    if (nl > 0)
465    {
466      if (DumpRhs(fd, (idhdl) &(l->m[nl])) == EOF) return EOF;
467    }
468    fprintf(fd, ")");
469  }
470  else  if (type_id == STRING_CMD)
471  {
472    char *pstr = IDSTRING(h);
473    fputc('"', fd);
474    while (*pstr != '\0')
475    {
476      if (*pstr == '"' || *pstr == '\\')  fputc('\\', fd);
477      fputc(*pstr, fd);
478      pstr++;
479    }
480    fputc('"', fd);
481  }
482  else  if (type_id == PROC_CMD)
483  {
484    procinfov pi = IDPROC(h);
485    if (pi->language == LANG_SINGULAR)
486    {
487      /* pi-Libname==NULL */
488      char *pstr = pi->data.s.body;
489      fputc('"', fd);
490      while (*pstr != '\0')
491      {
492        if (*pstr == '"' || *pstr == '\\') fputc('\\', fd);
493        fputc(*pstr, fd);
494        pstr++;
495      }
496      fputc('"', fd);
497    }
498    else fputs("(null)", fd);
499  }
500  else
501  {
502    char *rhs = h->String();
503
504    if (rhs == NULL) return EOF;
505
506    BOOLEAN need_klammer=FALSE;
507    if (type_id == INTVEC_CMD) { fprintf(fd, "intvec(");need_klammer=TRUE; }
508    else if (type_id == IDEAL_CMD) { fprintf(fd, "ideal(");need_klammer=TRUE; }
509    else if (type_id == MODUL_CMD) { fprintf(fd, "module(");need_klammer=TRUE; }
510    else if (type_id == BIGINT_CMD) { fprintf(fd, "bigint(");need_klammer=TRUE; }
511
512    if (fprintf(fd, "%s", rhs) == EOF) return EOF;
513    omFree(rhs);
514
515    if ((type_id == RING_CMD || type_id == QRING_CMD) &&
516        IDRING(h)->cf->type==n_algExt)
517    {
518      StringSetS("");
519      p_Write(IDRING(h)->cf->extRing->qideal->m[0],IDRING(h)->cf->extRing);
520      rhs = StringEndS();
521      if (fprintf(fd, "; minpoly = %s", rhs) == EOF) { omFree(rhs); return EOF;}
522      omFree(rhs);
523    }
524    else if (need_klammer) fprintf(fd, ")");
525  }
526  return 1;
527}
528
529BOOLEAN slGetDumpAscii(si_link l)
530{
531  if (l->name[0] == '\0')
532  {
533    WerrorS("getdump: Can not get dump from stdin");
534    return TRUE;
535  }
536  else
537  {
538    BOOLEAN status = newFile(l->name);
539    if (status)
540      return TRUE;
541
542    int old_echo=si_echo;
543    si_echo=0;
544
545    status=yyparse();
546
547    si_echo=old_echo;
548
549    if (status)
550      return TRUE;
551    else
552    {
553      // lets reset the file pointer to the end to reflect that
554      // we are finished with reading
555      FILE *f = (FILE *) l->data;
556      fseek(f, 0L, SEEK_END);
557      return FALSE;
558    }
559  }
560}
561
562
563void slStandardInit()
564{
565  si_link_extension s;
566  si_link_root=(si_link_extension)omAlloc0Bin(s_si_link_extension_bin);
567  si_link_root->Open=slOpenAscii;
568  si_link_root->Close=slCloseAscii;
569  si_link_root->Kill=NULL;
570  si_link_root->Read=slReadAscii;
571  si_link_root->Read2=slReadAscii2;
572  si_link_root->Write=slWriteAscii;
573  si_link_root->Dump=slDumpAscii;
574  si_link_root->GetDump=slGetDumpAscii;
575  si_link_root->Status=slStatusAscii;
576  si_link_root->type="ASCII";
577  s = si_link_root;
578  s->next = NULL;
579}
Note: See TracBrowser for help on using the repository browser.