170 lines
3.6 KiB
C
170 lines
3.6 KiB
C
/* SPDX-License-Identifier: BSD-2-Clause */
|
|
#define _GNU_SOURCE
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <dirent.h>
|
|
#include <time.h>
|
|
#include <locale.h>
|
|
#include <langinfo.h>
|
|
#include <wchar.h>
|
|
|
|
struct lc_msg_t {
|
|
char locale[64];
|
|
char yesstr[256];
|
|
char nostr[256];
|
|
char yesexpr[256];
|
|
char noexpr[256];
|
|
} msg[512];
|
|
int mcnt = 0;
|
|
|
|
char *
|
|
xfrm_utf (const wchar_t *ws)
|
|
{
|
|
static char xfrm[256];
|
|
char *p = xfrm;
|
|
int wconst = 0;
|
|
|
|
while (*ws)
|
|
{
|
|
if (*ws < 0x80 && (!wconst || !wcschr (L"aAbBcCdDeEfF", *ws)))
|
|
{
|
|
*p++ = *ws;
|
|
wconst = 0;
|
|
}
|
|
else
|
|
{
|
|
p += sprintf (p, "\\x%04lx", *ws);
|
|
wconst = 1;
|
|
}
|
|
++ws;
|
|
}
|
|
*p = '\0';
|
|
return xfrm;
|
|
}
|
|
|
|
void
|
|
read_locale_messages (char *name)
|
|
{
|
|
char *nl;
|
|
char locale[64];
|
|
wchar_t nlbuf[256];
|
|
|
|
strcpy (locale, name);
|
|
nl = strchr (locale, '@');
|
|
if (nl)
|
|
stpcpy (stpcpy (nl, ".utf8"), strchr (name, '@'));
|
|
else
|
|
strcat (locale, ".utf8");
|
|
printf ("%s\n", locale);
|
|
setlocale (LC_ALL, locale);
|
|
|
|
strcpy (msg[mcnt].locale, name);
|
|
nl = nl_langinfo (YESSTR);
|
|
mbstowcs (nlbuf, nl, 256);
|
|
strcpy (msg[mcnt].yesstr, xfrm_utf (nlbuf));
|
|
nl = nl_langinfo (NOSTR);
|
|
mbstowcs (nlbuf, nl, 256);
|
|
strcpy (msg[mcnt].nostr, xfrm_utf (nlbuf));
|
|
nl = nl_langinfo (YESEXPR);
|
|
mbstowcs (nlbuf, nl, 256);
|
|
strcpy (msg[mcnt].yesexpr, xfrm_utf (nlbuf));
|
|
nl = nl_langinfo (NOEXPR);
|
|
mbstowcs (nlbuf, nl, 256);
|
|
strcpy (msg[mcnt].noexpr, xfrm_utf (nlbuf));
|
|
/* Serbian locale rename weirdness */
|
|
if (!strncmp (msg[mcnt].locale, "sr_RS", 5))
|
|
{
|
|
/* Create additional equivalent entry for the old locale sr_SP. */
|
|
++mcnt;
|
|
memcpy (&msg[mcnt], &msg[mcnt - 1], sizeof msg[mcnt]);
|
|
msg[mcnt].locale[3] = 'S';
|
|
msg[mcnt].locale[4] = 'P';
|
|
/* Create additional equivalent entry for sr_ME@latin missing in Linux. */
|
|
if (!strcmp (msg[mcnt].locale, "sr_SP@latin"))
|
|
{
|
|
++mcnt;
|
|
memcpy (&msg[mcnt], &msg[mcnt - 1], sizeof msg[mcnt]);
|
|
msg[mcnt].locale[3] = 'M';
|
|
msg[mcnt].locale[4] = 'E';
|
|
}
|
|
}
|
|
++mcnt;
|
|
}
|
|
|
|
int
|
|
locale_cmp (const void *a, const void *b)
|
|
{
|
|
struct lc_msg_t *la = (struct lc_msg_t *) a;
|
|
struct lc_msg_t *lb = (struct lc_msg_t *) b;
|
|
return strcmp (la->locale, lb->locale);
|
|
}
|
|
|
|
void
|
|
create_list ()
|
|
{
|
|
FILE *fp = fopen ("lc_msg.h", "w");
|
|
FILE *pp = popen ("rpm -q glibc", "r");
|
|
char vers[64];
|
|
int i;
|
|
struct tm *tm;
|
|
time_t tim;
|
|
char tstr[64];
|
|
|
|
fgets (vers, 64, pp);
|
|
pclose (pp);
|
|
if (strchr (vers, '\n'))
|
|
*strchr (vers, '\n') = '\0';
|
|
tim = time (NULL);
|
|
tm = gmtime (&tim);
|
|
strftime (tstr, 64, "%F", tm);
|
|
fprintf (fp,
|
|
"/* This struct of LC_MESSAGES data has been generated by fetching locale\n"
|
|
" data from a Linux system using %s on %s. */\n"
|
|
"\n"
|
|
"struct lc_msg_t\n"
|
|
"{\n"
|
|
" const char *locale;\n"
|
|
" const wchar_t *yesexpr;\n"
|
|
" const wchar_t *noexpr;\n"
|
|
" const wchar_t *yesstr;\n"
|
|
" const wchar_t *nostr;\n"
|
|
"};\n"
|
|
"\n"
|
|
"static struct lc_msg_t lc_msg[] =\n"
|
|
"{\n", vers, tstr);
|
|
|
|
qsort (msg, mcnt, sizeof (struct lc_msg_t), locale_cmp);
|
|
for (i = 0; i < mcnt; ++i)
|
|
fprintf (fp, " { \"%s\", L\"%s\", L\"%s\", L\"%s\", L\"%s\" },\n",
|
|
msg[i].locale,
|
|
msg[i].yesexpr, msg[i].noexpr,
|
|
msg[i].yesstr, msg[i].nostr);
|
|
fputs ("};\n", fp);
|
|
fclose (fp);
|
|
}
|
|
|
|
int
|
|
main ()
|
|
{
|
|
char name[32], *c;
|
|
FILE *pp;
|
|
|
|
pp = popen ("locale -a | grep -a '_' | grep -F -v .", "r");
|
|
if (!pp)
|
|
{
|
|
perror ("popen failed");
|
|
return 1;
|
|
}
|
|
while (fgets (name, 32, pp))
|
|
{
|
|
c = strchr (name, '\n');
|
|
if (c)
|
|
*c = '\0';
|
|
read_locale_messages (name);
|
|
}
|
|
pclose (pp);
|
|
create_list ();
|
|
return 0;
|
|
}
|