📄 setlocale.c
字号:
#ifndef lintstatic char Sccsid[] = "@(#)setlocale.c 4.1 (ULTRIX) 7/3/90";#endif /* lint *//************************************************************************ * * * Copyright (c) 1987,1988,1989 by * * Digital Equipment Corporation, Maynard, MA * * Bull, France * * Siemens AG, FR Germany * * All rights reserved. * * * * This software is furnished under license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * * File name: setlocale.c * * Source file description: * This file implements the ANSI setlocale() function. This is done * by mapping onto the underlying base functions i_init() and i_ld*(). * Setlocale() is also called by the X/OPEN function nl_init(). * * Functions: * setlocale() * *//* * Modification history * ~~~~~~~~~~~~~~~~~~~~ * * 004 Dan Smith Feb 26, 1990 * Defined localeconv function. Removed spurious check for C locale * in setuptable(). Added code to set _pctype_siz which is the * size of the _pctype table. This is used by the multi-byte to * wide character functions. * * 003 Wendy Rannenberg Jan 25, 1990 * - Fixed up pointers to dbheaders so alternate property, * collation, and string tables could be accessed. * * 002 David Lindner Thu Jan 4 11:15:15 EST 1990 * - Modified setlocale so default language definitions could be * specified with LANG environment variable. * * 001 MRH 25-Sep-1987 * - Updated to current ANSI & X/OPEN standards. * * 000 ARG 3-Mar-1987 * - Created. * */#include <i_defs.h>#include <locale.h>#include <limits.h>#include <ctype.h> /* for definitions of tables */#include <langinfo.h>#define CNULL (char *)0#define SEPCH '\001'#define SEPSTR "\001"#define FALSE 0#define TRUE 1/* * setlocale -- set the program's locale. * * SYNOPSIS: * char * * setlocale(category, locale) * int category; * char *locale; * * DESCRIPTION: * This is the ANSI defined function used to set the programs locale * for the specified category, from <locale.h>. If this call fails * NO changes are made to ANY of the operations of the program. * * RETURN: * Returns the string specified by the locale for category. Currently * always the LANG string. If the call fails then a NULL pointer is * returned. */struct locale_info { char *environ; /* the related environment var */ char setting[2 * NL_LANGMAX + 1]; /* the current setting */};static struct locale_info cur_locale[] = { "LANG", "C", /* LC_ALL */ "LC_COLLATE", "C", "LC_CTYPE", "C", "LC_NUMERIC", "C", "LC_TIME", "C", "LC_MONETARY", "C"};struct new_locale_info { char new_setting[2*NL_LANGMAX+1]; /* new setting values */ intl *pi; /* new values of table pointers */};static struct new_locale_info new_locale[_LC_MAX + 1];static col_tab *collate; /* collation table pointer */static prp_tab *property; /* property table pointer */static str_tab *numstr, *timestr, *monstr; /* string table pointers */static struct lconv lconv; /* for localeconv result */char *setlocale(category, locale)register int category;char *locale;{ register int loop; register int LC_all_ok; register char *nptr, *locptr; char nsettings[2*NL_LANGMAX+1]; char *return_settings(), *getenv(); /* * check for a query on locale */ if (locale == CNULL) return(return_settings(category)); /* * special case of setlocale(LC_ALL, setlocale(LC_ALL, NULL)) * (ie. when a queried value of LC_ALL is fed back into setlocale). */ if (category == LC_ALL && *locale == SEPCH) { locptr = locale; for (loop=LC_ALL; loop <= _LC_MAX; loop++) { nptr = nsettings; locptr++; while (*locptr != SEPCH) *nptr++ = *locptr++; *nptr = '\0'; if (setuptable(loop, nsettings) != 0) return(CNULL); } commit_tables(LC_ALL); return(locale); } /* * change locale of a single category */ if (category != LC_ALL) { /* * verify category is within range before attempeting setup */ if (category > LC_ALL && category <= _LC_MAX && setuptable(category, locale) == 0) { commit_tables(category); return(new_locale[category].new_setting); } else return(CNULL); } /* * final case of when a string is not a component. * * NB: Take care of the special case of setlocale(LC_ALL, "") where * all the LC_* variables are set, but not $LANG! This is still a * legal call. */ LC_all_ok = FALSE; for (loop = LC_ALL; loop <= _LC_MAX; loop++) { if (setuptable(loop, locale) != 0) { if (loop != LC_ALL) return(CNULL); else LC_all_ok = TRUE; } } if (LC_all_ok == FALSE) commit_tables(LC_ALL); else for (loop = LC_ALL + 1; loop <= _LC_MAX; loop++) commit_tables(loop); return(return_settings(LC_ALL));}/* * setuptable -- set up & load a table from category * * SYNOPSIS * setuptable(cat, locale) * int cat; * char *locale; * * DESCRIPTION * * Sets up a table specified by cat according to the value passed * in locale. The setting of locale can either be a full locale * setting, a table specification or null. If a null locale is * given, setuptables will use the correct environment variable, * or if this is not set, the value of LC_ALL (LANG). * * The function loadtables is called to perform the required loading * from the tables. If at any point in the an error is encountered, * setuptables will exit & return an error. * * RETURNS * 0 on success or -1 on error. */staticsetuptable(cat, locale)register int cat;register char *locale;{ char lang[NL_LANGMAX + 1]; /* used to split locale into */ char terr[NL_LANGMAX + 1]; /* required components */ char code[NL_LANGMAX + 1]; char table[NL_LANGMAX + 1]; char namebuf[2 * NL_LANGMAX + 1];/* buffers to hold full names */ char dictbuf[2 * NL_LANGMAX + 1]; char *valptr; /* used to point to next valid */ /* locale */ char *getenv(), *setname(); intl *pi; /* table pointer */ /* * if locale is empty, search appropiate environment variable, * or if not set, $LANG. */ if (*locale == '\0') if ((locale = getenv(cur_locale[cat].environ)) == CNULL || *locale == '\0') if ((locale = getenv("LANG")) == CNULL) return(-1); /* * DJL 002 * if environment set to C, simply set the name return */ if (locale[0] == 'C' && locale[1] == '\0') { setname(new_locale[cat].new_setting, "C", CNULL, CNULL, CNULL); return (0); } /* * if just table modifier specified, correct table to prefix to */ if (*locale == '@') { if ((valptr = getenv(cur_locale[cat].environ)) == CNULL || *valptr == '\0' || *valptr == '@') if ((valptr = getenv("LANG")) == CNULL || *valptr == '\0' || *valptr == '@') return(-1); strcpy(dictbuf, valptr); strcat(dictbuf, locale); locale = dictbuf; } /* * split locale name into components */ if (form_lang(locale, lang, terr, code, table) == -1) return(-1); /* * attempt to open database and return file point on success * or exit on error. */ setname(namebuf,lang, terr, code, CNULL); if ((pi = i_init(namebuf)) == (intl *)0) return(-1); if (loadtables(cat, pi, table) == -1) { /* * we can't call i_end here since databases can be shared * amongst several categories and if we called i_end then * we could free up a table used by another category!!! */ return(-1); } setname(new_locale[cat].new_setting, lang, terr, code, table); new_locale[cat].pi = pi; return(0);}/* * loadtables -- load the appropriate tables from category * * SYNOPSIS * loadtables(cat, pi, table) * int cat; * intl *pi; * char *table; * * DESCRIPTION * Load the tables as specified by cat. Once all have been loaded * successfully switch the environment. If at any point we encounter * a problem, stop and return an error. * * RETURNS * 0 on success and -1 on error */staticloadtables(cat, pi, table)register int cat;register intl *pi;char *table;{ switch (cat) { case LC_COLLATE: /* * if a table given try to load it otherwise use the * default (load it if necessary). */ if (*table) pi->in_cldflt = collate = i_ldcol(table, pi); else if (pi->in_cldflt == (col_tab *)0) { if ((collate = i_ldcol(COL_DEF, pi)) == (col_tab *)0) return -1; pi->in_cldflt = collate; } else collate = pi->in_cldflt; /* * could not load the requested table so giveup now */ if (collate == (col_tab *)0) return -1; break; case LC_CTYPE: /* * if a table given try to load it otherwise use the * default (load it if necessary) */ if (*table) pi -> in_prdflt = property = i_ldprp(table, pi); else if (pi->in_prdflt == (prp_tab *)0) { if ((property = i_ldprp(PRP_DEF, pi)) == (prp_tab *)0) return -1; pi->in_prdflt = property; } else property = pi->in_prdflt; /* * could not load the requested table so giveup now */ if (property == (prp_tab *)0) return -1; /* * load the conversion tables */ if (pi->in_ilower == (cnv_tab *)0 && (pi->in_ilower = i_ldcnv("tolower", pi)) == (cnv_tab *)0) return -1; if (pi->in_iupper == (cnv_tab *)0 && (pi->in_iupper = i_ldcnv("toupper", pi)) == (cnv_tab *)0) return -1; break; case LC_NUMERIC: /* * if a table given try to load it otherwise use the * default (load it if necessary) */ if (*table) pi->in_sgdflt = numstr = i_ldstr(table, pi); else { if (pi->in_sgdflt == (str_tab*)0) { if ( (numstr = i_ldstr(FRM_DEF, pi)) == (str_tab*)0) return -1; pi->in_sgdflt = numstr; } else numstr = pi->in_sgdflt; } /* * could not load the requested table so giveup now */ if (numstr == (str_tab *)0) { return -1; } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -