示例#1
0
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;
}
示例#2
0
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;
}