Skip to content

Commit f0a33cd

Browse files
authored
Merge pull request #169 from gsmecher/negative_values_rebased
Add support for negative values
2 parents 2748cf0 + c10626a commit f0a33cd

2 files changed

Lines changed: 73 additions & 43 deletions

File tree

stresstest.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,18 @@
2020

2121
const char help[] =
2222
"Usage:\n"
23-
" stresstest [-2] [-c] [-g] [-r rate]\n"
23+
" stresstest [-2] [-c] [-g] [-n] [-r rate]\n"
2424
" stresstest -h\n"
2525
"\n"
2626
" -h print this help message and exit\n"
2727
" -2 output two waves\n"
2828
" -c randomly chunk the output\n"
2929
" -g occasionally output garbage\n"
30+
" -n output negative values\n"
3031
" -r rate sample rate in samples/s (default: 100)\n"
3132
" -s seed set random seed\n";
3233

33-
const char optstring[] = "h2cgr:s:";
34+
const char optstring[] = "h2cgnr:s:";
3435

3536
int main(int argc, char *argv[]) {
3637
char buffer[1024];
@@ -39,6 +40,7 @@ int main(int argc, char *argv[]) {
3940
bool two_waves = false;
4041
bool chunked = false;
4142
bool add_garbage = false;
43+
bool output_negative = false;
4244
double rate = 100;
4345
unsigned int seed = time(NULL);
4446

@@ -57,6 +59,9 @@ int main(int argc, char *argv[]) {
5759
case 'g':
5860
add_garbage = true;
5961
break;
62+
case 'n':
63+
output_negative = true;
64+
break;
6065
case 'r':
6166
rate = atof(optarg);
6267
break;
@@ -77,13 +82,14 @@ int main(int argc, char *argv[]) {
7782
srand(seed);
7883

7984
for (unsigned int n = 0;; n += 5) {
80-
buffer_pos +=
81-
sprintf(buffer + buffer_pos, "%.1f\n", (sin(n * M_PI / 180) * 5) + 5);
85+
buffer_pos += sprintf(buffer + buffer_pos, "%.1f\n",
86+
(sin(n * M_PI / 180) * 5) + (output_negative ? 0 : 5));
8287
if (add_garbage && rand() <= RAND_MAX / 5)
8388
buffer_pos += sprintf(buffer + buffer_pos, "garbage ");
8489
if (two_waves) {
8590
buffer_pos +=
86-
sprintf(buffer + buffer_pos, "%.1f\n", (cos(n * M_PI / 180) * 5) + 5);
91+
sprintf(buffer + buffer_pos, "%.1f\n",
92+
(cos(n * M_PI / 180) * 5) + (output_negative ? 0 : 5));
8793
if (add_garbage && rand() <= RAND_MAX / 5)
8894
buffer_pos += sprintf(buffer + buffer_pos, "garbage ");
8995
}

ttyplot.c

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,9 @@ static int signal_read_fd, signal_write_fd;
7474
static cchar_t plotchar, max_errchar, min_errchar;
7575
static struct timeval now;
7676
static double td;
77-
static struct tm *lt;
78-
static double max = FLT_MIN;
79-
static double softmax = FLT_MIN, hardmax = FLT_MAX, hardmin = 0.0;
77+
static double softmax = 0.0, hardmax = FLT_MAX, softmin = 0.0, hardmin = -FLT_MAX;
8078
static char title[256] = ".: ttyplot :.", unit[64] = {0}, ls[256] = {0};
8179
static double values1[1024] = {0}, values2[1024] = {0};
82-
static double min1 = FLT_MAX, max1 = FLT_MIN, avg1 = 0;
83-
static double min2 = FLT_MAX, max2 = FLT_MIN, avg2 = 0;
8480
static int width = 0, height = 0, n = -1, v = 0, c = 0, rate = 0, two = 0,
8581
plotwidth = 0, plotheight = 0;
8682
static bool fake_clock = false;
@@ -102,7 +98,8 @@ static void usage(void) {
10298
" -e character to use for error line when value exceeds hardmax (default: e)\n"
10399
" -E character to use for error symbol displayed when value is less than "
104100
"hardmin (default: v)\n"
105-
" -s initial scale of the plot (can go above if data input has larger value)\n"
101+
" -s initial maximum value (can go above if data input has larger value)\n"
102+
" -S initial minimum value (can go below if data input has smaller value)\n"
106103
" -m maximum value, if exceeded draws error line (see -e), upper-limit of "
107104
"plot scale is fixed\n"
108105
" -M minimum value, if entered less than this, draws error symbol (see -E), "
@@ -155,8 +152,7 @@ static void getminmax(int pw, double *values, double *min, double *max, double *
155152
int i = 0;
156153

157154
*min = FLT_MAX;
158-
*max = FLT_MIN;
159-
tot = FLT_MIN;
155+
*max = -FLT_MAX;
160156

161157
for (i = 0; i < pw && i < v; i++) {
162158
if (values[i] > *max)
@@ -203,27 +199,43 @@ static void draw_line(int x, int ph, int l1, int l2, cchar_t *c1, cchar_t *c2,
203199
}
204200

205201
static void plot_values(int ph, int pw, double *v1, double *v2, double max, double min,
206-
int n, cchar_t *pc, cchar_t *hce, cchar_t *lce, double hm) {
202+
int n, cchar_t *pc, cchar_t *hce, cchar_t *lce, double hardmax,
203+
double hardmin) {
207204
const int first_col = 3;
208205
int i = (n + 1) % pw;
209206
int x;
210-
max -= min;
211-
212-
for (x = first_col; x < first_col + pw; x++, i = (i + 1) % pw)
213-
draw_line(x, ph,
214-
(v1[i] > hm) ? ph
215-
: (v1[i] < min) ? 1
216-
: (int)(((v1[i] - min) / max) * (double)ph),
217-
(v2[i] > hm) ? ph
218-
: (v2[i] < min) ? 1
219-
: (int)(((v2[i] - min) / max) * (double)ph),
220-
(v1[i] > hm) ? hce
221-
: (v1[i] < min) ? lce
222-
: pc,
223-
(v2[i] > hm) ? hce
224-
: (v2[i] < min) ? lce
225-
: pc,
207+
int l1, l2;
208+
209+
for (x = first_col; x < first_col + pw; x++, i = (i + 1) % pw) {
210+
/* suppress drawing uninitialized entries */
211+
if (! v1 || isnan(v1[i]))
212+
continue;
213+
214+
if (v1[i] > hardmax)
215+
l1 = ph;
216+
else if (v1[i] < hardmin)
217+
l1 = 1;
218+
else
219+
l1 = lrint((v1[i] - min) / (max - min) * ph);
220+
221+
if (! v2 || isnan(v2[i]))
222+
l2 = 0;
223+
else if (v2[i] > hardmax)
224+
l2 = ph;
225+
else if (v2[i] < hardmin)
226+
l2 = 1;
227+
else
228+
l2 = lrint((v2[i] - min) / (max - min) * ph);
229+
230+
draw_line(x, ph, l1, l2,
231+
(v1[i] > hardmax) ? hce
232+
: (v1[i] < hardmin) ? lce
233+
: pc,
234+
(v2 && v2[i] > hardmax) ? hce
235+
: (v2 && v2[i] < hardmin) ? lce
236+
: pc,
226237
hce, lce);
238+
}
227239
}
228240

229241
static void show_all_centered(const char *message) {
@@ -242,6 +254,10 @@ static void show_window_size_error(void) {
242254
}
243255

244256
static void paint_plot(void) {
257+
double min, max;
258+
double min1 = FLT_MAX, max1 = -FLT_MAX, avg1 = 0;
259+
double min2 = FLT_MAX, max2 = -FLT_MAX, avg2 = 0;
260+
struct tm *lt;
245261
erase();
246262
getmaxyx(stdscr, height, width);
247263

@@ -253,16 +269,18 @@ static void paint_plot(void) {
253269
getminmax(plotwidth, values1, &min1, &max1, &avg1, v);
254270
getminmax(plotwidth, values2, &min2, &max2, &avg2, v);
255271

256-
if (max1 > max2)
257-
max = max1;
258-
else
259-
max = max2;
260-
272+
max = max1 > max2 ? max1 : max2;
261273
if (max < softmax)
262274
max = softmax;
263275
if (hardmax != FLT_MAX)
264276
max = hardmax;
265277

278+
min = min1 < min2 ? min1 : min2;
279+
if (min > softmin)
280+
min = softmin;
281+
if (hardmin != -FLT_MAX)
282+
min = hardmin;
283+
266284
mvaddstr(height - 1, width - strlen(verstring) - 1, verstring);
267285

268286
const char *clock_display;
@@ -290,10 +308,10 @@ static void paint_plot(void) {
290308
}
291309
}
292310

293-
plot_values(plotheight, plotwidth, values1, values2, max, hardmin, n, &plotchar,
294-
&max_errchar, &min_errchar, hardmax);
311+
plot_values(plotheight, plotwidth, values1, two ? values2 : NULL, max, min, n,
312+
&plotchar, &max_errchar, &min_errchar, hardmax, hardmin);
295313

296-
draw_axes(height, plotheight, plotwidth, max, hardmin, unit);
314+
draw_axes(height, plotheight, plotwidth, max, min, unit);
297315

298316
mvaddstr(0, (width / 2) - (strlen(title) / 2), title);
299317

@@ -528,10 +546,17 @@ int main(int argc, char *argv[]) {
528546
int i;
529547
bool stdin_is_open = true;
530548
int cached_opterr;
531-
const char *optstring = "2rc:e:E:s:m:M:t:u:vh";
549+
const char *optstring = "2rc:e:E:s:S:m:M:t:u:vh";
532550
int show_ver;
533551
int show_usage;
534552

553+
// Initialize values to NAN, rather than 0, so that we know when not to
554+
// draw them
555+
for (i = 0; i < (int)(sizeof(values1) / sizeof(*values1)); i++) {
556+
values1[i] = NAN;
557+
values2[i] = NAN;
558+
}
559+
535560
// To make UI testing more robust, we display a clock that is frozen at
536561
// "Thu Jan 1 00:00:03 1970" when variable FAKETIME is set
537562
fake_clock = (getenv("FAKETIME") != NULL);
@@ -606,15 +631,14 @@ int main(int argc, char *argv[]) {
606631
case 's':
607632
softmax = atof(optarg);
608633
break;
634+
case 'S':
635+
softmin = atof(optarg);
636+
break;
609637
case 'm':
610638
hardmax = atof(optarg);
611639
break;
612640
case 'M':
613641
hardmin = atof(optarg);
614-
for (i = 0; i < 1024; i++) {
615-
values1[i] = hardmin;
616-
values2[i] = hardmin;
617-
}
618642
break;
619643
case 't':
620644
snprintf(title, sizeof(title), "%s", optarg);

0 commit comments

Comments
 (0)