You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
7.4 KiB
330 lines
7.4 KiB
4 months ago
|
/*
|
||
|
* Localized printf/puts functions for CUPS.
|
||
|
*
|
||
|
* Copyright 2007-2014 by Apple Inc.
|
||
|
* Copyright 2002-2007 by Easy Software Products.
|
||
|
*
|
||
|
* Licensed under Apache License v2.0. See the file "LICENSE" for more information.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Include necessary headers...
|
||
|
*/
|
||
|
|
||
|
#include "cups-private.h"
|
||
|
#include "debug-internal.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);
|
||
|
}
|
||
|
}
|
||
|
}
|