/* $Id: swparse_supp.c,v 1.21 2000/02/19 16:24:47 jhl Exp jhl $
 * swparse_supp.c: support routines for the parser.
 *
 */

/*
 * Copyright (C) 1998  James H. Lowe, Jr.
 *
 * COPYING TERMS AND CONDITIONS
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */


#include "swuser_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "strob.h"
#include "uxfio.h"
#include "swparse.h"
#include "swlib.h"
#include "swheaderline.h"

extern int swparse_outputfd;
int swparse_construct_attribute (STROB * strb, int uxfio_ofd, char * src,
			int cmd, int level, char s_keytype, int form_flag);
static int do_indent_only(STROB * strb, int outputfd, int level);

static int
check_ignores(char * line, char ** ignores)
{
	char ** sp = ignores;
	while (*sp) {
		if (strncmp(line, *sp,  strlen(*sp)) == 0) return 1;
		sp++;
	}
	return 0;
}

static 
int 
do_indent_only(STROB * strb, int outputfd, int level)
{
	char * keyword = strob_get_str(strb);
	char * value = strchr(strob_get_str(strb), (int)' ');
	
	if (value) {
		*value='\0'; value++;
		return 
			swdef_write_attribute(keyword, value, level, 0,
				'A' /* SWPARSE_MD_TYPE_ATT */, outputfd);   
	} else {
		return swdef_write_attribute(keyword, value, level, (int)0,
				'O' /* SWPARSE_MD_TYPE_OBJ */, outputfd);   
	}
}

int
swparse_write_attribute_att(int outputfd, char * key, char * val,
					int level, int form_flag)
{
	int ret, newlen;
	STROB * strb;
	char * p;
    
	strb = strob_open (12);
	strob_strcpy(strb, key);
	strob_strcat(strb, " ");
	swparse_expand_n((void**)(&p), &newlen, val);
	strob_strcat ( strb, p );
	if (p) swbis_free(p);
	ret=swparse_construct_attribute(strb, outputfd, (char*)(NULL),
						SWPARSE_ACMD_EMIT, level,
		SWPARSE_MD_TYPE_ATT, form_flag);
	strob_close (strb);
	return ret;
}

int
swparse_ignore_attribute(int filetype, int location, char * line)
{
	int ret = 0;
	char * psf_file_ignores[] = 
		{ "cksum ",
		"compressed_cksum ",
		"compressed_size ",
		"compression_state ",
		"compression_type ",
		"size ",
		(char*)(NULL)
		};
	char * psf_fileset_ignores[] = 
		{ 
		"location ",
		"media_sequence_number ",
		"size ",
		"state ",
		(char*)(NULL)
		};
	char * psf_bundle_ignores[] = 
		{ 
		"location ",
		"qualifier ",
		(char*)(NULL)
		};
	char * psf_distribution_ignores[] = 
		{ 
		"uuid ",
		(char*)(NULL)
		};
	char * info_file_ignores[] = 
		{ 
		"source ",
		(char*)(NULL)
		};
	char * index_ignores[] = 
		{ 
		"size ",
		(char*)(NULL)
		};

	if (filetype == SWPARSE_SWDEF_FILETYPE_INFO) {
		if (location == SWPARSE_ILOC_FILE) {
			ret = check_ignores(line, info_file_ignores);
		}
	} else if (filetype == SWPARSE_SWDEF_FILETYPE_PSF) {
		if (location == SWPARSE_ILOC_FILE) {
			ret = check_ignores(line, psf_file_ignores);
		}
		else if (location == SWPARSE_ILOC_CONTROL_FILE) {
			ret = check_ignores(line, psf_file_ignores);
			if (ret == 0) {
				ret = !strncmp(line, "result ",
						strlen("result "));
			}
		}
		else if (location == SWPARSE_ILOC_FILESET) {
			ret = check_ignores(line, psf_fileset_ignores);
		}
		else if (location == SWPARSE_ILOC_BUNDLE) {
			ret = check_ignores(line, psf_bundle_ignores);
		}
		else if (location == SWPARSE_ILOC_DISTRIBUTION) {
			ret = check_ignores(line, psf_distribution_ignores);
		}
	} else if (filetype == SWPARSE_SWDEF_FILETYPE_INDEX) {
		ret = check_ignores(line, index_ignores);
	}

	return ret;
}

