#include "afx.h"


static struct {
	char opt;
	int flag;	
} options[] = {
	{ 'e', OPT_ERRFILE  },
	{ 'i', OPT_CPPFILE  },
	{ 'l', OPT_LSTFILE  },
	{ 'A', OPT_EXTEND   },
	{ 'm', OPT_MAPFILE  },
	{ 'n', OPT_NODEFLIB },
	{ 'v', OPT_DEBUG	},
	{ 'k', OPT_KEEPGEN 	},
	{ 'K', OPT_KEEPRSP 	},
	{ 'X', OPT_EXCEPTION},
	{ 'q', OPT_QUIET }
};


static struct {
	char *name;
	int flag;
} assemblers[] = {
	{ "nasm",	OPT_NASM },
	{ "tasm",	OPT_TASM },
	{ "tasmx",	OPT_TASMX },
	{ "tasm32", OPT_TASM32 },
	{ "masm",	OPT_MASM },
	{ "ml",		OPT_ML },
	{ "wasm",	OPT_WASM },
	{ "lasm", 	OPT_LASM },
	{ "lasm32", OPT_LASM32 }
};


static struct {
	char *name;
	int flag;
} linkers[] = {
	{ "valx",	OPT_VALX },
	{ "tlink",	OPT_TLINK },
	{ "link",	OPT_LINK },
	{ "wlink", 	OPT_WLINK }
};


static struct {
	char *name;
	int flag;
} dosexs[] = {
	{ "pmode",	OPT_PMODE },
	{ "pmodew",	OPT_PMODEW },
	{ "dos4g",	OPT_DOS4G },
	{ "wdosx", 	OPT_WDOSX },
	{ "dos32a",	OPT_DOS32A },
	{ "zrdx",	OPT_ZRDX },
	{ "causeway", OPT_CAUSEWAY },

	{ "w32con", OPT_W32CON },
	{ "w32gui", OPT_W32GUI },
	{ "w32dll", OPT_W32DLL }
};


static int make_opt = OPT_COMPILE | OPT_ASSEMBLY | OPT_LINKING;	
static int opts = OPT_ERRFILE;	/* -e+ -A+ */
static int assembler = OPT_NASM;		   
static int linker = OPT_VALX;
#ifdef MSDOS
static int dosex = OPT_PMODE;
#else
static int dosex = OPT_W32CON;
#endif

int get_assembler(void) { return assembler; }
int get_linker(void) { return linker; }
int get_dosex(void) { return dosex; }


static void set_option( int what, int value ) {
	if ( value ) {
		opts |= what;
	} else {
		opts &= ~what;
	}
}

int get_option( int what ) {
	return (opts & what);
}

int get_make_opt( int what ) {
	return (make_opt & what);
}


static char cc_opt[ LINE_MAX ];
static char inc_path[ LINE_MAX ];
static char lib_path[ LINE_MAX ];


char *get_cc_opt(void) { return cc_opt; }
char *get_inc_path(void) { return inc_path; }
char *get_lib_path(void) { return lib_path; }

char *get_syslib_path(void) {
	static char lib[LINE_MAX];
	int i;
	for (i = 0; lib_path[i] || lib_path[i] == ';'; i++)
		lib[i] = lib_path[i];
	lib[i] = 0;
	return lib;
}

void option( char *opt ) {
	int i;

	assert( opt != NULL );
	for ( i = 0; i < sizeof(options)/sizeof(options[0]); i++) {
		if ( opt[1] == options[i].opt ) {
			if ( opt[2] == '\0' || (opt[2] == '+' && opt[3] == '\0') ) {
				set_option( options[i].flag, 1 );
				return;
			} else if ( opt[2] == '-' && opt[3] == '\0' ) {
				set_option( options[i].flag, 0 );
				return;
			}
		}
	}

	for ( i = 0; i < sizeof(assemblers)/sizeof(assemblers[0]); i++) {
		if ( stricmp( opt+1, assemblers[i].name ) == 0 ) {
			assembler = assemblers[i].flag;
			return;
		}
	}
	
	for ( i = 0; i < sizeof(linkers)/sizeof(linkers[0]); i++) {
		if ( stricmp( opt+1, linkers[i].name ) == 0 ) {
			linker = linkers[i].flag;
			return;
		}
	}

	for ( i = 0; i < sizeof(dosexs)/sizeof(dosexs[0]); i++) {
		if ( stricmp( opt+1, dosexs[i].name ) == 0 ) {
			dosex = dosexs[i].flag;
			return;
		}
	}

	if ( opt[1] == 'e' && (opt[2] == '=' || opt[2] == '#' ) ) {
		set_exe_name( opt+3 );
		return;
	}

	if ( opt[1] == 'a' && opt[2] == '\0' ) {
		make_opt = OPT_ASSEMBLY;
		return;
	}

	if ( opt[1] == 'c' && opt[2] == '\0' ) {
		make_opt = OPT_ASSEMBLY | OPT_COMPILE;
		return;
	}

	if ( (opt[1] == '?' || opt[1] == 'h' || opt[1] == '?') && opt[2] == '\0' )
		help();

	if (   opt[1] == 'D' 
		|| opt[1] == 'w' 
		|| opt[1] == 'C' 
		|| opt[1] == 'E'
		|| opt[1] == 'O'
		) {
		add2path( cc_opt, opt, CC_DELIM /* ' ' */ );
		return;
	}

	if ( opt[1] == 'I' ) {
		add2path( inc_path, opt+2, PATH_DELIM /* ';' */);
		return;
	}

	if ( opt[1] == 'L' ) {
		add2path( lib_path, opt+2, PATH_DELIM /* ';' */);
		return;
	}

	fprintf( stderr, "Unknown option : '%s'\n", opt );
}