示例#1
0
文件: main.c 项目: KnightOS/scas
void validate_scas_runtime() {
	if (scas_runtime.input_files->length == 0) {
		scas_abort("No input files given");
	}
	if (scas_runtime.output_file == NULL) {
		/* Auto-assign an output file name */
		const char *ext;
		if ((scas_runtime.jobs & LINK) == LINK) {
			ext = scas_runtime.output_extension;
		} else {
			ext = "o";
		}
		scas_runtime.output_file = malloc(strlen(scas_runtime.input_files->items[0]) + strlen(ext) + 2);
		strcpy(scas_runtime.output_file, scas_runtime.input_files->items[0]);
		int i = strlen(scas_runtime.output_file);
		while (scas_runtime.output_file[--i] != '.' && i != 0);
		if (i == 0) {
			i = strlen(scas_runtime.output_file);
		} else {
			scas_runtime.output_file[i] = '\0';
		}
		strcat(scas_runtime.output_file, ".");
		strcat(scas_runtime.output_file, ext);
		scas_log(L_DEBUG, "Assigned output file name to %s", scas_runtime.output_file);
	}
}
示例#2
0
文件: main.c 项目: KnightOS/scas
instruction_set_t *find_inst() {
	const char *sets_dir = "/usr/share/scas/tables/";
	const char *ext = ".tab";
	FILE *f = fopen(scas_runtime.arch, "r");
	if (!f) {
		char *path = malloc(strlen(scas_runtime.arch) + strlen(sets_dir) + strlen(ext) + 1);
		strcpy(path, sets_dir);
		strcat(path, scas_runtime.arch);
		strcat(path, ext);
		f = fopen(path, "r");
		free(path);
		if (!f) {
			if (!strcmp(scas_runtime.arch, "z80")) {
				// Load from internal copy
				instruction_set_t *set = load_instruction_set_s(z80_tab);
				return set;
			} else {
				scas_abort("Unknown architecture: %s", scas_runtime.arch);
			}
		}
	}
	instruction_set_t *set = load_instruction_set(f);
	fclose(f);
	return set;
}
示例#3
0
文件: flags.c 项目: heddwch/scas
void parse_flag(const char *flag) {
	flag += 2;
	char *name = NULL;
	char *value = NULL;
	if ((value = strchr(flag, '='))) {
		name = malloc(value - flag + 1);
		strncpy(name, flag, value - flag);
		name[value - flag] = '\0';
		value++;
	} else {
		name = malloc(strlen(flag) + 1);
		strcpy(name, flag);
		value = "yes";
	}

	bool yes = !strcasecmp("yes", value);
	if (!strcasecmp("no", value)) {
		yes = false;
	}

	if (strcmp("explicit-export", name) == 0) {
		scas_runtime.options.explicit_export = yes;
	} else if (strcmp("no-explicit-export", name) == 0) {
		scas_runtime.options.explicit_export = !yes;
	} else if (strcmp("explicit-import", name) == 0) {
		scas_runtime.options.explicit_import = yes;
	} else if (strcmp("no-explicit-import", name) == 0) {
		scas_runtime.options.explicit_import = !yes;
	} else if (strcmp("auto-relocation", name) == 0) {
		scas_runtime.options.auto_relocation = yes;
	} else if (strcmp("no-auto-relocation", name) == 0) {
		scas_runtime.options.auto_relocation = !yes;
	} else if (strcmp("remove-unused-funcs", name) == 0) {
		scas_runtime.options.remove_unused_functions = yes;
	} else if (strcmp("no-remove-unused-funcs", name) == 0) {
		scas_runtime.options.remove_unused_functions = !yes;
	} else if (strcmp("format", name) == 0) {
		struct output_format o = { .name=value };
		struct output_format *res =
			bsearch(&o, output_formats,
				sizeof(output_formats) / sizeof(struct output_format),
				sizeof(struct output_format), format_compare);
		if (!res) {
			scas_abort("Unknown output format %s", value);
		}
		scas_runtime.options.output_format = res->writer;
		scas_runtime.output_extension = res->name;
	} else if (strcmp("8xp-name", name) == 0) {
示例#4
0
文件: main.c 项目: KnightOS/scas
void parse_arguments(int argc, char **argv) {
	int i;
	for (i = 1; i < argc; ++i) {
		if (argv[i][0] == '-' && argv[i][1] != '\0') {
			if (strcmp("-o", argv[i]) == 0 || strcmp("--output", argv[i]) == 0) {
				scas_runtime.output_file = argv[++i];
			} else if (strcmp("-S", argv[i]) == 0 || strcmp("--symbols", argv[i]) == 0) {
				validate_scas_optarg(i, argc, argv);
				scas_runtime.symbol_file = argv[++i];
			} else if (strcmp("-L", argv[i]) == 0 || strcmp("--listing", argv[i]) == 0) {
				validate_scas_optarg(i, argc, argv);
				scas_runtime.listing_file = argv[++i];
			} else if (strcmp("-i", argv[i]) == 0 || strcmp("--input", argv[i]) == 0) {
				validate_scas_optarg(i, argc, argv);
				list_add(scas_runtime.input_files, argv[++i]);
			} else if (strcmp("-c", argv[i]) == 0 || strcmp("--merge", argv[i]) == 0) {
				scas_runtime.jobs &= ~LINK;
			} else if (argv[i][1] == 'f') {
				parse_flag(argv[i]);
			} else if (argv[i][1] == 'I' || strcmp("--include", argv[i]) == 0) {
				char *path;
				if (argv[i][1] == 'I' && argv[i][2] != 0) {
					// -I/path/goes/here
					path = argv[i] + 2;
				} else {
					// [-I | --include] path/goes/here
					validate_scas_optarg(i, argc, argv);
					path = argv[++i];
				}
				int l = strlen(scas_runtime.include_path);
				scas_runtime.include_path = realloc(scas_runtime.include_path, l + strlen(path) + 2);
				strcat(scas_runtime.include_path, ":");
				strcat(scas_runtime.include_path, path);
			} else if (argv[i][1] == 'v') {
				int j;
				for (j = 1; argv[i][j] != '\0'; ++j) {
					if (argv[i][j] == 'v') {
						scas_runtime.verbosity++;
					} else {
						scas_abort("Invalid option %s", argv[i]);
					}
				}
			} else if (argv[i][1] == 'D' || strcmp("--define", argv[i]) == 0) {
				char *name = NULL, *value = NULL;
				if (argv[i][1] == 'D' && argv[i][2]) {
					name = argv[i] + 2;
				} else {
					validate_scas_optarg(i, argc, argv);
					name = argv[++i];
				}
				value = strchr(name, '=');
				if (value) {
					*value = '\0';
					++value;
				} else {
					value = "1";
				}
				macro_t *macro = malloc(sizeof(macro_t));
				macro->parameters = create_list();
				macro->macro_lines = create_list();
				list_add(macro->macro_lines, strdup(value));
				macro->name = strdup(name);
				list_add(scas_runtime.macros, macro);
			} else {
				scas_abort("Invalid option %s", argv[i]);
			}
		} else {
			if (scas_runtime.output_file != NULL || i != argc - 1 || scas_runtime.input_files->length == 0) {
				scas_log(L_INFO, "Added input file '%s'", argv[i]);
				list_add(scas_runtime.input_files, argv[i]);
			} else if (scas_runtime.output_file == NULL && i == argc - 1) {
				scas_runtime.output_file = argv[i];
			}
		}
	}
}
示例#5
0
文件: main.c 项目: KnightOS/scas
/* validate_scas_optarg: ensure that an option that takes an argument was indeed provided an
 *                       argument.
 *  args:
 *    optind: index of the option in _argv_.
 */
void validate_scas_optarg(int optind, int argc, char *argv[]) {
	if (optind == argc - 1 || argv[optind+1][0] == '-') {
		scas_abort("Option requires argument: %s", argv[optind]);
	}
}
示例#6
0
文件: main.c 项目: KnightOS/scas
int main(int argc, char **argv) {
	init_scas_runtime();
	parse_arguments(argc, argv);
	init_log(scas_runtime.verbosity);
	validate_scas_runtime();
	instruction_set_t *instruction_set = find_inst();
	scas_log(L_INFO, "Loaded instruction set: %s", instruction_set->arch);
	list_t *include_path = split_include_path();
	list_t *errors = create_list();
	list_t *warnings = create_list();

	list_t *objects = create_list();
	int i;
	for (i = 0; i < scas_runtime.input_files->length; ++i) {
		scas_log(L_INFO, "Assembling input file: '%s'", scas_runtime.input_files->items[i]);
		indent_log();
		FILE *f;
		if (strcasecmp(scas_runtime.input_files->items[i], "-") == 0) {
			f = stdin;
		} else {
			f = fopen(scas_runtime.input_files->items[i], "r");
		}
		if (!f) {
			scas_abort("Unable to open '%s' for assembly.", scas_runtime.input_files->items[i]);
		}
		char magic[7];
		bool is_object = false;
		if (fread(magic, sizeof(char), 7, f) == 7) {
			if (strncmp("SCASOBJ", magic, 7) == 0) {
				is_object = true;
			}
		}
		fseek(f, 0L, SEEK_SET);

		object_t *o;
		if (is_object) {
			scas_log(L_INFO, "Loading object file '%s'", scas_runtime.input_files->items[i]);
			o = freadobj(f, scas_runtime.input_files->items[i]);
		} else {
			assembler_settings_t settings = {
				.include_path = include_path,
				.set = instruction_set,
				.errors = errors,
				.warnings = warnings,
				.macros = scas_runtime.macros,
			};
			o = assemble(f, scas_runtime.input_files->items[i], &settings);
			fclose(f);
			scas_log(L_INFO, "Assembler returned %d errors, %d warnings for '%s'",
					errors->length, warnings->length, scas_runtime.input_files->items[i]);
		}
		list_add(objects, o);
		deindent_log();
	}

	scas_log(L_DEBUG, "Opening output file for writing: %s", scas_runtime.output_file);
	FILE *out;
	if (strcasecmp(scas_runtime.output_file, "-") == 0) {
		out = stdout;
	} else {
		out = fopen(scas_runtime.output_file, "w+");
	}
	if (!out) {
		scas_abort("Unable to open '%s' for output.", scas_runtime.output_file);
	}

	if ((scas_runtime.jobs & LINK) == LINK) {
		scas_log(L_INFO, "Passing objects to linker");
		linker_settings_t settings = {
			.automatic_relocation = scas_runtime.options.auto_relocation,
			.merge_only = (scas_runtime.jobs & MERGE) == MERGE,
			.errors = errors,
			.warnings = warnings,
			.write_output = scas_runtime.options.output_format
		};
		if (settings.merge_only) {
			object_t *merged = merge_objects(objects);
			fwriteobj(out, merged);
		} else {
			link_objects(out, objects, &settings);
		}
		scas_log(L_INFO, "Linker returned %d errors, %d warnings", errors->length, warnings->length);
	} else {
		scas_log(L_INFO, "Skipping linking - writing to object file");
		object_t *merged = merge_objects(objects);
		fwriteobj(out, merged);
		fflush(out);
		fclose(out);
	}
	if (errors->length != 0) {
		int i;
		for (i = 0; i < errors->length; ++i) {
			error_t *error = errors->items[i];
			fprintf(stderr, "%s:%d:%d: error #%d: %s\n", error->file_name,
					(int)error->line_number, (int)error->column, error->code,
					error->message);
			fprintf(stderr, "%s\n", error->line);
			if (error->column != 0) {
				int j;
				for (j = error->column; j > 0; --j) {
					fprintf(stderr, ".");
				}
				fprintf(stderr, "^\n");
			} else {
				fprintf(stderr, "\n");
			}
		}
		remove(scas_runtime.output_file);
	}
	if (warnings->length != 0) {
		int i;
		for (i = 0; i < errors->length; ++i) {
			warning_t *warning = warnings->items[i];
			fprintf(stderr, "%s:%d:%d: warning #%d: %s\n", warning->file_name,
					(int)warning->line_number, (int)warning->column, warning->code,
					get_warning_string(warning));
			fprintf(stderr, "%s\n", warning->line);
			if (warning->column != 0) {
				int j;
				for (j = warning->column; j > 0; --j) {
					fprintf(stderr, ".");
				}
				fprintf(stderr, "^\n");
			}
		}
	}

	int ret = errors->length;
	scas_log(L_DEBUG, "Exiting with status code %d, cleaning up", ret);
	list_free(scas_runtime.input_files);
	free_flat_list(include_path);
	list_free(objects);
	list_free(errors);
	list_free(warnings);
	instruction_set_free(instruction_set);
	return ret;
}