Updated/added MVSC++ 6.0 project files for compilation of
[rrdtool.git] / bindings / perl-shared / RRDs.xs
1 #ifdef __cplusplus
2 extern "C" {
3 #endif
4
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8 #include <time.h>
9
10 #ifdef __cplusplus
11 }
12 #endif
13
14 #include "../../src/rrd_tool.h"
15
16 /* perl 5.004 compatibility */
17 #if PERLPATCHLEVEL < 5 
18 #define PL_sv_undef sv_undef
19 #endif
20
21 #define rrdcode(name) \
22                 argv = (char **) malloc((items+1)*sizeof(char *));\
23                 argv[0] = "dummy";\
24                 for (i = 0; i < items; i++) { \
25                     STRLEN len; \
26                     char *handle= SvPV(ST(i),len);\
27                     /* actually copy the data to make sure possible modifications \
28                        on the argv data does not backfire into perl */ \
29                     argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char)); \
30                     strcpy(argv[i+1],handle); \
31                 } \
32                 optind=0; opterr=0; \
33                 rrd_clear_error();\
34                 RETVAL=name(items+1,argv); \
35                 for (i=0; i < items; i++) {\
36                     free(argv[i+1]);\
37                 } \
38                 free(argv);\
39                 \
40                 if (rrd_test_error()) XSRETURN_UNDEF;
41
42 /*
43  * should not be needed if libc is linked (see ntmake.pl)
44 #ifdef WIN32
45  #define free free
46  #define malloc malloc
47  #define realloc realloc
48 #endif
49 */
50
51
52 MODULE = RRDs   PACKAGE = RRDs  PREFIX = rrd_
53
54 BOOT:
55 #ifdef MUST_DISABLE_SIGFPE
56         signal(SIGFPE,SIG_IGN);
57 #endif
58 #ifdef MUST_DISABLE_FPMASK
59         fpsetmask(0);
60 #endif 
61         
62
63 SV*
64 rrd_error()
65         CODE:
66                 if (! rrd_test_error()) XSRETURN_UNDEF;
67                 RETVAL = newSVpv(rrd_get_error(),0);
68         OUTPUT:
69                 RETVAL
70
71         
72 int
73 rrd_last(...)
74       PROTOTYPE: @
75       PREINIT:
76       int i;
77       char **argv;
78       CODE:
79               rrdcode(rrd_last);
80       OUTPUT:
81             RETVAL
82
83
84 int
85 rrd_create(...)
86         PROTOTYPE: @    
87         PREINIT:
88         int i;
89         char **argv;
90         CODE:
91                 rrdcode(rrd_create);
92                 RETVAL = 1;
93         OUTPUT:
94                 RETVAL
95
96
97 int
98 rrd_update(...)
99         PROTOTYPE: @    
100         PREINIT:
101         int i;
102         char **argv;
103         CODE:
104                 rrdcode(rrd_update);
105                 RETVAL = 1;
106         OUTPUT:
107                 RETVAL
108
109
110 int
111 rrd_tune(...)
112         PROTOTYPE: @    
113         PREINIT:
114         int i;
115         char **argv;
116         CODE:
117                 rrdcode(rrd_tune);
118                 RETVAL = 1;
119         OUTPUT:
120                 RETVAL
121
122
123 void
124 rrd_graph(...)
125         PROTOTYPE: @    
126         PREINIT:
127         char **calcpr;
128         int i,xsize,ysize;
129         char **argv;
130         AV *retar;
131         PPCODE:
132                 argv = (char **) malloc((items+1)*sizeof(char *));
133                 argv[0] = "dummy";
134                 for (i = 0; i < items; i++) { 
135                     STRLEN len;
136                     char *handle = SvPV(ST(i),len);
137                     /* actually copy the data to make sure possible modifications
138                        on the argv data does not backfire into perl */ 
139                     argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
140                     strcpy(argv[i+1],handle);
141                 }
142                 optind=0; opterr=0; 
143                 rrd_clear_error();
144                 tzset();
145                 rrd_graph(items+1,argv,&calcpr,&xsize,&ysize); 
146                 for (i=0; i < items; i++) {
147                     free(argv[i+1]);
148                 }
149                 free(argv);
150
151                 if (rrd_test_error()) {
152                         if(calcpr)
153                            for(i=0;calcpr[i];i++)
154                                 free(calcpr[i]);
155                         XSRETURN_UNDEF;
156                 }
157                 retar=newAV();
158                 if(calcpr){
159                         for(i=0;calcpr[i];i++){
160                                  av_push(retar,newSVpv(calcpr[i],0));
161                                  free(calcpr[i]);
162                         }
163                         free(calcpr);
164                 }
165                 EXTEND(sp,4);
166                 PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
167                 PUSHs(sv_2mortal(newSViv(xsize)));
168                 PUSHs(sv_2mortal(newSViv(ysize)));
169
170 void
171 rrd_fetch(...)
172         PROTOTYPE: @    
173         PREINIT:
174                 time_t        start,end;                
175                 unsigned long step, ds_cnt,i,ii;
176                 rrd_value_t   *data,*datai;
177                 char **argv;
178                 char **ds_namv;
179                 AV *retar,*line,*names;
180         PPCODE:
181                 argv = (char **) malloc((items+1)*sizeof(char *));
182                 argv[0] = "dummy";
183                 for (i = 0; i < items; i++) { 
184                     STRLEN len;
185                     char *handle= SvPV(ST(i),len);
186                     /* actually copy the data to make sure possible modifications
187                        on the argv data does not backfire into perl */ 
188                     argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
189                     strcpy(argv[i+1],handle);
190                 }
191                 optind=0; opterr=0; 
192                 rrd_clear_error();
193                 rrd_fetch(items+1,argv,&start,&end,&step,&ds_cnt,&ds_namv,&data); 
194                 for (i=0; i < items; i++) {
195                     free(argv[i+1]);
196                 }
197                 free(argv);
198                 if (rrd_test_error()) XSRETURN_UNDEF;
199                 /* convert the ds_namv into perl format */
200                 names=newAV();
201                 for (ii = 0; ii < ds_cnt; ii++){
202                     av_push(names,newSVpv(ds_namv[ii],0));
203                     free(ds_namv[ii]);
204                 }
205                 free(ds_namv);                  
206                 /* convert the data array into perl format */
207                 datai=data;
208                 retar=newAV();
209                 for (i = start; i <= end; i += step){
210                         line = newAV();
211                         for (ii = 0; ii < ds_cnt; ii++){
212                           av_push(line,(isnan(*datai) ? &PL_sv_undef : newSVnv(*datai)));
213                           datai++;
214                         }
215                         av_push(retar,newRV_noinc((SV*)line));
216                 }
217                 free(data);
218                 EXTEND(sp,5);
219                 PUSHs(sv_2mortal(newSViv(start)));
220                 PUSHs(sv_2mortal(newSViv(step)));
221                 PUSHs(sv_2mortal(newRV_noinc((SV*)names)));
222                 PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
223
224
225 SV*
226 rrd_info(...)
227         PROTOTYPE: @    
228         PREINIT:
229                 info_t *data,*save;
230                 int i;
231                 char **argv;
232                 HV *hash;
233         CODE:
234                 /* prepare argument list */
235                 argv = (char **) malloc((items+1)*sizeof(char *));
236                 argv[0] = "dummy";
237                 for (i = 0; i < items; i++) { 
238                     STRLEN len;
239                     char *handle= SvPV(ST(i),len);
240                     /* actually copy the data to make sure possible modifications
241                        on the argv data does not backfire into perl */ 
242                     argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
243                     strcpy(argv[i+1],handle);
244                 }
245                 optind=0; opterr=0; 
246                 rrd_clear_error();
247                 data=rrd_info(items+1, argv);
248                 for (i=0; i < items; i++) {
249                     free(argv[i+1]);
250                 }
251                 free(argv);
252                 if (rrd_test_error()) XSRETURN_UNDEF;
253                 hash = newHV();
254                 while (data) {
255                     save=data;
256                 /* the newSV will get copied by hv so we create it as a mortal to make sure
257                    it does not keep hanging round after the fact */
258 #define hvs(VAL) hv_store_ent(hash, sv_2mortal(newSVpv(data->key,0)),VAL,0)                 
259                     switch (data->type) {
260                     case RD_I_VAL:
261                         if (isnan(data->value.u_val))
262                             hvs(&PL_sv_undef);
263                         else
264                             hvs(newSVnv(data->value.u_val));
265                         break;
266                     case RD_I_CNT:
267                         hvs(newSViv(data->value.u_cnt));
268                         break;
269                     case RD_I_STR:
270                         hvs(newSVpv(data->value.u_str,0));
271                         free(data->value.u_str);
272                         break;
273                     }
274 #undefine hvs
275                     free(data->key);
276                     data = data->next;              
277                     free(save);
278                 }
279                 free(data);
280                 RETVAL = newRV_noinc((SV*)hash);
281        OUTPUT:
282                 RETVAL
283
284