4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "gnu_msgfmt.h"
30 #include "../../lib/libc/inc/msgfmt.h"
33 doswap(unsigned int n
)
37 r
= (n
<< 24) | ((n
& 0xff00) << 8) |
38 ((n
>> 8) & 0xff00) | (n
>> 24);
43 search_msg(struct catalog
*p
, const char *id
, unsigned int hash_val
)
45 unsigned int i
, idx
, inc
;
48 idx
= hash_val
% p
->thash_size
;
49 inc
= 1 + (hash_val
% (p
->thash_size
- 2));
54 for (m
= p
->msg
; (i
= p
->thash
[idx
]) != 0;
55 idx
= (idx
+ inc
) % p
->thash_size
) {
56 if (strcmp(m
[i
- 1].id
, id
) == 0) {
65 msg_cmp(struct messages
*m1
, struct messages
*m2
)
67 return (strcmp(m1
->id
, m2
->id
));
71 output_all_gnu_mo_files(void)
73 struct catalog
*p
, *op
;
75 size_t id_len
, str_len
, id_off
, str_off
, ids_top
, strs_top
;
76 unsigned int *hash_tbl
;
77 unsigned int hash_size
, off_msgstr_tbl
, off_hashtbl
;
78 unsigned int num
= 0, fnum
= 0, unum
= 0;
81 struct msgtbl
*id_tbl
, *str_tbl
;
82 struct gnu_msg_info header
;
95 p
->msg
= (struct messages
*)Xrealloc(p
->msg
,
96 sizeof (struct messages
) * p
->nmsg
);
100 * Sort the message array
102 qsort(p
->msg
, p
->nmsg
, sizeof (struct messages
),
103 (int (*)(const void *, const void *))msg_cmp
);
106 hash_size
= find_prime(p
->nmsg
);
107 hash_tbl
= (unsigned int *)Xcalloc(hash_size
,
108 sizeof (unsigned int));
111 /* Setting Header info */
112 off_msgstr_tbl
= sizeof (struct gnu_msg_info
) +
113 p
->nmsg
* sizeof (struct msgtbl
);
114 off_hashtbl
= off_msgstr_tbl
+
115 p
->nmsg
* sizeof (struct msgtbl
);
117 header
.magic
= doswap(GNU_MAGIC
);
118 header
.revision
= doswap(GNU_REVISION
);
119 header
.num_of_str
= doswap(p
->nmsg
);
120 header
.off_msgid_tbl
=
121 doswap(sizeof (struct gnu_msg_info
));
122 header
.off_msgstr_tbl
= doswap(off_msgstr_tbl
);
123 header
.sz_hashtbl
= doswap(hash_size
);
124 header
.off_hashtbl
= doswap(off_hashtbl
);
130 for (i
= 0; i
< p
->nmsg
; i
++) {
131 id_len
+= m
[i
].id_len
;
132 str_len
+= m
[i
].str_len
;
134 ids
= (char *)Xmalloc(id_len
);
135 strs
= (char *)Xmalloc(str_len
);
136 id_tbl
= (struct msgtbl
*)Xmalloc(sizeof (struct msgtbl
) *
138 str_tbl
= (struct msgtbl
*)Xmalloc(sizeof (struct msgtbl
) *
142 ids_top
= off_hashtbl
+
143 sizeof (unsigned int) * hash_size
;
144 strs_top
= ids_top
+ id_len
;
145 for (i
= 0; i
< p
->nmsg
; i
++) {
149 idx
= get_hash_index(hash_tbl
, m
[i
].hash
, hash_size
);
150 hash_tbl
[idx
] = doswap(i
+ 1);
153 * rearrange msgid and msgstr
155 id_tbl
[i
].len
= doswap(m
[i
].id_len
- 1);
156 str_tbl
[i
].len
= doswap(m
[i
].str_len
- 1);
157 id_tbl
[i
].offset
= doswap(id_off
+ ids_top
);
158 str_tbl
[i
].offset
= doswap(str_off
+ strs_top
);
159 (void) memcpy(ids
+ id_off
, m
[i
].id
, m
[i
].id_len
);
160 (void) memcpy(strs
+ str_off
, m
[i
].str
, m
[i
].str_len
);
161 id_off
+= m
[i
].id_len
;
162 str_off
+= m
[i
].str_len
;
167 if ((out
= fopen(p
->fname
, "w")) == NULL
) {
168 error(gettext(ERR_OPEN_FAILED
), p
->fname
);
173 (void) fwrite(&header
, sizeof (struct gnu_msg_info
),
176 /* writing msgid offset table */
177 (void) fwrite(id_tbl
, sizeof (struct msgtbl
),
179 /* writing msgstr offset table */
180 (void) fwrite(str_tbl
, sizeof (struct msgtbl
),
182 /* writing hash table */
183 (void) fwrite(hash_tbl
, sizeof (unsigned int),
185 /* writing msgid table */
186 (void) fwrite(ids
, id_len
, 1, out
);
187 /* writing msgstr table */
188 (void) fwrite(strs
, str_len
, 1, out
);
203 diag(gettext(DIAG_RESULTS
), num
, fnum
, unum
);