/*
 * Main for cbind translator
 */
#include "ansi.h"
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "host.h"
#include "files.h"
#include "hash.h"
#include "buffer.h"
#include "cpp.h"
#include "il.h"
#include "allocate.h"
#include "types.h"
#include "vendor.h"

#undef NULL
#define NULL	0

extern int Num_Errors;

int enum_reps;					/* Flag to force enum reps */
int suppress_record_repspec;	/* Suppress record rep clauses */
int repspec_flag;				/* Flag to force record rep clauses */
int comment_size;				/* Flag to force type size output */
int auto_package;				/* Flag to gen packages automatically */
int flag_unions;
int import_decls = 1;			/* Import declarations from included headers */
int translate_comments;			/* Attempt to retain C comments */
int hex_flag;					/* Display values in hex */
int macro_functions;			/* Attempt to translate macros into functions */
int ada_version = 83;
int macro_warnings = 0;			/* Warn about untranslated macros */

vendor_t ada_compiler = unspecified_vendor;

static int
usage(prog)
	char *prog;
{
	fputs("Illegal invocation\n\n", stderr);
	fprintf(stderr, "Usage: %s [flags] input files\n", prog);
	fputs("\n\tflags:\n\n", stderr);
	fputs("\t\t-Dname\n", stderr);
	fputs("\t\t-Dname=value\n", stderr);
	fputs("\t\t\tDefine a macro with an optional value.  By default\n", stderr);
	fputs("\t\t\tmacros will be defined with the value 1.\n\n", stderr);
	fputs("\t\t-Uname\n", stderr);
	fputs("\t\t\tUndefine a builtin macro.\n\n", stderr);
	fputs("\t\t-Idir\n", stderr);
	fputs("\t\t\tAdd a search path for finding include files.\n\n", stderr);
	fputs("\t\t-builtin\n", stderr);
	fputs("\t\t\tDisplay all predefined macros.\n\n", stderr);
	fputs("\t\t-fun\n", stderr);
	fputs("\t\t\tFlag all union declarations.\n\n", stderr);
	fputs("\t\t-cs\n", stderr);
	fputs("\t\t\tAdd sizeof and alignof comments for all decls.\n\n", stderr);
	fputs("\t\t-erc\n", stderr);
	fputs("\t\t\tAlways gen enum rep clauses.\n\n", stderr);
	fputs("\t\t-sih\n", stderr);
	fputs("\t\t\tSuppress import declarations from included headers.\n\n", stderr);
	fputs("\t\t-rrc\n", stderr);
	fputs("\t\t\tAlways gen record rep clauses.\n\n", stderr);
	fputs("\t\t-hex\n", stderr);
	fputs("\t\t\tDisplay all numeric values in hex.\n\n", stderr);
	fputs("\t\t-src\n", stderr);
	fputs("\t\t\tSuppress all record rep clauses.\n\n", stderr);
	fputs("\t\t-ap\n", stderr);
	fputs("\t\t\tAutomatic packaging.\n\n", stderr);
	fputs("\t\t-C\n", stderr);
	fputs("\t\t\tAttempt to retain C comments in the translation.\n\n", stderr);
	fputs("\t\t-cf\n", stderr);
	fputs("\t\t\tAttempt to create C functions from macros.\n\n", stderr);
	fputs("\t\t-rational\n", stderr);
	fputs("\t\t\tSpecify Rational as the target compiler.\n\n", stderr);
	fputs("\t\t-gnat\n", stderr);
	fputs("\t\t\tSpecify gnat as the target compiler.\n\n", stderr);
	fputs("\t\t-vads\n", stderr);
	fputs("\t\t\tSpecify VADS as the target compiler.\n\n", stderr);
	fputs("\t\t-icc\n", stderr);
	fputs("\t\t\tSpecify Irvine Compiler as the target compiler.\n\n", stderr);
	fputs("\t\t-95\n", stderr);
	fputs("\t\t\tOutput Ada 95 (default is Ada 83).\n", stderr);
	
	return 1;
}

