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