atoll() is a terrible function -- you can't do any error checking with it.
Some of our option processing code uses it.  This means that eg.
'--log-fd=9xxx' logs to fd 9, and '--log-fd=blahblahblah' logs to 0 (because
atoll() returns 0 if the string doesn't contain a number!)

It turns out that most of our option processing uses VG_(strtoll*) instead
of VG_(atoll).  The reason that not all of it does is that the
option-processing macros are underpowered -- they currently work well if you
just want to assign the value to a variable, eg:

        VG_BOOL_CLO(arg, "--heap",   clo_heap)
   else VG_BOOL_CLO(arg, "--stacks", clo_stacks)

   else VG_NUM_CLO(arg, "--heap-admin", clo_heap_admin)
   else VG_NUM_CLO(arg, "--depth",      clo_depth)

(This works because they are actually an if-statement, but it looks odd.)

VG_NUM_CLO uses VG_(stroll10).  But if you want to do any checking or
processing, you can't use those macros, leading to code like this:

      else if (VG_CLO_STREQN(9,  arg, "--log-fd=")) {
         log_to            = VgLogTo_Fd;
         VG_(clo_log_name) = NULL;
         tmp_log_fd        = (Int)VG_(atoll)(&arg[9]);
      }

So this commit:
- Improves the *_CLO_* macros so that they can be used in all circumstances.
  They're now just expressions (albeit ones with side-effects, setting the
  named variable appropriately).  Thus they can be used as if-conditions,
  and any post-checking or processing can occur in the then-statement.  And
  malformed numeric arguments (eg. --log-fd=foo) aren't accepted.  This also
  means you don't have to specify the lengths of any option strings anywhere
  (eg.  the 9 in the --log-fd example above).  The use of a wrong number
  caused at least one bug, in Massif.
- Updates all places where the macros were used.
- Updates Helgrind to use the *_CLO_* macros (it didn't use them).
- Updates Callgrind to use the *_CLO_* macros (it didn't use them), except
  for the more esoteric option names (those with numbers in the option
  name).  This allowed getUInt() and getUWord() to be removed.
- Improves the cache option parsing in Cachegrind and Callgrind -- now uses
  VG_(strtoll10)(), detects overflow, and is shorter.
- Uses INT instead of NUM in the macro names, to distinguish better vs. the
  DBL macro.
- Removes VG_(atoll*) and the few remaining uses -- they're wretched
  functions and VG_(strtoll*) should be used instead.
- Adds the VG_STREQN macro.
- Changes VG_BINT_CLO and VG_BHEX_CLO to abort if the given value is outside
  the range -- the current silent truncation is likely to cause confusion as
  much as anything.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9255 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_demangle/vg_libciface.h b/coregrind/m_demangle/vg_libciface.h
index a4bb105..44ca0c5 100644
--- a/coregrind/m_demangle/vg_libciface.h
+++ b/coregrind/m_demangle/vg_libciface.h
@@ -45,7 +45,7 @@
 
 
 #define abort()              vg_assert(0)
-#define atoi(_str)           VG_(atoll)((_str))
+#define atoi(_str)           VG_(strtoll10)((_str), NULL)
 #define free(_pt)            VG_(arena_free)   (VG_AR_DEMANGLE,(_pt))
 #define memcmp(_s1,_s2,_sz)  VG_(memcmp)((_s1),(_s2),(_sz))
 #define memcpy(_dd,_ss,_sz)  VG_(memcpy)((_dd),(_ss),(_sz))
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index cf98350..abce99a 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -155,16 +155,6 @@
    return n;
 }
 
-Long VG_(atoll) ( Char* str )
-{
-   return VG_(strtoll10)(str, NULL);
-}
-
-Long VG_(atoll16) ( Char* str )
-{
-   return VG_(strtoll16)(str, NULL);
-}
-
 /* ---------------------------------------------------------------------
    String functions
    ------------------------------------------------------------------ */
diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c
index 9e4cd3e..bd31d63 100644
--- a/coregrind/m_libcproc.c
+++ b/coregrind/m_libcproc.c
@@ -401,8 +401,13 @@
       res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
                              (UWord)pid, sizeof(pid));
       if (!res.isError && res.res > 0) {
+         Char* s;
          pid[res.res] = '\0';
-         res.res = VG_(atoll)(pid);
+         res.res = VG_(strtoll10)(pid, &s);
+         if (*s != '\0') {
+            VG_(message)(Vg_DebugMsg, 
+               "Warning: invalid file name linked to by /proc/self: %s", pid);
+         }
       }
    }
 
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 8322da5..f8258d4 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -273,31 +273,25 @@
       str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
       vg_assert(str);
 
