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