NAME
newlocale, freelocale - 로캘 객체 생성, 변경, 해제하기
SYNOPSIS
#include <locale.h>
locale_t newlocale(int category_mask, const char *locale,
locale_t base);
void freelocale(locale_t locobj);
glibc 기능 확인 매크로 요건 (feature_test_macros(7) 참고):
newlocale()
,freelocale()
:-
- glibc 2.10부터:
_XOPEN_SOURCE >= 700
- glibc 2.10 전:
_GNU_SOURCE
DESCRIPTION
newlocale()
함수는 새 로캘 객체를 만들거나 기존 객체를 변경한 다음 그 새 객체 내지 변경된 객체에 대한 참조를 함수 결과로 반환한다. 새 객체를 만들지 기존 객체를 변경할지는 base
의 값에 따라 정해진다.
-
base
가(locale_t) 0
이면 새 객체를 만든다. -
base
가 유효한 기존 객체(앞선newlocale()
내지 duplocale(3) 호출이 반환한 객체)를 가리키는 경우엔 그 객체를 변경한다. 호출 성공 시base
의 내용물에 대해선 명세돼 있지 않다. (특히base
가 가리키는 객체가 해제되고 새 객체가 만들어졌을 수도 있다.) 따라서 호출자는newlocale()
를 호출하기 전에base
사용을 중단해야 하며, 이후로는 함수 결과로 반환된 참조가 가리키는 변경된 객체를 이용해야 한다. 호출이 실패한 경우에는base
의 내용물이 유효하게 유지되며 바뀌지 않는다.
base
가 특수 로캘 객체 LC_GLOBAL_LOCALE
(duplocale(3) 참고)인 경우, 또는 (locale_t) 0
이 아니면서 유효한 로캘 객체 핸들도 아닌 경우의 동작은 규정돼 있지 않다.
category_mask
인자는 새로 만드는 로캘 객체에 설정하거나 기존 객체에서 변경할 로캘 범주들을 나타내는 비트 마스크다. 상수 LC_ADDRESS_MASK
, LC_CTYPE_MASK
, LC_COLLATE_MASK
, LC_IDENTIFICATION_MASK
, LC_MEASUREMENT_MASK
, LC_MESSAGES_MASK
, LC_MONETARY_MASK
, LC_NUMERIC_MASK
, LC_NAME_MASK
, LC_PAPER_MASK
, LC_TELEPHONE_MASK
, LC_TIME_MASK
를 비트 OR 해서 마스크를 만든다. 또는 LC_ALL_MASK
를 지정할 수도 있는데, 앞선 상수들 모두를 OR 한 것과 동등하다.
newlocale()
이 반환하는 객체에서는 category_mask
에 지정한 범주 각각에 locale
에서 온 로캘 데이터가 쓰이게 된다. 로캘 객체가 새로 만들어지는 경우에 category_mask
에 지정하지 않는 범주들은 기본("POSIX") 로캘에서 데이터를 가져온다.
category_mask
에 지정할 수 있는 모든 범주들에 대해 다음 locale
값들이 기본적으로 정의돼 있다.
- "POSIX"
- C 언어 프로그램용 최소 로캘 환경.
- "C"
- "POSIX"와 동등.
- ""
LC_*
및LANG
환경 변수 값에 따라 정해지는 구현체별 기본 환경. (locale(7) 참고.)
freelocale()
freelocale()
함수는 앞선 newlocale()
내지 duplocale(3) 호출이 반환한 로캘 객체인 locobj
에 연계된 자원들을 해제한다. locobj
가 LC_GLOBAL_LOCALE
이거나 유효한 로캘 객체가 아닌 경우의 결과는 규정돼 있지 않다.
로캘 객체가 해제된 후에는 프로그램에서 더 이상 그 객체를 사용하지 말아야 한다.
RETURN VALUE
성공 시 newlocale()
은 핸들을 반환하며, 이를 duplocale(3)이나 freelocale()
, locale_t
인자를 받는 기타 함수들에 사용할 수 있다. 오류 발생 시 newlocale()
은 (locale_t) 0
을 반환하며 오류를 나타내도록 errno
를 설정한다.
ERRORS
EINVAL
category_mask
의 비트 중 하나 이상이 유효한 로캘 범주에 대응하지 않는다.EINVAL
locale
이 NULL이다.ENOENT
locale
이 유효한 로캘을 가리키는 문자열 포인터가 아니다.ENOMEM
- 로캘 객체를 만들 메모리가 충분치 않다.
VERSIONS
GNU C 라이브러리 버전 2.3에서 newlocale()
및 freelocale()
함수가 처음 등장했다.
CONFORMING TO
POSIX.1-2008.
NOTES
newlocale()
로 만든 로캘 객체 각각을 freelocale()
로 해제해 줘야 한다.
EXAMPLES
아래 프로그램은 로캘을 나타내는 명령행 인자를 최대 2개 받는다. 첫 번째 인자는 필수이며, newlocale()
로 만든 로캘 객체의 LC_NUMERIC
범주를 설정하는 데 쓰인다. 두 번째 명령행 인자는 선택적이며, 제공 시 로캘 객체의 LC_TIME
범주를 설정하는 데 쓰인다.
프로그램에서 로캘 객체를 만들어서 초기화한 다음 uselocale(3)로 적용하고, 다음 방식으로 로캘 변경 효과를 확인한다.
-
소수부 있는 부동소수점 수 찍기.
LC_NUMERIC
설정이 출력에 영향을 주게 된다. 여러 유럽어 로캘들에선 점이 아니라 쉼표로 정수부와 소수부를 구분한다. -
날짜 찍기.
LC_DATE
설정이 출력 형식과 언어에 영향을 주게 된다.
다음 셸 세션들은 프로그램 실행 예를 보여 준다.
LC_NUMERIC
범주를 fr_FR
(프랑스)로 설정하기:
$ ./a.out fr_FR
123456,789
Fri Mar 7 00:25:08 2014
LC_NUMERIC
범주를 fr_FR
(프랑스)로 설정하고 LC_TIME
범주를 it_IT
(이탈리아)로 설정하기:
$ ./a.out fr_FR it_IT
123456,789
ven 07 mar 2014 00:26:01 CET
LC_TIME
설정을 빈 문자열로 지정해서 환경 변수 설정 값(이 경우 뉴질랜드 마오리를 나타내는 mi_NZ
)을 가져오게 하기:
$ LC_ALL=mi_NZ ./a.out fr_FR ""
123456,789
Te Paraire, te 07 o Poutū-te-rangi, 2014 00:38:44 CET
프로그램 소스
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
char buf[100];
time_t t;
size_t s;
struct tm *tm;
locale_t loc, nloc;
if (argc < 2) {
fprintf(stderr, "Usage: %s locale1 [locale2]\n", argv[0]);
exit(EXIT_FAILURE);
}
/* 새 로캘 객체 만들기. argv[1]에 지정된 로캘에서
LC_NUMERIC 설정을 가져온다. */
loc = newlocale(LC_NUMERIC_MASK, argv[1], (locale_t) 0);
if (loc == (locale_t) 0)
errExit("newlocale");
/* 두 번째 명령행 인자가 있으면 argv[2]에 지정된 로캘에서
LC_TIME 설정을 가져오도록 로캘 객체를 변경한다. 이 호출이
실패한 경우 'loc'을 유지하고 싶을 수도 있을 테니까
newlocale() 호출 결과를 'loc'이 아닌 'nloc'에 할당한다. */
if (argc > 2) {
nloc = newlocale(LC_TIME_MASK, argv[2], loc);
if (nloc == (locale_t) 0)
errExit("newlocale");
loc = nloc;
}
/* 새로 만든 로캘을 현재 스레드에 적용하기. */
uselocale(loc);
/* LC_NUMERIC의 효과 확인하기. */
printf("%8.3f\n", 123456.789);
/* LC_TIME의 효과 확인하기. */
t = time(NULL);
tm = localtime(&t);
if (tm == NULL)
errExit("time");
s = strftime(buf, sizeof(buf), "%c", tm);
if (s == 0)
errExit("strftime");
printf("%s\n", buf);
/* 로캘 객체 해제하기. */
uselocale(LC_GLOBAL_HANDLE); /* 이제 'loc' 쓰는 곳 없음 */
freelocale(loc);
exit(EXIT_SUCCESS);
}
SEE ALSO
locale(1)
, duplocale(3), setlocale(3), uselocale(3), locale(5), locale(7)
2021-03-22