-      if (VG_STREQ(str, "--version")) {
-         // Ensure the version string goes to stdout
-         VG_(clo_log_fd) = 1;
+      // Nb: the version string goes to stdout.
+      if VG_XACT_CLO(str, "--version", VG_(clo_log_fd), 1) {
          VG_(printf)("valgrind-" VERSION "\n");
          VG_(exit)(0);
+      }
+      else if VG_XACT_CLO(str, "--help", *need_help, 1) {}
+      else if VG_XACT_CLO(str, "-h",     *need_help, 1) {}
 
-      } else if (VG_CLO_STREQ(str, "--help") ||
-                 VG_CLO_STREQ(str, "-h")) {
-         *need_help = 1;
-
-      } else if (VG_CLO_STREQ(str, "--help-debug")) {
-         *need_help = 2;
+      else if VG_XACT_CLO(str, "--help-debug", *need_help, 2) {}
 
       // The tool has already been determined, but we need to know the name
       // here.
-      } else if (VG_CLO_STREQN(7, str, "--tool=")) {
-         *tool = &str[7];
+      else if VG_STR_CLO(str, "--tool", *tool) {} 
 
       // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
       // These are needed by VG_(ii_create_image), which happens
       // before main_process_cmd_line_options().
-      } 
-      else VG_NUM_CLO(str, "--max-stackframe", VG_(clo_max_stackframe))
-      else VG_NUM_CLO(str, "--main-stacksize", VG_(clo_main_stacksize));
-
+      else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
+      else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
    }
 }
 
@@ -312,6 +306,7 @@
    SysRes sres;
    Int    i, tmp_log_fd;
    Int    toolname_len = VG_(strlen)(toolname);
