1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /*
5 * ABSTRACT: interpreter: printing
6 */
7 
8 #include "kernel/mod2.h"
9 
10 #include "misc/intvec.h"
11 
12 #include "polys/matpol.h"
13 
14 #include "kernel/polys.h"
15 #include "kernel/ideals.h"
16 
17 #include "tok.h"
18 #include "ipid.h"
19 #include "subexpr.h"
20 #include "ipshell.h"
21 #include "ipprint.h"
22 #include "attrib.h"
23 
24 /*2
25 * print for: int, string, poly, vector, ideal
26 */
27 /*2
28 * print for: intvec
29 */
ipPrint_INTVEC(intvec * v)30 static BOOLEAN ipPrint_INTVEC(intvec* v)
31 {
32   v->show();
33   PrintLn();
34   return FALSE;
35 }
36 
37 /*2
38 * print for: intmat
39 */
ipPrint_INTMAT(intvec * v)40 static BOOLEAN ipPrint_INTMAT(intvec* v)
41 {
42   int i,j;
43   for(i=0;i<v->rows();i++)
44   {
45     for(j=0;j<v->cols();j++)
46     {
47       Print(" %5d",IMATELEM(*v,i+1,j+1));
48     }
49     PrintLn();
50   }
51   return FALSE;
52 }
53 
54 /*2
55 * internal print for: matrix
56 */
ipPrint_MA0(matrix m,const char * name)57 void ipPrint_MA0(matrix m, const char *name)
58 {
59   if ((MATCOLS(m)>0)&&(MATROWS(m)>0))
60   {
61     char **s=(char **)omAlloc(MATCOLS(m)*MATROWS(m)*sizeof(char*));
62     char *ss;
63     int *l=(int *)omAlloc0(MATCOLS(m)*sizeof(int));
64     int i,j,k;
65     int vl=si_max(colmax/MATCOLS(m),8);
66 
67     /* make enough space for the "largest" name*/
68     ss=(char *)omAlloc(14+strlen(name));
69     sprintf(ss,"%s[%d,%d]",name,MATCOLS(m),MATROWS(m));
70     vl=si_max(vl,(int)strlen(ss));
71     omFree(ss);
72 
73     /* convert all polys to string */
74     i=MATCOLS(m)*MATROWS(m)-1;
75     ss=pString(m->m[i]);
76     if ((int)strlen(ss)>colmax) { s[i]=NULL; omFree(ss); }
77     else                        s[i]=ss;
78     for(i--;i>=0;i--)
79     {
80       StringSetS("");
81       pString0(m->m[i]);
82       StringAppendS(",");
83       ss=StringEndS();
84       if ((int)strlen(ss)>colmax) s[i]=NULL;
85       else                        s[i]=ss;
86     }
87     /* look up the width of all columns, put it in l[col_nr] */
88     /* insert names for very long entries */
89     for(i=MATROWS(m)-1;i>=0;i--)
90     {
91       for(j=MATCOLS(m)-1;j>=0;j--)
92       {
93         if (s[i*MATCOLS(m)+j]==NULL)
94         {
95           ss=(char *)omAlloc(14+strlen(name));
96           s[i*MATCOLS(m)+j]=ss;
97           ss[0]='\0';
98           sprintf(ss,"%s[%d,%d]",name,i+1,j+1);
99           if ((i!=MATROWS(m)-1) || (j!=MATCOLS(m)-1))
100           {
101             strcat(ss,",");
102             vl=si_max(vl,(int)strlen(ss));
103           }
104         }
105         k=strlen(s[i*MATCOLS(m)+j]);
106         if (k>l[j]) l[j]=k;
107       }
108     }
109     /* does it fit on a line ? */
110     int maxlen=0;
111     for(j=MATCOLS(m)-1;j>=0;j--)
112     {
113       maxlen+=l[j];
114     }
115     if (maxlen>colmax)
116     {
117       /* NO, it does not fit, so retry: */
118       /* look up the width of all columns, clear very long entriess */
119       /* put length in l[col_nr] */
120       /* insert names for cleared entries */
121       for(j=MATCOLS(m)-1;j>=0;j--)
122       {
123         for(i=MATROWS(m)-1;i>=0;i--)
124         {
125           k=strlen(s[i*MATCOLS(m)+j]);
126           if (/*strlen(s[i*MATCOLS(m)+j])*/ k > vl)
127           {
128             omFree((ADDRESS)s[i*MATCOLS(m)+j]);
129             ss=(char *)omAlloc(14+strlen(name));
130             s[i*MATCOLS(m)+j]=ss;
131             ss[0]='\0';
132             sprintf(ss,"%s[%d,%d]",name,i+1,j+1);
133             if ((i!=MATROWS(m)-1) || (j!=MATCOLS(m)-1))
134             {
135               strcat(ss,",");
136             }
137             l[j]=strlen(s[i*MATCOLS(m)+j]);
138             if (l[j]>vl)
139             {
140 //#ifdef TEST
141 //              PrintS("pagewidth too small in print(matrix)\n");
142 //#endif
143               vl=l[j]; /* make large names fit*/
144             }
145             i=MATROWS(m);
146           }
147           else
148           {
149             if (k>l[j]) l[j]=k;
150           }
151         }
152       }
153     }
154     /*output of the matrix*/
155     for(i=0;i<MATROWS(m);i++)
156     {
157       k=l[0];
158       Print("%-*.*s",l[0],l[0],s[i*MATCOLS(m)]);
159       omFree(s[i*MATCOLS(m)]);
160       for(j=1;j<MATCOLS(m);j++)
161       {
162         if (k+l[j]>colmax)
163         {
164           PrintS("\n  ");
165           k=2;
166         }
167         k+=l[j];
168         Print("%-*.*s",l[j],l[j],s[i*MATCOLS(m)+j]);
169         omFree(s[i*MATCOLS(m)+j]);
170       }
171       PrintLn();
172     }
173     /* clean up */
174     omFreeSize((ADDRESS)s,MATCOLS(m)*MATROWS(m)*sizeof(char*));
175     omFreeSize((ADDRESS)l,MATCOLS(m)*sizeof(int));
176   }
177   else Print("%d x %d zero matrix\n",MATROWS(m),MATCOLS(m));
178 }
179 
180 /*2
181 * print for: matrix
182 */
ipPrint_MA(leftv u)183 static BOOLEAN ipPrint_MA(leftv u)
184 {
185   matrix m=(matrix)u->Data();
186   ipPrint_MA0(m,u->Name());
187   return FALSE;
188 }
189 
190 /*2
191 * print for: ring
192 */
ipPrint_RING(ring r)193 static BOOLEAN ipPrint_RING(ring r)
194 {
195   PrintS("polynomial ring, over a ");
196   if (rField_is_Ring(r))
197   {
198     if (rField_is_Domain(r)) PrintS("domain");
199     else                     PrintS("ring (with zero-divisors)");
200   }
201   else PrintS("field");
202   if (r->OrdSgn==1)          PrintS(", global");
203   else if (r->MixedOrder==1) PrintS(", mixed");
204   else                       PrintS(", local");
205   PrintS(" ordering\n");
206   rWrite(r, TRUE);
207   return FALSE;
208 }
209 
ipPrint_CRING(coeffs r)210 static BOOLEAN ipPrint_CRING(coeffs r)
211 {
212   if (nCoeff_is_Ring(r))
213   {
214     if (nCoeff_is_Domain(r)) PrintS("domain: ");
215     else                     PrintS("ring (with zero-divisors): ");
216   }
217   else PrintS("field: ");
218   PrintS(nCoeffName(r));
219   return FALSE;
220 }
221 /*2
222 * print for: vector
223 */
ipPrint_V(poly u)224 static BOOLEAN ipPrint_V(poly u)
225 {
226   polyset m=NULL;
227   int l,j;
228   /*convert into an array of the components*/
229   p_Vec2Polys(u, &m, &l, currRing);
230   /*output*/
231   PrintS("[");
232   j=0;
233   loop
234   {
235     PrintS(pString(m[j]));
236     j++;
237     if (j<l) PrintS(",");
238     else
239     {
240       PrintS("]\n");
241       break;
242     }
243   }
244   /* clean up */
245   for(j=l-1;j>=0;j--) pDelete(&m[j]);
246   omFreeSize((ADDRESS)m,l*sizeof(poly));
247   return FALSE;
248 }
249 
jjPRINT(leftv res,leftv u)250 BOOLEAN jjPRINT(leftv res, leftv u)
251 {
252   SPrintStart();
253   BOOLEAN bo=FALSE;
254   void *d=u->Data();
255   switch(u->Typ())
256   {
257       case INTVEC_CMD:
258         bo=ipPrint_INTVEC((intvec*)d);
259         break;
260 
261       case INTMAT_CMD:
262         bo=ipPrint_INTMAT((intvec*)d);
263         break;
264 
265       case MATRIX_CMD:
266         bo=ipPrint_MA(u);
267         break;
268 
269       case IDEAL_CMD:
270       {
271         char* s = u->String(NULL, FALSE, 2);
272         PrintS(s);
273         PrintLn();
274         omFree(s);
275         break;
276       }
277 
278       case MODUL_CMD:
279       {
280         matrix m = id_Module2Matrix(id_Copy((ideal)d,currRing),currRing);
281         ipPrint_MA0(m, u->Name());
282         id_Delete((ideal *) &m,currRing);
283         break;
284       }
285 
286       case VECTOR_CMD:
287         bo=ipPrint_V((poly)d);
288         break;
289 
290       case RING_CMD:
291         bo=ipPrint_RING((ring)d);
292         break;
293 
294       case CRING_CMD:
295         bo=ipPrint_CRING((coeffs)d);
296         break;
297 
298       default:
299         u->Print();
300         break;
301   }
302   char *s=SPrintEnd();
303   if (u->next==NULL)
304   {
305     int l=strlen(s);
306     if (s[l-1]=='\n') s[l-1]='\0';
307   }
308   res->data=(void*)s;
309   return bo;
310 }
311 
312 
313 /*2
314 * dbprint
315 */
jjDBPRINT(leftv res,leftv u)316 BOOLEAN jjDBPRINT(leftv res, leftv u)
317 {
318   BOOLEAN print=(printlevel>myynest);
319   if ((u->next!=NULL)&&(u->Typ()==INT_CMD))
320   {
321     print=  (((int)((long)(u->Data()))) > 0);
322     u=u->next;
323   }
324   if (print)
325   {
326     // BOOLEAN r=FALSE;
327     leftv h=u;
328     leftv hh;
329     while (h!=NULL)
330     {
331       hh=h->next;
332       h->next=NULL;
333       if (jjPRINT(res, h)) return TRUE;
334       PrintS((char*)res->data);
335       omFree(res->data);
336       PrintLn();
337       h->next=hh;
338       h=hh;
339     }
340   }
341   return FALSE;
342 }
343 
ipPrintBetti(leftv u)344 static void ipPrintBetti(leftv u)
345 {
346   int i,j;
347   int row_shift=(int)((long)(atGet(u,"rowShift",INT_CMD)));
348   intvec * betti=(intvec *)u->Data();
349   // head line --------------------------------------------------------
350   PrintS("      "); // 6 spaces for no. and :
351   for(j=0;j<betti->cols();j++) Print(" %5d",j); // 6 spaces pro column
352   PrintS("\n------"); // 6 spaces for no. and :
353   for(j=0;j<betti->cols();j++) PrintS("------"); // 6 spaces pro column
354   PrintLn();
355   // the table --------------------------------------------------------
356   for(i=0;i<betti->rows();i++)
357   {
358     Print("%5d:",i+row_shift);
359     for(j=1;j<=betti->cols();j++)
360     {
361       int m=IMATELEM(*betti,i+1,j);
362       if (m==0)
363         PrintS("     -");
364       else
365         Print(" %5d",m);
366     }
367     PrintLn();
368   }
369   // sum --------------------------------------------------------------
370   PrintS("------"); // 6 spaces for no. and :
371   for(j=0;j<betti->cols();j++) PrintS("------"); // 6 spaces pro column
372   PrintS("\ntotal:");
373   for(j=0;j<betti->cols();j++)
374   {
375     int s=0;
376     for(i=0;i<betti->rows();i++)
377     {
378       s+=IMATELEM(*betti,i+1,j+1);
379     }
380     Print(" %5d",s); // 6 spaces pro column
381   }
382   PrintLn();
383 }
384 
385 
386 /*2
387 * print(...,"format")
388 */
jjPRINT_FORMAT(leftv res,leftv u,leftv v)389 BOOLEAN jjPRINT_FORMAT(leftv res, leftv u, leftv v)
390 {
391 /* ==================== betti ======================================== */
392   if ((u->Typ()==INTMAT_CMD)&&(strcmp((char *)v->Data(),"betti")==0))
393   {
394     SPrintStart();
395     ipPrintBetti(u);
396     char *s = SPrintEnd();
397     s[strlen(s)]='\0';
398     res->data=s;
399   }
400   else
401 /* ======================== end betti ================================= */
402   {
403     char* ns = omStrDup((char*) v->Data());
404     int dim = 1;
405     if (strlen(ns) == 3 && ns[1] == '2')
406     {
407       dim = 2;
408       ns[1] = ns[2];
409       ns[2] = '\0';
410     }
411     if (strcmp(ns,"%l") == 0)
412     {
413       res->data = (char*) u->String(NULL, TRUE, dim);
414       if (dim == 2)
415       {
416         char* ns = (char*) omAlloc(strlen((char*) res->data) + 2);
417         strcpy(ns, (char*) res->data);
418         omFree(res->data);
419         strcat(ns, "\n");
420         res->data = ns;
421       }
422     }
423     else if (strcmp(ns,"%t") == 0)
424     {
425       SPrintStart();
426       type_cmd(u);
427       res->data = SPrintEnd();
428       if (dim != 2)
429         ((char*)res->data)[strlen((char*)res->data) -1] = '\0';
430     }
431     else if (strcmp(ns,"%;") == 0)
432     {
433       SPrintStart();
434       u->Print();
435       if (dim == 2) PrintLn();
436       res->data = SPrintEnd();
437     }
438     else if  (strcmp(ns,"%p") == 0)
439     {
440       iiExprArith1(res, u, PRINT_CMD);
441     }
442     else if (strcmp(ns,"%b") == 0 && (u->Typ()==INTMAT_CMD))
443     {
444       SPrintStart();
445       ipPrintBetti(u);
446       if (dim == 2) PrintLn();
447       res->data = SPrintEnd();
448     }
449     else
450     {
451       res->data = u->String(NULL, FALSE, dim);
452       if (dim == 2)
453       {
454         char* ns = (char*) omAlloc(strlen((char*) res->data) + 2);
455         strcpy(ns, (char*) res->data);
456         omFree(res->data);
457         strcat(ns, "\n");
458         res->data = ns;
459       }
460     }
461     omFree(ns);
462   }
463   return FALSE;
464 }
465