diff --git a/configure.ac b/configure.ac index 2a595a638..18965a0f7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. # # This file is part of TALER -# Copyright (C) 2014 GNUnet e.V. +# Copyright (C) 2014, 2015 GNUnet e.V. # # TALER is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software @@ -187,6 +187,40 @@ AC_ARG_ENABLE([logging], ], []) AC_DEFINE_UNQUOTED([GNUNET_EXTRA_LOGGING],[$extra_logging],[1 if extra logging is enabled, 2 for very verbose extra logging, 0 otherwise]) +# gcov compilation +AC_MSG_CHECKING(whether to compile with support for code coverage analysis) +AC_ARG_ENABLE([coverage], + AS_HELP_STRING([--enable-coverage], + [compile the library with code coverage support]), + [use_gcov=${enableval}], + [use_gcov=no]) +AC_MSG_RESULT($use_gcov) +AM_CONDITIONAL([USE_COVERAGE], [test "x$use_gcov" = "xyes"]) + +# version info +AC_PATH_PROG(gitcommand, git) +AC_MSG_CHECKING(for source being under a VCS) +gitsvn_version= +AS_IF([test ! "X$gitcommand" = "X"], +[ + gitsvn_version=$(cd $srcdir ; git log -1 2>/dev/null | grep "git-svn-id" | sed -e 's/.*@\([[0-9]]\+\) .*/\1/') +]) +AS_IF([test "X$gitsvn_version" = "X"], + [ + vcs_name="no" + vcs_version="\"release\"" + ], + [ + vcs_name="yes, git-svn" + vcs_version="\"svn-r$gitsvn_version\"" + ]) +AC_MSG_RESULT($vcs_name) + +AC_MSG_CHECKING(VCS version) +AC_MSG_RESULT($vcs_version) +AC_DEFINE_UNQUOTED(VCS_VERSION, [$vcs_version], [VCS revision/hash or tarball version]) + + # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_PID_T AC_TYPE_SIZE_T diff --git a/src/include/taler_util.h b/src/include/taler_util.h index 7bba573d1..cad899685 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -111,4 +111,28 @@ char * TALER_os_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind); +/** + * Print out details on command line options (implements --help). + * + * @param ctx command line processing context + * @param scls additional closure (points to about text) + * @param option name of the option + * @param value not used (NULL) + * @return #GNUNET_NO (do not continue, not an error) + */ +int +TALER_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, + void *scls, + const char *option, + const char *value); + +/** + * Macro defining the option to print the command line + * help text (-h option). + * + * @param about string with brief description of the application + */ +#define TALER_GETOPT_OPTION_HELP(about) \ + { 'h', "help", (const char *) NULL, gettext_noop("print this help"), 0, &TALER_GETOPT_format_help_, (void *) about } + #endif diff --git a/src/mint-tools/taler-mint-dbinit.c b/src/mint-tools/taler-mint-dbinit.c index f49916a6d..88af251e1 100644 --- a/src/mint-tools/taler-mint-dbinit.c +++ b/src/mint-tools/taler-mint-dbinit.c @@ -54,10 +54,11 @@ main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_HELP ("gnunet-mint-dbinit OPTIONS"), {'d', "mint-dir", "DIR", "mint directory", 1, &GNUNET_GETOPT_set_filename, &mint_base_dir}, + GNUNET_GETOPT_OPTION_HELP ("Initialize Taler Mint database"), + GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION,) GNUNET_GETOPT_OPTION_END }; diff --git a/src/mint-tools/taler-mint-keyup.c b/src/mint-tools/taler-mint-keyup.c index 6685aab0b..cc60756a9 100644 --- a/src/mint-tools/taler-mint-keyup.c +++ b/src/mint-tools/taler-mint-keyup.c @@ -867,16 +867,17 @@ main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_HELP ("gnunet-mint-keyup OPTIONS"), - {'m', "master-key", "FILE", - "master key file (private key)", 1, - &GNUNET_GETOPT_set_filename, &masterkeyfile}, {'d', "mint-dir", "DIR", "mint directory with keys to update", 1, &GNUNET_GETOPT_set_filename, &mint_directory}, + TALER_GETOPT_OPTION_HELP ("Setup signing and denomination keys for a Taler mint"), + {'m', "master-key", "FILE", + "master key file (private key)", 1, + &GNUNET_GETOPT_set_filename, &masterkeyfile}, {'t', "time", "TIMESTAMP", "pretend it is a different time for the update", 0, &GNUNET_GETOPT_set_string, &pretend_time_str}, + GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END }; struct GNUNET_TIME_Relative lookahead_sign; diff --git a/src/mint-tools/taler-mint-reservemod.c b/src/mint-tools/taler-mint-reservemod.c index 3f3bdcd98..ce35ecc4c 100644 --- a/src/mint-tools/taler-mint-reservemod.c +++ b/src/mint-tools/taler-mint-reservemod.c @@ -212,16 +212,17 @@ main (int argc, char *const *argv) static char *reserve_pub_str; static char *add_str; static const struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_HELP ("gnunet-mint-reservemod OPTIONS"), - {'d', "mint-dir", "DIR", - "mint directory with keys to update", 1, - &GNUNET_GETOPT_set_filename, &mint_directory}, - {'R', "reserve", "KEY", - "reserve (public key) to modify", 1, - &GNUNET_GETOPT_set_string, &reserve_pub_str}, {'a', "add", "DENOM", "value to add", 1, &GNUNET_GETOPT_set_string, &add_str}, + {'d', "mint-dir", "DIR", + "mint directory with keys to update", 1, + &GNUNET_GETOPT_set_filename, &mint_directory}, + TALER_GETOPT_OPTION_HELP ("Deposit funds into a Taler reserve"), + {'R', "reserve", "KEY", + "reserve (public key) to modify", 1, + &GNUNET_GETOPT_set_string, &reserve_pub_str}, + GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END }; char *connection_cfg_str; diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c index 43c2fa557..86781978a 100644 --- a/src/mint/taler-mint-httpd.c +++ b/src/mint/taler-mint-httpd.c @@ -247,7 +247,7 @@ mint_serve_process_config (const char *mint_directory) { fprintf (stderr, "Failed to load mint configuration\n"); - return 1; + return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -257,7 +257,7 @@ mint_serve_process_config (const char *mint_directory) { fprintf (stderr, "No currency given in mint configuration."); - return GNUNET_NO; + return GNUNET_SYSERR; } if (strlen (TMH_mint_currency_string) >= TALER_CURRENCY_LEN) { @@ -265,7 +265,7 @@ mint_serve_process_config (const char *mint_directory) "Currency `%s' longer than the allowed limit of %u characters.", TMH_mint_currency_string, (unsigned int) TALER_CURRENCY_LEN); - return GNUNET_NO; + return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -275,7 +275,7 @@ mint_serve_process_config (const char *mint_directory) { fprintf (stderr, "No wireformat given in mint configuration."); - return GNUNET_NO; + return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -285,7 +285,7 @@ mint_serve_process_config (const char *mint_directory) { fprintf (stderr, "No master public key given in mint configuration."); - return GNUNET_NO; + return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string (TMH_master_public_key_str, @@ -295,7 +295,7 @@ mint_serve_process_config (const char *mint_directory) fprintf (stderr, "Invalid master public key given in mint configuration."); GNUNET_free (TMH_master_public_key_str); - return GNUNET_NO; + return GNUNET_SYSERR; } GNUNET_free (TMH_master_public_key_str); @@ -303,8 +303,8 @@ mint_serve_process_config (const char *mint_directory) (TMH_plugin = TALER_MINTDB_plugin_load (cfg))) { fprintf (stderr, - "failed to initialize DB subsystem\n"); - return GNUNET_NO; + "Failed to initialize DB subsystem\n"); + return GNUNET_SYSERR; } if (GNUNET_OK != @@ -315,7 +315,7 @@ mint_serve_process_config (const char *mint_directory) { fprintf (stderr, "Missing or invalid configuration for the port of the mint\n"); - return GNUNET_NO; + return GNUNET_SYSERR; } if ( (0 == port) || @@ -324,7 +324,7 @@ mint_serve_process_config (const char *mint_directory) fprintf (stderr, "Invalid configuration (value out of range): %llu is not a valid port\n", port); - return GNUNET_NO; + return GNUNET_SYSERR; } serve_port = (uint16_t) port; @@ -343,44 +343,46 @@ int main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_HELP ("gnunet-mint-keyup OPTIONS"), {'d', "mint-dir", "DIR", "mint directory", 1, &GNUNET_GETOPT_set_filename, &TMH_mint_directory}, + TALER_GETOPT_OPTION_HELP ("HTTP server providing a RESTful API to access a Taler mint"), + GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END }; int ret; GNUNET_assert (GNUNET_OK == - GNUNET_log_setup ("taler-mint-serve", + GNUNET_log_setup ("taler-mint-httpd", "INFO", NULL)); - if (GNUNET_GETOPT_run ("taler-mint-serve", + if (0 >= + GNUNET_GETOPT_run ("taler-mint-httpd", options, - argc, argv) < 0) + argc, argv)) return 1; if (NULL == TMH_mint_directory) { fprintf (stderr, - "no mint dir given\n"); + "Mint directory not specified\n"); return 1; } - if (GNUNET_OK != mint_serve_process_config (TMH_mint_directory)) + if (GNUNET_OK != + mint_serve_process_config (TMH_mint_directory)) return 1; - mydaemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG, serve_port, NULL, NULL, &handle_mhd_request, NULL, - MHD_OPTION_NOTIFY_COMPLETED, &handle_mhd_completion_callback, + MHD_OPTION_NOTIFY_COMPLETED, &handle_mhd_completion_callback, NULL, MHD_OPTION_END); if (NULL == mydaemon) { fprintf (stderr, - "Failed to start MHD.\n"); + "Failed to start HTTP server.\n"); return 1; } diff --git a/src/util/util.c b/src/util/util.c index 7beff8348..2973a11c2 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -85,4 +85,113 @@ TALER_config_load (const char *base_dir) return cfg; } + + +/** + * At what offset does the help text start? + */ +#define BORDER 29 + +/** + * Print out details on command line options (implements --help). + * + * @param ctx command line processing context + * @param scls additional closure (points to about text) + * @param option name of the option + * @param value not used (NULL) + * @return #GNUNET_NO (do not continue, not an error) + */ +int +TALER_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, + void *scls, + const char *option, + const char *value) +{ + const char *about = scls; + size_t slen; + unsigned int i; + int j; + size_t ml; + size_t p; + char *scp; + const char *trans; + const struct GNUNET_GETOPT_CommandLineOption *opt; + + if (NULL != about) + { + printf ("%s\n%s\n", + ctx->binaryOptions, + gettext (about)); + printf (_("Arguments mandatory for long options are also mandatory for short options.\n")); + } + opt = ctx->allOptions; + for (i=0;NULL != opt[i].description;i++) + { + if (opt[i].shortName == '\0') + printf (" "); + else + printf (" -%c, ", opt[i].shortName); + printf ("--%s", opt[i].name); + slen = 8 + strlen (opt[i].name); + if (opt[i].argumentHelp != NULL) + { + printf ("=%s", opt[i].argumentHelp); + slen += 1 + strlen (opt[i].argumentHelp); + } + if (slen > BORDER) + { + printf ("\n%*s", BORDER, ""); + slen = BORDER; + } + if (slen < BORDER) + { + printf ("%*s", (int) (BORDER - slen), ""); + slen = BORDER; + } + if (0 < strlen (opt[i].description)) + trans = gettext (opt[i].description); + else + trans = ""; + ml = strlen (trans); + p = 0; +OUTER: + while (ml - p > 78 - slen) + { + for (j = p + 78 - slen; j > p; j--) + { + if (isspace ((unsigned char) trans[j])) + { + scp = GNUNET_malloc (j - p + 1); + memcpy (scp, &trans[p], j - p); + scp[j - p] = '\0'; + printf ("%s\n%*s", scp, BORDER + 2, ""); + GNUNET_free (scp); + p = j + 1; + slen = BORDER + 2; + goto OUTER; + } + } + /* could not find space to break line */ + scp = GNUNET_malloc (78 - slen + 1); + memcpy (scp, &trans[p], 78 - slen); + scp[78 - slen] = '\0'; + printf ("%s\n%*s", scp, BORDER + 2, ""); + GNUNET_free (scp); + slen = BORDER + 2; + p = p + 78 - slen; + } + /* print rest */ + if (p < ml) + printf ("%s\n", &trans[p]); + if (strlen (trans) == 0) + printf ("\n"); + } + printf ("Report bugs to taler@gnu.org.\n" + "Taler home page: http://www.gnu.org/software/taler/\n" + "General help using GNU software: http://www.gnu.org/gethelp/\n"); + return GNUNET_NO; +} + + + /* end of util.c */