/* Parses the pattern string \p FilenamePat and stores the result to * lprofcurFilename structure. */ static int parseFilenamePattern(const char *FilenamePat) { int NumPids = 0, NumHosts = 0, I; char *PidChars = &lprofCurFilename.PidChars[0]; char *Hostname = &lprofCurFilename.Hostname[0]; int MergingEnabled = 0; lprofCurFilename.FilenamePat = FilenamePat; /* Check the filename for "%p", which indicates a pid-substitution. */ for (I = 0; FilenamePat[I]; ++I) if (FilenamePat[I] == '%') { if (FilenamePat[++I] == 'p') { if (!NumPids++) { if (snprintf(PidChars, MAX_PID_SIZE, "%d", getpid()) <= 0) { PROF_WARN( "Unable to parse filename pattern %s. Using the default name.", FilenamePat); return -1; } } } else if (FilenamePat[I] == 'h') { if (!NumHosts++) if (COMPILER_RT_GETHOSTNAME(Hostname, COMPILER_RT_MAX_HOSTLEN)) { PROF_WARN( "Unable to parse filename pattern %s. Using the default name.", FilenamePat); return -1; } } else if (containsMergeSpecifier(FilenamePat, I)) { if (MergingEnabled) { PROF_WARN( "%%m specifier can only be specified once at the end of %s.\n", FilenamePat); return -1; } MergingEnabled = 1; if (FilenamePat[I] == 'm') lprofCurFilename.MergePoolSize = 1; else { lprofCurFilename.MergePoolSize = FilenamePat[I] - '0'; I++; /* advance to 'm' */ } } } lprofCurFilename.NumPids = NumPids; lprofCurFilename.NumHosts = NumHosts; return 0; }
static int setFilenamePossiblyWithPid(const char *Filename) { #define MAX_PID_SIZE 16 char PidChars[MAX_PID_SIZE] = {0}; int NumPids = 0, PidLength = 0, NumHosts = 0, HostNameLength = 0; char *Allocated; int I, J; char Hostname[COMPILER_RT_MAX_HOSTLEN]; /* Reset filename on NULL, except with env var which is checked by caller. */ if (!Filename) { resetFilenameToDefault(); return 0; } /* Check the filename for "%p", which indicates a pid-substitution. */ for (I = 0; Filename[I]; ++I) if (Filename[I] == '%') { if (Filename[++I] == 'p') { if (!NumPids++) { PidLength = snprintf(PidChars, MAX_PID_SIZE, "%d", getpid()); if (PidLength <= 0) return -1; } } else if (Filename[I] == 'h') { if (!NumHosts++) if (COMPILER_RT_GETHOSTNAME(Hostname, COMPILER_RT_MAX_HOSTLEN)) return -1; HostNameLength = strlen(Hostname); } } if (!(NumPids || NumHosts)) { setFilename(Filename, 0); return 0; } /* Allocate enough space for the substituted filename. */ Allocated = malloc(I + NumPids*(PidLength - 2) + NumHosts*(HostNameLength - 2) + 1); if (!Allocated) return -1; /* Construct the new filename. */ for (I = 0, J = 0; Filename[I]; ++I) if (Filename[I] == '%') { if (Filename[++I] == 'p') { memcpy(Allocated + J, PidChars, PidLength); J += PidLength; } else if (Filename[I] == 'h') { memcpy(Allocated + J, Hostname, HostNameLength); J += HostNameLength; } /* Drop any unknown substitutions. */ } else Allocated[J++] = Filename[I]; Allocated[J] = 0; /* Use the computed name. */ setFilename(Allocated, 1); return 0; }