/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1989-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* locale command
*/
static const char usage[] =
"[-?\n@(#)$Id: locale (AT&T Research) 2009-10-21 $\n]"
"[+NAME?locale - get locale-specific information]"
"[+DESCRIPTION?\blocale\b writes information about the current locale to"
" the standard output. If no options or operands are specified then the"
" environment for each locale category is summarized. If operands are"
" spcified then information is written about each operand: a locale"
" category name operand (\fcategories\f) selects all keywords in that"
" category; other operands name keywords within a category. Keyword"
" names are unique across all categories, so there is no ambiguity."
" \acategory=value\a operands set the corresponding locale \acategory\a"
" to \avalue\a by a call to \bsetlocale\b(3). A \avalue\a of \b-\b is"
" interpreted as \bNULL\b, allowing \acategory\a to be queried. The"
" \bTEST\b category converts the \avalue\a locale name to a canonical"
" form and lists the converted name on the standard output.]"
"[+?If the \b--all\b or \b--undefined\b options are specified and no operands"
" are specified then the names of all defined locales are listed on the"
" standard output. A \adefined\a locale name should work as an argument"
" to \bsetlocale\b(3). An \aundefined\a name is valid but not supported"
" on the local system. Locale names have the general form"
" \alanguage\a_\aterritory\a.\acharset\a@\aattribute\a[,\aattribute\a]]*"
" At least one of \alanguage\a or \aterritory\a is always specified, the"
" other parts are optional. The \b--abbreviated\b, \b--qualified\b,"
" \b--verbose\b and \b--local\b options determine the locale name"
" listing style. The default is \b--abbreviated\b. If multiple styles"
" are specified then the names are listed in columns in this order:"
" \babbreviated\b, \bqualified\b, \bverbose\b and \blocal\b.]"
"[a:all?List all defined locale names on the standard output.]"
"[b:abbreviated?List abbreviated locale names: \alanguage\a and \aterritory\a"
" as the two character ISO codes; non-default \acharset\a and"
" \aattributes\a. This is the default.]"
"[c:category?List the category names for each operand on the standard output.]"
"[e:element?The operands are interpreted as collation elements. Each element"
" name is listed on the standard output followed by a \btab\b character"
" and the space separated list of \bstrxfrm\b(3) collation weights.]"
"[i:indent?Indent keyword output lines for readability.]"
"[k:keyword?List the keyword name for each operand on the standard output.]"
"[l:local?List the locale names returned by the local system \bsetlocale\b(3)."
" NOTE: these names may contain embedded space.]"
"[m:charmaps?List the names of available charmaps.]"
"[q:qualified?List qualified locale names: \alanguage\a and \aterritory\a"
" as the two character ISO codes; default and non-default \acharset\a and"
" \aattributes\a.]"
"[t:composite?List the composite value of LC_ALL on the standard output.]"
"[u:undefined?List all undefined locale names on the standard output.]"
"[v:verbose?List verbose locale names: \alanguage\a and \aterritory\a"
" as the long English strings; non-default \acharset\a and"
" \aattributes\a.]"
"[x:transform?The operands are interpreted as strings. Each string is listed"
" on the standard output followed by a \btab\b character and the"
" space separated list of \bstrxfrm\b(3) collation weights.]"
"\n"
"\n[ name | name=value ... ]\n"
"\n"
"[+SEE ALSO?\blocaleconv\b(3), \bnl_langinfo\b(3), \bsetlocale\b(3)]"
;
#include <ast.h>
#include <cdt.h>
#include <ctype.h>
#include <error.h>
#include <lc.h>
#include <tm.h>
#include <regex.h>
#include <proc.h>
#if _hdr_nl_types && _hdr_langinfo
#include <nl_types.h>
#include <langinfo.h>
#else
#endif
typedef struct Keyword_s
{
const char* name;
int index;
int type;
int elements;
long offset;
} Keyword_t;
#define C 1
#define I 4
#define N 3
#define S 0
#define X 5
#ifdef NOEXPR
#else
#endif
#ifdef NOSTR
#else
#endif
#ifdef YESEXPR
#else
#endif
#ifdef YESSTR
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#define T_language N
#else
#define T_language X
#endif
#define T_territory N
#else
#define T_territory X
#endif
#define T_attributes N
#else
#define T_attributes X
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#else
#endif
#ifndef MB_CUR_MIN
#endif
{
};
static struct State_s
{
int all;
int output;
int sep;
} state;
/*
* list the locale name(s) for lc according to flags
*/
static void
{
register int i;
int n;
char* fmt;
char* sep;
n = 0;
for (i = 0; i < elementsof(types); i++)
n++;
if (!n)
{
n++;
flags |= LC_abbreviated;
}
n = n == 1;
if (key)
{
{
n = 0;
}
{
n = 0;
}
}
sep = "";
for (i = 0; i < elementsof(types); i++)
{
return;
sep = ";";
}
}
/*
* print the numeric value i for key
*/
static void
{
if (flags & LC_keyword)
else
}
/*
* print one string value, possibly quoted and converted to upper case
*/
static void
{
register int c;
register int u;
{
return;
}
while (c = *s++)
{
if (islower(c))
c = toupper(c);
}
{
u = 1;
while (c = *s++)
{
if (!isalnum(c))
u = 1;
else
{
if (u && islower(c))
c = toupper(c);
u = 0;
}
}
}
else
}
/*
* print the string value(s) v[n] for key
*/
static void
{
char** e;
register const Lc_attribute_list_t* a;
if (flags & LC_keyword)
if (n)
{
e = v + n - 1;
while (v++ < e)
{
}
}
else if (v && (a = *((Lc_attribute_list_t**)v)))
{
while (a = a->next)
{
}
}
}
/*
* extact and list info for key with base info at data
*/
static void
{
register int i;
char* s;
char** v;
{
case C:
else
i = CHAR_MAX;
if (i == CHAR_MAX)
i = -1;
break;
case I:
else
i = -1;
break;
case N:
#if _lib_nl_langinfo
{
/*
* redhat decided to change the nl_langinfo()
* return value after umpteen years of stability
* to optionally return an int for some numeric
* values -- botch botch botch
*/
if (((unsigned int)s) < 8196)
{
s = xxx;
}
#endif
}
else
#endif
s = "";
break;
case S:
{
}
else
{
s = "";
v = &s;
i = 1;
}
break;
case X:
i = 1;
{
}
{
}
{
s = (char*)lc->attributes;
i = 0;
}
else
s = "";
break;
}
}
/*
* list LC_ALL info
*/
static void
{
if (!lc)
else
if (flags & LC_category)
if (flags & LC_keyword)
{
}
}
/*
* list info for key
*/
static void
{
register int i;
register int j;
register int n;
register unsigned int f;
char* s;
{
case AST_LC_COLLATE:
break;
case AST_LC_CTYPE:
{
case CV_charset:
break;
case CV_mb_cur_max:
break;
case CV_mb_cur_min:
break;
}
break;
case AST_LC_MONETARY:
case AST_LC_NUMERIC:
break;
case AST_LC_ADDRESS:
case AST_LC_IDENTIFICATION:
case AST_LC_MEASUREMENT:
case AST_LC_MESSAGES:
case AST_LC_NAME:
case AST_LC_PAPER:
case AST_LC_TELEPHONE:
case AST_LC_TIME:
break;
case AST_LC_ALL:
if (value)
{
value = 0;
}
else
{
{
{
break;
}
i = 1;
n = AST_LC_COUNT - 1;
}
else
for (; i <= n; i++)
{
f = flags;
for (j = 0; j < elementsof(keywords); j++)
{
f &= ~LC_category;
}
}
}
break;
case TEST:
if (!value)
else
{
value = 0;
}
break;
}
}
/*
* scan all locales matching flags
*/
static int
{
{
{
case LC_defined:
continue;
break;
case LC_undefined:
continue;
break;
}
if (!key)
}
return 0;
}
int
{
register char* name;
register char* s;
register int i;
register unsigned int flags;
int collate;
int composite;
int transform;
int j;
char* value;
char** oargv;
flags = 0;
collate = 0;
composite = 0;
transform = 0;
for (;;)
{
{
case 'a':
flags |= LC_defined;
continue;
case 'b':
flags |= LC_abbreviated;
continue;
case 'c':
flags |= LC_category;
continue;
case 'e':
collate = 1;
continue;
case 'i':
continue;
case 'k':
flags |= LC_keyword;
continue;
case 'l':
continue;
case 'm':
case 'q':
flags |= LC_qualified;
continue;
case 't':
composite = 1;
continue;
case 'u':
flags |= LC_undefined;
continue;
case 'v':
flags |= LC_verbose;
continue;
case 'x':
transform = 1;
continue;
case '?':
break;
case ':':
break;
}
break;
}
if (error_info.errors)
if (collate)
{
{
{
continue;
}
{
if (i > 1)
{
continue;
}
collate = i;
}
else if (i > 1)
{
buf[1] = 0;
{
continue;
}
}
}
return error_info.errors != 0;
}
if (composite)
{
return error_info.errors != 0;
}
if (transform)
{
{
}
return error_info.errors != 0;
}
if (!*argv)
{
{
flags |= LC_abbreviated;
}
if (!flags)
{
name = "LANG";
if (!(s = getenv("LANG")))
s = "POSIX";
for (i = 1; i < AST_LC_COUNT; i++)
{
sfprintf(sfstdout, "%s=%s\n", state.categories[i].name, fmtquote(s, "\"", "\"", strlen(s), (value || !getenv(state.categories[i].name)) ? FMT_ALWAYS : 0));
}
if (value)
{
}
return 0;
}
}
for (i = 0; i < elementsof(keywords); i++)
for (i = 0; i < AST_LC_COUNT; i++)
{
}
{
*value++ = 0;
{
else if (oargv[0][0] != '/')
{
cmd[2] = 0;
}
else
}
else
}
return error_info.errors != 0;
}