/**********************************************************************
 
	Copyright (C) 2003-2004
	Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/


#include	<unistd.h>
#include	<stdio.h>
#include	<fcntl.h>
#include	<stdlib.h>
#include	<string.h>

int inp_len;
char * input;

void
input_buffer(char * filename)
{
int fd;
int len;
	fd = open(filename,O_RDONLY);
	if ( fd < 0 ) {
		perror("input buffer");
		exit(1);
	}
	inp_len = len = lseek(fd,0,SEEK_END);
	input = malloc(len);
	lseek(fd,0,SEEK_SET);
	read(fd,input,len);
	close(fd);
}

int
name_ch(char ch)
{
	if ( 'a' <= ch && ch <= 'z' )
		return 0;
	if ( 'A' <= ch && ch <= 'Z' )
		return 0;
	if ( '0' <= ch && ch <= '9' )
		return 0;
	if ( ch == '_' )
		return 0;
	return -1;
}

int
replace_cmp(char * target,int pos)
{
int len;
	len = strlen(target);
	if ( inp_len - pos < len )
		return -1;
	if ( pos ) {
		if ( name_ch(input[pos-1]) == 0 )
			return -1;
	}
	if ( memcmp(target,&input[pos],len) )
		return -1;
	if ( inp_len - pos == len )
		return 0;
	else {
		if ( name_ch(input[pos+len]) == 0 )
			return -1;
		else	return 0;
	}
}

int
replace_check(char * target,char * replace)
{
int pt;
	for ( pt = 0 ; pt < inp_len ; pt ++ )
		if ( replace_cmp(target,pt) == 0 )
			return 0;
	return -1;
}


void
output_buffer(char * filename,char * target,char * replace)
{
int pt;
int fd;
int rep_len,tar_len;
	rep_len = strlen(replace);
	tar_len = strlen(target);
	fd = open(filename,O_TRUNC|O_RDWR);
	if ( fd < 0 ) {
		perror("output buffer");
		exit(1);
	}
	for ( pt = 0 ; pt < inp_len ; ) {
		if ( replace_cmp(target,pt) == 0 ) {
			write(fd,replace,rep_len);
			pt += tar_len;
		}
		else {
			write(fd,&input[pt],1);
			pt ++;
		}
	}
	close(fd);
}


int replace_flag;

int
_main(int argc,char ** argv)
{
	input_buffer(argv[1]);
	if ( replace_check(argv[2],argv[3]) )
		return 0;
	replace_flag = 1;
	printf("REPLACE %s\n",argv[1]);
	output_buffer(argv[1],argv[2],argv[3]);
	return 0;
}


int
main(int argc,char ** argv)
{
int fd;
char * switch_argv[4];
int ret;
	if ( strcmp(argv[1],"-switch-add2") == 0 ) {
		_main(argc-1,&argv[1]);
		if ( replace_flag == 1 )
			return 0;
		switch_argv[0] = "replace";
		switch_argv[1] = argv[2];
		switch_argv[2] = argv[4];
		switch_argv[3] = argv[4];
		replace_flag = 0;
		_main(4,switch_argv);
		if ( replace_flag == 1 )
			return 0;
		fd = open(argv[2],O_RDWR|O_APPEND);
		if ( fd < 0 ) {
			perror(argv[2]);
			return -1;
		}
		write(fd,argv[4],strlen(argv[4]));
		write(fd,"\n",1);
		return 0;
	}
	else if ( strcmp(argv[1],"-topc") == 0 ) {
		switch_argv[0] = "replace";
		switch_argv[1] = argv[2];
		switch_argv[2] = "\n";
		switch_argv[3] = "\r\n";
		switch_argv[4] = 0;
		return _main(4,switch_argv);
	}
	else if ( strcmp(argv[1],"-cmp") == 0 ) {
		ret = strcmp(argv[2],argv[3]);
		if ( ret < 0 )
			printf("large");
		else if ( ret > 0 )
			printf("small");
		else	printf("equ");
		return 0;
	}
	else return _main(argc,argv);
}