+   Char*  tmp_str;         // Used in a couple of places.
    enum {
       VgLogTo_Fd,
       VgLogTo_File,
@@ -341,9 +336,9 @@
       // in case someone has combined a prefix with a core-specific option,
       // eg.  "--memcheck:verbose".
       if (*colon == ':') {
-         if (VG_CLO_STREQN(2,            arg,                "--") && 
-             VG_CLO_STREQN(toolname_len, arg+2,              toolname) &&
-             VG_CLO_STREQN(1,            arg+2+toolname_len, ":"))
+         if (VG_STREQN(2,            arg,                "--") && 
+             VG_STREQN(toolname_len, arg+2,              toolname) &&
+             VG_STREQN(1,            arg+2+toolname_len, ":"))
          {
             // Prefix matches, convert "--toolname:foo" to "--foo".
             // Two things to note:
@@ -373,134 +368,124 @@
       }
       
       /* Ignore these options - they've already been handled */
-      if      (VG_CLO_STREQN( 7, arg, "--tool="))              { }
-      else if (VG_CLO_STREQN(20, arg, "--command-line-only=")) { }
-      else if (VG_CLO_STREQ(arg, "--"))                        { }
-      else if (VG_CLO_STREQ(arg, "-d"))                        { }
+      if      VG_STREQN( 7, arg, "--tool=")              {}
+      else if VG_STREQN(20, arg, "--command-line-only=") {}
+      else if VG_STREQ(     arg, "--")                   {}
+      else if VG_STREQ(     arg, "-d")                   {}
+      else if VG_STREQN(16, arg, "--max-stackframe")     {}
+      else if VG_STREQN(16, arg, "--main-stacksize")     {}
+      else if VG_STREQN(14, arg, "--profile-heap")       {}
 
-      else if (VG_CLO_STREQ(arg, "-v") ||
-               VG_CLO_STREQ(arg, "--verbose"))
+      // These options are new.
+      else if (VG_STREQ(arg, "-v") ||
+               VG_STREQ(arg, "--verbose"))
          VG_(clo_verbosity)++;
 
-      else if (VG_CLO_STREQ(arg, "-q") ||
-               VG_CLO_STREQ(arg, "--quiet"))
+      else if (VG_STREQ(arg, "-q") ||
+               VG_STREQ(arg, "--quiet"))
          VG_(clo_verbosity)--;
 
-      else VG_BOOL_CLO(arg, "--xml",              VG_(clo_xml))
-      else VG_BOOL_CLO(arg, "--db-attach",        VG_(clo_db_attach))
-      else VG_BOOL_CLO(arg, "--demangle",         VG_(clo_demangle))
-      else VG_BOOL_CLO(arg, "--error-limit",      VG_(clo_error_limit))
-      else VG_NUM_CLO (arg, "--error-exitcode",   VG_(clo_error_exitcode))
-      else VG_BOOL_CLO(arg, "--show-emwarns",     VG_(clo_show_emwarns))
+      else if VG_BOOL_CLO(arg, "--xml",            VG_(clo_xml)) {}
+      else if VG_BOOL_CLO(arg, "--db-attach",      VG_(clo_db_attach)) {}
+      else if VG_BOOL_CLO(arg, "--demangle",       VG_(clo_demangle)) {}
+      else if VG_BOOL_CLO(arg, "--error-limit",    VG_(clo_error_limit)) {}
+      else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
+      else if VG_BOOL_CLO(arg, "--show-emwarns",   VG_(clo_show_emwarns)) {}
 
-      /* The next two are already done in
-         early_process_cmd_line_options, but we need to redundantly
-         handle them again, so they do not get rejected as invalid. */
-      else VG_NUM_CLO (arg, "--max-stackframe",   VG_(clo_max_stackframe))
-      else VG_NUM_CLO (arg, "--main-stacksize",   VG_(clo_main_stacksize))
+      else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
+      else if VG_BOOL_CLO(arg, "--show-below-main",  VG_(clo_show_below_main)) {}
+      else if VG_BOOL_CLO(arg, "--time-stamp",       VG_(clo_time_stamp)) {}
+      else if VG_BOOL_CLO(arg, "--track-fds",        VG_(clo_track_fds)) {}
+      else if VG_BOOL_CLO(arg, "--trace-children",   VG_(clo_trace_children)) {}
+      else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
+                            VG_(clo_child_silent_after_fork)) {}
+      else if VG_BOOL_CLO(arg, "--trace-sched",      VG_(clo_trace_sched)) {}
+      else if VG_BOOL_CLO(arg, "--trace-signals",    VG_(clo_trace_signals)) {}
+      else if VG_BOOL_CLO(arg, "--trace-symtab",     VG_(clo_trace_symtab)) {}
+      else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
+      else if VG_BOOL_CLO(arg, "--trace-cfi",        VG_(clo_trace_cfi)) {}
+      else if VG_XACT_CLO(arg, "--debug-dump=syms",  VG_(clo_debug_dump_syms),
+                                                     True) {}
+      else if VG_XACT_CLO(arg, "--debug-dump=line",  VG_(clo_debug_dump_line),
+                                                     True) {}
+      else if VG_XACT_CLO(arg, "--debug-dump=frames",
+                               VG_(clo_debug_dump_frames), True) {}
+      else if VG_BOOL_CLO(arg, "--trace-redir",      VG_(clo_trace_redir)) {}
 
-      else VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres))
-      else VG_BOOL_CLO(arg, "--show-below-main",  VG_(clo_show_below_main))
-      else VG_BOOL_CLO(arg, "--time-stamp",       VG_(clo_time_stamp))
-      else VG_BOOL_CLO(arg, "--track-fds",        VG_(clo_track_fds))
-      else VG_BOOL_CLO(arg, "--trace-children",   VG_(clo_trace_children))
-      else VG_BOOL_CLO(arg, "--child-silent-after-fork",
-                            VG_(clo_child_silent_after_fork))
-      else VG_BOOL_CLO(arg, "--trace-sched",      VG_(clo_trace_sched))
-      else VG_BOOL_CLO(arg, "--trace-signals",    VG_(clo_trace_signals))
-      else VG_BOOL_CLO(arg, "--trace-symtab",     VG_(clo_trace_symtab))
-      else VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt))
-      else VG_BOOL_CLO(arg, "--trace-cfi",        VG_(clo_trace_cfi))
-      else VG_XACT_CLO(arg, "--debug-dump=syms",  VG_(clo_debug_dump_syms))
-      else VG_XACT_CLO(arg, "--debug-dump=line",  VG_(clo_debug_dump_line))
-      else VG_XACT_CLO(arg, "--debug-dump=frames", VG_(clo_debug_dump_frames))
-      else VG_BOOL_CLO(arg, "--trace-redir",      VG_(clo_trace_redir))
+      else if VG_BOOL_CLO(arg, "--trace-syscalls",   VG_(clo_trace_syscalls)) {}
+      else if VG_BOOL_CLO(arg, "--wait-for-gdb",     VG_(clo_wait_for_gdb)) {}
+      else if VG_STR_CLO (arg, "--db-command",       VG_(clo_db_command)) {}
+      else if VG_STR_CLO (arg, "--sim-hints",        VG_(clo_sim_hints)) {}
+      else if VG_BOOL_CLO(arg, "--sym-offsets",      VG_(clo_sym_offsets)) {}
+      else if VG_BOOL_CLO(arg, "--read-var-info",    VG_(clo_read_var_info)) {}
 
