Exemple #1
0
// Include source file ("!source" or "!src"). Has to be re-entrant.
static enum eos_t PO_source(void) {// Now GotByte = illegal char
	FILE*	fd;
	char	local_gotbyte;
	input_t	new_input,
		*outer_input;

	// Enter new nesting level.
	// Quit program if recursion too deep.
	if(--source_recursions_left < 0)
		Throw_serious_error("Too deeply nested. Recursive \"!source\"?");
	// Read file name. Quit function on error.
	if(Input_read_filename(TRUE))
		return(SKIP_REMAINDER);
	// If file could be opened, parse it. Otherwise, complain.
	if((fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY))) {
		char	*filename = (char *) safe_malloc(GlobalDynaBuf->size);	// MPi: Arrays must be a constant expression

		strcpy(filename, GLOBALDYNABUF_CURRENT);
		outer_input = Input_now;// remember old input
		local_gotbyte = GotByte;// CAUTION - ugly kluge
		Input_now = &new_input;// activate new input
		Parse_and_close_file(fd, filename);
		Input_now = outer_input;// restore previous input
		GotByte = local_gotbyte;// CAUTION - ugly kluge
		free(filename);
	} else
		Throw_error(exception_cannot_open_input_file);
	// Leave nesting level
	source_recursions_left++;
	return(ENSURE_EOS);
}
Exemple #2
0
// Tidy up before exiting by saving label dump
int ACME_finalize(int exit_code) {
	FILE*	fd;

	if(labeldump_filename) {
#if defined(USE_FOPEN_S)
		errno_t err = fopen_s(&fd,labeldump_filename, FILE_WRITETEXT);
		if(ferr(fd,err)) {
#else
		fd = fopen(labeldump_filename, FILE_WRITETEXT);
		if(fd) {
#endif
			Label_dump_all(fd);
			fclose(fd);
		} else {
			fprintf(stderr,
				"Error: Cannot open label dump file \"%s\".\n",
				labeldump_filename);
			exit_code = EXIT_FAILURE;
		}
	}

	if(vicelabeldump_filename) {
#if defined(USE_FOPEN_S)
		errno_t err = fopen_s(&fd,vicelabeldump_filename, FILE_WRITETEXT);
		if(ferr(fd,err)) {
#else
		fd = fopen(vicelabeldump_filename, FILE_WRITETEXT);
		if(fd) {
#endif
			Label_dump_all_vice(fd);
			fclose(fd);
		} else {
			fprintf(stderr,
				"Error: Cannot open label dump file \"%s\".\n",
				vicelabeldump_filename);
			exit_code = EXIT_FAILURE;
		}
	}

	return(exit_code);
}

// Save output file
static void save_output_file(void) {
	FILE*	fd;
#if defined(USE_FOPEN_S)
 	errno_t err;
#endif

	// if no output file chosen, tell user and do nothing
	if(output_filename == NULL) {
		fputs("No output file specified (use the \"-o\" option or the \"!to\" pseudo opcode).", stderr);
		return;
	}

#if defined(USE_FOPEN_S)
		err = fopen_s(&fd,output_filename, FILE_WRITETEXT);
		if((fd == NULL) | (err != NULL)) {
#else
		fd = fopen(output_filename, FILE_WRITEBINARY);
		if(fd == NULL) {
#endif
		fprintf(stderr, "Error: Cannot open output file \"%s\".\n",
			output_filename);
		return;
	}
	Output_save_file(fd);
	fclose(fd);
}

// Perform a single pass. Returns number of "NeedValue" type errors.
static int perform_pass(void) {
	FILE*	fd;
	int	i;

	// call modules' "pass init" functions
	CPU_passinit(default_cpu);// set default cpu values (PC undefined)
	Output_passinit(start_addr);// call after CPU_passinit(), to define PC
	Encoding_passinit();	// set default encoding
	Section_passinit();	// set initial zone (untitled)
	// init variables
	pass_undefined_count = 0;	// no "NeedValue" errors yet
	pass_real_errors = 0;	// no real errors yet
	// Process toplevel files
	for(i = 0; i<toplevel_src_count; i++) {
#if defined(USE_FOPEN_S)
		errno_t err = fopen_s(&fd,toplevel_sources[i], FILE_READBINARY);
		if(ferr(fd,err))
#else
		fd = fopen(toplevel_sources[i], FILE_READBINARY);
		if(fd)
#endif
			Parse_and_close_file(fd, toplevel_sources[i]);
		else {
			fprintf(stderr, "Error: Cannot open toplevel file \"%s\".\n", toplevel_sources[i]);
			pass_real_errors++;
		}
	}
	if(pass_real_errors)
		exit(ACME_finalize(EXIT_FAILURE));
	else
		Output_end_segment();
	return(pass_undefined_count);
}

// do passes until done (or errors occured). Return whether output is ready.
static bool do_actual_work(void) {
	int	undefined_prev,	// "NeedValue" errors of previous pass
		undefined_curr;	// "NeedValue" errors of current pass

	if(Process_verbosity > 1)
		puts("First pass.");
	pass_count = 0;
	undefined_curr = perform_pass();	// First pass
	// now pretend there has been a pass before the first one
	undefined_prev = undefined_curr + 1;
	// As long as the number of "NeedValue" errors is decreasing but
	// non-zero, keep doing passes.
	while(undefined_curr && (undefined_curr < undefined_prev)) {
		pass_count++;
		undefined_prev = undefined_curr;
		if(Process_verbosity > 1)
			puts("Further pass.");
		undefined_curr = perform_pass();
	}
	// If still errors (unsolvable by doing further passes),
	// perform additional pass to find and show them
	if(undefined_curr == 0)
		return(TRUE);
	if(Process_verbosity > 1)
		puts("Further pass needed to find error.");
	ALU_throw_errors();	// activate error output (CAUTION - one-way!)
	pass_count++;
	perform_pass();	// perform pass, but now show "value undefined"
	return(FALSE);
}