njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 1 | |
| 2 | /*--------------------------------------------------------------------*/ |
| 3 | /*--- Command line options. pub_tool_options.h ---*/ |
| 4 | /*--------------------------------------------------------------------*/ |
| 5 | |
| 6 | /* |
| 7 | This file is part of Valgrind, a dynamic binary instrumentation |
| 8 | framework. |
| 9 | |
sewardj | 0f157dd | 2013-10-18 14:27:36 +0000 | [diff] [blame] | 10 | Copyright (C) 2000-2013 Julian Seward |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 11 | jseward@acm.org |
| 12 | |
| 13 | This program is free software; you can redistribute it and/or |
| 14 | modify it under the terms of the GNU General Public License as |
| 15 | published by the Free Software Foundation; either version 2 of the |
| 16 | License, or (at your option) any later version. |
| 17 | |
| 18 | This program is distributed in the hope that it will be useful, but |
| 19 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 21 | General Public License for more details. |
| 22 | |
| 23 | You should have received a copy of the GNU General Public License |
| 24 | along with this program; if not, write to the Free Software |
| 25 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 26 | 02111-1307, USA. |
| 27 | |
| 28 | The GNU General Public License is contained in the file COPYING. |
| 29 | */ |
| 30 | |
| 31 | #ifndef __PUB_TOOL_OPTIONS_H |
| 32 | #define __PUB_TOOL_OPTIONS_H |
| 33 | |
florian | 535fb1b | 2013-09-15 13:54:34 +0000 | [diff] [blame] | 34 | #include "pub_tool_basics.h" // for VG_ macro |
sewardj | f9b5b7d | 2005-07-26 23:47:00 +0000 | [diff] [blame] | 35 | #include "libvex.h" // for VexControl |
| 36 | |
| 37 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 38 | // Higher-level command-line option recognisers; use in if/else chains. |
| 39 | // Note that they assign a value to the 'qq_var' argument. So often they |
| 40 | // can be used like this: |
| 41 | // |
| 42 | // if VG_STR_CLO(arg, "--foo", clo_foo) { } |
| 43 | // |
| 44 | // But if you want to do further checking or processing, you can do this: |
| 45 | // |
| 46 | // if VG_STR_CLO(arg, "--foo", clo_foo) { <further checking or processing> } |
| 47 | // |
| 48 | // They use GNU statement expressions to do the qq_var assignment within a |
| 49 | // conditional expression. |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 50 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 51 | // String argument, eg. --foo=yes or --foo=no |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 52 | #define VG_BOOL_CLO(qq_arg, qq_option, qq_var) \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 53 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 54 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 55 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 56 | if VG_STREQ(val, "yes") (qq_var) = True; \ |
| 57 | else if VG_STREQ(val, "no") (qq_var) = False; \ |
sewardj | 36f3c79 | 2011-05-17 16:29:29 +0000 | [diff] [blame] | 58 | else VG_(fmsg_bad_option)(qq_arg, "Invalid boolean value '%s'" \ |
| 59 | " (should be 'yes' or 'no')\n", val); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 60 | True; \ |
| 61 | }) \ |
| 62 | ) |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 63 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 64 | // String argument, eg. --foo=bar |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 65 | #define VG_STR_CLO(qq_arg, qq_option, qq_var) \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 66 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 67 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 68 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 69 | (qq_var) = val; \ |
| 70 | True; \ |
| 71 | }) \ |
| 72 | ) |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 73 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 74 | // Unbounded integer arg, eg. --foo=10 |
| 75 | #define VG_INT_CLO(qq_arg, qq_option, qq_var) \ |
| 76 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 77 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 78 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 79 | HChar* s; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 80 | Long n = VG_(strtoll10)( val, &s ); \ |
njn | ea5d235 | 2007-11-11 21:58:21 +0000 | [diff] [blame] | 81 | (qq_var) = n; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 82 | /* Check for non-numeralness, or overflow. */ \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 83 | if ('\0' != s[0] || (qq_var) != n) VG_(fmsg_bad_option)(qq_arg, ""); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 84 | True; \ |
| 85 | }) \ |
| 86 | ) |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 87 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 88 | // Bounded integer arg, eg. --foo=10 ; if the value exceeds the bounds it |
| 89 | // causes an abort. 'qq_base' can be 10 or 16. |
| 90 | #define VG_BINTN_CLO(qq_base, qq_arg, qq_option, qq_var, qq_lo, qq_hi) \ |
| 91 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 92 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 93 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 94 | HChar* s; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 95 | Long n = VG_(strtoll##qq_base)( val, &s ); \ |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 96 | (qq_var) = n; \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 97 | /* MMM: separate the two cases, and explain the problem; likewise */ \ |
| 98 | /* for all the other macros in this file. */ \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 99 | /* Check for non-numeralness, or overflow. */ \ |
| 100 | /* Nb: it will overflow if qq_var is unsigned and qq_val is negative! */ \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 101 | if ('\0' != s[0] || (qq_var) != n) VG_(fmsg_bad_option)(qq_arg, ""); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 102 | /* Check bounds. */ \ |
| 103 | if ((qq_var) < (qq_lo) || (qq_var) > (qq_hi)) { \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 104 | VG_(fmsg_bad_option)(qq_arg, \ |
| 105 | "'%s' argument must be between %lld and %lld\n", \ |
| 106 | (qq_option), (Long)(qq_lo), (Long)(qq_hi)); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 107 | } \ |
| 108 | True; \ |
| 109 | }) \ |
| 110 | ) |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 111 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 112 | // Bounded decimal integer arg, eg. --foo=100 |
| 113 | #define VG_BINT_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \ |
| 114 | VG_BINTN_CLO(10, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi)) |
| 115 | |
| 116 | // Bounded hexadecimal integer arg, eg. --foo=0x1fa8 |
sewardj | eb0fa93 | 2007-11-30 21:41:40 +0000 | [diff] [blame] | 117 | #define VG_BHEX_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 118 | VG_BINTN_CLO(16, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi)) |
sewardj | eb0fa93 | 2007-11-30 21:41:40 +0000 | [diff] [blame] | 119 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 120 | // Double (decimal) arg, eg. --foo=4.6 |
| 121 | // XXX: there's not VG_BDBL_CLO because we don't have a good way of printing |
| 122 | // floats at the moment! |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 123 | #define VG_DBL_CLO(qq_arg, qq_option, qq_var) \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 124 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 125 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 126 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 127 | HChar* s; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 128 | double n = VG_(strtod)( val, &s ); \ |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 129 | (qq_var) = n; \ |
| 130 | /* Check for non-numeralness */ \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 131 | if ('\0' != s[0]) VG_(fmsg_bad_option)(qq_arg, ""); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 132 | True; \ |
| 133 | }) \ |
| 134 | ) |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 135 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 136 | // Arg whose value is denoted by the exact presence of the given string; |
| 137 | // if it matches, qq_var is assigned the value in qq_val. |
| 138 | #define VG_XACT_CLO(qq_arg, qq_option, qq_var, qq_val) \ |
| 139 | (VG_STREQ((qq_arg), (qq_option)) && \ |
| 140 | ({ \ |
| 141 | (qq_var) = (qq_val); \ |
| 142 | True; \ |
| 143 | }) \ |
| 144 | ) |
sewardj | f767d96 | 2007-02-12 17:47:14 +0000 | [diff] [blame] | 145 | |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 146 | /* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */ |
sewardj | 71bc3cb | 2005-05-19 00:25:45 +0000 | [diff] [blame] | 147 | extern Int VG_(clo_verbosity); |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 148 | |
sewardj | 2d9e874 | 2009-08-07 15:46:56 +0000 | [diff] [blame] | 149 | /* Show tool and core statistics */ |
| 150 | extern Bool VG_(clo_stats); |
| 151 | |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 152 | /* wait for vgdb/gdb after reporting that amount of error. |
| 153 | Note that this is the initial value provided from the command line. |
| 154 | The real value is maintained in VG_(dyn_vgdb_error) and |
| 155 | can be changed dynamically.*/ |
| 156 | extern Int VG_(clo_vgdb_error); |
| 157 | |
philippe | cffe2a5 | 2014-01-11 13:56:48 +0000 | [diff] [blame] | 158 | /* If user has provided the --vgdb-prefix command line option, |
| 159 | VG_(arg_vgdb_prefix) points at the provided argument (including the |
| 160 | '--vgdb-prefix=' string). |
| 161 | Otherwise, it is NULL. |
| 162 | Typically, this is used by tools to produce user message with the |
| 163 | expected vgdb prefix argument, if the user has changed the default. */ |
| 164 | extern const HChar *VG_(arg_vgdb_prefix); |
| 165 | |
sewardj | 71bc3cb | 2005-05-19 00:25:45 +0000 | [diff] [blame] | 166 | /* Emit all messages as XML? default: NO */ |
| 167 | /* If clo_xml is set, various other options are set in a non-default |
| 168 | way. See vg_main.c and mc_main.c. */ |
| 169 | extern Bool VG_(clo_xml); |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 170 | |
sewardj | 768db0e | 2005-07-19 14:18:56 +0000 | [diff] [blame] | 171 | /* An arbitrary user-supplied string which is copied into the |
| 172 | XML output, in between <usercomment> tags. */ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 173 | extern const HChar* VG_(clo_xml_user_comment); |
sewardj | 768db0e | 2005-07-19 14:18:56 +0000 | [diff] [blame] | 174 | |
sewardj | f9b5b7d | 2005-07-26 23:47:00 +0000 | [diff] [blame] | 175 | /* Vex iropt control. Tool-visible so tools can make Vex optimise |
| 176 | less aggressively if that is needed (callgrind needs this). */ |
| 177 | extern VexControl VG_(clo_vex_control); |
| 178 | |
sewardj | da09859 | 2008-01-09 18:37:41 +0000 | [diff] [blame] | 179 | /* Number of parents of a backtrace. Default: 8. */ |
| 180 | extern Int VG_(clo_backtrace_size); |
| 181 | |
njn | 6882443 | 2009-02-10 06:48:00 +0000 | [diff] [blame] | 182 | /* Continue stack traces below main()? Default: NO */ |
| 183 | extern Bool VG_(clo_show_below_main); |
| 184 | |
| 185 | |
sewardj | 5eed741 | 2008-11-17 12:45:01 +0000 | [diff] [blame] | 186 | /* Used to expand file names. "option_name" is the option name, eg. |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 187 | "--log-file". 'format' is what follows, eg. "cachegrind.out.%p". In |
| 188 | 'format': |
| 189 | - "%p" is replaced with PID. |
| 190 | - "%q{QUAL}" is replaced with the environment variable $QUAL. If $QUAL |
| 191 | isn't set, we abort. If the "{QUAL}" part is malformed, we abort. |
| 192 | - "%%" is replaced with "%". |
| 193 | Anything else after '%' causes an abort. |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 194 | If the format specifies a relative file name, it's put in the program's |
| 195 | initial working directory. If it specifies an absolute file name (ie. |
| 196 | starts with '/') then it is put there. |
sewardj | 5eed741 | 2008-11-17 12:45:01 +0000 | [diff] [blame] | 197 | |
| 198 | Note that "option_name" has no effect on the returned string: the |
| 199 | returned string depends only on "format" and the PIDs and |
| 200 | environment variables that it references (if any). "option_name" is |
| 201 | merely used in printing error messages, if an error message needs |
| 202 | to be printed due to malformedness of the "format" argument. |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 203 | */ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 204 | extern HChar* VG_(expand_file_name)(const HChar* option_name, |
| 205 | const HChar* format); |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 206 | |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 207 | #endif // __PUB_TOOL_OPTIONS_H |
| 208 | |
| 209 | /*--------------------------------------------------------------------*/ |
| 210 | /*--- end ---*/ |
| 211 | /*--------------------------------------------------------------------*/ |