-      else VG_BOOL_CLO(arg, "--trace-syscalls",   VG_(clo_trace_syscalls))
-      else VG_BOOL_CLO(arg, "--wait-for-gdb",     VG_(clo_wait_for_gdb))
-      else VG_STR_CLO (arg, "--db-command",       VG_(clo_db_command))
-      else VG_STR_CLO (arg, "--sim-hints",        VG_(clo_sim_hints))
-      else VG_BOOL_CLO(arg, "--sym-offsets",      VG_(clo_sym_offsets))
-      else VG_BOOL_CLO(arg, "--read-var-info",    VG_(clo_read_var_info))
+      else if VG_INT_CLO (arg, "--dump-error",       VG_(clo_dump_error))   {}
+      else if VG_INT_CLO (arg, "--input-fd",         VG_(clo_input_fd))     {}
+      else if VG_INT_CLO (arg, "--sanity-level",     VG_(clo_sanity_level)) {}
+      else if VG_BINT_CLO(arg, "--num-callers",      VG_(clo_backtrace_size), 1,
+                                                     VG_DEEPEST_BACKTRACE) {}
 
-      else VG_NUM_CLO (arg, "--dump-error",       VG_(clo_dump_error))
-      else VG_NUM_CLO (arg, "--input-fd",         VG_(clo_input_fd))
-      else VG_NUM_CLO (arg, "--sanity-level",     VG_(clo_sanity_level))
-      else VG_BNUM_CLO(arg, "--num-callers",      VG_(clo_backtrace_size), 1,
-                                                  VG_DEEPEST_BACKTRACE)
+      else if VG_XACT_CLO(arg, "--smc-check=none",  VG_(clo_smc_check),
+                                                    Vg_SmcNone);
+      else if VG_XACT_CLO(arg, "--smc-check=stack", VG_(clo_smc_check),
+                                                    Vg_SmcStack);
+      else if VG_XACT_CLO(arg, "--smc-check=all",   VG_(clo_smc_check),
+                                                    Vg_SmcAll);
 
-      else if (VG_CLO_STREQ(arg, "--smc-check=none"))
-         VG_(clo_smc_check) = Vg_SmcNone;
-      else if (VG_CLO_STREQ(arg, "--smc-check=stack"))
-         VG_(clo_smc_check) = Vg_SmcStack;
-      else if (VG_CLO_STREQ(arg, "--smc-check=all"))
-         VG_(clo_smc_check) = Vg_SmcAll;
+      else if VG_STR_CLO (arg, "--kernel-variant",   VG_(clo_kernel_variant)) {}
 
-      else if (VG_CLO_STREQ(arg, "--profile-heap=no"))
-         ; /* We already handled it right at the top of valgrind_main.
-              Just ignore. */
-      else if (VG_CLO_STREQ(arg, "--profile-heap=yes"))
-         ; /* ditto */
+      else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
+                       VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
+      else if VG_BINT_CLO(arg, "--vex-iropt-level",
+                       VG_(clo_vex_control).iropt_level, 0, 2) {}
+      else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
+                       VG_(clo_vex_control).iropt_precise_memory_exns) {}
+      else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
+                       VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
+      else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
+                       VG_(clo_vex_control).guest_max_insns, 1, 100) {}
+      else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
+                       VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
 
-      else VG_STR_CLO (arg, "--kernel-variant",   VG_(clo_kernel_variant))
-
-      else VG_BNUM_CLO(arg, "--vex-iropt-verbosity",
-                       VG_(clo_vex_control).iropt_verbosity, 0, 10)
-      else VG_BNUM_CLO(arg, "--vex-iropt-level",
-                       VG_(clo_vex_control).iropt_level, 0, 2)
-      else VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
-                       VG_(clo_vex_control).iropt_precise_memory_exns)
-      else VG_BNUM_CLO(arg, "--vex-iropt-unroll-thresh",
-                       VG_(clo_vex_control).iropt_unroll_thresh, 0, 400)
-      else VG_BNUM_CLO(arg, "--vex-guest-max-insns",
-                       VG_(clo_vex_control).guest_max_insns, 1, 100)
-      else VG_BNUM_CLO(arg, "--vex-guest-chase-thresh",
-                       VG_(clo_vex_control).guest_chase_thresh, 0, 99)
-
-      else if (VG_CLO_STREQN(9,  arg, "--log-fd=")) {
-         log_to            = VgLogTo_Fd;
+      else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
+         log_to = VgLogTo_Fd;
          VG_(clo_log_name) = NULL;
-         tmp_log_fd        = (Int)VG_(atoll)(&arg[9]);
       }
 
