9b97cc4b817816f5e57c11986f1ba84c2a6a33eb
[src/app-framework-main.git] / src / wgt-locales.c
1 /*
2  Copyright 2015 IoT.bzh
3
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8      http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16
17
18 #define _GNU_SOURCE
19 #include <string.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <ctype.h>
23
24 #include "wgt.h"
25
26 struct locarr {
27         int count;
28         char **arr;
29 };
30
31 static struct locarr locarr = { 0, NULL };
32
33 static int add(const char *locstr, int length)
34 {
35         int i;
36         char *item, **ptr;
37
38         item = strndup(locstr, length);
39         if (item != NULL) {
40                 for (i = 0 ; item[i] ; i++)
41                         item[i] = tolower(item[i]);
42                 for (i = 0 ; i < locarr.count ; i++)
43                         if (!strcmp(item, locarr.arr[i])) {
44                                 free(item);
45                                 return 0;
46                         }
47
48                 ptr = realloc(locarr.arr, (1 + locarr.count) * sizeof(locarr.arr[0]));
49                 if (ptr) {
50                         locarr.arr = ptr;
51                         locarr.arr[locarr.count++] = item;
52                         return 0;
53                 }
54                 free(item);
55         }
56         errno = ENOMEM;
57         return -1;
58 }
59
60 void locales_reset()
61 {
62         while (locarr.count)
63                 free(locarr.arr[--locarr.count]);
64 }
65
66 int locales_add(const char *locstr)
67 {
68         const char *stop, *next;
69         while (*locstr) {
70                 stop = strchrnul(locstr, ',');
71                 next = stop + !!*stop;
72                 while (locstr != stop) {
73                         if (add(locstr, stop - locstr))
74                                 return -1;
75                         do { stop--; } while(stop > locstr && *stop != '-');
76                 }
77                 locstr = next;
78         }
79         return 0;
80 }
81
82 int locales_score(const char *lang)
83 {
84         int i;
85
86         if (lang)
87                 for (i = 0 ; i < locarr.count ; i++)
88                         if (!strcasecmp(lang, locarr.arr[i]))
89                                 return i;
90
91         return INT_MAX;
92 }
93
94 char *locales_locate_file(const char *filename)
95 {
96         int i;
97         char path[PATH_MAX];
98         char * result;
99
100         for (i = 0 ; i < locarr.count ; i++) {
101                 if (snprintf(path, sizeof path, "locales/%s/%s", locarr.arr[i], filename) >= (int)(sizeof path)) {
102                         errno = EINVAL;
103                         return NULL;
104                 }
105                 if (widget_has(path)) {
106                         result = strdup(path);
107                         if (!result)
108                                 errno = ENOMEM;
109                         return result;
110                 }
111         }
112         if (widget_has(filename)) {
113                 result = strdup(filename);
114                 if (!result)
115                         errno = ENOMEM;
116                 return result;
117         }
118         errno = ENOENT;
119         return NULL;
120 }
121