static void
do_define(name)
	char *name;
{
	char buf[128];
	char *val, *p, *s;

	if (name[0] == 0) return;

	val = strchr(name, '=');

	if (val == NULL) {
		macro_def(name, "1", 1, -1, 0);
		return;
	}

	val++;

	for (p = buf, s = name; s != val; s++, p++) {
		*p = *s;
	}

	*p = 0;
	macro_def(new_string(buf), val, strlen(val), -1, 0);
}

int
main(argc, argv)
	int argc;
	char *argv[];
{
	extern void gen();

	int i, c;
	int fstart = 0;
	int show = 0;

	macro_init(0);

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			if (fstart != 0) {
				fputs("Place flags before files\n", stderr);
				return usage(argv[0]);
			}

			switch (argv[i][1]) {
			  case 'a':
				if (strcmp(argv[i], "-ap")) {
					return usage(argv[0]);
				}
				else {
					auto_package = 1;
				}
				break;
			  case 'C':
				if (argv[i][2] == 0) {
					translate_comments = 1;
				}
				else {
					return usage(argv[0]);
				}
				break;
			  case 'c':
				if (!strcmp(argv[i], "-cs")) {
					comment_size = 1;
				}
				else if (!strcmp(argv[i], "-cf")) {
					macro_functions = 1;
				}
				else {
					return usage(argv[0]);
				}
				break;
			  case 'e':
				if (strcmp(argv[i], "-erc")) {
					return usage(argv[0]);
				}
				else {
					enum_reps = 1;
				}
				break;
			  case 'f':
				if (strcmp(argv[i], "-fun")) {
					return usage(argv[0]);
				}
				else {
					flag_unions = 1;
				}
				break;
			  case 'D':
				do_define(&argv[i][2]);
				break;
			  case 'm':
				if (strcmp(argv[i], "-mwarn")) {
					return usage(argv[0]);
				}
				else {
					macro_warnings = 1;
				}
				break;
			  case 'g':
				if (strcmp(argv[i], "-gnat")) {
					return usage(argv[0]);
				} else {
					ada_compiler = GNAT;
				}
				break;
			  case '9':
				if (!strcmp(argv[i], "-95")) {
					ada_version = 95;
				} else {
					return usage(argv[0]);
				}
				break;
			  case 'U':
				macro_undef(&argv[i][2]);
				break;
			  case 'I':
				cpp_search_path(&argv[i][2]);
				break;
			  case 'b':
				if (strcmp(argv[i], "-builtin")) {
					return usage(argv[0]);
				}
				else {
					show = 1;
				}
				break;
			  case 'v':
				if (strcmp(argv[i], "-vads")) {
					return usage(argv[0]);
				}
				else {
					ada_compiler = VADS;
				}
				break;
			  case 'i':
				if (!strcmp(argv[i], "-icc")) {
					ada_compiler = ICC;
				}
				else {
					return usage(argv[0]);
				}
				break;
			  case 's':
				if (!strcmp(argv[i], "-sih")) {
					import_decls = 0;
				}
				else if (!strcmp(argv[i], "-src")) {
					suppress_record_repspec = 1;
					repspec_flag = 0;
				}
				else {
					return usage(argv[0]);
				}
				break;
			  case 'h':
				if (!strcmp(argv[i], "-hex")) {
					hex_flag = 1;
				}
				else {
					return usage(argv[0]);
				}
				break;
			  case 'r':
				if (!strcmp(argv[i], "-rational")) {
					ada_compiler = Rational;
				}
				else if (!strcmp(argv[i], "-rrc")) {
					repspec_flag = 1;
				}
				else {
					return usage(argv[0]);
				}
				break;
			  default:
				return usage(argv[0]);
			}
		}
		else if (fstart == 0) {
			fstart = i;
		}
	}

	if (show) {
		cpp_show_predefines();
		if (fstart == 0) return 0;
	}

	if (fstart == 0) {
		return usage(argv[0]);
	}

	type_init();

	for (i = fstart; i < argc; i++) {
		if (cpp_open(argv[i]) != 0) {
			syserr(argv[i],0);
			continue;
		}

		yylex_init();
		yyparse();

		cpp_cleanup();
	}

	gen();

	return !!Num_Errors;
}


syntax highlighted by Code2HTML, v. 0.9.1