Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use a proper commandline interface, complete with a help option that'…
…s actually helpful.
- Loading branch information
Showing
6 changed files
with
266 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#include <getopt.h> | ||
#include "cli.h" | ||
|
||
const char *cli_info_purpose = "A flexible command-line interface for the FSEvents API"; | ||
const char *cli_info_usage = "Usage: fsevent_watch [OPTIONS]... [PATHS]..."; | ||
const char *cli_info_help[] = { | ||
" -h, --help you're looking at it", | ||
" -V, --version print version number and exit", | ||
" -s, --since-when=EventID fire historical events since ID", | ||
" -l, --latency=seconds latency period (default='0.5')", | ||
" -n, --no-defer enable no-defer latency modifier", | ||
" -r, --watch-root watch for when the root path has changed", | ||
" -i, --ignore-self ignore current process", | ||
" -F, --file-events provide file level event data", | ||
" -f, --format=name output format (classic, niw)", | ||
0 | ||
}; | ||
|
||
static void default_args (struct cli_info *args_info) | ||
{ | ||
// args_info->since_when_arg = 0xFFFFFFFFFFFFFFFFULL; | ||
args_info->since_when_arg = kFSEventStreamEventIdSinceNow; | ||
args_info->latency_arg = 0.5; | ||
args_info->no_defer_flag = false; | ||
args_info->watch_root_flag = false; | ||
args_info->ignore_self_flag = false; | ||
args_info->file_events_flag = false; | ||
args_info->format_arg = format_arg_classic; | ||
} | ||
|
||
static void cli_parser_release (struct cli_info *args_info) | ||
{ | ||
unsigned int i; | ||
|
||
for (i=0; i < args_info->inputs_num; ++i) | ||
free(args_info->inputs[i]); | ||
|
||
if (args_info->inputs_num) | ||
free(args_info->inputs); | ||
|
||
args_info->inputs_num = 0; | ||
} | ||
|
||
void cli_parser_init (struct cli_info *args_info) | ||
{ | ||
default_args(args_info); | ||
|
||
args_info->inputs = 0; | ||
args_info->inputs_num = 0; | ||
} | ||
|
||
void cli_parser_free (struct cli_info *args_info) | ||
{ | ||
cli_parser_release(args_info); | ||
} | ||
|
||
void cli_print_version (void) | ||
{ | ||
printf("%s %s\n", CLI_NAME, CLI_VERSION); | ||
} | ||
|
||
void cli_print_help (void) | ||
{ | ||
cli_print_version(); | ||
|
||
printf("\n%s\n", cli_info_purpose); | ||
printf("\n%s\n", cli_info_usage); | ||
printf("\n"); | ||
|
||
int i = 0; | ||
while (cli_info_help[i]) { | ||
printf("%s\n", cli_info_help[i++]); | ||
} | ||
} | ||
|
||
int cli_parser (int argc, const char **argv, struct cli_info *args_info) | ||
{ | ||
static struct option longopts[] = { | ||
{ "help", no_argument, NULL, 'h' }, | ||
{ "version", no_argument, NULL, 'V' }, | ||
{ "since-when", required_argument, NULL, 's' }, | ||
{ "latency", required_argument, NULL, 'l' }, | ||
{ "no-defer", no_argument, NULL, 'n' }, | ||
{ "watch-root", no_argument, NULL, 'r' }, | ||
{ "ignore-self", no_argument, NULL, 'i' }, | ||
{ "file-events", no_argument, NULL, 'F' }, | ||
{ "format", required_argument, NULL, 'f' }, | ||
{ 0, 0, 0, 0 } | ||
}; | ||
|
||
const char *shortopts = "hVs:l:nriFf:"; | ||
|
||
int c = -1; | ||
|
||
while ((c = getopt_long(argc, (char * const *)argv, shortopts, longopts, NULL)) != -1) | ||
{ | ||
switch(c) | ||
{ | ||
case 's': // since-when | ||
args_info->since_when_arg = strtoull(optarg, NULL, 0); | ||
break; | ||
case 'l': // latency | ||
args_info->latency_arg = strtod(optarg, NULL); | ||
break; | ||
case 'n': // no-defer | ||
args_info->no_defer_flag = true; | ||
break; | ||
case 'r': // watch-root | ||
args_info->watch_root_flag = true; | ||
break; | ||
case 'i': // ignore-self | ||
args_info->ignore_self_flag = true; | ||
break; | ||
case 'F': // file-events | ||
args_info->file_events_flag = true; | ||
break; | ||
case 'f': // format | ||
if (strcmp(optarg, "classic") == 0) { | ||
args_info->format_arg = format_arg_classic; | ||
} else if (strcmp(optarg, "niw") == 0) { | ||
args_info->format_arg = format_arg_niw; | ||
} else { | ||
fprintf(stderr, "Unknown output format: %s\n", optarg); | ||
exit(EXIT_FAILURE); | ||
} | ||
break; | ||
case 'V': // version | ||
cli_print_version(); | ||
exit(EXIT_SUCCESS); | ||
break; | ||
case 'h': // help | ||
case '?': // invalid option | ||
case ':': // missing argument | ||
cli_print_help(); | ||
exit((c == 'h') ? EXIT_SUCCESS : EXIT_FAILURE); | ||
break; | ||
} | ||
} | ||
|
||
if (optind < argc) | ||
{ | ||
int i = 0; | ||
args_info->inputs_num = argc - optind; | ||
args_info->inputs = | ||
(char **)(malloc ((args_info->inputs_num)*sizeof(char *))); | ||
while (optind < argc) | ||
if (argv[optind++] != argv[0]) | ||
args_info->inputs[i++] = strdup(argv[optind-1]); | ||
} | ||
|
||
return EXIT_SUCCESS; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// | ||
// cli.h | ||
// fsevent_watch | ||
// | ||
// Copyright (c) 2011 Travis Tilley. All rights reserved. | ||
// | ||
|
||
#ifndef CLI_H | ||
#define CLI_H | ||
|
||
#define CLI_NAME "fsevent_watch" | ||
#define CLI_VERSION "0.0.1" | ||
|
||
#include "common.h" | ||
|
||
enum output_format { | ||
format_arg_classic = 0, | ||
format_arg_niw | ||
}; | ||
|
||
struct cli_info { | ||
UInt64 since_when_arg; | ||
double latency_arg; | ||
bool no_defer_flag; | ||
bool watch_root_flag; | ||
bool ignore_self_flag; | ||
bool file_events_flag; | ||
enum output_format format_arg; | ||
|
||
char **inputs; | ||
unsigned inputs_num; | ||
}; | ||
|
||
extern const char *cli_info_purpose; | ||
extern const char *cli_info_usage; | ||
extern const char *cli_info_help[]; | ||
|
||
void cli_print_help(void); | ||
void cli_print_version(void); | ||
|
||
int cli_parser (int argc, const char **argv, struct cli_info *args_info); | ||
void cli_parser_init (struct cli_info *args_info); | ||
void cli_parser_free (struct cli_info *args_info); | ||
|
||
|
||
#endif /* CLI_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// | ||
// common.h | ||
// fsevent_watch | ||
// | ||
// Copyright (c) 2011 Travis Tilley. All rights reserved. | ||
// | ||
|
||
#ifndef fsevent_watch_common_h | ||
#define fsevent_watch_common_h | ||
|
||
#include <CoreServices/CoreServices.h> | ||
#include "compat.h" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters