/*
 * Copyright (c) 1999 Sun Microsystems, Inc.
 * Copyright (c) 1999 Nihon Sun Microsystems K.K.
 * All rights reserved.
 */

/*
 * "$Id: parse_ct_map_conf.c,v 1.1.1.1 2000/10/29 16:45:09 himi Exp $"
 */

#pragma ident	"@(#)parse_ct_map_conf.c 1.1	99/04/28 SMI"


#include "config.h"

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

#include "csc_conf_info.h"
#include "ct_map.h"


static void *
malloc_vital(size_t size)
{
	void *	p;

	if (NULL == (p = malloc(size))) {
		perror("malloc");
		exit(1);
	}

	memset(p, 0, size);

	return p;
}


ct_map_conf_t *
parse_ct_map_conf(void)
{
	csc_conf_file_t	*	conf_file;
	csc_conf_str_t		conf_str[16];
	ct_map_conf_t *		ct_map_conf_first;
	ct_map_conf_t *		ct_map_conf_last;
	ct_map_conf_t *		ctmp;
	const char *		p;
	int			cs_num;
	int			num;
	int			i;

	conf_file = csc_conf_open(CT_MAP_CONF, 0, NULL, 0);
	if (NULL == conf_file) {
		fprintf(stderr, "failed to open %s\n", CT_MAP_CONF);
		exit(1);
	}

	ct_map_conf_first = NULL;
	ct_map_conf_last = NULL;

	cs_num = 0;

	while (0 < (num = csc_conf_read(conf_file, conf_str, 8))) {
		if (num < 8) {
			continue;
		}

		ctmp = malloc_vital(sizeof (ct_map_conf_t));
		if (NULL == ct_map_conf_last) {
			ct_map_conf_first = ctmp;
			ct_map_conf_last = ctmp;
		} else {
			ct_map_conf_last->next = ctmp;
			ct_map_conf_last = ctmp;
		}
		ctmp->next = NULL;

		ctmp->cs_num = cs_num;
		ctmp->cs_id = (0x00000001 << cs_num);

		ctmp->enc_name = malloc_vital(conf_str[0].len + 1);
		memcpy(ctmp->enc_name, conf_str[0].ptr, conf_str[0].len);
		*(ctmp->enc_name + conf_str[0].len) = '\0';

		ctmp->path_data = malloc_vital(2 + conf_str[1].len + 1);
		sprintf(ctmp->path_data, "./%.*s", conf_str[1].len, conf_str[1].ptr);

		ctmp->stem = malloc_vital(conf_str[2].len + 1);
		memcpy(ctmp->stem, conf_str[2].ptr, conf_str[2].len);
		*(ctmp->stem + conf_str[2].len) = '\0';

		ctmp->path_u_n = malloc_vital(10 + conf_str[2].len + 3);
		sprintf(ctmp->path_u_n, "map_utf16_%s.c", ctmp->stem);

		ctmp->path_n_u = malloc_vital(4 + conf_str[2].len + 9);
		sprintf(ctmp->path_n_u, "map_%s_utf16.c", ctmp->stem);

		ctmp->cs_u_n_map_name = malloc_vital(10 + conf_str[2].len + 5);
		sprintf(ctmp->cs_u_n_map_name, "csc_utf16_%s_map", ctmp->stem);

		ctmp->cs_n_u_map_name = malloc_vital(10 + conf_str[2].len + 5);
		sprintf(ctmp->cs_n_u_map_name, "csc_%s_utf16_map", ctmp->stem);

		ctmp->design_name = malloc_vital(7 + conf_str[2].len + 1);
		sprintf(ctmp->design_name, "design_%s", ctmp->stem);

		ctmp->index_n = strtol(conf_str[3].ptr, NULL, 0);
		ctmp->index_u = strtol(conf_str[4].ptr, NULL, 0);

		p = conf_str[5].ptr;
		i = conf_str[5].len;
		if (0 == strncmp(ENC_GL_STR, p, i)) {
			ctmp->enc_gl_gr = ENC_GL;
			ctmp->enc_gl_gr_str = ENC_GL_STR;
		} else if (0 == strncmp(ENC_GR_STR, p, i)) {
			ctmp->enc_gl_gr = ENC_GR;
			ctmp->enc_gl_gr_str = ENC_GR_STR;
		} else if (0 == strncmp(ENC_GLGR_STR, p, i)) {
			ctmp->enc_gl_gr = ENC_GLGR;
			ctmp->enc_gl_gr_str = ENC_GLGR_STR;
		} else {
			fprintf(stderr, "invalid GL/GR encode: %.*s\n", i, p);
			exit(1);
		}

		ctmp->byte_number = strtol(conf_str[6].ptr, NULL, 0);
		if (ctmp->byte_number <= 0) {
			fprintf(stderr,
				"invalid byte number: %d\n", ctmp->byte_number);
			exit(1);
		}

		if ((5 <= conf_str[7].len) &&
		    (0x0025 == *(conf_str[7].ptr + 0)) &&
		    (0x002f == *(conf_str[7].ptr + 1)) &&
		    (0x0030 <= *(conf_str[7].ptr + 2)) &&
		    (*(conf_str[7].ptr + 2) <= 0x0034)) {
			/* Non-Standard Character Set Encodings */
			ctmp->design_length = (1 + conf_str[7].len + 1);
			ctmp->design_str = malloc_vital(1 + conf_str[7].len + 1);
			*(ctmp->design_str + 0) = 0x1b;
			memcpy(ctmp->design_str + 1, conf_str[7].ptr,
			       ctmp->design_length - 2);
			*(ctmp->design_str + 1 + ctmp->design_length - 2) = 0x02;
			ctmp->extended_segment = 1;
		} else {
			ctmp->design_length = (1 + conf_str[7].len);
			ctmp->design_str = malloc_vital(1 + conf_str[7].len);
			*(ctmp->design_str + 0) = 0x1b;
			memcpy(ctmp->design_str + 1, conf_str[7].ptr,
			       conf_str[7].len);
			ctmp->extended_segment = 0;
		}

		cs_num += 1;
	}
	csc_conf_close(conf_file);

	return ct_map_conf_first;
}
