2 strip - program for stripcharting ASCII data read from a named pipe.
3 Copyright (C) 2008, William Trevor King
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 3 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 The author may be contacted at <wking@drexel.edu> on the Internet, or
21 write to Trevor King, Drexel University, Physics Dept., 3141 Chestnut St.,
22 Philadelphia PA 19104, USA.
30 #include <sys/stat.h> /* mkfifo(), S_IRUSR, S_IWUSR */
32 #include "stripchart.h"
36 //#define AUTOGEN /* for testing */
39 static int string2double(char *string, double *pDouble);
40 static int getargs(int argc, char **argv, unsigned int *pFlags,
41 char **pTitle, char **pGeometry, char **pPipe_name,
42 double *pY_max, double *pY_min, int *pPoints_shown_at_once);
43 static int open_pipe(char *name, unsigned int flags, FILE **pInStream);
44 static int close_pipe(char *name, FILE **pInStream);
45 static int get_num(FILE *stream, double *px);
47 static const char options[] = "t:g:p:cuM:m:n:avh";
48 static const char *func_name = NULL;
49 static const char *description =
50 "Pops up an X window strip chart, and a FIFO to dump data into";
52 static int verbose = 0;
54 #define FLAG_CREATE_FIFO 0x1
55 #define FLAG_AXES_ON 0x2
57 static void help(char *title, char *geometry, char *pipe_name,
58 double y_max, double y_min, int num_points)
60 printf("usage: %s [-%s]\n", func_name, options);
62 printf("Version: %s\n\n", VERSION);
66 printf("-t <title>\tSet the window title (default: %s)\n", title);
67 printf("-g <geometry>\tSet the initial window geometry (default: %s)\n", geometry);
68 printf("-p <file>\tSet FIFO name (default: %s)\n", pipe_name);
70 printf(" %s can either create its own FIFO or use an already existing one.\n",
72 puts(" Using an existing FIFO avoids the following race condition:");
74 printf("\tProcess 1 starts %s\n", func_name);
75 puts("\tProcess 2 sends data to FIFO, but it doesn't exist,");
76 puts("\t\tso file system creates a new file");
77 puts("\tProcess 1 gets around to trying to create the FIFO,");
78 puts("\t\tbut fails because the file already exists");
79 printf("-u\t%s uses an already created FIFO\n", func_name);
80 printf("-c\t%s create the input FIFO (default)\n", func_name);
82 printf("-M\tSet Maximum y value (default: %g)\n", y_max);
83 printf("-m\tSet minimum y value (default: %g)\n", y_min);
84 printf("-n\tSet number of points shown at once (default: %d)\n", num_points);
85 puts("-a\tToggle axes (default: on)");
87 puts("-v\tIncrement verbosity");
88 puts("-h\tDisplay this help and exit");
92 int main(int argc, char **argv)
94 stripchart_t *chart = NULL;
96 double x=0, y_max, y_min;
98 int points_shown_at_once;
99 char *title, *geometry, *pipe_name;
101 CHK( getargs(argc, argv, &flags,
102 &title, &geometry, &pipe_name,
103 &y_max, &y_min, &points_shown_at_once) );
105 CHK( open_pipe(pipe_name, flags, &input) );
107 fprintf(stderr, "creating stripchart on pipe %s with geom %s\n",
108 pipe_name, geometry);
110 CHK( stripchart_create(&chart, title, geometry,
112 points_shown_at_once,
113 flags & FLAG_AXES_ON) );
116 if (get_num(input, &x) != 0)
123 CHK( stripchart_point(chart, x) );
125 CHK( stripchart_destroy(&chart) );
127 CHK( close_pipe(pipe_name, &input) );
132 static int string2double(char *string, double *pDouble)
136 //perror("sloppy error checking");
137 //fprintf(stderr, "errno = %d\n", errno);
138 //return 1; /* unrecognized input */
139 /* HACK!!! Some Xlib function calls (XOpenDisplay, and others) seem to set
140 * errno to 29, or 11, but still return successfully. I have no idea why,
141 * since I can't find any mention of errno in the Xlib documents, but we'll
142 * just ignore any previous errnos and hope everything works out...
146 *pDouble = strtod(string, &endp);
147 if (errno != 0 || endp[0] != '\0') {
150 fprintf(stderr, "could not parse '%s'\n", string);
151 fprintf(stderr, "endp = \"%s\"\n", endp);
152 fprintf(stderr, "errno = %d\n", errno);
154 return 1; /* unrecognized input */
159 static int getargs(int argc, char **argv, unsigned int *pFlags,
160 char **pTitle, char **pGeometry, char **pPipe_name,
161 double *pY_max, double *pY_min, int *pPoints_shown_at_once)
167 *pFlags = FLAG_CREATE_FIFO | FLAG_AXES_ON;
168 *pTitle = "Stripchart";
169 *pGeometry = "500x200+0+0";
170 *pPipe_name = "strip_pipe";
173 *pPoints_shown_at_once = 100;
175 while ((c=getopt(argc, argv, options)) != -1) {
184 *pPipe_name = optarg;
187 *pFlags &= ~FLAG_CREATE_FIFO;
190 *pFlags |= FLAG_CREATE_FIFO;
193 if (string2double(optarg, pY_max) != 0)
197 if (string2double(optarg, pY_min) != 0)
201 if (string2double(optarg, &temp) != 0)
203 *pPoints_shown_at_once = (int)temp;
206 *pFlags ^= FLAG_AXES_ON;
212 printf("Unrecognized option '%c'\n", c);
213 case 'h': /* default falls through */
215 printf("Problem with option '%c' (%s)\n", c, optarg);
216 help(*pTitle, *pGeometry, *pPipe_name, *pY_max, *pY_min, *pPoints_shown_at_once);
223 static int open_pipe(char *name, unsigned int flags, FILE **pStream)
225 if (flags & FLAG_CREATE_FIFO) {
226 /* make a fifo with read/write permision for the user */
227 if (mkfifo(name, S_IRUSR | S_IWUSR) != 0) {
229 fprintf(stderr, "Error creating FIFO '%s', aborting\n", name);
233 AST( (*pStream = fopen(name, "a+")) != NULL );
237 static int close_pipe(char *name, FILE **pInStream)
239 CHK( fclose(*pInStream) );
240 CHK( remove( name ) );
244 static int get_num(FILE *stream, double *px)
248 if (fgets(buf, BUFSZ, stream) == NULL)
249 return 1; /* end of file or error */
250 if (buf[strlen(buf)-1] == '\n')
251 buf[strlen(buf)-1] = '\0';
252 if ( string2double(buf, px) != 0)