Finish to replace sciprint by Scierror when needed in graphics
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_plot2d.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
5  * 
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at    
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 /*------------------------------------------------------------------------*/
15 /* file: sci_plot2d.c                                                     */
16 /* desc : interface for plot2d routine                                    */
17 /*------------------------------------------------------------------------*/
18
19 #include <string.h>
20
21 #include "sci_demo.h"
22 #include "GetCommandArg.h"
23 #include "stack-c.h"
24 #include "BuildObjects.h"
25 #include "gw_graphics.h"
26 #include "DestroyObjects.h"
27 #include "GetProperty.h"
28 #include "BasicAlgos.h"
29 #include "sciCall.h"
30 #include "DefaultCommandArg.h"
31 #include "sci_plot2d.h"
32 #include "Scierror.h"
33 #include "localization.h"
34 #include "CurrentObjectsManagement.h"
35 #include "Scierror.h"
36
37 /*------------------------------------------------------------------------*/
38 int sci_plot2d( char * fname, unsigned long fname_len )
39 {
40   static char str[]="x=(0:0.1:2*%pi)';plot2d(x,[sin(x),sin(2*x),sin(3*x)],style=[-1,-2,3],rect=[0,-2,2*%pi,2], axesflag=1);";
41
42   int m1, n1, l1, m2, n2, l2, lt;
43   int test,i,j,iskip;
44   int frame_def=8;
45   int *frame=&frame_def;
46   int axes_def=1;
47   int *axes=&axes_def;
48
49   /* F.Leray 18.05.04 : log. case test*/
50   int size_x,size_y;
51   double xd[2];
52   double *x1;
53   char dataflag;
54
55   char   * logFlags = NULL  ;
56   int    * style    = NULL  ;
57   double * rect     = NULL  ;
58   char   * strf     = NULL  ;
59   char   * legend   = NULL  ;
60   int    * nax      = NULL  ;
61   BOOL     flagNax  = FALSE ;
62
63   static rhs_opts opts[]= { {-1,"axesflag","?",0,0,0},
64                                               {-1,"frameflag","?",0,0,0},
65                                         {-1,"leg","?",0,0,0},
66                                         {-1,"logflag","?",0,0,0},
67                                         {-1,"nax","?",0,0,0},
68                                         {-1,"rect","?",0,0,0},
69                                         {-1,"strf","?",0,0,0},
70                                         {-1,"style","?",0,0,0},
71                             {-1,NULL,NULL,0,0}};
72   if (Rhs == 0) 
73   {
74     int zero = 0 ;
75     sci_demo(fname,str,&zero);
76     return 0;
77   }
78
79   CheckRhs(1,9);
80
81   iskip=0;
82   if ( get_optionals(fname,opts) == 0) { return 0 ; }
83
84   if (GetType(1)==sci_strings)
85   {
86     /* logflags */
87     GetLogflags( fname, 1, opts, &logFlags ) ;
88     iskip=1;
89   }
90
91   if ( Rhs == 1 + iskip )       /** plot2d([loglags,] y); **/
92   {
93     if ( FirstOpt() <= Rhs )
94     {
95             Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"),fname,1, 3+iskip);
96             return -1;
97     }
98
99     GetRhsVar(1+iskip,MATRIX_OF_DOUBLE_DATATYPE, &m2, &n2, &l2);
100     CreateVar(2+iskip,MATRIX_OF_DOUBLE_DATATYPE,  &m2, &n2, &l1);
101     if (m2 == 1 && n2 > 1) { m2 = n2; n2 = 1;}
102     m1 = m2;  n1 = n2;
103     for (i = 0; i < m2 ; ++i) 
104     {
105             for (j = 0 ; j < n2 ;  ++j)
106       {
107               *stk( l1 + i + m2*j) = (double) i+1;
108       }
109     }
110   }
111
112   if (Rhs >= 2+iskip)
113   {
114     if ( FirstOpt() < 3+iskip)
115     {
116       Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"), fname,1, 3+iskip);
117       return -1;
118     }
119
120     /** plot2d([loglags,] x,y,....); **/
121
122     /* x */
123     GetRhsVar(1+iskip,MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1);
124
125     /* y */
126     GetRhsVar(2+iskip,MATRIX_OF_DOUBLE_DATATYPE, &m2, &n2, &l2);
127
128     test = (m1*n1 == 0)||
129       ((m1 == 1 || n1 == 1) && (m2 == 1 || n2 ==1) && (m1*n1 == m2*n2))  ||
130       ((m1 == m2) && (n1 == n2)) ||
131       ((m1 == 1 && n1 == m2) || (n1 == 1 && m1 == m2));
132     CheckDimProp(1+iskip,2+iskip,!test);
133
134     if (m1*n1 == 0)
135     { /* default x=1:n */
136       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m2, &n2, &lt);
137       if (m2 == 1 && n2 > 1) { m2 = n2; n2 = 1;}
138       for (i = 0; i < m2 ; ++i) 
139       {
140               for (j = 0 ; j < n2 ;  ++j)
141         {
142                  *stk( lt + i + m2*j) = (double) i+1;
143         }
144       }
145       m1 = m2;
146       n1 = n2;
147       l1 = lt;
148     }
149     else if ((m1 == 1 || n1 == 1) && (m2 != 1 && n2 != 1) )
150     {
151       /* a single x vector for mutiple columns for y */
152       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m2, &n2, &lt);
153       for (i = 0; i < m2 ; ++i)
154       {
155               for (j = 0 ; j < n2 ;  ++j)
156         {
157                 *stk( lt + i + m2*j) = *stk(l1 +i);
158         }
159       }
160       m1 = m2;
161       n1 = n2;
162       l1 = lt;
163     }
164     else if ((m1 == 1 && n1 == 1) && (n2 != 1) )
165     {
166       /* a single y row vector  for a single x */
167       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m1, &n2, &lt);
168       for (j = 0 ; j < n2 ;  ++j)
169       {
170               *stk( lt + j ) = *stk(l1);
171       }
172       n1 = n2;
173       l1 = lt;
174     }
175     else
176     {
177       if (m2 == 1 && n2 > 1) { m2 = n2; n2 = 1;}
178       if (m1 == 1 && n1 > 1) { m1 = n1; n1 = 1;}
179     }
180   }
181
182   if(n1 == -1 || n2 == -1 || m1 == -1 || m2 == -1)
183   {
184           Scierror(999, _("%s: Wrong size for input arguments #%d and #%d.\n"), fname, 1, 2); /* @TODO : detail error */
185   }
186
187   sciGetStyle( fname, 3+iskip, n1, opts, &style ) ;
188   GetStrf( fname, 4+iskip, opts, &strf ) ;
189   GetLegend( fname, 5+iskip, opts, &legend );
190   GetRect( fname, 6+iskip, opts, &rect );
191   GetNax( 7+iskip, opts, &nax, &flagNax ) ;
192   if (iskip==0) { GetLogflags( fname, 8, opts, &logFlags ) ; }
193
194   if ( isDefStrf( strf ) )
195   {
196     char strfl[4];
197     strcpy(strfl,DEFSTRFN);
198
199     strf = strfl;
200     if ( !isDefRect( rect ) )
201     {
202       strfl[1] = '7';
203     }
204     if ( !isDefLegend( legend ) )
205     {
206       strfl[0] = '1';
207     }
208
209     GetOptionalIntArg(fname,9,"frameflag",&frame,1,opts);
210     if( frame != &frame_def )
211     {
212       strfl[1] = (char)(*frame+48);
213     }
214     GetOptionalIntArg(fname, 9,"axesflag",&axes,1,opts);
215     if(axes != &axes_def)
216     {
217       strfl[2] = (char)(*axes+48);
218     }
219   }
220
221   /* Make a test on log. mode : available or not depending on the bounds set by Rect arg. or xmin/xmax :
222   Rect case :
223   - if the min bound is strictly posivite, we can use log. mode
224   - if not, send error message 
225   x/y min/max case:
226   - we find the first strictly positive min bound in Plo2dn.c ?? */
227
228   switch (strf[1])
229   {
230   case '0': 
231     /* no computation, the plot use the previous (or default) scale */
232     break;
233   case '1' : case '3' : case '5' : case '7':
234     /* based on Rect arg */ 
235     if( rect[0] > rect[2] || rect[1] > rect[3])
236     {
237       Scierror(999, _("%s: Impossible status min > max in x or y rect data.\n"),fname);
238       return -1;
239     }
240
241     if( rect[0] <= 0. && logFlags[1] =='l') /* xmin */
242     {
243       Scierror(999, _("%s: Bounds on x axis must be strictly positive to use logarithmic mode.\n"),fname);
244       return -1 ;
245     }
246
247     if( rect[1] <= 0. && logFlags[2] =='l') /* ymin */
248     {
249       Scierror(999, _("%s: Bounds on y axis must be strictly positive to use logarithmic mode.\n"),fname);
250       return -1 ;
251     }
252
253     break;
254   case '2' : case '4' : case '6' : case '8': case '9':
255     /* computed from the x/y min/max */
256     if ( (int)strlen(logFlags) < 1)
257     {
258       dataflag='g' ;
259     }
260     else
261     {
262       dataflag=logFlags[0];
263     }
264
265     switch ( dataflag )
266     {
267     case 'e' : 
268       xd[0] = 1.0; xd[1] = (double)m1;
269       x1 = xd;size_x = (m1 != 0) ? 2 : 0 ;
270       break; 
271     case 'o' : 
272       x1 = stk(l1);size_x = m1;
273       break;
274     case 'g' : 
275     default  : 
276       x1 = stk(l1);size_x = (n1*m1) ;
277       break; 
278     }
279
280     if (size_x != 0)
281     {
282       if(logFlags[1] == 'l' && sciFindStPosMin(stk(l1),size_x) <= 0.0 )
283       {
284         Scierror(999, _("%s: At least one x data must be strictly positive to compute the bounds and use logarithmic mode.\n"),fname);
285         return -1 ;
286       }
287     }
288
289     size_y = (n1*m1) ;
290
291     if (size_y != 0)
292     {
293       if( logFlags[2] == 'l' && sciFindStPosMin(stk(l2),size_y) <= 0.0 )
294       {
295         Scierror(999, _("%s: At least one y data must be strictly positive to compute the bounds and use logarithmic mode\n"),fname);
296         return -1 ;
297       }
298     }
299
300     break;
301   }
302
303   // open a figure if none already exists
304   sciGetCurrentFigure();
305   Objplot2d (1,logFlags,stk(l1), stk(l2), &n1, &m1, style, strf,legend, rect,nax,flagNax);
306
307   LhsVar(1)=0;
308   return 0;
309 }
310 /*------------------------------------------------------------------------*/