/* A self-testing framework, for use by -fself-test.
   Copyright (C) 2015-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 "system.h"
#include "coretypes.h"
#include "selftest.h"
#include "intl.h"

#if CHECKING_P

namespace selftest {

int num_passes;

/* Record the successful outcome of some aspect of a test.  */

void
pass (const location &/*loc*/, const char */*msg*/)
{
  num_passes++;
}

/* Report the failed outcome of some aspect of a test and abort.  */

void
fail (const location &loc, const char *msg)
{
  fprintf (stderr,"%s:%i: %s: FAIL: %s\n", loc.m_file, loc.m_line,
	   loc.m_function, msg);
  abort ();
}

/* As "fail", but using printf-style formatted output.  */

void
fail_formatted (const location &loc, const char *fmt, ...)
{
  va_list ap;

  fprintf (stderr, "%s:%i: %s: FAIL: ", loc.m_file, loc.m_line,
	   loc.m_function);
  va_start (ap, fmt);
  vfprintf (stderr, fmt, ap);
  va_end (ap);
  fprintf (stderr, "\n");
  abort ();
}

/* Implementation detail of ASSERT_STREQ.
   Compare val1 and val2 with strcmp.  They ought
   to be non-NULL; fail gracefully if either or both are NULL.  */

void
assert_streq (const location &loc,
	      const char *desc_val1, const char *desc_val2,
	      const char *val1, const char *val2)
{
  /* If val1 or val2 are NULL, fail with a custom error message.  */
  if (val1 == NULL)
    if (val2 == NULL)
      fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=NULL val2=NULL",
		      desc_val1, desc_val2);
    else
      fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=NULL val2=\"%s\"",
		      desc_val1, desc_val2, val2);
  else
    if (val2 == NULL)
      fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=\"%s\" val2=NULL",
		      desc_val1, desc_val2, val1);
    else
      {
	if (strcmp (val1, val2) == 0)
	  pass (loc, "ASSERT_STREQ");
	else
	  fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=\"%s\" val2=\"%s\"",
			  desc_val1, desc_val2, val1, val2);
      }
}

/* Implementation detail of ASSERT_STR_CONTAINS.
   Use strstr to determine if val_needle is within val_haystack.
   ::selftest::pass if it is found.
   ::selftest::fail if it is not found.  */

void
assert_str_contains (const location &loc,
		     const char *desc_haystack,
		     const char *desc_needle,
		     const char *val_haystack,
		     const char *val_needle)
{
  /* If val_haystack is NULL, fail with a custom error message.  */
  if (val_haystack == NULL)
    fail_formatted (loc, "ASSERT_STR_CONTAINS (%s, %s) haystack=NULL",
		    desc_haystack, desc_needle);

  /* If val_needle is NULL, fail with a custom error message.  */
  if (val_needle == NULL)
    fail_formatted (loc,
		    "ASSERT_STR_CONTAINS (%s, %s) haystack=\"%s\" needle=NULL",
		    desc_haystack, desc_needle, val_haystack);

  const char *test = strstr (val_haystack, val_needle);
  if (test)
    pass (loc, "ASSERT_STR_CONTAINS");
  else
    fail_formatted
	(loc, "ASSERT_STR_CONTAINS (%s, %s) haystack=\"%s\" needle=\"%s\"",
	 desc_haystack, desc_needle, val_haystack, val_needle);
}

/* Implementation detail of ASSERT_STR_STARTSWITH.
   Determine if VAL_STR starts with VAL_PREFIX.
   ::selftest::pass if VAL_STR does start with VAL_PREFIX.
   ::selftest::fail if it does not, or either is NULL (using
   DESC_STR and DESC_PREFIX in the error message).  */

