/*
 * Localized printf/puts functions for CUPS.
 *
 * Copyright 2007-2014 by Apple Inc.
 * Copyright 2002-2007 by Easy Software Products.
 *
 * These coded instructions, statements, and computer programs are the
 * property of Apple Inc. and are protected by Federal copyright
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
 * which should have been included with this file.  If this file is
 * missing or damaged, see the license at "http://www.cups.org/".
 *
 * This file is subject to the Apple OS-Developed Software exception.
 */

/*
 * Include necessary headers...
 */

#include "cups-private.h"


/*
 * '_cupsLangPrintError()' - Print a message followed by a standard error.
 */

void
_cupsLangPrintError(const char *prefix,	/* I - Non-localized message prefix */
                    const char *message)/* I - Message */
{
  ssize_t	bytes;			/* Number of bytes formatted */
  int		last_errno;		/* Last error */
  char		buffer[2048],		/* Message buffer */
		*bufptr,		/* Pointer into buffer */
		output[8192];		/* Output buffer */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!message)
    return;

 /*
  * Save the errno value...
  */

  last_errno = errno;

 /*
  * Get the message catalog...
  */

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Format the message...
  */

  if (prefix)
  {
    snprintf(buffer, sizeof(buffer), "%s:", prefix);
    bufptr = buffer + strlen(buffer);
  }
  else
    bufptr = buffer;

  snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer),
	   /* TRANSLATORS: Message is "subject: error" */
	   _cupsLangString(cg->lang_default, _("%s: %s")),
	   _cupsLangString(cg->lang_default, message), strerror(last_errno));
  strlcat(buffer, "\n", sizeof(buffer));

 /*
  * Convert and write to stderr...
  */

  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
                            cg->lang_default->encoding);

  if (bytes > 0)
    fwrite(output, 1, (size_t)bytes, stderr);
}


/*
 * '_cupsLangPrintFilter()' - Print a formatted filter message string to a file.
 */

int					/* O - Number of bytes written */
_cupsLangPrintFilter(
    FILE       *fp,			/* I - File to write to */
    const char *prefix,			/* I - Non-localized message prefix */
    const char *message,		/* I - Message string to use */
    ...)				/* I - Additional arguments as needed */
{
  ssize_t	bytes;			/* Number of bytes formatted */
  char		temp[2048],		/* Temporary format buffer */
		buffer[2048],		/* Message buffer */
		output[8192];		/* Output buffer */
  va_list 	ap;			/* Pointer to additional arguments */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!fp || !message)
    return (-1);

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Format the string...
  */

  va_start(ap, message);
  snprintf(temp, sizeof(temp), "%s: %s\n", prefix,
	   _cupsLangString(cg->lang_default, message));
  vsnprintf(buffer, sizeof(buffer), temp, ap);
  va_end(ap);

 /*
  * Transcode to the destination charset...
  */

  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
                            cg->lang_default->encoding);

 /*
  * Write the string and return the number of bytes written...
  */

  if (bytes > 0)
    return ((int)fwrite(output, 1, (size_t)bytes, fp));
  else
    return ((int)bytes);
}


/*
 * '_cupsLangPrintf()' - Print a formatted message string to a file.
 */

int					/* O - Number of bytes written */
_cupsLangPrintf(FILE       *fp,		/* I - File to write to */
		const char *message,	/* I - Message string to use */
	        ...)			/* I - Additional arguments as needed */
{
  ssize_t	bytes;			/* Number of bytes formatted */
  char		buffer[2048],		/* Message buffer */
		output[8192];		/* Output buffer */
  va_list 	ap;			/* Pointer to additional arguments */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!fp || !message)
    return (-1);

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Format the string...
  */

  va_start(ap, message);
  vsnprintf(buffer, sizeof(buffer) - 1,
	    _cupsLangString(cg->lang_default, message), ap);
  va_end(ap);

  strlcat(buffer, "\n", sizeof(buffer));

 /*
  * Transcode to the destination charset...
  */

  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
                            cg->lang_default->encoding);

 /*
  * Write the string and return the number of bytes written...
  */

  if (bytes > 0)
    return ((int)fwrite(output, 1, (size_t)bytes, fp));
  else
    return ((int)bytes);
}


/*
 * '_cupsLangPuts()' - Print a static message string to a file.
 */

int					/* O - Number of bytes written */
_cupsLangPuts(FILE       *fp,		/* I - File to write to */
              const char *message)	/* I - Message string to use */
{
  ssize_t	bytes;			/* Number of bytes formatted */
  char		output[8192];		/* Message buffer */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!fp || !message)
    return (-1);

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Transcode to the destination charset...
  */

  bytes = cupsUTF8ToCharset(output,
			    (cups_utf8_t *)_cupsLangString(cg->lang_default,
							   message),
			    sizeof(output) - 4, cg->lang_default->encoding);
  bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n", (int)(sizeof(output) - (size_t)bytes), cg->lang_default->encoding);

 /*
  * Write the string and return the number of bytes written...
  */

  if (bytes > 0)
    return ((int)fwrite(output, 1, (size_t)bytes, fp));
  else
    return ((int)bytes);
}


/*
 * '_cupsSetLocale()' - Set the current locale and transcode the command-line.
 */

void
_cupsSetLocale(char *argv[])		/* IO - Command-line arguments */
{
  int		i;			/* Looping var */
  char		buffer[8192];		/* Command-line argument buffer */
  _cups_globals_t *cg;			/* Global data */
#ifdef LC_TIME
  const char	*lc_time;		/* Current LC_TIME value */
  char		new_lc_time[255],	/* New LC_TIME value */
		*charset;		/* Pointer to character set */
#endif /* LC_TIME */


 /*
  * Set the locale so that times, etc. are displayed properly.
  *
  * Unfortunately, while we need the localized time value, we *don't*
  * want to use the localized charset for the time value, so we need
  * to set LC_TIME to the locale name with .UTF-8 on the end (if
  * the locale includes a character set specifier...)
  */

  setlocale(LC_ALL, "");

#ifdef LC_TIME
  if ((lc_time = setlocale(LC_TIME, NULL)) == NULL)
    lc_time = setlocale(LC_ALL, NULL);

  if (lc_time)
  {
    strlcpy(new_lc_time, lc_time, sizeof(new_lc_time));
    if ((charset = strchr(new_lc_time, '.')) == NULL)
      charset = new_lc_time + strlen(new_lc_time);

    strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (size_t)(charset - new_lc_time));
  }
  else
    strlcpy(new_lc_time, "C", sizeof(new_lc_time));

  setlocale(LC_TIME, new_lc_time);
#endif /* LC_TIME */

 /*
  * Initialize the default language info...
  */

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Transcode the command-line arguments from the locale charset to
  * UTF-8...
  */

  if (cg->lang_default->encoding != CUPS_US_ASCII &&
      cg->lang_default->encoding != CUPS_UTF8)
  {
    for (i = 1; argv[i]; i ++)
    {
     /*
      * Try converting from the locale charset to UTF-8...
      */

      if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer),
                            cg->lang_default->encoding) < 0)
        continue;

     /*
      * Save the new string if it differs from the original...
      */

      if (strcmp(buffer, argv[i]))
        argv[i] = strdup(buffer);
    }
  }
}
