Introduction
Introduction Statistics Contact Development Disclaimer Help
plotting complete - ploot - simple plotting tools
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65…
Log
Files
Refs
Tags
README
LICENSE
---
commit df6b2deeefb42f4102a9bba819e7d06d15a3aebf
parent 980b7ae7316438998c953a8e098d894aec001c57
Author: Josuah Demangeon <[email protected]>
Date: Tue, 1 May 2018 18:35:48 +0200
plotting complete
Diffstat:
M Makefile | 5 +++--
M ffdraw.c | 56 +++++++++++++++++++++++------…
M ffdraw.h | 27 +++++++++++++++++++++------
M main.c | 295 +++++++++++++++++++++++------…
M ploot.c | 34 ++++++++++++++++-------------…
5 files changed, 308 insertions(+), 109 deletions(-)
---
diff --git a/Makefile b/Makefile
@@ -1,13 +1,14 @@
CFLAGS = -Wall -Wextra -Werror -std=c89 -pedantic -D_POSIX_C_SOURCE=200…
+LDFLAGS = -static
SRC = main.c ffdraw.c font_14x7.c
-
OBJ = $(SRC:.c=.o)
+LIB = -lm
all:x ploot
ploot: $(OBJ)
- ${CC} -static -o $@ $(OBJ)
+ ${CC} $(LDFLAGS) -o $@ $(OBJ) $(LIB)
install:x ploot
mkdir -p ${PREFIX}/bin
diff --git a/ffdraw.c b/ffdraw.c
@@ -12,27 +12,25 @@
#include "ffdraw.h"
-#define WIDTH 100
-#define HEIGHT 100
-
-Color buffer[WIDTH * HEIGHT];
-
/*
* Convert (x,y) coordinates to (row,col) for printing into the buffer.
* The buffer only contain one number, so the coordinate is a single integer:
* width * x + y.
+ * The coordinates are shifted by offx and offy to permit relative coordinates.
*/
void
-ffdraw_pixel(Canvas *can, Color col,
+ffdraw_pixel(Canvas *can, Color *col,
int x, int y)
{
- if (x >= can->h || y >= can->w)
+ x += can->x;
+ y += can->y;
+ if (x < 0 || x >= can->h || y < 0 || y >= can->w)
return;
memcpy(can->b + can->w * (can->h - 1 - x) + y, col, sizeof(*can->b));
}
void
-ffdraw_rectangle(Canvas *can, Color col,
+ffdraw_rectangle(Canvas *can, Color *col,
int x1, int y1,
int x2, int y2)
{
@@ -50,7 +48,7 @@ ffdraw_rectangle(Canvas *can, Color col,
* From Bresenham's line algorithm and dcat's tplot.
*/
void
-ffdraw_line(Canvas *can, Color col,
+ffdraw_line(Canvas *can, Color *col,
int x0, int y0,
int x1, int y1)
{
@@ -81,18 +79,18 @@ ffdraw_line(Canvas *can, Color col,
}
/*
- * Draw a coloured glyph from font f centerd on x, y
+ * Draw a coloured glyph from font f centered on x.
*/
void
-ffdraw_char(Canvas *can, Color col, char c, Font *f,
+ffdraw_char(Canvas *can, Color *col, char c, Font *f,
int x, int y)
{
int xf, yf;
if (c & 0x80)
c = '\0';
+
x -= f->h / 2;
- y -= f->w / 2;
for (xf = 0; xf < f->h; xf++)
for (yf = 0; yf < f->w; yf++)
@@ -104,15 +102,45 @@ ffdraw_char(Canvas *can, Color col, char c, Font *f,
* Draw a left aligned string without wrapping it.
*/
void
-ffdraw_str(Canvas *can, Color col, char *s, Font *f,
+ffdraw_str_left(Canvas *can, Color *col, char *s, Font *f,
int x, int y)
{
for (; *s != '\0'; y += f->w, s++)
ffdraw_char(can, col, *s, f, x, y);
}
+/*
+ * Draw a center aligned string without wrapping it.
+ */
+void
+ffdraw_str_center(Canvas *can, Color *col, char *s, Font *f,
+ int x, int y)
+{
+ y -= f->w * strlen(s) / 2;
+ ffdraw_str_left(can, col, s, f, x, y);
+}
+
+/*
+ * Draw a right aligned string without wrapping it.
+ */
+void
+ffdraw_str_right(Canvas *can, Color *col, char *s, Font *f,
+ int x, int y)
+{
+ y -= f->w * strlen(s);
+ ffdraw_str_left(can, col, s, f, x, y);
+}
+
void
-ffdraw_fill(Canvas *can, Color col)
+ffdraw_fill(Canvas *can, Color *col)
{
+ int x, y;
+
+ x = can->x; can->x = 0;
+ y = can->y; can->y = 0;
+
ffdraw_rectangle(can, col, 0, 0, can->h - 1, can->w - 1);
+
+ can->x = x;
+ can->y = y;
}
diff --git a/ffdraw.h b/ffdraw.h
@@ -1,3 +1,5 @@
+#include <time.h>
+
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -7,6 +9,8 @@ typedef struct {
int w; /* width */
int h; /* height */
Color *b; /* buffer */
+ int x; /* x offset */
+ int y; /* x offset */
} Canvas;
typedef struct {
@@ -15,10 +19,21 @@ typedef struct {
char *b[128]; /* buffer */
} Font;
+typedef struct {
+ Color col; /* for drawing the curve and the legend */
+/* time_t *t; / * array of timestamps */
+ double *v; /* array of values */
+ int n; /* number of values */
+ time_t step;
+ char *name; /* for the legend */
+} Vlist;
+
/* ffdraw.c */
-void ffdraw_pixel (Canvas *, Color, int, int);
-void ffdraw_rectangle(Canvas *, Color, int, int, int, int);
-void ffdraw_line (Canvas *, Color, int, int, int, int);
-void ffdraw_char (Canvas *, Color, char, Font *, int, i…
-void ffdraw_str (Canvas *, Color, char *, Font *, int, …
-void ffdraw_fill (Canvas *, Color);
+void ffdraw_pixel (Canvas *, Color *, int, int);
+void ffdraw_rectangle(Canvas *, Color *, int, int, int, int);
+void ffdraw_line (Canvas *, Color *, int, int, int, int…
+void ffdraw_char (Canvas *, Color *, char, Font *, int,…
+void ffdraw_str_left(Canvas *, Color *, char *, Font *, int, i…
+void ffdraw_str_center(Canvas *, Color *, char *, Font *, int,…
+void ffdraw_str_right(Canvas *, Color *, char *, Font *, int, …
+void ffdraw_fill (Canvas *, Color *);
diff --git a/main.c b/main.c
@@ -1,134 +1,289 @@
#include <arpa/inet.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <time.h>
+#include <math.h>
+
#include "ffdraw.h"
#include "font_14x7.h"
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#define LEN(x) (sizeof(x) / sizeof(*x))
+
+/*
+ * Sizes and positions:
+ *
+ * Title on the first row legend
+ * y ^ here
+ * label |- + - + - + - + - with
+ * here |- + - + - + - + - the
+ * +--+---+---+---+--> full
+ * x label here height
+ */
+
+#define MARGIN 4
+
#define FONT_H 14
#define FONT_W 7
-/* as you see, no css skills needed */
+#define TITLE_X (IMAGE_H - TITLE_H)
+#define TITLE_Y (XLABEL_W)
+#define TITLE_H (FONT_H * 2)
+#define TITLE_W (PLOT_W)
+
+#define XLABEL_X (PLOT_X)
+#define XLABEL_Y (0)
+#define XLABEL_H (PLOT_H)
+#define XLABEL_W (FONT_W * 9 + MARGIN)
-#define MARGIN 2
+#define YLABEL_X (0)
+#define YLABEL_Y (PLOT_Y)
+#define YLABEL_H (FONT_H * 2)
+#define YLABEL_W (PLOT_W)
+
+#define PLOT_X (YLABEL_H)
+#define PLOT_Y (XLABEL_W)
+#define PLOT_W 700
+#define PLOT_H 200
+
+#define LEGEND_X (YLABEL_H)
+#define LEGEND_Y (IMAGE_W - LEGEND_W)
+#define LEGEND_W (FONT_W + 150 + FONT_W)
+#define LEGEND_H (PLOT_H)
+
+#define IMAGE_H (TITLE_H + PLOT_H + YLABEL_H)
+#define IMAGE_W (XLABEL_W + PLOT_W + LEGEND_W)
+
+Color buffer[IMAGE_W * IMAGE_H];
+
+Color c_axis = { 0xffff, 0xffff, 0xffff, 0xfff };
+Font *font = &font_14x7;
-/* height */
+int
+ffplot_t2y(time_t t, time_t tmin, time_t tmax)
+{
+ return (t - tmin) * PLOT_W / (tmax - tmin);
+}
-#define TITLE_H (MARGIN + FONT_H + MARGIN)
-#define PLOT_H 100
-#define XLABEL_H (MARGIN + FONT_H + MARGIN)
+int
+ffplot_v2x(double v, double vmin, double vmax)
+{
+ return (v - vmin) * PLOT_H / (vmax - vmin);
+}
-#define IMAGE_H (TITLE_H + PLOT_H + XLABEL_H)
+/*
+ * Set 'str' to a human-readable form of 'num' with always a width of 8 (+ 1
+ * the '\0' terminator). Buffer overflow is ensured not to happen due to the
+ * max size of a double. Return the exponent.
+ */
+int
+humanize(char *str, double val)
+{
+ int exp, precision;
+ char label[] = { '\0', 'M', 'G', 'T', 'E' };
-#define TITLE_MAX (IMAGE_H)
-#define TITLE_MIN (IMAGE_H - TITLE_H)
-#define PLOT_X_MAX (IMAGE_H - TITLE_H)
-#define PLOT_X_MIN (XLABEL_H)
-#define XLABEL_MAX (XLABEL_H)
-#define XLABEL_MIN (0)
+ for (exp = 0; ABS(val) > 1000; exp++)
+ val /= 1000;
-/* width */
+ precision = (ABS(val) < 10) ? 2 : (ABS(val) < 100) ? 1 : 0;
+ precision += (exp == 0);
-#define YLABEL_W (MARGIN + 20 + MARGIN)
-#define PLOT_W 500
-#define LEGEND_W (MARGIN + 70 + MARGIN)
+ snprintf(str, 9, "%+.*f %c", precision, val, label[exp]);
+ str[8] = '\0';
+ if (val >= 0)
+ str[0] = ' ';
-#define IMAGE_W (YLABEL_W + PLOT_W + LEGEND_W)
+ return exp * 3;
+}
-#define LEGEND_MAX (IMAGE_W)
-#define LEGEND_MIN (IMAGE_W - LEGEND_W)
-#define PLOT_Y_MAX (IMAGE_W - LEGEND_W)
-#define PLOT_Y_MIN (YLABEL_W)
-#define YLABEL_MAX (YLABEL_W)
-#define YLABEL_MIN (0)
+void
+ffplot_xaxis(Canvas *can, Color *label, Color *grid,
+ double vmin, double vmax, double vstep)
+{
+ double v;
+ int x;
+ char str[8 + 1];
-#define MID(x, y) ((x - y) / 2)
+ for (v = vmax - fmod(vmax, vstep); v >= vmin; v -= vstep) {
+ x = ffplot_v2x(v, vmin, vmax);
-Color buffer[IMAGE_W * IMAGE_H];
+ ffdraw_line(can, grid,
+ x, XLABEL_W,
+ x, XLABEL_W + PLOT_W);
-Color c_axis = { 0xffff, 0xffff, 0xffff, 0xfff };
-Font *font = &font_14x7;
+ humanize(str, v);
+ ffdraw_str_right(can, label, str, font,
+ x, XLABEL_W - MARGIN);
+ }
+}
void
-ffplot_xaxis(Canvas *can, Color label, Color grid, time_t tmax, time_t tstep)
+ffplot_yaxis(Canvas *can, Color *label, Color *grid,
+ time_t tmin, time_t tmax, time_t tstep)
{
time_t t;
- int y, ystep;
+ int y;
char str[sizeof("YYYY/MM/DD")], *fmt;
- if (tstep < 3600) {
- fmt = " %H:%M:%S ";
- ystep = sizeof(" HH:MM:SS ") * FONT_W;
- } else {
- fmt = " %Y/%m/%d ";
- ystep = sizeof(" YYYY/MM/DD ") * FONT_W;
- }
+ fmt = (tstep < 3600 * 24) ? " %H:%M:%S " : " %Y/%m/%d ";
- t = tmax % tstep;
- y = PLOT_Y_MAX + PLOT_W % ystep - ystep;
+ for (t = tmax - tmax % tstep; t >= tmin; t -= tstep) {
+ y = ffplot_t2y(t, tmin, tmax);
- while (y > PLOT_Y_MIN) {
- strftime(str, sizeof(str), fmt, localtime(&t));
- ffdraw_str(can, label, str, font,
- XLABEL_MIN + XLABEL_H / 2, y - ystep / 2 + FONT_W);
ffdraw_line(can, grid,
- PLOT_X_MIN, y,
- PLOT_X_MAX, y);
- y -= ystep;
- t -= tstep;
+ YLABEL_H, y,
+ YLABEL_H + PLOT_H, y);
+
+ strftime(str, sizeof(str), fmt, localtime(&t));
+ ffdraw_str_center(can, label, str, font,
+ YLABEL_H / 2, y);
}
}
void
-ffplot_(Canvas *can)
+ffplot_title(Canvas *can,
+ Color *ct, char *title,
+ Color *cu, char *unit)
{
- (void)can;
+ ffdraw_str_left(can, ct, title, font,
+ TITLE_H / 2, 0);
+ ffdraw_str_right(can, cu, unit, font,
+ TITLE_H / 2, TITLE_W);
}
void
-ffplot_graph(Canvas *can)
+ffplot_graph(Canvas *can, Vlist *v,
+ double vmin, double vmax,
+ time_t tmin, time_t tmax)
{
- (void)can;
+ time_t t;
+ double *vp;
+ int x, y, n, xlast, ylast, first;
+
+ first = 1;
+ t = tmin;
+ for (vp = v->v, n = v->n; n-- > 0; n--, vp++) {
+ x = ffplot_v2x(*vp, vmin, vmax);
+ y = ffplot_t2y(t, tmin, tmax);
+
+ if (!first)
+ ffdraw_line(can, &v->col, xlast, ylast, x, y);
+
+ xlast = x;
+ ylast = y;
+ t += v->step;
+ first = 0;
+ }
}
void
-ffplot_legend(Canvas *can)
+ffplot_plot(Canvas *can, Vlist **v,
+ double vmin, double vmax,
+ time_t tmin, time_t tmax)
{
- (void)can;
+ for (; *v != NULL; v++)
+ ffplot_graph(can, *v, vmin, vmax, tmin, tmax);
}
-static void
-ffdraw(Canvas *can)
+void
+ffplot_legend(Canvas *can, Color *label_fg, Vlist **v)
{
- Color col1 = { 0x2222, 0x2222, 0x2222, 0xffff };
- Color label = { 0x3333, 0xffff, 0x8888, 0xffff };
- Color grid = { 0x4444, 0x4444, 0x4444, 0xffff };
+ int n, x, y;
- ffdraw_fill(can, col1);
- ffplot_xaxis(can, label, grid, 3600 * 24 * 30, 360);
-/*
- ffdraw_line(can, col2, 49,1,9,79);
- ffdraw_str(can, col2, "R\\S`T'UaVbWcYdZe\nfghb\tjoi\rklmnopqrstuvwxyz{…
-*/
+ for (n = 0; *v != NULL; v++, n++) {
+ x = LEGEND_H - n * (FONT_H + MARGIN) - FONT_H / 2;
+
+ y = MARGIN + FONT_W;
+ ffdraw_str_left(can, &(*v)->col, "\1", font, x, y);
+
+ y += FONT_W * 2;
+ ffdraw_str_left(can, label_fg, (*v)->name, font, x, y);
+ }
+}
+
+void
+ffdraw(Canvas *can, char *title, char *units, Vlist **vlistv,
+ double vmin, double vmax, double vstep,
+ time_t tmin, time_t tmax, time_t tstep)
+{
+ Color plot_bg = { 0x2222, 0x2222, 0x2222, 0xffff };
+ Color grid_bg = { 0x2929, 0x2929, 0x2929, 0xffff };
+ Color grid_fg = { 0x3737, 0x3737, 0x3737, 0xffff };
+ Color label_fg = { 0x8888, 0x8888, 0x8888, 0xffff };
+ Color title_fg = { 0xdddd, 0xdddd, 0xdddd, 0xffff };
+
+ can->x = 0;
+ can->y = 0;
+ ffdraw_fill(can, &plot_bg);
+
+ can->x = PLOT_X;
+ can->y = PLOT_Y;
+ ffdraw_rectangle(can, &grid_bg, 0, 0, PLOT_H, PLOT_W);
+
+ can->x = YLABEL_X;
+ can->y = YLABEL_Y;
+ ffplot_yaxis(can, &label_fg, &grid_fg, tmin, tmax, tstep);
+
+ can->x = XLABEL_X;
+ can->y = XLABEL_Y;
+ ffplot_xaxis(can, &label_fg, &grid_fg, vmin, vmax, vstep);
+
+ can->x = TITLE_X;
+ can->y = TITLE_Y;
+ ffplot_title(can, &title_fg, title, &label_fg, units);
+
+ can->x = PLOT_X;
+ can->y = PLOT_Y;
+ ffplot_plot(can, vlistv, vmin, vmax, tmin, tmax);
+
+ can->x = LEGEND_X;
+ can->y = LEGEND_Y;
+ ffplot_legend(can, &label_fg, vlistv);
}
int
main(void)
{
+ Canvas can = { IMAGE_W, IMAGE_H, buffer, 0, 0 };
+ double v1[] = { 0.1, 30, -3, 42, 559, 343, 10, 345, 0 };
+ double v2[] = { 30, -3, 42, 559, 343, 10, 345, 0, 0.3 };
+ double v3[] = { 0, 0.3, 30, -3, 42, 5, 43, 345, 0, 10,
+ 0.3, 30, -3, 42, 59, 33, 35, 0, 40, 0.3, 30,
+ 0.3, 30, -3, 42, 55, 3, 5, 0, 100, 0.3, 30,
+ 95, 43, 45, 0, 40, 0.3, 30, 0.3, 30, -3, 42,
+ 0.3, 30, -3, 42, 5, 43, 3, 0, 100, 0.3, 30,
+ 0.3, 30, -3, 42, 59, 43, 45, 0, 4, 0.3, 30,
+ -3, 42, 559, 343, 45, 0, 10 };
+ Vlist vl1 = { { 0x0000, 0xffff, 0xdddd, 0xffff }, NULL, LEN(v1), 500, …
+ Vlist vl2 = { { 0xffff, 0x9999, 0x4444, 0xffff }, NULL, LEN(v2), 500, …
+ Vlist vl3 = { { 0x1111, 0xffff, 0x5555, 0xffff }, NULL, LEN(v3), 57, …
+ Vlist *vlistv[] = { NULL, NULL, NULL, NULL };
+ double vmin, vmax, vstep;
+ time_t tmin, tmax, tstep;
uint32_t w, h;
- Canvas can;
- can.b = buffer;
- can.w = IMAGE_W;
- can.h = IMAGE_H;
+ vlistv[0] = &vl1; vl1.v = v1;
+ vlistv[1] = &vl2; vl2.v = v2;
+ vlistv[2] = &vl3; vl3.v = v3;
+ vlistv[3] = NULL;
+
+ vmin = -30; vmax = 700; vstep = 120;
+ tmin = 0; tmax = 2000; tstep = 300;
+
+ ffdraw(&can, "Council of the ravens", "(feather per second)", vlistv,
+ vmin, vmax, vstep,
+ tmin, tmax, tstep);
+
w = htonl(IMAGE_W);
h = htonl(IMAGE_H);
+
fputs("farbfeld", stdout);
fwrite(&w, sizeof(w), 1, stdout);
fwrite(&h, sizeof(h), 1, stdout);
- ffdraw(&can);
fwrite(can.b, IMAGE_W * IMAGE_H, sizeof(*can.b), stdout);
+
return 0;
}
diff --git a/ploot.c b/ploot.c
@@ -17,7 +17,7 @@
char *argv0;
/*
-** Add `val' at the current position `pos' of the `ring' buffer and set pos to
+** Add 'val' at the current position 'pos' of the 'ring' buffer and set pos to
** the next postion.
*/
#define RING_ADD(rbuf, len, pos, val) \
@@ -27,8 +27,8 @@ do { …
} while (0)
/*
-** Copy the ring buffer `rbuf' content with current position `pos' into the
-** buffer `buf'. Both buffer of length `len'.
+** Copy the ring buffer 'rbuf' content with current position 'pos' into the
+** buffer 'buf'. Both buffer of length 'len'.
*/
#define RING_COPY(buf, rbuf, len, pos) \
do { \
@@ -44,7 +44,7 @@ char *tflag = NULL;
time_t oflag = 0;
/*
-** Set `str' to a human-readable form of `num' with always a width of 7 (+ 1
+** Set 'str' to a human-readable form of 'num' with always a width of 7 (+ 1
** the '\0' terminator). Buffer overflow is ensured not to happen due to the
** max size of a double.
*/
@@ -67,7 +67,7 @@ humanize(char *str, double val)
}
/*
-** Returns the maximal double of values between `beg' and `end'.
+** Returns the maximal double of values between 'beg' and 'end'.
*/
double
maxdv(double *beg, double *end)
@@ -83,7 +83,7 @@ maxdv(double *beg, double *end)
}
/*
-** If not null, print the title `str' centered on width.
+** If not null, print the title 'str' centered on width.
*/
void
title(char *str, int width)
@@ -95,7 +95,7 @@ title(char *str, int width)
/*
** Print vertical axis with humanized number from time to time, with occurences
-** determined after the position on the vertical axis from the bottom `pos'.
+** determined after the position on the vertical axis from the bottom 'pos'.
*/
void
vaxis(double val, int pos)
@@ -111,7 +111,7 @@ vaxis(double val, int pos)
}
/*
-** Print horizontal axis for up to `col' values along with dates if reading ti…
+** Print horizontal axis for up to 'col' values along with dates if reading ti…
** series.
*/
void
@@ -152,8 +152,8 @@ line(double *beg, double *end, double top, double bot)
}
/*
-** Plot values between `beg' and `end' in a plot of height `height'.
-** If `str' is not NULL, it is set as a title above the graph.
+** Plot values between 'beg' and 'end' in a plot of height 'height'.
+** If 'str' is not NULL, it is set as a title above the graph.
*/
void
plot(double *beg, double *end, int height, char *str, time_t start)
@@ -181,8 +181,8 @@ plot(double *beg, double *end, int height, char *str, time_…
}
/*
-** Read a simple format with one double per line and save the last `MAX_WIDTH'
-** values into `buf' which must be at least MAX_VAL wide and return a pointer
+** Read a simple format with one double per line and save the last 'MAX_WIDTH'
+** values into 'buf' which must be at least MAX_VAL wide and return a pointer
** to the last element or NULL if the input contains error.
*/
double *
@@ -203,8 +203,8 @@ read_simple(double buf[MAX_VAL])
/*
** Read a format with blank separated time_t-double pairs, one per line and sa…
-** the last `MAX_WIDTH' values into `tbuf' and `vbuf' which must both be at
-** least MAX_VAL wide and return a pointer to the last element of `vbuf' or
+** the last 'MAX_WIDTH' values into 'tbuf' and 'vbuf' which must both be at
+** least MAX_VAL wide and return a pointer to the last element of 'vbuf' or
** NULL if the input contains error.
*/
time_t *
@@ -229,8 +229,8 @@ read_time_series(double *vbuf, time_t *tbuf)
}
/*
-** Walk from `tbeg' and `tend' and add offset in `tbuf' every time there is no
-** value in `step' amount of time, by setting a value to -1.
+** Walk from 'tbeg' and 'tend' and add offset in 'tbuf' every time there is no
+** value in 'step' amount of time, by setting a value to -1.
*/
double *
skip_gaps(time_t *tbeg, time_t *tend, double *vbuf, time_t step)
@@ -246,7 +246,7 @@ skip_gaps(time_t *tbeg, time_t *tend, double *vbuf, time_t …
toff += *tp % step;
toff = *tbeg + toff / (tend - tbeg) + step / 2;
- /* Fill `vbuf' with gap added at each time gap using vrbuf as
+ /* Fill 'vbuf' with gap added at each time gap using vrbuf as
** intermediate ring buffer. */
len = LEN(vrbuf);
for (p = pos = 0, tp = tbeg, vp = vbuf; tp < tend; p++, vp++, tp++) {
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.