void
assert_str_startswith (const location &loc,
		       const char *desc_str,
		       const char *desc_prefix,
		       const char *val_str,
		       const char *val_prefix)
{
  /* If val_str is NULL, fail with a custom error message.  */
  if (val_str == NULL)
    fail_formatted (loc, "ASSERT_STR_STARTSWITH (%s, %s) str=NULL",
		    desc_str, desc_prefix);

  /* If val_prefix is NULL, fail with a custom error message.  */
  if (val_prefix == NULL)
    fail_formatted (loc,
		    "ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=NULL",
		    desc_str, desc_prefix, val_str);

  const char *test = strstr (val_str, val_prefix);
  if (test == val_str)
    pass (loc, "ASSERT_STR_STARTSWITH");
  else
    fail_formatted
	(loc, "ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=\"%s\"",
	 desc_str, desc_prefix, val_str, val_prefix);
}


/* Constructor.  Generate a name for the file.  */

named_temp_file::named_temp_file (const char *suffix)
{
  m_filename = make_temp_file (suffix);
  ASSERT_NE (m_filename, NULL);
}

/* Destructor.  Delete the tempfile.  */

named_temp_file::~named_temp_file ()
{
  unlink (m_filename);
  diagnostics_file_cache_forcibly_evict_file (m_filename);
  free (m_filename);
}

/* Constructor.  Create a tempfile using SUFFIX, and write CONTENT to
   it.  Abort if anything goes wrong, using LOC as the effective
   location in the problem report.  */

temp_source_file::temp_source_file (const location &loc,
				    const char *suffix,
				    const char *content)
: named_temp_file (suffix)
{
  FILE *out = fopen (get_filename (), "w");
  if (!out)
    fail_formatted (loc, "unable to open tempfile: %s", get_filename ());
  fprintf (out, "%s", content);
  fclose (out);
}

/* Avoid introducing locale-specific differences in the results
   by hardcoding open_quote and close_quote.  */

auto_fix_quotes::auto_fix_quotes ()
{
  m_saved_open_quote = open_quote;
  m_saved_close_quote = close_quote;
  open_quote = "`";
  close_quote = "'";
}

/* Restore old values of open_quote and close_quote.  */

auto_fix_quotes::~auto_fix_quotes ()
{
  open_quote = m_saved_open_quote;
  close_quote = m_saved_close_quote;
}

/* Read the contents of PATH into memory, returning a 0-terminated buffer
   that must be freed by the caller.
   Fail (and abort) if there are any problems, with LOC as the reported
   location of the failure.  */

char *
read_file (const location &loc, const char *path)
{
  FILE *f_in = fopen (path, "r");
  if (!f_in)
    fail_formatted (loc, "unable to open file: %s", path);

  /* Read content, allocating FIXME.  */
  char *result = NULL;
  size_t total_sz = 0;
  size_t alloc_sz = 0;
  char buf[4096];
  size_t iter_sz_in;

  while ( (iter_sz_in = fread (buf, 1, sizeof (buf), f_in)) )
    {
      gcc_assert (alloc_sz >= total_sz);
      size_t old_total_sz = total_sz;
      total_sz += iter_sz_in;
      /* Allow 1 extra byte for 0-termination.  */
      if (alloc_sz < (total_sz + 1))
	{
	  size_t new_alloc_sz = alloc_sz ? alloc_sz * 2: total_sz + 1;
	  result = (char *)xrealloc (result, new_alloc_sz);
	  alloc_sz = new_alloc_sz;
	}
      memcpy (result + old_total_sz, buf, iter_sz_in);
    }

  if (!feof (f_in))
    fail_formatted (loc, "error reading from %s: %s", path,
		    xstrerror (errno));

  fclose (f_in);

  /* 0-terminate the buffer.  */
  gcc_assert (total_sz < alloc_sz);
  result[total_sz] = '\0';

  return result;
}

/* The path of SRCDIR/testsuite/selftests.  */

const char *path_to_selftest_files = NULL;

/* Convert a path relative to SRCDIR/testsuite/selftests
   to a real path (either absolute, or relative to pwd).
   The result should be freed by the caller.  */

char *
locate_file (const char *name)
{
  ASSERT_NE (NULL, path_to_selftest_files);
  return concat (path_to_selftest_files, "/", name, NULL);
}

