diff options
author | Xinliang David Li <davidxl@google.com> | 2016-07-18 16:16:12 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2016-07-18 16:16:12 +0000 |
commit | 53e2f16931e10e7d32edd927739836169f80f2a5 (patch) | |
tree | 5c473b3fe651ded937d9b78a521e52c166a9112a | |
parent | 3e87a261cdc57c4d8f686161f9ecfff4bdacb6a3 (diff) |
Code refactoring: extract path prefix handling code
.. into reusable interfaces. No functional change is expected.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@275807 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/profile/GCDAProfiling.c | 44 | ||||
-rw-r--r-- | lib/profile/InstrProfilingInternal.h | 14 | ||||
-rw-r--r-- | lib/profile/InstrProfilingUtil.c | 52 |
3 files changed, 74 insertions, 36 deletions
diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c index 51a40c5b6..2756084f5 100644 --- a/lib/profile/GCDAProfiling.c +++ b/lib/profile/GCDAProfiling.c @@ -20,8 +20,9 @@ |* \*===----------------------------------------------------------------------===*/ -#include "InstrProfilingUtil.h" +#include "InstrProfilingInternal.h" #include "InstrProfilingPort.h" +#include "InstrProfilingUtil.h" #include <errno.h> #include <fcntl.h> @@ -171,45 +172,16 @@ static uint64_t read_64bit_value() { static char *mangle_filename(const char *orig_filename) { char *new_filename; - size_t filename_len, prefix_len; + size_t prefix_len; int prefix_strip; - int level = 0; - const char *fname, *ptr; - const char *prefix = getenv("GCOV_PREFIX"); - const char *prefix_strip_str = getenv("GCOV_PREFIX_STRIP"); + const char *prefix = lprofGetPathPrefix(&prefix_strip, &prefix_len); - if (prefix == NULL || prefix[0] == '\0') + if (prefix == NULL) return strdup(orig_filename); - if (prefix_strip_str) { - prefix_strip = atoi(prefix_strip_str); - - /* Negative GCOV_PREFIX_STRIP values are ignored */ - if (prefix_strip < 0) - prefix_strip = 0; - } else { - prefix_strip = 0; - } - - fname = orig_filename; - for (level = 0, ptr = fname + 1; level < prefix_strip; ++ptr) { - if (*ptr == '\0') - break; - - if (!IS_DIR_SEPARATOR(*ptr)) - continue; - fname = ptr; - ++level; - } - - filename_len = strlen(fname); - prefix_len = strlen(prefix); - new_filename = malloc(prefix_len + 1 + filename_len + 1); - memcpy(new_filename, prefix, prefix_len); - - if (!IS_DIR_SEPARATOR(prefix[prefix_len - 1])) - new_filename[prefix_len++] = DIR_SEPARATOR; - memcpy(new_filename + prefix_len, fname, filename_len + 1); + new_filename = malloc(prefix_len + 1 + strlen(orig_filename) + 1); + lprofApplyPathPrefix(new_filename, orig_filename, prefix, prefix_len, + prefix_strip); return new_filename; } diff --git a/lib/profile/InstrProfilingInternal.h b/lib/profile/InstrProfilingInternal.h index bcbe29a03..44f308206 100644 --- a/lib/profile/InstrProfilingInternal.h +++ b/lib/profile/InstrProfilingInternal.h @@ -163,6 +163,20 @@ void lprofSetupValueProfiler(); * to dump merged profile data into its own profile file. */ uint64_t lprofGetLoadModuleSignature(); +/* GCOV_PREFIX and GCOV_PREFIX_STRIP support */ +/* Return the path prefix specified by GCOV_PREFIX environment variable. + * If GCOV_PREFIX_STRIP is also specified, the strip level (integer value) + * is returned via \c *PrefixStrip. The prefix length is stored in *PrefixLen. + */ +const char *lprofGetPathPrefix(int *PrefixStrip, size_t *PrefixLen); +/* Apply the path prefix specified in \c Prefix to path string in \c PathStr, + * and store the result to buffer pointed to by \c Buffer. If \c PrefixStrip + * is not zero, path prefixes are stripped from \c PathStr (the level of + * stripping is specified by \c PrefixStrip) before \c Prefix is added. + */ +void lprofApplyPathPrefix(char *Dest, const char *PathStr, const char *Prefix, + size_t PrefixLen, int PrefixStrip); + COMPILER_RT_VISIBILITY extern char *(*GetEnvHook)(const char *); COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *); COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer; diff --git a/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c index dc58d731b..5c66933bc 100644 --- a/lib/profile/InstrProfilingUtil.c +++ b/lib/profile/InstrProfilingUtil.c @@ -26,6 +26,7 @@ #include <sys/utsname.h> #endif +#include <stdlib.h> #include <string.h> COMPILER_RT_VISIBILITY @@ -132,3 +133,54 @@ COMPILER_RT_VISIBILITY FILE *lprofOpenFileEx(const char *ProfileName) { return f; } + +COMPILER_RT_VISIBILITY const char *lprofGetPathPrefix(int *PrefixStrip, + size_t *PrefixLen) { + const char *Prefix = getenv("GCOV_PREFIX"); + const char *PrefixStripStr = getenv("GCOV_PREFIX_STRIP"); + + *PrefixLen = 0; + *PrefixStrip = 0; + if (Prefix == NULL || Prefix[0] == '\0') + return NULL; + + if (PrefixStripStr) { + *PrefixStrip = atoi(PrefixStripStr); + + /* Negative GCOV_PREFIX_STRIP values are ignored */ + if (*PrefixStrip < 0) + *PrefixStrip = 0; + } else { + *PrefixStrip = 0; + } + *PrefixLen = strlen(Prefix); + + return Prefix; +} + +COMPILER_RT_VISIBILITY void +lprofApplyPathPrefix(char *Dest, const char *PathStr, const char *Prefix, + size_t PrefixLen, int PrefixStrip) { + + const char *Ptr; + int Level; + const char *StrippedPathStr = PathStr; + + for (Level = 0, Ptr = PathStr + 1; Level < PrefixStrip; ++Ptr) { + if (*Ptr == '\0') + break; + + if (!IS_DIR_SEPARATOR(*Ptr)) + continue; + + StrippedPathStr = Ptr; + ++Level; + } + + memcpy(Dest, Prefix, PrefixLen); + + if (!IS_DIR_SEPARATOR(Prefix[PrefixLen - 1])) + Dest[PrefixLen++] = DIR_SEPARATOR; + + memcpy(Dest + PrefixLen, StrippedPathStr, strlen(StrippedPathStr) + 1); +} |