Asterisk - The Open Source Telephony Project GIT-master-a358458
Macros | Functions | Variables
test_locale.c File Reference

Locale Test. More...

#include "asterisk.h"
#include <sys/types.h>
#include <dirent.h>
#include <locale.h>
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/localtime.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
Include dependency graph for test_locale.c:

Go to the source code of this file.

Macros

#define __USE_GNU   1
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static char * handle_cli_test_locales (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Locale tests" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_locales []
 

Detailed Description

Locale Test.

Author
Tilghman Lesher <tlesher AT digium DOT com> 

Definition in file test_locale.c.

Macro Definition Documentation

◆ __USE_GNU

#define __USE_GNU   1

Definition at line 38 of file test_locale.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 186 of file test_locale.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 186 of file test_locale.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 186 of file test_locale.c.

◆ handle_cli_test_locales()

static char * handle_cli_test_locales ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 49 of file test_locale.c.

50{
51 DIR *localedir;
52 struct dirent *dent;
53 struct ast_tm atm;
54 struct timeval tv;
55 const char *orig_locale;
56 char origlocalformat[200] = "", localformat[200] = "";
57 struct test_locales {
58 AST_LIST_ENTRY(test_locales) list;
59 char *localformat;
60 char name[0];
61 } *tl = NULL;
62 AST_LIST_HEAD_NOLOCK(locales, test_locales) locales;
63 int varies = 0, all_successful = 1, count = 0, count_fail = 0;
64
65 switch (cmd) {
66 case CLI_INIT:
67 e->command = "test locale";
68 e->usage = ""
69 "Usage: test locale\n"
70 " Test thread safety of locale functions.\n";
71 return NULL;
72 case CLI_GENERATE:
73 return NULL;
74 }
75
76 if (a->argc != e->args) {
77 return CLI_SHOWUSAGE;
78 }
79
80 /* First we run a set of tests with the global locale, which isn't thread-safe. */
81 if (!(localedir = opendir(
82#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
83 "/usr/share/locale"
84#else /* Linux */
85 "/usr/lib/locale"
86#endif
87 ))) {
88 ast_cli(a->fd, "No locales seem to exist on this platform.\n");
89 return CLI_SUCCESS;
90 }
91
92 tv = ast_tvnow();
93 ast_localtime(&tv, &atm, NULL);
94 orig_locale = setlocale(LC_ALL, NULL);
96
97 /* Get something different, to compare against. */
98 ast_strftime(origlocalformat, sizeof(origlocalformat), "%c", &atm);
99
100 while ((dent = readdir(localedir))) {
101 size_t locallen;
102 size_t namelen;
103
104 if (dent->d_name[0] == '.') {
105 continue;
106 }
107
108 setlocale(LC_ALL, dent->d_name);
109 ast_strftime(localformat, sizeof(localformat), "%c", &atm);
110
111 locallen = strlen(localformat) + 1;
112 namelen = strlen(dent->d_name) + 1;
113
114 /* Store values */
115 if (!(tl = ast_calloc(1, sizeof(*tl) + locallen + namelen))) {
116 continue;
117 }
118
119 ast_copy_string(tl->name, dent->d_name, namelen); /* SAFE */
120 tl->localformat = tl->name + namelen;
121 ast_copy_string(tl->localformat, localformat, locallen); /* SAFE */
122
123 AST_LIST_INSERT_TAIL(&locales, tl, list);
124
125 /* Ensure that at least two entries differ, otherwise this test doesn't mean much. */
126 if (!varies && strcmp(AST_LIST_FIRST(&locales)->localformat, localformat)) {
127 varies = 1;
128 }
129 }
130
131 setlocale(LC_ALL, orig_locale);
132
133 closedir(localedir);
134
135 if (!varies) {
136 if (!strcmp(origlocalformat, localformat)) {
137 ast_cli(a->fd, "WARNING: the locales on your system don't differ. Install more locales if you want this test to mean something.\n");
138 }
139 }
140
141 orig_locale = ast_setlocale(AST_LIST_FIRST(&locales)->name);
142
143 while ((tl = AST_LIST_REMOVE_HEAD(&locales, list))) {
144 ast_setlocale(tl->name);
145 ast_strftime(localformat, sizeof(localformat), "%c", &atm);
146 if (strcmp(localformat, tl->localformat)) {
147 ast_cli(a->fd, "WARNING: locale test fails for locale %s\n", tl->name);
148 all_successful = 0;
149 count_fail++;
150 }
151 ast_free(tl);
152 count++;
153 }
154
155 ast_setlocale(orig_locale);
156
157 if (all_successful) {
158 ast_cli(a->fd, "All %d locale tests successful\n", count);
159 } else if (count_fail == count && count > 0) {
160 ast_cli(a->fd, "No locale tests successful out of %d tries\n", count);
161 } else if (count > 0) {
162 ast_cli(a->fd, "Partial failure (%d/%d) for a %.0f%% failure rate\n", count_fail, count, count_fail * 100.0 / count);
163 } else {
164 ast_cli(a->fd, "No locales tested. Install more locales.\n");
165 }
166
167 return CLI_SUCCESS;
168}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
static const char name[]
Definition: format_mp3.c:68
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Definition: linkedlists.h:225
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_HEAD_SET_NOLOCK(head, entry)
Initializes a list head structure with a specified first entry.
Definition: linkedlists.h:388
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
const char * ast_setlocale(const char *locale)
Set the thread-local representation of the current locale.
Definition: localtime.c:2420
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
#define __APPLE__
Definition: mpool.c:316
#define NULL
Definition: resample.c:96
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
int args
This gets set in ast_cli_register()
Definition: cli.h:185
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
const char * name
static struct test_val a
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References __APPLE__, a, ast_cli_entry::args, ast_calloc, ast_cli(), ast_copy_string(), ast_free, AST_LIST_ENTRY, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_localtime(), ast_setlocale(), ast_strftime(), ast_tvnow(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, name, test_val::name, NULL, and ast_cli_entry::usage.

◆ load_module()

static int load_module ( void  )
static

Definition at line 180 of file test_locale.c.

181{
184}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
static struct ast_cli_entry cli_locales[]
Definition: test_locale.c:170
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_SUCCESS, and cli_locales.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 174 of file test_locale.c.

175{
177 return 0;
178}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_locales.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Locale tests" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 186 of file test_locale.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 186 of file test_locale.c.

◆ cli_locales

struct ast_cli_entry cli_locales[]
static
Initial value:
= {
{ .handler = handle_cli_test_locales , .summary = "Test locales for thread-safety" ,},
}
static char * handle_cli_test_locales(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: test_locale.c:49

Definition at line 170 of file test_locale.c.

Referenced by load_module(), and unload_module().