/* Find the correct compiler.
   Copyright (C) 2014-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include <config.h>
#include <string>
#include <dirent.h>
#include <stdlib.h>

#include "libiberty.h"
#include "xregex.h"
#include "findcomp.hh"
#include "system.h"

class scanner
{
public:

  scanner (const std::string &dir)
  {
    m_dir = opendir (dir.c_str ());
  }

  ~scanner ()
  {
    if (m_dir != NULL)
      closedir (m_dir);
  }

  const char *next ()
  {
    if (m_dir == NULL)
      return NULL;

    struct dirent *entry = readdir (m_dir);
    if (entry == NULL)
      return NULL;

    return entry->d_name;
  }

private:

  DIR *m_dir;
};

static bool
search_dir (const regex_t &regexp, const std::string &dir, std::string *result)
{
  scanner scan (dir);
  const char *filename;

  while ((filename = scan.next ()) != NULL)
    {
      if (regexec (&regexp, filename, 0, NULL, 0) == 0)
	{
	  *result = dir + DIR_SEPARATOR + filename;
	  return true;
	}
    }

  return false;
}

class tokenizer
{
public:

  tokenizer (const char *str)
    : m_str (str),
      m_pos (0)
  {
  }

  bool done () const
  {
    return m_pos == std::string::npos;
  }

  std::string next ()
  {
    std::string::size_type last_pos = m_pos;
    std::string::size_type colon = m_str.find(':', last_pos);

    std::string result;
    if (colon == std::string::npos)
      {
	m_pos = colon;
	result = m_str.substr(last_pos, colon);
      }
    else
      {
	m_pos = colon + 1;
	result = m_str.substr(last_pos, colon - last_pos);
      }
    if (result == "")
      result = ".";

    return result;
  }

private:

  std::string m_str;
  std::string::size_type m_pos;
};

bool
find_compiler (const regex_t &regexp, std::string *result)
{
  const char *cpath = getenv ("PATH");

  if (cpath == NULL)
    return false;

  tokenizer dirs (cpath);
  while (!dirs.done ())
    {
      std::string dir = dirs.next ();
      if (search_dir (regexp, dir, result))
	return true;
    }

  return false;
}
