/* ========================================================================== */
/*! \file
 * \brief Test of \c posix_strcasecmp_l() implementation
 *
 * Copyright (c) 2015-2020 by the developers. See the LICENSE file for details.
 */


/* ========================================================================== */
/* Include headers */

#include "posix.h"  /* Include this first because of feature test macros */

#include <stdio.h>

#include "config.h"

#include "test.h"
#include "test_strcasecmp_l.h"


/* ========================================================================== */
/*! \addtogroup TEST */
/*! @{ */


/* ========================================================================== */
/*! \brief Test \c posix_strcasecmp_l() implementation
 *
 * The following cases are tested using POSIX locale:
 * - Identical ASCII strings (equal, trivial case)
 * - Different strings with same length (not equal)
 * - First string longer (not equal)
 * - Second string longer (not equal)
 * - Strings that only differ in case of ASCII letters (equal)
 * - Unicode strings with non-ASCII characters that only differ in their case
 *   (not equal in POSIX locale)
 *
 * \return
 * - \c EXIT_SUCCESS on success
 * - \c EXIT_FAILURE on error
 */

int  test_strcasecmp_l(void)
{
   int  res = POSIX_EXIT_SUCCESS;
   posix_locale_t  loc_ctype_posix;
   const char*  string1_1 = "x1: 10, y2: 50%, eol";
   const char*  string1_2 = "x1: 10, y2: 50%, eol";
   const char*  string2_1 = "XXX";
   const char*  string2_2 = "YYY";
   const char*  string3_1 = "Longer";
   const char*  string3_2 = "Long";
   const char*  string4_1 = "Long";
   const char*  string4_2 = "Longer";
   const char*  string5_1 = "case";
   const char*  string5_2 = "Case";
   const char*  string6_1 = "B\xC3\xA4ume";
   const char*  string6_2 = "B\xC3\x84ume";
   int  rv;
   const char*  loc;

   /* Create a locale object with LC_CTYPE == POSIX */
   loc_ctype_posix = posix_newlocale(POSIX_LC_CTYPE_MASK, "POSIX",
                                     (posix_locale_t) 0);
   if((posix_locale_t) 0 == loc_ctype_posix)
   {
      print_error("Creation of locale object failed");
      res = POSIX_EXIT_FAILURE;
   }

   if(!res)
   {
      /*
       * This test the following things:
       * - Identical strings (trivial case)
       */
      rv = posix_strcasecmp_l(string1_1, string1_2, loc_ctype_posix);
      if(rv)
      {
         print_error("Result is not correct (should indicate match)");
         res = POSIX_EXIT_FAILURE;
      }
      if(res)
      {
         /* For debugging */
         fprintf(stderr, TEST_TAB "String 1: \"%s\"\n", string1_1);
         fprintf(stderr, TEST_TAB "String 2: \"%s\"\n", string1_2);
      }
   }

   if(!res)
   {
      /*
       * This test the following things:
       * - Different strings with same length
       */
      rv = posix_strcasecmp_l(string2_1, string2_2, loc_ctype_posix);
      if(!rv)
      {
         print_error("Result is not correct (should indicate no match)");
         res = POSIX_EXIT_FAILURE;
      }
      if(res)
      {
         /* For debugging */
         fprintf(stderr, TEST_TAB "String 1: \"%s\"\n", string2_1);
         fprintf(stderr, TEST_TAB "String 2: \"%s\"\n", string2_2);
      }
   }

   if(!res)
   {
      /*
       * This test the following things:
       * - First string longer
       */
      rv = posix_strcasecmp_l(string3_1, string3_2, loc_ctype_posix);
      if(!rv)
      {
         print_error("Result is not correct (should indicate no match)");
         res = POSIX_EXIT_FAILURE;
      }
      if(res)
      {
         /* For debugging */
         fprintf(stderr, TEST_TAB "String 1: \"%s\"\n", string3_1);
         fprintf(stderr, TEST_TAB "String 2: \"%s\"\n", string3_2);
      }
   }

   if(!res)
   {
      /*
       * This test the following things:
       * - Second string longer
       */
      rv = posix_strcasecmp_l(string4_1, string4_2, loc_ctype_posix);
      if(!rv)
      {
         print_error("Result is not correct (should indicate no match)");
         res = POSIX_EXIT_FAILURE;
      }
      if(res)
      {
         /* For debugging */
         fprintf(stderr, TEST_TAB "String 1: \"%s\"\n", string4_1);
         fprintf(stderr, TEST_TAB "String 2: \"%s\"\n", string4_2);
      }
   }

   if(!res)
   {
      /*
       * This test the following things:
       * - Strings that only differ in case of ASCII letters
       */
      rv = posix_strcasecmp_l(string5_1, string5_2, loc_ctype_posix);
      if(rv)
      {
         print_error("Result is not correct (should indicate match)");
         res = POSIX_EXIT_FAILURE;
      }
      if(res)
      {
         /* For debugging */
         fprintf(stderr, TEST_TAB "String 1: \"%s\"\n", string5_1);
         fprintf(stderr, TEST_TAB "String 2: \"%s\"\n", string5_2);
      }
   }

   if(!res)
   {
      /*
       * This test the following things:
       * - Unicode strings with non-ASCII characters that only differ in their
       *   case
       */
      rv = posix_strcasecmp_l(string6_1, string6_2, loc_ctype_posix);
      if(!rv)
      {
         print_error("Result is not correct (should indicate no match)");
         res = POSIX_EXIT_FAILURE;
      }
      if(res)
      {
         /* For debugging */
#if CFG_USE_POSIX_API >= 200112 || CFG_USE_XSI
         loc = posix_setlocale(POSIX_LC_CTYPE, "");
#else  /* CFG_USE_POSIX_API >= 200112 || CFG_USE_XSI */
         loc = NULL;
#endif  /* CFG_USE_POSIX_API >= 200112 || CFG_USE_XSI */
         if(NULL == loc)
         {
            print_error("Setting locale for debug messages failed");
         }
         else
         {
            /* Print Unicode data only if terminal use Unicode locale */
            if(NULL == strstr(loc, "UTF") && NULL == strstr(loc, "utf"))
            {
               print_error(
                  "Debug messages can't be printed with current locale");
            }
            else
            {
               /* For debugging */
               fprintf(stderr, TEST_TAB "String 1: \"%s\"\n", string6_1);
               fprintf(stderr, TEST_TAB "String 2: \"%s\"\n", string6_2);
            }
         }
      }
   }

   /* Free memory of locale object */
   posix_freelocale(loc_ctype_posix);

   return(res);
}


/*! @} */

/* EOF */