int
swparse_write_attribute_obj(int outputfd, char * key, int level, int form_flag)
{
	int ret;
	STROB * strb;
  
	if (form_flag & SWPARSE_FORM_INDENT) {
		return swdef_write_keyword(key, level, 
				'O' /* SWPARSE_MD_TYPE_OBJ */ , outputfd); 
	}
    
	strb = strob_open (12);
	strob_strcpy(strb, key);
	ret=swparse_construct_attribute(strb, outputfd, (char*)NULL,
						SWPARSE_ACMD_EMIT, level, 
					SWPARSE_MD_TYPE_OBJ, form_flag);
	strob_close (strb);
	return ret;
}

int
swparse_construct_attribute(STROB * strb, int outputfd, char * src,
			int cmd, int level, char s_keytype, int form_flag)
{
	char * ptr, *eptr; 
	char * p;
	char l_swws[]="                                       ";
	int newlen, ret=0, value_length;
	int extra_len;

	if (level > 10) return -1;
	if ((form_flag & SWPARSE_FORM_INDENT) && cmd == SWPARSE_ACMD_EMIT) {
		return do_indent_only(strb, outputfd, level);
	}

	l_swws[level]='\0';
	if ((form_flag & SWPARSE_FORM_MKUP) ||
		((form_flag & SWPARSE_FORM_ALL) == 0)) {
		extra_len=0;
	} else { 
		extra_len=SWPARSE_MKUP_RES; 
	}

	if (cmd == SWPARSE_ACMD_COPY) {
		swparse_expand_n((void**)(&p), &newlen, src);
		strob_strcpy(strb, p);
		swbis_free(p);
	} else if (cmd == SWPARSE_ACMD_CAT) {
		swparse_expand_n((void**)(&p), &newlen, src);
		strob_strcat(strb, p);
		swbis_free(p);
	} else if (cmd == SWPARSE_ACMD_EMIT) {
		int memlen;
		ptr=strob_str(strb);
		if (!strlen(ptr)) {
			strob_strcat(strb,"\"\"");
			ptr=strob_str(strb);
		}
		memlen = strlen(ptr) + level + 6 + extra_len;
		eptr = malloc(memlen);
		strob_setlen(strb, memlen);
		ptr=strob_str(strb);
		if (form_flag & SWPARSE_FORM_MKUP) {
			snprintf(eptr, memlen,
				"%c%02d%s%s\n", s_keytype, level, l_swws, ptr);
			eptr[memlen - 1] = '\0';
		} else if (form_flag & SWPARSE_FORM_MKUP_LEN) {
			p=ptr; 
			while(*p && !isspace((int)*p)) p++; 
			p++;
			value_length=strlen(p);
			snprintf(eptr, memlen,  
				"%-" SWPARSE_MKUP_LEN_WIDTH_C "d %c%02d %s\n",
					value_length, s_keytype, level, ptr);
			eptr[memlen - 1] = '\0';
		} else {
			return -1;
		}
		ret=uxfio_write(outputfd, eptr, strlen(eptr));
		swbis_free(eptr); 
	} else {
		return -1;
	}
	return ret;
}

int 
swparse_print_filename(char * buf, int len, char * filetype,
		char * ws_level_string, char * lex_filename, int form_flag)
{ 
	int value_length; 
	if (form_flag & SWPARSE_FORM_MKUP) {
		snprintf(buf, len, "F%02d %s%s %s\n",
			(int)strlen(ws_level_string)+1,
			ws_level_string, filetype, lex_filename);
		buf[len-1] = '\0';
		uxfio_write (swparse_outputfd, buf, strlen(buf));
	} else {
		value_length=strlen(lex_filename); 
		snprintf(buf, len, 
			"%-" SWPARSE_MKUP_LEN_WIDTH_C "d F%02d %s%s %s\n",
					(int)value_length,
                			(int)strlen(ws_level_string)+1, 
					ws_level_string,  
					filetype, lex_filename);
		buf[len-1] = '\0';
		uxfio_write(swparse_outputfd, buf, strlen(buf));
	}
	return 0;
}
