commit 56b76a0bf99cdb6c1ec4d7564d9692352960ec02
parent 914fb4ad0fa9e4e14541ccd0baf749c582e6227a
Author: z3bra <willyatmailoodotorg>
Date: Sun, 31 Jan 2016 15:18:58 +0100
Make invocation simpler and more robust
* uses arg.h for argument parsing
* removes -e argument. now everything passed beyond arguments
is considered to be the command
* makes IN_CLOSE_WRITE the default mask (aka, file modification)
Diffstat:
A | arg.h | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | wendy.c | | | 59 | +++++++++++++++++++++++++++++++---------------------------- |
2 files changed, 96 insertions(+), 28 deletions(-)
diff --git a/arg.h b/arg.h
@@ -0,0 +1,65 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][1]\
+ && argv[0][0] == '-';\
+ argc--, argv++) {\
+ char argc_;\
+ char **argv_;\
+ int brk_;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (brk_ = 0, argv[0]++, argv_ = argv;\
+ argv[0][0] && !brk_;\
+ argv[0]++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][0];\
+ switch (argc_)
+
+/* Handles obsolete -NUM syntax */
+#define ARGNUM case '0':\
+ case '1':\
+ case '2':\
+ case '3':\
+ case '4':\
+ case '5':\
+ case '6':\
+ case '7':\
+ case '8':\
+ case '9'
+
+#define ARGEND }\
+ }
+
+#define ARGC() argc_
+
+#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
+
+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define LNGARG() &argv[0][0]
+
+#endif
diff --git a/wendy.c b/wendy.c
@@ -23,6 +23,8 @@
#include <sys/inotify.h>
#include <sys/wait.h>
+#include "arg.h"
+
/* definitions, defaults, bla bla blah */
#define EVENT_SIZE (sizeof(struct inotify_event))
/* maximum number of event * queuing at the same time */
@@ -42,17 +44,10 @@ int verbose = 0, nb = 0;
struct node_t *head = NULL;
void
-usage()
+usage(char *name)
{
- fputs("usage: wendy [-m mask] [-l] [-f file] [-t timeout] [-q] "
- "[-e command [args] ..]\n"
- "\t-m mask : set mask manually (see -l))\n"
- "\t-l : list events mask values\n"
- "\t-f file : file to watch (everything is a file)\n"
- "\t-t timeout : time between event check (in seconds)\n"
- "\t-v : talk to me, program\n"
- "\t-e command : command to launch (must be the last arg!)\n",
- stdout);
+ fprintf(stderr, "usage: %s [-lq] [-m mask] [-f file] [-t timeout] "
+ "[cmd [args..]]\n", name);
exit(1);
}
@@ -89,7 +84,6 @@ list_events()
IN_ALL_EVENTS,
IN_UNMOUNT
);
- exit(0);
}
char *
@@ -177,33 +171,42 @@ watch_node(int fd, const char *path, uint32_t mask)
int
main (int argc, char **argv)
{
- int fd, len, i = 0, timeout = 0, ignore = 0;
- uint32_t mask = 0;
+ int fd, len, i = 0, timeout = 0;
+ uint32_t mask = IN_CLOSE_WRITE;
char buf[BUF_LEN];
- char *fn = NULL;
+ char *fn = NULL, *argv0 = NULL;
char **cmd = NULL;
struct inotify_event *ev;
- if ((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')) usage();
-
/* get file descriptor */
fd = inotify_init();
if (fd < 0)
perror("inotify_init");
- /* parse option given. see usage() above */
- for(i = 1; (i < argc) && (argv[i][0] == '-') && !ignore; i++) {
- switch (argv[i][1]) {
- case 'm': mask = atoi(argv[++i]); break;
- case 'l': list_events(); break;
- case 'v': verbose += 1; break;
- case 'f': watch_node(fd, argv[++i], mask); break;
- case 't': timeout = atoi(argv[++i]); break;
- case 'e': cmd = &argv[++i]; ignore=1; break;
- default: usage();
- }
- }
+ ARGBEGIN{
+ case 'm':
+ mask = atoi(EARGF(usage(argv0)));
+ break;
+ case 'l':
+ list_events();
+ return 0;
+ break; /* NOT REACHED */
+ case 'v':
+ verbose++;
+ break;
+ case 'f':
+ watch_node(fd, EARGF(usage(argv0)), mask);
+ break;
+ case 't':
+ timeout = atoi(EARGF(usage(argv0)));
+ break;
+ default:
+ usage(argv0);
+ }ARGEND;
+
+ if (argc > 0)
+ cmd = argv;
/* test given arguments */
if (!timeout) { timeout = DEFAULT_CHECK; }