/* selftest::test_runner's ctor.  */

test_runner::test_runner (const char *name)
: m_name (name),
  m_start_time (get_run_time ())
{
}

/* selftest::test_runner's dtor.  Print a summary line to stderr.  */

test_runner::~test_runner ()
{
  /* Finished running tests.  */
  long finish_time = get_run_time ();
  long elapsed_time = finish_time - m_start_time;

  fprintf (stderr,
	   "%s: %i pass(es) in %ld.%06ld seconds\n",
	   m_name, num_passes,
	   elapsed_time / 1000000, elapsed_time % 1000000);
}

/* Selftests for libiberty.  */

/* Verify that xstrndup generates EXPECTED when called on SRC and N.  */

static void
assert_xstrndup_eq (const char *expected, const char *src, size_t n)
{
  char *buf = xstrndup (src, n);
  ASSERT_STREQ (expected, buf);
  free (buf);
}

/* Verify that xstrndup works as expected.  */

static void
test_xstrndup ()
{
  assert_xstrndup_eq ("", "test", 0);
  assert_xstrndup_eq ("t", "test", 1);
  assert_xstrndup_eq ("te", "test", 2);
  assert_xstrndup_eq ("tes", "test", 3);
  assert_xstrndup_eq ("test", "test", 4);
  assert_xstrndup_eq ("test", "test", 5);

  /* Test on an string without zero termination.  */
  const char src[4] = {'t', 'e', 's', 't'};
  assert_xstrndup_eq ("", src, 0);
  assert_xstrndup_eq ("t", src, 1);
  assert_xstrndup_eq ("te", src, 2);
  assert_xstrndup_eq ("tes", src, 3);
  assert_xstrndup_eq ("test", src, 4);
}

/* Run selftests for libiberty.  */

static void
test_libiberty ()
{
  test_xstrndup ();
}

/* Selftests for the selftest system itself.  */

/* Sanity-check the ASSERT_ macros with various passing cases.  */

static void
test_assertions ()
{
  ASSERT_TRUE (true);
  ASSERT_FALSE (false);
  ASSERT_EQ (1, 1);
  ASSERT_EQ_AT (SELFTEST_LOCATION, 1, 1);
  ASSERT_NE (1, 2);
  ASSERT_GT (2, 1);
  ASSERT_GT_AT (SELFTEST_LOCATION, 2, 1);
  ASSERT_LT (1, 2);
  ASSERT_LT_AT (SELFTEST_LOCATION, 1, 2);
  ASSERT_STREQ ("test", "test");
  ASSERT_STREQ_AT (SELFTEST_LOCATION, "test", "test");
  ASSERT_STR_CONTAINS ("foo bar baz", "bar");
}

/* Verify named_temp_file.  */

static void
test_named_temp_file ()
{
  named_temp_file t (".txt");
  FILE *f = fopen (t.get_filename (), "w");
  if (!f)
    fail_formatted (SELFTEST_LOCATION,
		    "unable to open %s for writing", t.get_filename ());
  fclose (f);
}

/* Verify read_file (and also temp_source_file).  */

static void
test_read_file ()
{
  temp_source_file t (SELFTEST_LOCATION, "test1.s",
		      "\tjmp\t.L2\n");
  char *buf = read_file (SELFTEST_LOCATION, t.get_filename ());
  ASSERT_STREQ ("\tjmp\t.L2\n", buf);
  free (buf);
}

/* Verify locate_file (and read_file).  */

static void
test_locate_file ()
{
  char *path = locate_file ("example.txt");
  char *buf = read_file (SELFTEST_LOCATION, path);
  ASSERT_STREQ ("example of a selftest file\n", buf);
  free (buf);
  free (path);
}

/* Run all of the selftests within this file.  */

void
selftest_c_tests ()
{
  test_libiberty ();
  test_assertions ();
  test_named_temp_file ();
  test_read_file ();
  test_locate_file ();
}

} // namespace selftest

#endif /* #if CHECKING_P */
