#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
-#include <time.h>
#ifdef __cplusplus
}
#endif
-#include "../src/rrd_tool.h"
+#include "../../src/rrd_tool.h"
/* perl 5.004 compatibility */
-#if PERLPATCHLEVEL < 5
+#if PERLPATCHLEVEL < 5
#define PL_sv_undef sv_undef
#endif
+
#define rrdcode(name) \
argv = (char **) malloc((items+1)*sizeof(char *));\
argv[0] = "dummy";\
\
if (rrd_test_error()) XSRETURN_UNDEF;
+#define hvs(VAL) hv_store_ent(hash, sv_2mortal(newSVpv(data->key,0)),VAL,0)
+
+#define rrdinfocode(name) \
+ /* prepare argument list */ \
+ 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(); \
+ data=name(items+1, argv); \
+ for (i=0; i < items; i++) { \
+ free(argv[i+1]); \
+ } \
+ free(argv); \
+ if (rrd_test_error()) XSRETURN_UNDEF; \
+ hash = newHV(); \
+ while (data) { \
+ save=data; \
+ /* the newSV will get copied by hv so we create it as a mortal \
+ to make sure it does not keep hanging round after the fact */ \
+ switch (data->type) { \
+ case RD_I_VAL: \
+ if (isnan(data->value.u_val)) \
+ hvs(&PL_sv_undef); \
+ else \
+ hvs(newSVnv(data->value.u_val)); \
+ break; \
+ case RD_I_INT: \
+ hvs(newSViv(data->value.u_int)); \
+ break; \
+ case RD_I_CNT: \
+ hvs(newSViv(data->value.u_cnt)); \
+ break; \
+ case RD_I_STR: \
+ hvs(newSVpv(data->value.u_str,0)); \
+ rrd_freemem(data->value.u_str); \
+ break; \
+ } \
+ rrd_freemem(data->key); \
+ data = data->next; \
+ rrd_freemem(save); \
+ } \
+ rrd_freemem(data); \
+ RETVAL = newRV_noinc((SV*)hash);
+/*
+ * should not be needed if libc is linked (see ntmake.pl)
#ifdef WIN32
#define free free
#define malloc malloc
#define realloc realloc
-#endif /*WIN32*/
+#endif
+*/
MODULE = RRDs PACKAGE = RRDs PREFIX = rrd_
OUTPUT:
RETVAL
+int
+rrd_last(...)
+ PROTOTYPE: @
+ PREINIT:
+ int i;
+ char **argv;
+ CODE:
+ rrdcode(rrd_first);
+ OUTPUT:
+ RETVAL
+
int
rrd_create(...)
rrd_graph(...)
PROTOTYPE: @
PREINIT:
- char **calcpr;
+ char **calcpr=NULL;
int i,xsize,ysize;
+ double ymin,ymax;
char **argv;
AV *retar;
PPCODE:
}
optind=0; opterr=0;
rrd_clear_error();
- tzset();
- rrd_graph(items+1,argv,&calcpr,&xsize,&ysize);
+ rrd_graph(items+1,argv,&calcpr,&xsize,&ysize,NULL,&ymin,&ymax);
for (i=0; i < items; i++) {
free(argv[i+1]);
}
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)));
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)));
}
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)));
+void
+rrd_times(start, end)
+ char *start
+ char *end
+ PREINIT:
+ struct rrd_time_value start_tv, end_tv;
+ char *parsetime_error = NULL;
+ time_t start_tmp, end_tmp;
+ PPCODE:
+ rrd_clear_error();
+ if( (parsetime_error = parsetime( start, &start_tv))) {
+ rrd_set_error( "start time: %s", parsetime_error);
+ XSRETURN_UNDEF;
+ }
+ if( (parsetime_error = parsetime( end, &end_tv))) {
+ rrd_set_error( "end time: %s", parsetime_error);
+ XSRETURN_UNDEF;
+ }
+ if( proc_start_end( &start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+ XSRETURN_UNDEF;
+ }
+ EXTEND(sp,2);
+ PUSHs(sv_2mortal(newSVuv(start_tmp)));
+ PUSHs(sv_2mortal(newSVuv(end_tmp)));
-SV*
-rrd_info(...)
+int
+rrd_xport(...)
PROTOTYPE: @
PREINIT:
- info_t *data,*save;
- int i;
- char **argv;
- HV *hash;
- CODE:
- /* prepare argument list */
+ 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);
+ 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();
- data=rrd_info(items+1, argv);
- for (i=0; i < items; i++) {
+ 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;
- hash = newHV();
- while (data) {
- save=data;
- /* the newSV will get copied by hv so we create it as a mortal to make sure
- it does not keep hanging round after the fact */
-#define hvs(VAL) hv_store_ent(hash, sv_2mortal(newSVpv(data->key,0)),VAL,0)
- switch (data->type) {
- case RD_I_VAL:
- if (isnan(data->value.u_val))
- hvs(&PL_sv_undef);
- else
- hvs(newSVnv(data->value.u_val));
- break;
- case RD_I_CNT:
- hvs(newSViv(data->value.u_cnt));
- break;
- case RD_I_STR:
- hvs(newSVpv(data->value.u_str,0));
- free(data->value.u_str);
- break;
- }
-#undefine hvs
- free(data->key);
- data = data->next;
- free(save);
+ 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));
}
- free(data);
- RETVAL = newRV_noinc((SV*)hash);
+ 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: @
+ PREINIT:
+ info_t *data,*save;
+ int i;
+ char **argv;
+ HV *hash;
+ CODE:
+ rrdinfocode(rrd_info);
+ OUTPUT:
+ RETVAL
+
+SV*
+rrd_updatev(...)
+ PROTOTYPE: @
+ PREINIT:
+ info_t *data,*save;
+ int i;
+ char **argv;
+ HV *hash;
+ CODE:
+ rrdinfocode(rrd_update_v);
+ OUTPUT:
+ RETVAL
+
+int
+rrd_dump(...)
+ PROTOTYPE: @
+ PREINIT:
+ int i;
+ char **argv;
+ CODE:
+ rrdcode(rrd_dump);
+ RETVAL = 1;
OUTPUT:
- RETVAL
+ RETVAL
+int
+rrd_restore(...)
+ PROTOTYPE: @
+ PREINIT:
+ int i;
+ char **argv;
+ CODE:
+ rrdcode(rrd_restore);
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL