Author: njn Date: 2007-11-22 23:01:59 +0000 (Thu, 22 Nov 2007) New Revision: 7200
Log: Add support for %q in --massif-out-file. Todo: use this mechanism for the core and Cachegrind. Modified: trunk/coregrind/m_options.c trunk/coregrind/pub_core_options.h trunk/include/pub_tool_options.h trunk/massif/ms_main.c Modified: trunk/coregrind/m_options.c =================================================================== --- trunk/coregrind/m_options.c 2007-11-22 01:21:56 UTC (rev 7199) +++ trunk/coregrind/m_options.c 2007-11-22 23:01:59 UTC (rev 7200) @@ -96,6 +96,7 @@ VG_(clo_log_fd) = 2; /* stderr */ } +__attribute__((noreturn)) void VG_(err_bad_option) ( Char* opt ) { revert_to_stderr(); @@ -104,6 +105,7 @@ VG_(exit)(1); } +__attribute__((noreturn)) void VG_(err_missing_prog) ( void ) { revert_to_stderr(); @@ -112,6 +114,7 @@ VG_(exit)(1); } +__attribute__((noreturn)) void VG_(err_config_error) ( Char* msg ) { revert_to_stderr(); Modified: trunk/coregrind/pub_core_options.h =================================================================== --- trunk/coregrind/pub_core_options.h 2007-11-22 01:21:56 UTC (rev 7199) +++ trunk/coregrind/pub_core_options.h 2007-11-22 23:01:59 UTC (rev 7200) @@ -191,10 +191,12 @@ /* Call this if the executable is missing. This function prints an error message, then shuts down the entire system. */ +__attribute__((noreturn)) extern void VG_(err_missing_prog) ( void ); /* Similarly - complain and stop if there is some kind of config error. */ +__attribute__((noreturn)) extern void VG_(err_config_error) ( Char* msg ); Modified: trunk/include/pub_tool_options.h =================================================================== --- trunk/include/pub_tool_options.h 2007-11-22 01:21:56 UTC (rev 7199) +++ trunk/include/pub_tool_options.h 2007-11-22 23:01:59 UTC (rev 7200) @@ -124,6 +124,7 @@ 'False' from VG_(tdict).tool_process_cmd_line_option) to indicate that. This function prints an error message, then shuts down the entire system. */ +__attribute__((noreturn)) extern void VG_(err_bad_option) ( Char* opt ); Modified: trunk/massif/ms_main.c =================================================================== --- trunk/massif/ms_main.c 2007-11-22 01:21:56 UTC (rev 7199) +++ trunk/massif/ms_main.c 2007-11-22 23:01:59 UTC (rev 7200) @@ -2054,7 +2054,7 @@ // Copies the string, prepending it with the startup working directory, and // expanding %p and %q entries. Returns a new, malloc'd string. -static Char* expand_file_name(Char* format) +static Char* VG_(expand_file_name)(Char* option_name, Char* format) { static Char base_dir[VKI_PATH_MAX]; Int len, i = 0, j = 0; @@ -2069,49 +2069,85 @@ out = VG_(malloc)( len ); VG_(strcpy)(out, base_dir); -#define GROW_IF_j_IS_GEQ_THAN(x) \ - if (j >= x) { \ - len *= 2; \ +#define ENSURE_THIS_MUCH_SPACE(x) \ + if (j + x >= len) { \ + len += (10 + x); \ out = VG_(realloc)(out, len); \ - OINK(len);\ } out[j++] = '/'; while (format[i]) { if (format[i] != '%') { - GROW_IF_j_IS_GEQ_THAN(len); + ENSURE_THIS_MUCH_SPACE(1); out[j++] = format[i++]; } else { // We saw a '%'. What's next... i++; - if (0 == format[i]) { - // At end of string, stop. - break; - } - else if ('%' == format[i]) { + if ('%' == format[i]) { // Replace '%%' with '%'. - GROW_IF_j_IS_GEQ_THAN(len); + ENSURE_THIS_MUCH_SPACE(1); out[j++] = format[i++]; } else if ('p' == format[i]) { - // Print the PID. - GROW_IF_j_IS_GEQ_THAN(len - 10); - j += VG_(sprintf)(&out[j], "%d", VG_(getpid)()); + // Print the PID. Assume that it's not longer than 10 chars -- + // reasonable since 'pid' is an Int (ie. 32 bits). + Int pid = VG_(getpid)(); + ENSURE_THIS_MUCH_SPACE(10); + j += VG_(sprintf)(&out[j], "%d", pid); i++; } + else if ('q' == format[i] && '{' == format[i+1]) { + // Get the env var name, print its contents. + Char* qualname; + Char* qual; + i += 2; + qualname = &format[i]; + while (True) { + if (0 == format[i]) { + VG_(message)(Vg_UserMsg, "%s: malformed %%q specifier", + option_name); + goto bad; + } else if ('}' == format[i]) { + // Temporarily replace the '}' with NUL to extract var name. + format[i] = 0; + qual = VG_(getenv)(qualname); + if (NULL == qual) { + VG_(message)(Vg_UserMsg, + "%s: environment variable %s is not set", + option_name, qualname); + goto bad; + } + format[i] = '}'; // Put the '}' back. + i++; + break; + } + i++; + } + ENSURE_THIS_MUCH_SPACE(VG_(strlen)(qual)); + j += VG_(sprintf)(&out[j], "%s", qual); + } else { - // Other char, treat both the '%' and its subsequent normally. - GROW_IF_j_IS_GEQ_THAN(len - 1); - out[j++] = '%'; - out[j++] = format[i++]; + // Something else, abort. + VG_(message)(Vg_UserMsg, + "%s: expected 'p' or 'q' or '%%' after '%%'", option_name); + goto bad; } } } - GROW_IF_j_IS_GEQ_THAN(len); + ENSURE_THIS_MUCH_SPACE(1); out[j++] = 0; return out; + + bad: { + Char* opt = // 2: 1 for the '=', 1 for the NUL. + VG_(malloc)( VG_(strlen)(option_name) + VG_(strlen)(format) + 2 ); + VG_(strcpy)(opt, option_name); + VG_(strcat)(opt, "="); + VG_(strcat)(opt, format); + VG_(err_bad_option)(opt); + } } @@ -2174,7 +2210,8 @@ sanity_check_snapshots_array(); // Setup output filename. - massif_out_file = expand_file_name(clo_massif_out_file); + massif_out_file = + VG_(expand_file_name)("--massif-out-file", clo_massif_out_file); } static void ms_pre_clo_init(void) ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Valgrind-developers mailing list Valgrind-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-developers