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

#define INC_LIST_LEN	1000
#define FILE_LEN	100
#define BUF_LEN		1000
char inc_list[INC_LIST_LEN][FILE_LEN];
int inc_max;
FILE * out;

char dep_list[INC_LIST_LEN][FILE_LEN];
int dep_max;


char read_buffer[BUF_LEN];
int read_ptr,read_len;
char output_file[FILE_LEN];

search_dep(char * str)
{
int i;
	for ( i = 0 ; i < dep_max ; i ++ )
		if ( strcmp(dep_list[i],str) == 0 )
			return 1;
	strcpy(dep_list[dep_max],str);
	dep_max ++;
	if ( dep_max > INC_LIST_LEN ) {
		fprintf(stderr,"search_dep over capacity\n");
		exit(1);
	}
	return 0;
}

get_char(char * ch,int fd)
{
int er;
	if ( read_ptr >= read_len ) {
		read_len = read(fd,read_buffer,BUF_LEN);
		if ( read_len <= 0 ) {
			read_ptr = read_len = 0;
			return 1;
		}
		read_ptr = 0;
	}
	*ch = read_buffer[read_ptr++];
	return 0;
}

out_file(char * dep)
{
	if ( out == 0 ) {
		out = fopen(output_file,"w+");
		if ( out == 0 ) {
			printf("cannot open the output file \"%s\"\n",
				output_file);
			exit(1);
		}
	}
	else fprintf(out," ");
	fprintf(out,"%s",dep);
}

scan_include(char * file)
{
char buffer[2*FILE_LEN];
int i,len;
int fd;

	if ( search_dep(file) )
		return;

/*
	printf("open %s\n",file);
*/
	for ( i = 0 ; i < inc_max ; i ++ ) {
		strcpy(buffer,inc_list[i]);
		len = strlen(buffer);
		buffer[len] = '/';
		len ++;
		strcpy(&buffer[len],file);
		fd = open(buffer,O_RDONLY);
		if ( fd >= 0 ) {
			scan(fd);
			close(fd);
			out_file(buffer);
			return;
		}
	}
/*
	printf("cannot open\n");
*/
}


#define GET_CHAR	\
	if ( get_char(&ch,fd) ) \
		return;
scan(int fd)
{
char ch;
char buffer[100];
int ptr;
sharp:



	for ( ; ; ) {
		GET_CHAR
		switch ( ch ) {
		case '#':
			goto inc;
		case '\n':
			goto sharp;
		case ' ':
		case '\t':
			break;
		default:
			goto cr;
		}
	}
inc:
	for ( ; ; ) {
		GET_CHAR
		switch ( ch ) {
		case 'i':
			goto nclude;
		case '\n':
			goto sharp;
		case ' ':
		case '\t':
			break;
		default:
			goto cr;
		}
	}
nclude:
	GET_CHAR
	switch ( ch ) {
	case 'n':
		goto clude;
	case '\n':
		goto sharp;
	default:
		goto cr;
	}
clude:
	GET_CHAR
	switch ( ch ) {
	case 'c':
		goto lude;
	case '\n':
		goto sharp;
	default:
		goto cr;
	}
lude:
	GET_CHAR
	switch ( ch ) {
	case 'l':
		goto ude;
	case '\n':
		goto sharp;
	default:
		goto cr;
	}
ude:
	GET_CHAR
	switch ( ch ) {
	case 'u':
		goto de;
	case '\n':
		goto sharp;
	default:
		goto cr;
	}
de:
	GET_CHAR
	switch ( ch ) {
	case 'd':
		goto e;
	case '\n':
		goto sharp;
	default:
		goto cr;
	}
e:
	GET_CHAR
	switch ( ch ) {
	case 'e':
		goto panc_st;
	case '\n':
		goto sharp;
	default:
		goto cr;
	}
panc_st:
	for ( ; ; ) {
		GET_CHAR
		switch ( ch ) {
		case '"':
			ptr = 0;
			goto panc_end;
		case '\n':
			goto sharp;
		case ' ':
		case '\t':
			break;
		default:
			goto cr;
		}
	}
panc_end:
	for ( ; ; ) {

		GET_CHAR
		switch ( ch ) {
		case '"':
			buffer[ptr] = 0;
			scan_include(buffer);
			goto sharp;
		case '\n':
			goto sharp;
		default:
			buffer[ptr++] = ch;
			break;
		}
	}
cr:

	for ( ; ; ) {

		GET_CHAR
		switch ( ch ) {
		case '\n':
			goto sharp;
		default:
			break;
		}
	}
}


main(int argc,char ** argv)
{
int i;
int inp;
	printf("MDEP\n");
	inp = -1;
	out = 0;
	strcpy(inc_list[inc_max++],".");
	for ( i = 1 ; i < argc ; i ++ ) {
		if ( memcmp(argv[i],"-I",2) == 0 ) {
			strcpy(inc_list[inc_max],
				&argv[i][2]);
			inc_max++;
			if ( inc_max >= INC_LIST_LEN ) {
				fprintf(stderr,"too many -I list\n");
				exit(1);
			}
		}
		else if ( memcmp(argv[i],"-o",2) == 0 ) {
			strcpy(output_file,&argv[i][2]);
		}
		else if ( memcmp(argv[i],"-i",2) == 0 ) {
		char * pt,*pt2;
			inp = open(&argv[i][2],O_RDONLY);
			if ( inp < 0 ) {
				printf("cannot open the file \"%s\"\n",
					argv[i]);
				exit(1);
			}
			strcpy(inc_list[inc_max],
					&argv[i][2]);
			pt = inc_list[inc_max];
			pt2 = pt + strlen(pt);
			for ( ; (unsigned long)pt2 >= (unsigned long)pt ; ) {
				if ( *pt2 == '/' ) {
					*pt2 = 0;
					break;
				}
				pt2--;
			}
			inc_max++;
		}
	}
	if ( inp == -1 || output_file[0] == 0 ) {
		printf("inputfile and/or outputfile is needed\n");
		exit(1);
	}
	scan(inp);
	close(inp);
	if ( out )
		fclose(out);
	exit(0);
}
