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 | |
philippe | ec905f7 | 2014-08-17 20:03:51 +0000 | [diff] [blame] | 74 | // UInt enum set arg, eg. --foo=fubar,bar,baz or --foo=none |
| 75 | // or --foo=all (if qq_all is True) |
| 76 | #define VG_USETGEN_CLO(qq_arg, qq_option, qq_vals, qq_var, qq_all) \ |
| 77 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 78 | ({ \ |
| 79 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 80 | if (!VG_(parse_enum_set)(qq_vals, \ |
| 81 | qq_all,/*allow_all*/ \ |
| 82 | val, \ |
| 83 | &(qq_var))) \ |
| 84 | VG_(fmsg_bad_option)(qq_arg, "%s is an invalid %s set\n", \ |
| 85 | val, qq_option+2); \ |
| 86 | True; \ |
| 87 | }) \ |
| 88 | ) |
| 89 | |
| 90 | // UInt enum set arg, eg. --foo=fubar,bar,baz or --foo=none or --foo=all |
| 91 | #define VG_USET_CLO(qq_arg, qq_option, qq_vals, qq_var) \ |
| 92 | VG_USETGEN_CLO((qq_arg), qq_option, (qq_vals), (qq_var), True) |
| 93 | |
| 94 | /* Same as VG_USET_CLO but not allowing --foo=all. |
| 95 | To be used when some or all of the enum set are mutually eXclusive. */ |
| 96 | #define VG_USETX_CLO(qq_arg, qq_option, qq_vals, qq_var) \ |
| 97 | VG_USETGEN_CLO((qq_arg), qq_option, (qq_vals), (qq_var), False) |
| 98 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 99 | // Unbounded integer arg, eg. --foo=10 |
| 100 | #define VG_INT_CLO(qq_arg, qq_option, qq_var) \ |
| 101 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 102 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 103 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 104 | HChar* s; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 105 | Long n = VG_(strtoll10)( val, &s ); \ |
njn | ea5d235 | 2007-11-11 21:58:21 +0000 | [diff] [blame] | 106 | (qq_var) = n; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 107 | /* Check for non-numeralness, or overflow. */ \ |
florian | 5b99e66 | 2014-11-29 14:41:32 +0000 | [diff] [blame] | 108 | if ('\0' != s[0] || (qq_var) != n) VG_(fmsg_bad_option)(qq_arg, \ |
| 109 | "Invalid integer value '%s'\n", val); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 110 | True; \ |
| 111 | }) \ |
| 112 | ) |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 113 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 114 | // Bounded integer arg, eg. --foo=10 ; if the value exceeds the bounds it |
| 115 | // causes an abort. 'qq_base' can be 10 or 16. |
| 116 | #define VG_BINTN_CLO(qq_base, qq_arg, qq_option, qq_var, qq_lo, qq_hi) \ |
| 117 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 118 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 119 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 120 | HChar* s; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 121 | Long n = VG_(strtoll##qq_base)( val, &s ); \ |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 122 | (qq_var) = n; \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 123 | /* MMM: separate the two cases, and explain the problem; likewise */ \ |
| 124 | /* for all the other macros in this file. */ \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 125 | /* Check for non-numeralness, or overflow. */ \ |
| 126 | /* Nb: it will overflow if qq_var is unsigned and qq_val is negative! */ \ |
florian | 5b99e66 | 2014-11-29 14:41:32 +0000 | [diff] [blame] | 127 | if ('\0' != s[0] || (qq_var) != n) VG_(fmsg_bad_option)(qq_arg, \ |
| 128 | "Invalid integer value '%s'\n", val); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 129 | /* Check bounds. */ \ |
| 130 | if ((qq_var) < (qq_lo) || (qq_var) > (qq_hi)) { \ |
njn | b1cc5d6 | 2010-07-06 04:05:23 +0000 | [diff] [blame] | 131 | VG_(fmsg_bad_option)(qq_arg, \ |
| 132 | "'%s' argument must be between %lld and %lld\n", \ |
| 133 | (qq_option), (Long)(qq_lo), (Long)(qq_hi)); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 134 | } \ |
| 135 | True; \ |
| 136 | }) \ |
| 137 | ) |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 138 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 139 | // Bounded decimal integer arg, eg. --foo=100 |
| 140 | #define VG_BINT_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \ |
| 141 | VG_BINTN_CLO(10, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi)) |
| 142 | |
| 143 | // Bounded hexadecimal integer arg, eg. --foo=0x1fa8 |
sewardj | eb0fa93 | 2007-11-30 21:41:40 +0000 | [diff] [blame] | 144 | #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] | 145 | 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] | 146 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 147 | // Double (decimal) arg, eg. --foo=4.6 |
| 148 | // XXX: there's not VG_BDBL_CLO because we don't have a good way of printing |
| 149 | // floats at the moment! |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 150 | #define VG_DBL_CLO(qq_arg, qq_option, qq_var) \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 151 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 152 | ({ \ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 153 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 154 | HChar* s; \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 155 | double n = VG_(strtod)( val, &s ); \ |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 156 | (qq_var) = n; \ |
| 157 | /* Check for non-numeralness */ \ |
florian | 5b99e66 | 2014-11-29 14:41:32 +0000 | [diff] [blame] | 158 | if ('\0' != s[0]) VG_(fmsg_bad_option)(qq_arg, \ |
| 159 | "Invalid floating point value '%s'\n",val); \ |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 160 | True; \ |
| 161 | }) \ |
| 162 | ) |
njn | 62721e9 | 2007-11-11 22:15:58 +0000 | [diff] [blame] | 163 | |
njn | 83df0b6 | 2009-02-25 01:01:05 +0000 | [diff] [blame] | 164 | // Arg whose value is denoted by the exact presence of the given string; |
| 165 | // if it matches, qq_var is assigned the value in qq_val. |
| 166 | #define VG_XACT_CLO(qq_arg, qq_option, qq_var, qq_val) \ |
| 167 | (VG_STREQ((qq_arg), (qq_option)) && \ |
| 168 | ({ \ |
| 169 | (qq_var) = (qq_val); \ |
| 170 | True; \ |
| 171 | }) \ |
| 172 | ) |
sewardj | f767d96 | 2007-02-12 17:47:14 +0000 | [diff] [blame] | 173 | |
sewardj | 8d47a61 | 2015-02-05 12:59:46 +0000 | [diff] [blame] | 174 | // Arg that can be one of a set of strings, as specified in an NULL |
| 175 | // terminated array. Returns the index of the string in |qq_ix|, or |
| 176 | // aborts if not found. |
| 177 | #define VG_STRINDEX_CLO(qq_arg, qq_option, qq_strings, qq_ix) \ |
| 178 | (VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=") && \ |
| 179 | ({ \ |
| 180 | const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \ |
| 181 | for (qq_ix = 0; (qq_strings)[qq_ix]; qq_ix++) { \ |
| 182 | if (VG_STREQ(val, (qq_strings)[qq_ix])) \ |
| 183 | break; \ |
| 184 | } \ |
| 185 | if ((qq_strings)[qq_ix] == NULL) \ |
| 186 | VG_(fmsg_bad_option)(qq_arg, \ |
| 187 | "Invalid string '%s' in '%s'\n", val, qq_arg); \ |
| 188 | True; \ |
| 189 | }) \ |
| 190 | ) |
| 191 | |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 192 | /* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */ |
sewardj | 71bc3cb | 2005-05-19 00:25:45 +0000 | [diff] [blame] | 193 | extern Int VG_(clo_verbosity); |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 194 | |
sewardj | 2d9e874 | 2009-08-07 15:46:56 +0000 | [diff] [blame] | 195 | /* Show tool and core statistics */ |
| 196 | extern Bool VG_(clo_stats); |
| 197 | |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 198 | /* wait for vgdb/gdb after reporting that amount of error. |
| 199 | Note that this is the initial value provided from the command line. |
| 200 | The real value is maintained in VG_(dyn_vgdb_error) and |
| 201 | can be changed dynamically.*/ |
| 202 | extern Int VG_(clo_vgdb_error); |
| 203 | |
philippe | cffe2a5 | 2014-01-11 13:56:48 +0000 | [diff] [blame] | 204 | /* If user has provided the --vgdb-prefix command line option, |
| 205 | VG_(arg_vgdb_prefix) points at the provided argument (including the |
| 206 | '--vgdb-prefix=' string). |
| 207 | Otherwise, it is NULL. |
| 208 | Typically, this is used by tools to produce user message with the |
| 209 | expected vgdb prefix argument, if the user has changed the default. */ |
| 210 | extern const HChar *VG_(arg_vgdb_prefix); |
| 211 | |
sewardj | 71bc3cb | 2005-05-19 00:25:45 +0000 | [diff] [blame] | 212 | /* Emit all messages as XML? default: NO */ |
| 213 | /* If clo_xml is set, various other options are set in a non-default |
| 214 | way. See vg_main.c and mc_main.c. */ |
| 215 | extern Bool VG_(clo_xml); |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 216 | |
sewardj | 768db0e | 2005-07-19 14:18:56 +0000 | [diff] [blame] | 217 | /* An arbitrary user-supplied string which is copied into the |
| 218 | XML output, in between <usercomment> tags. */ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 219 | extern const HChar* VG_(clo_xml_user_comment); |
sewardj | 768db0e | 2005-07-19 14:18:56 +0000 | [diff] [blame] | 220 | |
sewardj | f9b5b7d | 2005-07-26 23:47:00 +0000 | [diff] [blame] | 221 | /* Vex iropt control. Tool-visible so tools can make Vex optimise |
| 222 | less aggressively if that is needed (callgrind needs this). */ |
| 223 | extern VexControl VG_(clo_vex_control); |
sewardj | 8d47a61 | 2015-02-05 12:59:46 +0000 | [diff] [blame] | 224 | extern VexRegisterUpdates VG_(clo_px_file_backed); |
sewardj | f9b5b7d | 2005-07-26 23:47:00 +0000 | [diff] [blame] | 225 | |
florian | 5914aec | 2014-08-11 15:48:51 +0000 | [diff] [blame] | 226 | /* Number of parents of a backtrace. Default: 12 */ |
sewardj | da09859 | 2008-01-09 18:37:41 +0000 | [diff] [blame] | 227 | extern Int VG_(clo_backtrace_size); |
| 228 | |
njn | 6882443 | 2009-02-10 06:48:00 +0000 | [diff] [blame] | 229 | /* Continue stack traces below main()? Default: NO */ |
| 230 | extern Bool VG_(clo_show_below_main); |
| 231 | |
| 232 | |
sewardj | 5eed741 | 2008-11-17 12:45:01 +0000 | [diff] [blame] | 233 | /* Used to expand file names. "option_name" is the option name, eg. |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 234 | "--log-file". 'format' is what follows, eg. "cachegrind.out.%p". In |
| 235 | 'format': |
| 236 | - "%p" is replaced with PID. |
| 237 | - "%q{QUAL}" is replaced with the environment variable $QUAL. If $QUAL |
| 238 | isn't set, we abort. If the "{QUAL}" part is malformed, we abort. |
| 239 | - "%%" is replaced with "%". |
| 240 | Anything else after '%' causes an abort. |
njn | 2dd08f5 | 2007-11-23 22:37:35 +0000 | [diff] [blame] | 241 | If the format specifies a relative file name, it's put in the program's |
| 242 | initial working directory. If it specifies an absolute file name (ie. |
| 243 | starts with '/') then it is put there. |
sewardj | 5eed741 | 2008-11-17 12:45:01 +0000 | [diff] [blame] | 244 | |
| 245 | Note that "option_name" has no effect on the returned string: the |
| 246 | returned string depends only on "format" and the PIDs and |
| 247 | environment variables that it references (if any). "option_name" is |
| 248 | merely used in printing error messages, if an error message needs |
| 249 | to be printed due to malformedness of the "format" argument. |
njn | 374a36d | 2007-11-23 01:41:32 +0000 | [diff] [blame] | 250 | */ |
florian | 19f91bb | 2012-11-10 22:29:54 +0000 | [diff] [blame] | 251 | extern HChar* VG_(expand_file_name)(const HChar* option_name, |
| 252 | const HChar* format); |
sewardj | 6893d65 | 2006-10-15 01:25:13 +0000 | [diff] [blame] | 253 | |
njn | 2024234 | 2005-05-16 23:31:24 +0000 | [diff] [blame] | 254 | #endif // __PUB_TOOL_OPTIONS_H |
| 255 | |
| 256 | /*--------------------------------------------------------------------*/ |
| 257 | /*--- end ---*/ |
| 258 | /*--------------------------------------------------------------------*/ |