155682Smarkm/* $FreeBSD$ */
2178825Sdfr/* $NetBSD: citrus_lookup_factory.c,v 1.4 2003/10/27 00:12:42 lukem Exp $ */
355682Smarkm
455682Smarkm/*-
555682Smarkm * Copyright (c)2003 Citrus Project,
655682Smarkm * All rights reserved.
755682Smarkm *
855682Smarkm * Redistribution and use in source and binary forms, with or without
955682Smarkm * modification, are permitted provided that the following conditions
1055682Smarkm * are met:
1155682Smarkm * 1. Redistributions of source code must retain the above copyright
1255682Smarkm *    notice, this list of conditions and the following disclaimer.
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1855682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1955682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2055682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2155682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2255682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2355682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2455682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2555682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2655682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2755682Smarkm * SUCH DAMAGE.
2855682Smarkm */
2955682Smarkm
3055682Smarkm#include <sys/cdefs.h>
3155682Smarkm
3255682Smarkm#include <assert.h>
3355682Smarkm#include <ctype.h>
34178825Sdfr#include <errno.h>
3555682Smarkm#include <limits.h>
3655682Smarkm#include <stdio.h>
3755682Smarkm#include <stdlib.h>
3855682Smarkm#include <string.h>
39178825Sdfr
40178825Sdfr#include "citrus_namespace.h"
41178825Sdfr#include "citrus_region.h"
42178825Sdfr#include "citrus_bcs.h"
43178825Sdfr#include "citrus_db_factory.h"
44178825Sdfr#include "citrus_db_hash.h"
4555682Smarkm#include "citrus_lookup_factory.h"
4655682Smarkm#include "citrus_lookup_file.h"
4755682Smarkm
48178825Sdfr#define T_COMM '#'
49178825Sdfrstatic int
5055682Smarkmconvert_line(struct _citrus_db_factory *df, const char *line, size_t len)
5155682Smarkm{
5255682Smarkm	const char *p;
53178825Sdfr	char data[LINE_MAX], key[LINE_MAX];
54178825Sdfr
55178825Sdfr	/* cut off trailing comment */
56178825Sdfr	p = memchr(line, T_COMM, len);
57178825Sdfr	if (p)
58178825Sdfr		len = p - line;
59178825Sdfr
60178825Sdfr	/* key */
61178825Sdfr	line = _bcs_skip_ws_len(line, &len);
62178825Sdfr	if (len == 0)
63178825Sdfr		return (0);
64178825Sdfr	p = _bcs_skip_nonws_len(line, &len);
65178825Sdfr	if (p == line)
66178825Sdfr		return (0);
67178825Sdfr	snprintf(key, sizeof(key), "%.*s", (int)(p-line), line);
68178825Sdfr	_bcs_convert_to_lower(key);
69178825Sdfr
70178825Sdfr	/* data */
71178825Sdfr	line = _bcs_skip_ws_len(p, &len);
72178825Sdfr	_bcs_trunc_rws_len(line, &len);
73178825Sdfr	snprintf(data, sizeof(data), "%.*s", (int)len, line);
74178825Sdfr
75178825Sdfr	return (_db_factory_addstr_by_s(df, key, data));
76178825Sdfr}
77178825Sdfr
78178825Sdfrstatic int
79178825Sdfrdump_db(struct _citrus_db_factory *df, struct _region *r)
80178825Sdfr{
81178825Sdfr	void *ptr;
8255682Smarkm	size_t size;
8355682Smarkm
8455682Smarkm	size = _db_factory_calc_size(df);
8555682Smarkm	ptr = malloc(size);
86178825Sdfr	if (ptr == NULL)
87178825Sdfr		return (errno);
88178825Sdfr	_region_init(r, ptr, size);
89178825Sdfr
9055682Smarkm	return (_db_factory_serialize(df, _CITRUS_LOOKUP_MAGIC, r));
91178825Sdfr}
92178825Sdfr
93178825Sdfrint
94178825Sdfr_citrus_lookup_factory_convert(FILE *out, FILE *in)
95178825Sdfr{
9655682Smarkm	struct _citrus_db_factory *df;
97178825Sdfr	struct _region r;
9855682Smarkm	char *line;
99178825Sdfr	size_t size;
100178825Sdfr	int ret;
101178825Sdfr
10255682Smarkm	ret = _db_factory_create(&df, &_db_hash_std, NULL);
10355682Smarkm	if (ret)
104		return (ret);
105
106	while ((line = fgetln(in, &size)) != NULL)
107		if ((ret = convert_line(df, line, size))) {
108			_db_factory_free(df);
109			return (ret);
110		}
111
112	ret = dump_db(df, &r);
113	_db_factory_free(df);
114	if (ret)
115		return (ret);
116
117	if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1)
118		return (errno);
119
120	return (0);
121}
122