1
2 /****************************************
3 * Computer Algebra System SINGULAR *
4 ****************************************/
5 /*
6 * ABSTRACT: output system
7 */
8
9 #include "misc/auxiliary.h"
10
11 #include "reporter/reporter.h"
12 #include "resources/feResource.h"
13 #include "resources/feFopen.h"
14 //#include "options.h"
15 #include "omalloc/omalloc.h"
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include "misc/mylimits.h"
20 #include <stdarg.h>
21 #include <sys/stat.h>
22 #include <ctype.h>
23 #include <unistd.h>
24
25 #ifdef HAVE_PWD_H
26 #include <pwd.h>
27 #endif
28
29
30 #define fePutChar(c) fputc((unsigned char)(c),stdout)
31 /*0 implementation */
32
33 // output/print buffer:
34 #define INITIAL_PRINT_BUFFER 24*1024L
35 // line buffer for reading:
36 // minimal value for MAX_FILE_BUFFER: 4*4096 - see Tst/Long/gcd0_l.tst
37 // this is an upper limit for the size of monomials/numbers read via the interpreter
38 #define MAX_FILE_BUFFER 4*4096
39 STATIC_VAR long feBufferLength=0;
40 STATIC_VAR char * feBuffer=NULL;
41 STATIC_VAR long feBufferLength_save[8];
42 STATIC_VAR char * feBuffer_save[8];
43 STATIC_VAR int feBuffer_cnt=0;
44 STATIC_VAR char * feBufferStart_save[8];
45
46
47 VAR char * feErrors=NULL;
48 VAR int feErrorsLen=0;
49 VAR BOOLEAN feWarn = TRUE;
50 VAR BOOLEAN feOut = TRUE;
51
52 //void (*WerrorS_callback)(const char *s) = NULL;
53
54 const char feNotImplemented[]="not implemented";
55
56 VAR int feProt = FALSE;
57 VAR FILE* feProtFile;
58
59 STATIC_VAR char * feBufferStart;
60 /* only used in StringSet(S)/StringAppend(S)*/
StringAppend(const char * fmt,...)61 void StringAppend(const char *fmt, ...)
62 {
63 va_list ap;
64 char *s = feBufferStart; /*feBuffer + strlen(feBuffer);*/
65 int vs;
66 long more;
67 va_start(ap, fmt);
68 if ((more=feBufferStart-feBuffer+strlen(fmt)+100)>feBufferLength)
69 {
70 more = ((more + (8*1024-1))/(8*1024))*(8*1024);
71 int l=s-feBuffer;
72 feBuffer=(char *)omReallocSize((void *)feBuffer,feBufferLength,
73 more);
74 #if (!defined(SING_NDEBUG)) && (!defined(OM_NDEBUG))
75 omMarkAsStaticAddr(feBuffer);
76 #endif
77 feBufferLength=more;
78 s=feBuffer+l;
79 #ifndef BSD_SPRINTF
80 feBufferStart=s;
81 #endif
82 }
83 #ifdef BSD_SPRINTF
84 vsprintf(s, fmt, ap);
85 while (*s!='\0') s++;
86 feBufferStart =s;
87 #else
88 #ifdef HAVE_VSNPRINTF
89 vs = vsnprintf(s, feBufferLength - (feBufferStart - feBuffer), fmt, ap);
90 if (vs == -1)
91 {
92 assume(0);
93 feBufferStart = feBuffer + feBufferLength -1;
94 }
95 else
96 {
97 feBufferStart += vs;
98 }
99 #else
100 feBufferStart += vsprintf(s, fmt, ap);
101 #endif
102 #endif
103 omCheckAddrSize(feBuffer, feBufferLength);
104 va_end(ap);
105 }
106
StringAppendS(const char * st)107 void StringAppendS(const char *st)
108 {
109 if (*st!='\0')
110 {
111 /* feBufferStart is feBuffer + strlen(feBuffer);*/
112 int l=strlen(st);
113 long more;
114 int ll=feBufferStart-feBuffer;
115 if ((more=ll+2+l)>feBufferLength)
116 {
117 more = ((more + (8*1024-1))/(8*1024))*(8*1024);
118 feBuffer=(char *)omreallocSize((void *)feBuffer,feBufferLength,
119 more);
120 feBufferLength=more;
121 feBufferStart=feBuffer+ll;
122 }
123 strncat(feBufferStart, st,l);
124 feBufferStart +=l;
125 }
126 }
127
StringSetS(const char * st)128 void StringSetS(const char *st)
129 {
130 feBuffer_save[feBuffer_cnt]=feBuffer;
131 feBuffer=(char*)omAlloc0(INITIAL_PRINT_BUFFER);
132 feBufferLength_save[feBuffer_cnt]=feBufferLength;
133 feBufferLength=INITIAL_PRINT_BUFFER;
134 feBufferStart_save[feBuffer_cnt]=feBufferStart;
135 feBufferStart=feBuffer;
136 feBuffer_cnt++;
137 assume(feBuffer_cnt<8);
138 int l=strlen(st);
139 long more;
140 if (l>feBufferLength)
141 {
142 more = ((l + (4*1024-1))/(4*1024))*(4*1024);
143 feBuffer=(char *)omReallocSize((ADDRESS)feBuffer,feBufferLength,
144 more);
145 feBufferLength=more;
146 }
147 strcpy(feBuffer,st);
148 feBufferStart=feBuffer+l;
149 }
150
StringEndS()151 char * StringEndS()
152 {
153 char *r=feBuffer;
154 feBuffer_cnt--;
155 assume(feBuffer_cnt >=0);
156 feBuffer=feBuffer_save[feBuffer_cnt];
157 feBufferLength=feBufferLength_save[feBuffer_cnt];
158 feBufferStart=feBufferStart_save[feBuffer_cnt];
159 if (strlen(r)<1024)
160 {
161 // if the used buffer is a "small block",
162 // substitue the "large" initial block by a small one
163 char *s=omStrDup(r); omFree(r); r=s;
164 }
165 return r;
166 }
167
WerrorS_batch(const char * s)168 void WerrorS_batch(const char *s)
169 {
170 if (feErrors==NULL)
171 {
172 feErrors=(char *)omAlloc(256);
173 feErrorsLen=256;
174 *feErrors = '\0';
175 }
176 else
177 {
178 if (((int)(strlen((char *)s)+ 20 +strlen(feErrors)))>=feErrorsLen)
179 {
180 feErrors=(char *)omReallocSize(feErrors,feErrorsLen,feErrorsLen+256);
181 feErrorsLen+=256;
182 }
183 }
184 strcat(feErrors, "Singular error: ");
185 strcat(feErrors, (char *)s);
186 errorreported = TRUE;
187 }
188
Werror(const char * fmt,...)189 void Werror(const char *fmt, ...)
190 {
191 va_list ap;
192 va_start(ap, fmt);
193 char *s=(char *)omAlloc(256);
194 vsprintf(s, fmt, ap);
195 WerrorS(s);
196 omFreeSize(s,256);
197 va_end(ap);
198 }
199
200 VAR void (*WarnS_callback)(const char *s) = NULL;
201
WarnS(const char * s)202 void WarnS(const char *s)
203 {
204 #define warn_str "// ** "
205 if (feWarn) /* ignore warnings if option --no-warn was given */
206 {
207 if (WarnS_callback==NULL)
208 {
209 fwrite(warn_str,1,6,stdout);
210 fwrite(s,1,strlen(s),stdout);
211 fwrite("\n",1,1,stdout);
212 fflush(stdout);
213 if (feProt&SI_PROT_O)
214 {
215 fwrite(warn_str,1,6,feProtFile);
216 fwrite(s,1,strlen(s),feProtFile);
217 fwrite("\n",1,1,feProtFile);
218 }
219 }
220 else
221 {
222 WarnS_callback(s);
223 }
224 }
225 }
226
Warn(const char * fmt,...)227 void Warn(const char *fmt, ...)
228 {
229 va_list ap;
230 va_start(ap, fmt);
231 char *s=(char *)omAlloc(256);
232 #ifdef HAVE_VSNPRINTF
233 vsnprintf(s, 256, fmt, ap);
234 #else
235 vsprintf(s, fmt, ap);
236 #endif
237 WarnS(s);
238 omFreeSize(s,256);
239 va_end(ap);
240 }
241
242
243 // some routines which redirect the output of print to a string
244 STATIC_VAR char* sprint = NULL;
245 STATIC_VAR char* sprint_backup = NULL;
SPrintStart()246 void SPrintStart()
247 {
248 if (sprint!=NULL)
249 {
250 if (sprint_backup!=NULL) WerrorS("internal error: SPrintStart");
251 else sprint_backup=sprint;
252 }
253 sprint = omStrDup("");
254 }
255
SPrintS(const char * s)256 static inline void SPrintS(const char* s)
257 {
258 omCheckAddr(sprint);
259 if ((s == NULL)||(*s == '\0')) return;
260 int ls = strlen(s);
261
262 char* ns;
263 int l = strlen(sprint);
264 ns = (char*) omAlloc((l + ls + 1)*sizeof(char));
265 if (l > 0) strcpy(ns, sprint);
266
267 strcpy(&(ns[l]), s);
268 omFree(sprint);
269 sprint = ns;
270 omCheckAddr(sprint);
271 }
272
SPrintEnd()273 char* SPrintEnd()
274 {
275 char* ns = sprint;
276 sprint = sprint_backup;
277 sprint_backup=NULL;
278 omCheckAddr(ns);
279 return ns;
280 }
281
282 // Print routines
283 extern "C" {
PrintS(const char * s)284 void PrintS(const char *s)
285 {
286 if (sprint != NULL)
287 {
288 SPrintS(s);
289 return;
290 }
291 else if (feOut) /* do not print when option --no-out was given */
292 {
293
294 if (PrintS_callback!=NULL)
295 {
296 PrintS_callback(s);
297 }
298 else
299 {
300 fwrite(s,1,strlen(s),stdout);
301 fflush(stdout);
302 if (feProt&SI_PROT_O)
303 {
304 fwrite(s,1,strlen(s),feProtFile);
305 }
306 }
307 }
308 }
309
PrintLn()310 void PrintLn()
311 {
312 PrintS("\n");
313 }
314
Print(const char * fmt,...)315 void Print(const char *fmt, ...)
316 {
317 if (sprint != NULL)
318 {
319 va_list ap;
320 va_start(ap, fmt);
321 omCheckAddr(sprint);
322 int ls = strlen(fmt);
323 if (fmt != NULL && ls > 0)
324 {
325 char* ns;
326 int l = strlen(sprint);
327 ns = (char*) omAlloc(sizeof(char)*(ls + l + 512));
328 if (l > 0) strcpy(ns, sprint);
329
330 #ifdef HAVE_VSNPRINTF
331 l = vsnprintf(&(ns[l]), ls+511, fmt, ap);
332 assume(l != -1);
333 #else
334 vsprintf(&(ns[l]), fmt, ap);
335 #endif
336 omCheckAddr(ns);
337 omFree(sprint);
338 sprint = ns;
339 }
340 va_end(ap);
341 return;
342 }
343 else if (feOut)
344 {
345 va_list ap;
346 va_start(ap, fmt);
347 int l;
348 long ls=strlen(fmt);
349 char *s=(char *)omAlloc(ls+512);
350 #ifdef HAVE_VSNPRINTF
351 l = vsnprintf(s, ls+511, fmt, ap);
352 if ((l==-1)||(s[l]!='\0')||(l!=(int)strlen(s)))
353 {
354 printf("Print problem: l=%d, fmt=>>%s<<\n",l,fmt);
355 }
356 #else
357 vsprintf(s, fmt, ap);
358 #endif
359 PrintS(s);
360 omFree(s);
361 va_end(ap);
362 }
363 }
PrintNSpaces(const int n)364 void PrintNSpaces(const int n)
365 {
366 int l=n-1;
367 while(l>=0) { PrintS(" "); l--; }
368 }
369
370 /* end extern "C" */
371 }
372
eati(const char * s,int * i)373 const char* eati(const char *s, int *i)
374 {
375 int l=0;
376
377 if (*s >= '0' && *s <= '9')
378 {
379 *i = 0;
380 while (*s >= '0' && *s <= '9')
381 {
382 *i *= 10;
383 *i += *s++ - '0';
384 l++;
385 if ((l>=MAX_INT_LEN)||((*i) <0))
386 {
387 s-=l;
388 Werror("`%s` greater than %d(max. integer representation)",
389 s,MAX_INT_VAL);
390 return s;
391 }
392 }
393 }
394 else *i = 1;
395 return s;
396 }
397
feStringAppendResources(int warn)398 void feStringAppendResources(int warn)
399 {
400 int i = 0;
401 char* r;
402 StringAppend("%-10s:\t%s\n", "argv[0]", feArgv0);
403 while (feResourceConfigs[i].key != NULL)
404 {
405 r = feResource(feResourceConfigs[i].key, warn);
406 StringAppend("%-10s:\t%s\n", feResourceConfigs[i].key,
407 (r != NULL ? r : ""));
408 i++;
409 }
410 }
411