don't bother resolving onbld python module deps
[unleashed.git] / bin / localedef / localedef.c
blob132f4a857611449703df2e7920fbe8996f9cf763
1 /*
2 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
3 * Copyright 2013 DEY Storage Systems, Inc.
4 * Copyright 2015 John Marino <draco@marino.st>
6 * This source code is derived from the illumos localedef command, and
7 * provided under BSD-style license terms by Nexenta Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * POSIX localedef.
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <errno.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <libgen.h>
44 #include <stddef.h>
45 #include <unistd.h>
46 #include <limits.h>
47 #include <locale.h>
48 #include <dirent.h>
49 #include "localedef.h"
50 #include "parser.h"
52 #ifndef TEXT_DOMAIN
53 #define TEXT_DOMAIN "SYS_TEST"
54 #endif
56 static int bsd = 0;
57 int verbose = 0;
58 int undefok = 0;
59 int warnok = 0;
60 static char *locname = NULL;
61 static char locpath[PATH_MAX];
63 const char *
64 category_name(void)
66 switch (get_category()) {
67 case T_CHARMAP:
68 return ("CHARMAP");
69 case T_WIDTH:
70 return ("WIDTH");
71 case T_COLLATE:
72 return ("LC_COLLATE");
73 case T_CTYPE:
74 return ("LC_CTYPE");
75 case T_MESSAGES:
76 return ("LC_MESSAGES");
77 case T_MONETARY:
78 return ("LC_MONETARY");
79 case T_NUMERIC:
80 return ("LC_NUMERIC");
81 case T_TIME:
82 return ("LC_TIME");
83 default:
84 INTERR;
85 return (NULL);
89 static char *
90 category_file(void)
92 if (bsd)
93 (void) snprintf(locpath, sizeof (locpath), "%s.%s",
94 locname, category_name());
95 else
96 (void) snprintf(locpath, sizeof (locpath), "%s/%s/LCL_DATA",
97 locname, category_name());
98 return (locpath);
101 FILE *
102 open_category(void)
104 FILE *file;
106 if (verbose) {
107 (void) printf(_("Writing category %s: "), category_name());
108 (void) fflush(stdout);
111 /* make the parent directory */
112 if (!bsd)
113 (void) mkdirp(dirname(category_file()), 0755);
116 * note that we have to regenerate the file name, as dirname
117 * clobbered it.
119 file = fopen(category_file(), "w");
120 if (file == NULL) {
121 errf(strerror(errno));
122 return (NULL);
124 return (file);
127 void
128 close_category(FILE *f)
130 if (fchmod(fileno(f), 0644) < 0) {
131 (void) fclose(f);
132 (void) unlink(category_file());
133 errf(strerror(errno));
135 if (fclose(f) < 0) {
136 (void) unlink(category_file());
137 errf(strerror(errno));
139 if (verbose) {
140 (void) fprintf(stdout, _("done.\n"));
141 (void) fflush(stdout);
146 * This function is used when copying the category from another
147 * locale. Note that the copy is actually performed using a hard
148 * link for efficiency.
150 void
151 copy_category(char *src)
153 char srcpath[PATH_MAX];
154 int rv;
156 (void) snprintf(srcpath, sizeof (srcpath), "%s/%s/LCL_DATA",
157 src, category_name());
158 rv = access(srcpath, R_OK);
159 if ((rv != 0) && (strchr(srcpath, '/') == NULL)) {
160 /* Maybe we should try the system locale */
161 (void) snprintf(srcpath, sizeof (srcpath),
162 "/usr/lib/locale/%s/%s/LCL_DATA", src, category_name());
163 rv = access(srcpath, R_OK);
166 if (rv != 0) {
167 errf(_("source locale data unavailable"), src);
168 return;
171 if (verbose > 1) {
172 (void) printf(_("Copying category %s from %s: "),
173 category_name(), src);
174 (void) fflush(stdout);
177 /* make the parent directory */
178 if (!bsd)
179 (void) mkdirp(dirname(category_file()), 0755);
181 if (link(srcpath, category_file()) != 0) {
182 errf(_("unable to copy locale data: %s"), strerror(errno));
183 return;
185 if (verbose > 1) {
186 (void) printf(_("done.\n"));
191 putl_category(const char *s, FILE *f)
193 if (s && fputs(s, f) == EOF) {
194 (void) fclose(f);
195 (void) unlink(category_file());
196 errf(strerror(errno));
197 return (EOF);
199 if (fputc('\n', f) == EOF) {
200 (void) fclose(f);
201 (void) unlink(category_file());
202 errf(strerror(errno));
203 return (EOF);
205 return (0);
209 wr_category(void *buf, size_t sz, FILE *f)
211 if (!sz) {
212 return (0);
214 if (fwrite(buf, sz, 1, f) < 1) {
215 (void) fclose(f);
216 (void) unlink(category_file());
217 errf(strerror(errno));
218 return (EOF);
220 return (0);
223 int yyparse(void);
225 static void
226 usage(void)
228 (void) fprintf(stderr,
229 _("Usage: localedef [options] localename\n"));
230 (void) fprintf(stderr, ("[options] are:\n"));
231 (void) fprintf(stderr, (" -c : ignore warnings\n"));
232 (void) fprintf(stderr, (" -D : BSD-style output\n"));
233 (void) fprintf(stderr, (" -v : verbose output\n"));
234 (void) fprintf(stderr, (" -U : ignore undefined symbols\n"));
235 (void) fprintf(stderr, (" -f charmap : use given charmap file\n"));
236 (void) fprintf(stderr, (" -u encoding : assume encoding\n"));
237 (void) fprintf(stderr, (" -w widths : use screen widths file\n"));
238 (void) fprintf(stderr, (" -i locsrc : source file for locale\n"));
239 exit(4);
243 main(int argc, char **argv)
245 int c;
246 char *lfname = NULL;
247 char *cfname = NULL;
248 char *wfname = NULL;
249 DIR *dir;
251 init_charmap();
252 init_collate();
253 init_ctype();
254 init_messages();
255 init_monetary();
256 init_numeric();
257 init_time();
259 yydebug = 0;
261 (void) setlocale(LC_ALL, "");
262 (void) textdomain(TEXT_DOMAIN);
264 while ((c = getopt(argc, argv, "w:i:cf:u:vUD")) != -1) {
265 switch (c) {
266 case 'D':
267 bsd = 1;
268 break;
269 case 'v':
270 verbose++;
271 break;
272 case 'i':
273 lfname = optarg;
274 break;
275 case 'u':
276 set_wide_encoding(optarg);
277 break;
278 case 'f':
279 cfname = optarg;
280 break;
281 case 'U':
282 undefok++;
283 break;
284 case 'c':
285 warnok++;
286 break;
287 case 'w':
288 wfname = optarg;
289 break;
290 case '?':
291 usage();
292 break;
296 if ((argc - 1) != (optind)) {
297 usage();
299 locname = argv[argc - 1];
300 if (verbose) {
301 (void) printf(_("Processing locale %s.\n"), locname);
304 if (cfname) {
305 if (verbose)
306 (void) printf(_("Loading charmap %s.\n"), cfname);
307 reset_scanner(cfname);
308 (void) yyparse();
311 if (wfname) {
312 if (verbose)
313 (void) printf(_("Loading widths %s.\n"), wfname);
314 reset_scanner(wfname);
315 (void) yyparse();
318 if (verbose) {
319 (void) printf(_("Loading POSIX portable characters.\n"));
321 add_charmap_posix();
323 if (lfname) {
324 reset_scanner(lfname);
325 } else {
326 reset_scanner(NULL);
329 /* make the directory for the locale if not already present */
330 if (!bsd) {
331 while ((dir = opendir(locname)) == NULL) {
332 if ((errno != ENOENT) ||
333 (mkdir(locname, 0755) < 0)) {
334 errf(strerror(errno));
337 (void) closedir(dir);
338 (void) mkdirp(dirname(category_file()), 0755);
341 (void) yyparse();
342 if (verbose) {
343 (void) printf(_("All done.\n"));
345 return (warnings ? 1 : 0);