More Win32 build changes; thanks to Kerry Calvert.
[rrdtool.git] / bindings / perl-shared / RRDs.xs
index 17b3d85..1340b6f 100644 (file)
@@ -5,7 +5,6 @@ extern "C" {
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
-#include <time.h>
 
 #ifdef __cplusplus
 }
@@ -18,6 +17,7 @@ extern "C" {
 #define PL_sv_undef sv_undef
 #endif
 
+
 #define rrdcode(name) \
                argv = (char **) malloc((items+1)*sizeof(char *));\
                argv[0] = "dummy";\
@@ -141,7 +141,6 @@ rrd_graph(...)
                }
                optind=0; opterr=0; 
                rrd_clear_error();
-                tzset();
                rrd_graph(items+1,argv,&calcpr,&xsize,&ysize); 
                for (i=0; i < items; i++) {
                    free(argv[i+1]);
@@ -151,16 +150,16 @@ rrd_graph(...)
                if (rrd_test_error()) {
                        if(calcpr)
                           for(i=0;calcpr[i];i++)
-                               free(calcpr[i]);
+                               rrd_freemem(calcpr[i]);
                        XSRETURN_UNDEF;
                }
                retar=newAV();
                if(calcpr){
                        for(i=0;calcpr[i];i++){
                                 av_push(retar,newSVpv(calcpr[i],0));
-                                free(calcpr[i]);
+                                rrd_freemem(calcpr[i]);
                        }
-                       free(calcpr);
+                       rrd_freemem(calcpr);
                }
                EXTEND(sp,4);
                PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
@@ -200,13 +199,13 @@ rrd_fetch(...)
                names=newAV();
                for (ii = 0; ii < ds_cnt; ii++){
                    av_push(names,newSVpv(ds_namv[ii],0));
-                   free(ds_namv[ii]);
+                   rrd_freemem(ds_namv[ii]);
                }
-               free(ds_namv);                  
+               rrd_freemem(ds_namv);                   
                /* convert the data array into perl format */
                datai=data;
                retar=newAV();
-               for (i = start; i <= end; i += step){
+               for (i = start+step; i <= end; i += step){
                        line = newAV();
                        for (ii = 0; ii < ds_cnt; ii++){
                          av_push(line,(isnan(*datai) ? &PL_sv_undef : newSVnv(*datai)));
@@ -214,14 +213,73 @@ rrd_fetch(...)
                        }
                        av_push(retar,newRV_noinc((SV*)line));
                }
-               free(data);
+               rrd_freemem(data);
                EXTEND(sp,5);
-               PUSHs(sv_2mortal(newSViv(start)));
+               PUSHs(sv_2mortal(newSViv(start+step)));
                PUSHs(sv_2mortal(newSViv(step)));
                PUSHs(sv_2mortal(newRV_noinc((SV*)names)));
                PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
 
 
+int
+rrd_xport(...)
+       PROTOTYPE: @    
+       PREINIT:
+                time_t start,end;              
+                int xsize;
+               unsigned long step, col_cnt,row_cnt,i,ii;
+               rrd_value_t *data,*ptr;
+                char **argv,**legend_v;
+               AV *retar,*line,*names;
+       PPCODE:
+               argv = (char **) malloc((items+1)*sizeof(char *));
+               argv[0] = "dummy";
+               for (i = 0; i < items; i++) { 
+                   STRLEN len;
+                   char *handle = SvPV(ST(i),len);
+                   /* actually copy the data to make sure possible modifications
+                      on the argv data does not backfire into perl */ 
+                   argv[i+1] = (char *) malloc((strlen(handle)+1)*sizeof(char));
+                   strcpy(argv[i+1],handle);
+               }
+               optind=0; opterr=0; 
+               rrd_clear_error();
+               rrd_xport(items+1,argv,&xsize,&start,&end,&step,&col_cnt,&legend_v,&data); 
+               for (i=0; i < items; i++) {
+                   free(argv[i+1]);
+               }
+               free(argv);
+               if (rrd_test_error()) XSRETURN_UNDEF;
+
+                /* convert the legend_v into perl format */
+               names=newAV();
+               for (ii = 0; ii < col_cnt; ii++){
+                   av_push(names,newSVpv(legend_v[ii],0));
+                   rrd_freemem(legend_v[ii]);
+               }
+               rrd_freemem(legend_v);                  
+
+               /* convert the data array into perl format */
+               ptr=data;
+               retar=newAV();
+               for (i = start+step; i <= end; i += step){
+                       line = newAV();
+                       for (ii = 0; ii < col_cnt; ii++){
+                         av_push(line,(isnan(*ptr) ? &PL_sv_undef : newSVnv(*ptr)));
+                         ptr++;
+                       }
+                       av_push(retar,newRV_noinc((SV*)line));
+               }
+               rrd_freemem(data);
+
+               EXTEND(sp,7);
+               PUSHs(sv_2mortal(newSViv(start+step)));
+               PUSHs(sv_2mortal(newSViv(end)));
+               PUSHs(sv_2mortal(newSViv(step)));
+               PUSHs(sv_2mortal(newSViv(col_cnt)));
+               PUSHs(sv_2mortal(newRV_noinc((SV*)names)));
+               PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
+
 SV*
 rrd_info(...)
        PROTOTYPE: @    
@@ -268,15 +326,15 @@ rrd_info(...)
                        break;
                    case RD_I_STR:
                        hvs(newSVpv(data->value.u_str,0));
-                       free(data->value.u_str);
+                       rrd_freemem(data->value.u_str);
                        break;
                    }
 #undefine hvs
-                   free(data->key);
+                   rrd_freemem(data->key);
                    data = data->next;              
-                   free(save);
+                   rrd_freemem(save);
                }
-                free(data);
+                rrd_freemem(data);
                 RETVAL = newRV_noinc((SV*)hash);
        OUTPUT:
                RETVAL