xref: /haiku/src/system/libroot/posix/locale/LocaleInternal.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
1 /*
2  * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de
3  * Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de
4  * All rights reserved. Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "LocaleInternal.h"
9 
10 #include <locale.h>
11 #include <stdlib.h>
12 #include <strings.h>
13 
14 #include <Debug.h>
15 
16 
17 namespace BPrivate {
18 namespace Libroot {
19 
20 
21 status_t
22 GetLocalesFromEnvironment(int category, const char** locales)
23 {
24 	if (category > LC_LAST) {
25 		return B_BAD_VALUE;
26 	}
27 
28 	const char* locale = getenv("LC_ALL");
29 	if (locale != NULL && *locale != '\0')
30 		locales[category] = locale;
31 	else {
32 		// the order of the names must match the one specified in locale.h
33 		const char* const categoryNames[] = {
34 			"LC_ALL",
35 			"LC_COLLATE",
36 			"LC_CTYPE",
37 			"LC_MONETARY",
38 			"LC_NUMERIC",
39 			"LC_TIME",
40 			"LC_MESSAGES"
41 		};
42 
43 		STATIC_ASSERT(B_COUNT_OF(categoryNames) == LC_LAST + 1);
44 
45 		int from, to;
46 		if (category == LC_ALL) {
47 			// we need to check each real category if all of them should be set
48 			from = 1;
49 			to = LC_LAST;
50 		} else
51 			from = to = category;
52 		bool haveDifferentLocales = false;
53 		locale = NULL;
54 		for (int lc = from; lc <= to; lc++) {
55 			const char* lastLocale = locale;
56 			locale = getenv(categoryNames[lc]);
57 			if (locale == NULL || *locale == '\0')
58 				locale = getenv("LANG");
59 			if (locale == NULL || *locale == '\0')
60 				locale = "POSIX";
61 			locales[lc] = locale;
62 			if (lastLocale != NULL && strcasecmp(locale, lastLocale) != 0)
63 				haveDifferentLocales = true;
64 		}
65 		if (!haveDifferentLocales) {
66 			// we can set all locales at once
67 			locales[LC_ALL] = locale;
68 		}
69 	}
70 
71 	return B_OK;
72 }
73 
74 }	// namespace Libroot
75 }	// namespace BPrivate
76