-      else if (VG_CLO_STREQN(11, arg, "--log-file=")) {
-         log_to            = VgLogTo_File;
-         VG_(clo_log_name) = &arg[11];
+      else if VG_STR_CLO(arg, "--log-file", VG_(clo_log_name)) {
+         log_to = VgLogTo_File;
       }
 
-      else if (VG_CLO_STREQN(13, arg, "--log-socket=")) {
-         log_to            = VgLogTo_Socket;
-         VG_(clo_log_name) = &arg[13];
+      else if VG_STR_CLO(arg, "--log-socket", VG_(clo_log_name)) {
+         log_to = VgLogTo_Socket;
       }
 
-      else if (VG_CLO_STREQN(19, arg, "--xml-user-comment=")) {
-         VG_(clo_xml_user_comment) = &arg[19];
-      }
+      else if VG_STR_CLO(arg, "--xml-user-comment",
+                              VG_(clo_xml_user_comment)) {}
 
-      else if (VG_CLO_STREQN(15, arg, "--suppressions=")) {
+      else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
          if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
             VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
             VG_(message)(Vg_UserMsg, 
                          "Increase VG_CLO_MAX_SFILES and recompile.");
             VG_(err_bad_option)(arg);
          }
-         VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &arg[15];
+         VG_(clo_suppressions)[VG_(clo_n_suppressions)] = tmp_str;
          VG_(clo_n_suppressions)++;
       }
 
       /* "stuvwxyz" --> stuvwxyz (binary) */
-      else if (VG_CLO_STREQN(14, arg, "--trace-flags=")) {
+      else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
          Int j;
-         char* opt = & arg[14];
    
-         if (8 != VG_(strlen)(opt)) {
+         if (8 != VG_(strlen)(tmp_str)) {
             VG_(message)(Vg_UserMsg, 
                          "--trace-flags argument must have 8 digits");
             VG_(err_bad_option)(arg);
          }
          for (j = 0; j < 8; j++) {
-            if      ('0' == opt[j]) { /* do nothing */ }
-            else if ('1' == opt[j]) VG_(clo_trace_flags) |= (1 << (7-j));
+            if      ('0' == tmp_str[j]) { /* do nothing */ }
+            else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
             else {
                VG_(message)(Vg_UserMsg, "--trace-flags argument can only "
                                         "contain 0s and 1s");
@@ -510,18 +495,17 @@
       }
 
       /* "stuvwxyz" --> stuvwxyz (binary) */
-      else if (VG_CLO_STREQN(16, arg, "--profile-flags=")) {
+      else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
          Int j;
-         char* opt = & arg[16];
    
-         if (8 != VG_(strlen)(opt)) {
+         if (8 != VG_(strlen)(tmp_str)) {
             VG_(message)(Vg_UserMsg, 
                          "--profile-flags argument must have 8 digits");
             VG_(err_bad_option)(arg);
          }
          for (j = 0; j < 8; j++) {
-            if      ('0' == opt[j]) { /* do nothing */ }
-            else if ('1' == opt[j]) VG_(clo_profile_flags) |= (1 << (7-j));
+            if      ('0' == tmp_str[j]) { /* do nothing */ }
+            else if ('1' == tmp_str[j]) VG_(clo_profile_flags) |= (1 << (7-j));
             else {
                VG_(message)(Vg_UserMsg, "--profile-flags argument can only "
                                         "contain 0s and 1s");
@@ -530,14 +514,14 @@
          }
       }
 
-      else VG_NUM_CLO (arg, "--trace-notbelow",   VG_(clo_trace_notbelow))
+      else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
 
-      else if (VG_CLO_STREQ(arg, "--gen-suppressions=no"))
-         VG_(clo_gen_suppressions) = 0;
-      else if (VG_CLO_STREQ(arg, "--gen-suppressions=yes"))
-         VG_(clo_gen_suppressions) = 1;
-      else if (VG_CLO_STREQ(arg, "--gen-suppressions=all"))
-         VG_(clo_gen_suppressions) = 2;
+      else if VG_XACT_CLO(arg, "--gen-suppressions=no",
+                               VG_(clo_gen_suppressions), 0) {}
+      else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
+                               VG_(clo_gen_suppressions), 1) {}
+      else if VG_XACT_CLO(arg, "--gen-suppressions=all",
+                               VG_(clo_gen_suppressions), 2) {}
 
       else if ( ! VG_(needs).command_line_options
              || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
@@ -1206,19 +1190,15 @@
    //   p: none
    //--------------------------------------------------------------
    /* Start the debugging-log system ASAP.  First find out how many 
-      "-d"s were specified.  This is a pre-scan of the command line. */
+      "-d"s were specified.  This is a pre-scan of the command line.  Also
+      get --profile-heap=yes which is needed by the time we start up dynamic
+      memory management.  */
    loglevel = 0;
    for (i = 1; i < argc; i++) {
-      if (argv[i][0] != '-')
-         break;
-      if (VG_STREQ(argv[i], "--")) 
-         break;
-      if (VG_STREQ(argv[i], "-d")) 
-         loglevel++;
-      if (VG_STREQ(argv[i], "--profile-heap=yes"))
-         VG_(clo_profile_heap) = True;
-      if (VG_STREQ(argv[i], "--profile-heap=no"))
-         VG_(clo_profile_heap) = False;
+      if (argv[i][0] != '-') break;
+      if VG_STREQ(argv[i], "--") break;
+      if VG_STREQ(argv[i], "-d") loglevel++;
+      if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
    }
 
    /* ... and start the debug logger.  Now we can safely emit logging
@@ -1330,6 +1310,7 @@
    //--------------------------------------------------------------
    // Start up the dynamic memory manager
    //   p: address space management
+   //   p: getting --profile-heap
    //   In fact m_mallocfree is self-initialising, so there's no
    //   initialisation call to do.  Instead, try a simple malloc/
    //   free pair right now to check that nothing is broken.
@@ -1481,7 +1462,9 @@
 
    //--------------------------------------------------------------
    // Load client executable, finding in $PATH if necessary
-   //   p: early_process_cmd_line_options()  [for 'exec', 'need_help']
+   //   p: early_process_cmd_line_options()  [for 'exec', 'need_help',
+   //                                         clo_max_stackframe,
+   //                                         clo_main_stacksize]
    //   p: layout_remaining_space            [so there's space]
    //
    // Set up client's environment
diff --git a/coregrind/m_replacemalloc/replacemalloc_core.c b/coregrind/m_replacemalloc/replacemalloc_core.c
index 175402b..4373232 100644
--- a/coregrind/m_replacemalloc/replacemalloc_core.c
+++ b/coregrind/m_replacemalloc/replacemalloc_core.c
@@ -53,13 +53,11 @@
 
 Bool VG_(replacement_malloc_process_cmd_line_option)(Char* arg)
 {
-   if (VG_CLO_STREQN(12, arg, "--alignment=")) {
-      VG_(clo_alignment) = (UInt)VG_(atoll)(&arg[12]);
-
-      if (VG_(clo_alignment) < VG_MIN_MALLOC_SZB
-          || VG_(clo_alignment) > 4096
-          || VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */) {
-         VG_(message)(Vg_UserMsg, "");
+   if VG_INT_CLO(arg, "--alignment", VG_(clo_alignment)) {
+      if (VG_(clo_alignment) < VG_MIN_MALLOC_SZB ||
+          VG_(clo_alignment) > 4096 ||
+          VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */)
+      {
          VG_(message)(Vg_UserMsg, 
             "Invalid --alignment= setting.  "
             "Should be a power of 2, >= %d, <= 4096.", VG_MIN_MALLOC_SZB);
@@ -67,7 +65,7 @@
       }
    }
 
-   else VG_BOOL_CLO(arg, "--trace-malloc",  VG_(clo_trace_malloc))
+   else if VG_BOOL_CLO(arg, "--trace-malloc",  VG_(clo_trace_malloc)) {}
    else 
       return False;
 
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index ca07ffe..9e26c58 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -750,11 +750,16 @@
          goto out;
 
       if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
-         Int fno = VG_(atoll)(d.d_name);
-
-         if (fno != f.res)
-            if (VG_(clo_track_fds))
-               ML_(record_fd_open_named)(-1, fno);
+         Char* s;
+         Int fno = VG_(strtoll10)(d.d_name, &s);
+         if (*s == '\0') {
+            if (fno != f.res)
+               if (VG_(clo_track_fds))
+                  ML_(record_fd_open_named)(-1, fno);
+         } else {
+            VG_(message)(Vg_DebugMsg, 
+               "Warning: invalid file name in /proc/self/fd: %s", d.d_name);
+         }
       }
 
       VG_(lseek)(f.res, d.d_off, VKI_SEEK_SET);