diff options
-rw-r--r-- | include/grpc/support/cmdline.h | 2 | ||||
-rw-r--r-- | src/core/support/cmdline.c | 70 | ||||
-rw-r--r-- | src/csharp/README.md | 23 | ||||
-rw-r--r-- | test/core/support/cmdline_test.c | 23 |
4 files changed, 87 insertions, 31 deletions
diff --git a/include/grpc/support/cmdline.h b/include/grpc/support/cmdline.h index c2350a07e8..e5a266666e 100644 --- a/include/grpc/support/cmdline.h +++ b/include/grpc/support/cmdline.h @@ -87,6 +87,8 @@ void gpr_cmdline_on_extra_arg( void gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv); /* Destroy the parser */ void gpr_cmdline_destroy(gpr_cmdline *cl); +/* Get a string describing usage */ +char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0); #ifdef __cplusplus } diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c index 72f46c1bd7..530952c437 100644 --- a/src/core/support/cmdline.c +++ b/src/core/support/cmdline.c @@ -131,33 +131,63 @@ void gpr_cmdline_on_extra_arg( cl->extra_arg_help = help; } -static void print_usage_and_die(gpr_cmdline *cl) { +/* recursively descend argument list, adding the last element + to s first - so that arguments are added in the order they were + added to the list by api calls */ +static void add_args_to_usage(gpr_strvec *s, arg *a) { + char *tmp; + + if (!a) return; + add_args_to_usage(s, a->next); + + switch (a->type) { + case ARGTYPE_BOOL: + gpr_asprintf(&tmp, " [--%s|--no-%s]", a->name, a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_STRING: + gpr_asprintf(&tmp, " [--%s=string]", a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_INT: + gpr_asprintf(&tmp, " [--%s=int]", a->name); + gpr_strvec_add(s, tmp); + break; + } +} + +char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0) { /* TODO(ctiller): make this prettier */ - arg *a; - const char *name = strrchr(cl->argv0, '/'); + gpr_strvec s; + char *tmp; + const char *name = strrchr(argv0, '/'); + if (name) { name++; } else { - name = cl->argv0; - } - fprintf(stderr, "Usage: %s", name); - for (a = cl->args; a; a = a->next) { - switch (a->type) { - case ARGTYPE_BOOL: - fprintf(stderr, " [--%s|--no-%s]", a->name, a->name); - break; - case ARGTYPE_STRING: - fprintf(stderr, " [--%s=string]", a->name); - break; - case ARGTYPE_INT: - fprintf(stderr, " [--%s=int]", a->name); - break; - } + name = argv0; } + + gpr_strvec_init(&s); + + gpr_asprintf(&tmp, "Usage: %s", name); + gpr_strvec_add(&s, tmp); + add_args_to_usage(&s, cl->args); if (cl->extra_arg) { - fprintf(stderr, " [%s...]", cl->extra_arg_name); + gpr_asprintf(&tmp, " [%s...]", cl->extra_arg_name); + gpr_strvec_add(&s, tmp); } - fprintf(stderr, "\n"); + gpr_strvec_add(&s, gpr_strdup("\n")); + + tmp = gpr_strvec_flatten(&s, NULL); + gpr_strvec_destroy(&s); + return tmp; +} + +static void print_usage_and_die(gpr_cmdline *cl) { + char *usage = gpr_cmdline_usage_string(cl, cl->argv0); + fprintf(stderr, "%s", usage); + gpr_free(usage); exit(1); } diff --git a/src/csharp/README.md b/src/csharp/README.md index 43d519349f..bb5e165986 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -35,15 +35,16 @@ Usage: Linux (Mono) - (preferred approach) add `libgrpc_csharp_ext.so` to `/etc/ld.so.cache` by running: ```sh - echo "$HOME/.linuxbrew/lib" | sudo tee /etc/ld.so.conf.d/zzz_brew_lib.conf - sudo ldconfig + $ echo "$HOME/.linuxbrew/lib" | sudo tee /etc/ld.so.conf.d/zzz_brew_lib.conf + $ sudo ldconfig ``` - (adhoc approach) set `LD_LIBRARY_PATH` environment variable to point to directory containing `libgrpc_csharp_ext.so`: ```sh - export LD_LIBRARY_PATH=$HOME/.linuxbrew/lib:${LD_LIBRARY_PATH} + $ export LD_LIBRARY_PATH=$HOME/.linuxbrew/lib:${LD_LIBRARY_PATH} ``` + - (if you are contributor) installing gRPC from sources using `sudo make install_grpc_csharp_ext` also works. - Open MonoDevelop and start a new project/solution. @@ -87,14 +88,14 @@ If you are a user of gRPC C#, go to Usage section above. a convenience batch script that builds everything for you. ``` - buildall.bat + > buildall.bat ``` - Open Grpc.sln using Visual Studio 2013. NuGet dependencies will be restored upon build (you need to have NuGet add-in installed). -Building: Linux & Mono +Building: Linux (Mono) ---------------------- You only need to go through these steps if you are planning to develop gRPC C#. @@ -103,8 +104,8 @@ If you are a user of gRPC C#, go to Usage section above. - Prerequisites for development: Mono 3.2.8+, MonoDevelop 5.9 with NuGet and NUnit add-ins installed. ```sh - sudo apt-get install mono-devel - sudo apt-get install nunit nunit-console + $ sudo apt-get install mono-devel + $ sudo apt-get install nunit nunit-console ``` You can use older versions of MonoDevelop, but then you might need to restore @@ -114,8 +115,8 @@ don't support NuGet add-in. - Compile and install the gRPC C# extension library (that will be used via P/Invoke from C#). ```sh - make grpc_csharp_ext - sudo make install_grpc_csharp_ext + $ make grpc_csharp_ext + $ sudo make install_grpc_csharp_ext ``` - Use MonoDevelop to open the solution Grpc.sln @@ -135,9 +136,9 @@ Then you should be able to run all the test from the Test View. After building the solution, you can also run the tests from command line using nunit-console tool. -``` +```sh # from Grpc.Core.Test/bin/Debug directory -nunit-console Grpc.Core.Tests.dll +$ nunit-console Grpc.Core.Tests.dll ``` Contents diff --git a/test/core/support/cmdline_test.c b/test/core/support/cmdline_test.c index a7767ace5e..26153b192c 100644 --- a/test/core/support/cmdline_test.c +++ b/test/core/support/cmdline_test.c @@ -35,6 +35,7 @@ #include <string.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/useful.h> #include "test/core/util/test_config.h" @@ -272,6 +273,27 @@ static void test_many(void) { gpr_cmdline_destroy(cl); } +static void test_usage(void) { + gpr_cmdline *cl; + char *usage; + + char *str = NULL; + int x = 0; + int flag = 2; + + cl = gpr_cmdline_create(NULL); + gpr_cmdline_add_string(cl, "str", NULL, &str); + gpr_cmdline_add_int(cl, "x", NULL, &x); + gpr_cmdline_add_flag(cl, "flag", NULL, &flag); + + usage = gpr_cmdline_usage_string(cl, "test"); + GPR_ASSERT(0 == strcmp(usage, + "Usage: test [--str=string] [--x=int] [--flag|--no-flag]\n")); + gpr_free(usage); + + gpr_cmdline_destroy(cl); +} + int main(int argc, char **argv) { grpc_test_init(argc, argv); test_simple_int(); @@ -289,5 +311,6 @@ int main(int argc, char **argv) { test_flag_val_true(); test_flag_val_false(); test_many(); + test_usage(); return 0; } |