LoggerAction* loggerActionNew(char const* toolName_) { LoggerAction* act = (LoggerAction*) malloc(sizeof(LoggerAction)); if (!act) { return NULL; } loggerFileInitFromPath(&act->output, "./_noobj"); loggerVectorInit(&act->arguments); loggerVectorInit(&act->sources); strcpy(act->toolName, toolName_); return act; }
int loggerGccParserCollectActions( const char* prog_, const char* toolName_, const char* const argv_[], LoggerVector* actions_) { size_t i; /* Position of the last include path + 1 */ size_t lastIncPos = 1; GccArgsState state = Normal; LoggerAction* action = loggerActionNew(toolName_); loggerVectorAdd(&action->arguments, loggerStrDup(toolName_)); for (i = 1; argv_[i]; ++i) { state = processArgument(state, argv_[i], action); if (argv_[i][0] == '-' && argv_[i][1] == 'I') { if (argv_[i][2]) { /* -I with path argument */ lastIncPos = action->arguments.size; } else { /* The path should be the next argument */ lastIncPos = action->arguments.size + 1; } } } if (!getenv("CC_LOGGER_NO_DEF_DIRS")) { LoggerVector defIncludes; loggerVectorInit(&defIncludes); getDefaultArguments(prog_, &defIncludes); if (defIncludes.size) { loggerVectorAddFrom(&action->arguments, &defIncludes, &lastIncPos, (LoggerDupFuc) &loggerStrDup); } loggerVectorClear(&defIncludes); } /* * Workaround for -MT and friends: if the source set contains the output, * then we have to remove it from the set. */ i = loggerVectorFind(&action->sources, action->output.path, (LoggerCmpFuc) &strcmp); if (i != SIZE_MAX) { loggerVectorErase(&action->sources, i); } loggerVectorAdd(actions_, action); return 1; }
int loggerGccParserCollectActions( const char* prog_, const char* toolName_, const char* const argv_[], LoggerVector* actions_) { enum Language { C, CPP, OBJC } lang = CPP; size_t i; /* Position of the last include path + 1 */ char full_prog_path[PATH_MAX+1]; char *path_ptr; size_t lastIncPos = 1; size_t lastSysIncPos = 1; GccArgsState state = Normal; LoggerAction* action = loggerActionNew(toolName_); char* keepLinkVar = getenv("CC_LOGGER_KEEP_LINK"); int keepLink = keepLinkVar && strcmp(keepLinkVar, "true") == 0; /* If prog_ is a relative path we try to * convert it to absolute path. */ path_ptr = realpath(prog_, full_prog_path); /* If we cannot convert it, we try to find the * executable in the PATH. */ if (!path_ptr) path_ptr = findFullPath(toolName_, full_prog_path); if (path_ptr) /* Log compiler with full path. */ loggerVectorAdd(&action->arguments, loggerStrDup(full_prog_path)); else /* Compiler was not found in path, log the binary name only. */ loggerVectorAdd(&action->arguments, loggerStrDup(toolName_)); /* Determine programming language based on compiler name. */ for (i = 0; cCompiler[i]; ++i) if (strstr(toolName_, cCompiler[i])) lang = C; for (i = 0; cppCompiler[i]; ++i) if (strstr(toolName_, cppCompiler[i])) lang = CPP; for (i = 1; argv_[i]; ++i) { const char* current = argv_[i]; state = processArgument(state, current, action); if (current[0] == '-') { /* Determine the position of the last -I and -isystem flags. * Depending on whether the parameter of -I or -isystem is separated * from the flag by a space character. * 2 == strlen("-I") && 8 == strlen("-isystem") */ if (current[1] == 'I') lastIncPos = action->arguments.size + (current[2] ? 0 : 1); else if (strstr(current, "-isystem") == current) lastSysIncPos = action->arguments.size + (current[8] ? 0 : 1); /* Determine the programming language based on -x flag. */ else if (strcmp(current, "-x") == 0) { /* TODO: The language value after -x can be others too. See the man * page of GCC. * TODO: According to a GCC warning the -x flag has no effect when it * is placed after the last input file to be compiled. */ const char* l = argv_[i + 1]; if (strcmp(l, "c") == 0 || strcmp(l, "c-header") == 0) lang = C; else if (strcmp(l, "c++") == 0 || strcmp(l, "c++-header") == 0) lang = CPP; } } } if (getenv("CC_LOGGER_DEF_DIRS")) { LoggerVector defIncludes; loggerVectorInit(&defIncludes); getDefaultArguments(prog_, &defIncludes); if (defIncludes.size) { loggerVectorAddFrom(&action->arguments, &defIncludes, &lastIncPos, (LoggerDupFuc) &loggerStrDup); if (lastSysIncPos > lastIncPos) lastSysIncPos += defIncludes.size; lastIncPos += defIncludes.size; } loggerVectorClear(&defIncludes); } if (getenv("CPATH")) { LoggerVector includes; loggerVectorInit(&includes); getPathsFromEnvVar(&includes, "CPATH", "-I"); if (includes.size) { loggerVectorAddFrom(&action->arguments, &includes, &lastIncPos, (LoggerDupFuc) &loggerStrDup); if (lastSysIncPos > lastIncPos) lastSysIncPos += includes.size; lastIncPos += includes.size; } loggerVectorClear(&includes); } if (lang == CPP && getenv("CPLUS_INCLUDE_PATH")) { LoggerVector includes; loggerVectorInit(&includes); getPathsFromEnvVar(&includes, "CPLUS_INCLUDE_PATH", "-isystem"); if (includes.size) { loggerVectorAddFrom(&action->arguments, &includes, &lastSysIncPos, (LoggerDupFuc) &loggerStrDup); } loggerVectorClear(&includes); } else if (lang == C && getenv("C_INCLUDE_PATH")) { LoggerVector includes; loggerVectorInit(&includes); getPathsFromEnvVar(&includes, "C_INCLUDE_PATH", "-isystem"); if (includes.size) { loggerVectorAddFrom(&action->arguments, &includes, &lastSysIncPos, (LoggerDupFuc) &loggerStrDup); } loggerVectorClear(&includes); } /* * Workaround for -MT and friends: if the source set contains the output, * then we have to remove it from the set. */ i = loggerVectorFind(&action->sources, action->output.path, (LoggerCmpFuc) &strcmp); if (i != SIZE_MAX) { loggerVectorErase(&action->sources, i); } if (!keepLink) do { i = loggerVectorFindIf(&action->sources, (LoggerPredFuc) &isObjectFile); loggerVectorErase(&action->sources, i); } while (i != SIZE_MAX); if (action->sources.size != 0) loggerVectorAdd(actions_, action); return 1; }
int loggerJavacParserCollectActions( const char* prog_, const char* toolName_, const char* const argv_[], LoggerVector* actions_) { ParserData data; size_t i; assert(prog_ == prog_); /* suppress unused variable */ data.hasSourcePath = 0; data.state = Normal; loggerVectorInit(&data.commonArgs); loggerVectorInit(&data.sources); memset(data.classdir, 0, sizeof(data.classdir)); loggerVectorAdd(&data.commonArgs, loggerStrDup(toolName_)); for (i = 1; argv_[i]; ++i) { if (argv_[i][0] == '@') { size_t j; LoggerVector fargs; loggerVectorInit(&fargs); readArgumentsFromFile(argv_[i] + 1, &fargs); for (j = 0; j < fargs.size; ++j) { processArg((const char*) fargs.data[j], &data); } loggerVectorClear(&fargs); } else { processArg(argv_[i], &data); } } if (!data.hasSourcePath) { char workdir[PATH_MAX]; if (loggerMakePathAbs(".", workdir, 0)) { loggerVectorAdd(&data.commonArgs, loggerStrDup("-sourcepath")); loggerVectorAdd(&data.commonArgs, loggerStrDup(workdir)); } } for (i = 0; i < data.sources.size; ++i) { char outputFile[PATH_MAX]; const char* src = (char*) data.sources.data[i]; LoggerAction* action = loggerActionNew(toolName_); if (!action) { continue; } loggerVectorAddFrom(&action->arguments, &data.commonArgs, NULL, (LoggerDupFuc) &loggerStrDup); loggerVectorAdd(&action->arguments, loggerStrDup(src)); loggerVectorAdd(&action->sources, loggerStrDup(src)); if (data.classdir[0] != 0) { char* fname = loggerGetFileName(src, 1); strcpy(outputFile, data.classdir); strcat(outputFile, "/"); strcat(outputFile, fname); strcat(outputFile, ".class"); free(fname); } else { char* path = loggerGetFilePathWithoutExt(src); strcpy(outputFile, path); strcat(outputFile, ".class"); free(path); } loggerFileInitFromPath(&action->output, outputFile); loggerVectorAdd(actions_, action); } loggerVectorClear(&data.commonArgs); loggerVectorClear(&data.sources); return 1; }