1 /* $NetBSD: src/lib/libc/citrus/citrus_pivot_factory.c,v 1.4 2004/01/02 21:49:35 itojun Exp $ */
2 /* $DragonFly: src/lib/libc/citrus/citrus_pivot_factory.c,v 1.1 2005/03/12 00:33:53 joerg Exp $ */
5 * Copyright (c)2003 Citrus Project,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/endian.h>
31 #include <sys/queue.h>
40 #include "citrus_namespace.h"
41 #include "citrus_region.h"
42 #include "citrus_bcs.h"
43 #include "citrus_db_factory.h"
44 #include "citrus_db_hash.h"
45 #include "citrus_pivot_file.h"
46 #include "citrus_pivot_factory.h"
50 struct _citrus_db_factory
*se_df
;
51 STAILQ_ENTRY(src_entry
) se_entry
;
53 STAILQ_HEAD(src_head
, src_entry
);
56 find_src(struct src_head
*sh
, struct src_entry
**rse
, const char *name
)
61 STAILQ_FOREACH(se
, sh
, se_entry
) {
62 if (_bcs_strcasecmp(se
->se_name
, name
) == 0) {
67 se
= malloc(sizeof(*se
));
70 se
->se_name
= strdup(name
);
71 if (se
->se_name
== NULL
) {
76 ret
= _db_factory_create(&se
->se_df
, &_db_hash_std
, NULL
);
82 STAILQ_INSERT_TAIL(sh
, se
, se_entry
);
89 free_src(struct src_head
*sh
)
93 while ((se
= STAILQ_FIRST(sh
)) != NULL
) {
94 STAILQ_REMOVE_HEAD(sh
, se_entry
);
95 _db_factory_free(se
->se_df
);
104 convert_line(struct src_head
*sh
, const char *line
, size_t len
)
107 struct src_entry
*se
;
109 char key1
[LINE_MAX
], key2
[LINE_MAX
], data
[LINE_MAX
];
112 /* cut off trailing comment */
113 p
= memchr(line
, T_COMM
, len
);
118 line
= _bcs_skip_ws_len(line
, &len
);
121 p
= _bcs_skip_nonws_len(line
, &len
);
124 snprintf(key1
, sizeof(key1
), "%.*s", (int)(p
-line
), line
);
127 line
= _bcs_skip_ws_len(p
, &len
);
130 p
= _bcs_skip_nonws_len(line
, &len
);
133 snprintf(key2
, sizeof(key2
), "%.*s", (int)(p
-line
), line
);
136 line
= _bcs_skip_ws_len(p
, &len
);
137 _bcs_trunc_rws_len(line
, &len
);
138 snprintf(data
, sizeof(data
), "%.*s", (int)len
, line
);
139 /* LINTED: discard const */
140 val
= strtoul(data
, __DECONST(char **, &p
), 0);
145 ret
= find_src(sh
, &se
, key1
);
149 return _db_factory_add32_by_s(se
->se_df
, key2
, val
);
153 dump_db(struct src_head
*sh
, struct _region
*r
)
156 struct _db_factory
*df
;
157 struct src_entry
*se
;
162 ret
= _db_factory_create(&df
, &_db_hash_std
, NULL
);
166 STAILQ_FOREACH(se
, sh
, se_entry
) {
167 size
= _db_factory_calc_size(se
->se_df
);
171 _region_init(&subr
, ptr
, size
);
172 ret
= _db_factory_serialize(se
->se_df
, _CITRUS_PIVOT_SUB_MAGIC
,
176 ret
= _db_factory_add_by_s(df
, se
->se_name
, &subr
, 1);
181 size
= _db_factory_calc_size(df
);
185 _region_init(r
, ptr
, size
);
187 ret
= _db_factory_serialize(df
, _CITRUS_PIVOT_MAGIC
, r
);
192 _db_factory_free(df
);
197 _citrus_pivot_factory_convert(FILE *out
, FILE *in
)
207 while ((line
= fgetln(in
, &size
)) != NULL
)
208 if ((ret
= convert_line(&sh
, line
, size
))) {
213 ret
= dump_db(&sh
, &r
);
218 if (fwrite(_region_head(&r
), _region_size(&r
), 1, out
) != 1)