Esempio n. 1
0
FILE *cfh_fopen(const char *filename, const char *mode)
{
	char filename1[MAX_PATH];
	
	fix_filename(filename, filename1);
	
	return fopen(filename1, mode);	
}
Esempio n. 2
0
int Files::OpenFile(Str255 Name)
{
	char filename1[MAX_PATH];
	
	fix_filename((char *)Name, filename1);
	
	sFile = open(filename1, O_RDONLY | O_BINARY);
	return sFile;
}
Esempio n. 3
0
/*
  Our own special magic version that fixes the filename.
 */
void alutLoadWAVFile_CFH(char *filename, ALenum *format, void **wave,
	unsigned int *size, ALsizei *freq)
{
	char filename1[MAX_PATH];
	ALsizei format1, size1, bits1, freq1;
	
	fix_filename(filename, filename1);
	
	alutLoadWAV(filename1, wave, &format1, &size1, &bits1, &freq1);
	
	*format = format1;
	*size = size1;
	*freq = freq1;
}
Esempio n. 4
0
static int get_value(struct parse_opt_ctx_t *p,
		     const struct option *opt,
		     const struct option *all_opts,
		     int flags)
{
	const char *s, *arg;
	const int unset = flags & OPT_UNSET;
	int err;

	if (unset && p->opt)
		return opterror(opt, "takes no value", flags);
	if (unset && (opt->flags & PARSE_OPT_NONEG))
		return opterror(opt, "isn't available", flags);
	if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
		return opterror(opt, "takes no value", flags);

	switch (opt->type) {
	case OPTION_LOWLEVEL_CALLBACK:
		return (*(parse_opt_ll_cb *)opt->callback)(p, opt, unset);

	case OPTION_BIT:
		if (unset)
			*(int *)opt->value &= ~opt->defval;
		else
			*(int *)opt->value |= opt->defval;
		return 0;

	case OPTION_NEGBIT:
		if (unset)
			*(int *)opt->value |= opt->defval;
		else
			*(int *)opt->value &= ~opt->defval;
		return 0;

	case OPTION_COUNTUP:
		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
		return 0;

	case OPTION_SET_INT:
		*(int *)opt->value = unset ? 0 : opt->defval;
		return 0;

	case OPTION_CMDMODE:
		/*
		 * Giving the same mode option twice, although is unnecessary,
		 * is not a grave error, so let it pass.
		 */
		if (*(int *)opt->value && *(int *)opt->value != opt->defval)
			return opt_command_mode_error(opt, all_opts, flags);
		*(int *)opt->value = opt->defval;
		return 0;

	case OPTION_STRING:
		if (unset)
			*(const char **)opt->value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			*(const char **)opt->value = (const char *)opt->defval;
		else
			return get_arg(p, opt, flags, (const char **)opt->value);
		return 0;

	case OPTION_FILENAME:
		err = 0;
		if (unset)
			*(const char **)opt->value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			*(const char **)opt->value = (const char *)opt->defval;
		else
			err = get_arg(p, opt, flags, (const char **)opt->value);

		if (!err)
			fix_filename(p->prefix, (const char **)opt->value);
		return err;

	case OPTION_CALLBACK:
		if (unset)
			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
		if (opt->flags & PARSE_OPT_NOARG)
			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
		if (get_arg(p, opt, flags, &arg))
			return -1;
		return (*opt->callback)(opt, arg, 0) ? (-1) : 0;

	case OPTION_INTEGER:
		if (unset) {
			*(int *)opt->value = 0;
			return 0;
		}
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			*(int *)opt->value = opt->defval;
			return 0;
		}
		if (get_arg(p, opt, flags, &arg))
			return -1;
		*(int *)opt->value = strtol(arg, (char **)&s, 10);
		if (*s)
			return opterror(opt, "expects a numerical value", flags);
		return 0;

	default:
		die("should not happen, someone must be hit on the forehead");
	}
}
Esempio n. 5
0
/*
Read the requested OGG file into memory, and extract the information required
by OpenAL
*/
void LoadOGG_CFH(char *filename, ALenum *format, void **wave,
	unsigned int *size, ALsizei *freq)
{
	char filename1[MAX_PATH];
	ALsizei format1, size1, freq1;
	void *wave1;
	OggVorbis_File vf;
	vorbis_info *vi;
	FILE *fp;
	int current_section;
	char *buf;
	int asize;
	int err;
	int eof;

#if BYTE_ORDER == BIG_ENDIAN
	const int endian = 1;
#else
	const int endian = 0;
#endif

	/* try to find the real file (and place it in filename1) */
	fix_filename(filename, filename1);

	/* open it for reading */
	fp = fopen(filename1, "rb");
	if (fp == NULL) {
		fprintf(stderr, "ERROR: unable to open %s\n", filename1);
		exit(EXIT_FAILURE);
	}
	
	/* open it up */
	err = ov_open(fp, &vf, NULL, 0);	
	if (err < 0) {
		fprintf(stderr, "ERROR: vorbis error %d opening %s\n", -err, filename1);
		exit(EXIT_FAILURE);
	}

	/* get the ogg information */
	vi = ov_info(&vf, -1);
	if (vi == NULL) {
		fprintf(stderr, "ERROR: vorbis error opening %s (ov_info failed)\n", filename1);
		exit(EXIT_FAILURE);
	}
	
	/* calculate the byte size */
	size1 = vi->channels * 2 * ov_pcm_total(&vf, -1);

	/* hack around some possible ogg vorbis weirdness */
	asize = ((size1 + 2047) / 2048 + 1) * 2048;
	
	/* allocate our buffer */	
	wave1 = malloc(asize);
	
	if (wave1 == NULL) {
		fprintf(stderr, "ERROR: could not allocate %d bytes while loading %s\n", size1, filename1);
		exit(EXIT_FAILURE);
	}

	/* read it in */
	eof = 0;
	buf = (char *)wave1;
	
	while(!eof) {
		long ret = ov_read(&vf, buf, 1024, endian, 2, 1, 
			&current_section);
		
		if (ret == 0) {
			/* end of file */
			eof = 1;
		} else if (ret < 0) {
			/* some sort of error */
			
			/* TODO: is this ok to ignore? */
		} else {
			buf += ret;
		}
	}

	/* get the rest of the information */
	if (vi->channels == 1) {
		format1 = AL_FORMAT_MONO16;
	} else if (vi->channels == 2) {
		format1 = AL_FORMAT_STEREO16;
	} else {
		fprintf(stderr, "ERROR: ogg %s has %d channels\n", filename1, vi->channels);
		exit(EXIT_FAILURE);
	}
	
	freq1 = vi->rate;

	/* we are done with the ogg, so free it */
	ov_clear(&vf);
	
	/* finall, give the values to the caller */	
	*format = format1;
	*size = size1;
	*freq = freq1;
	*wave = wave1;
}
Esempio n. 6
0
char *handle_directive (const char *ptr) {
	static const char *dirs[] = {"db", "dw", "end", "org", "byte", "word", "fill", "block", "addinstr",
		"echo", "error", "list", "nolist", "equ", "show", "option", "seek", "assume", "dl", "long", NULL};
	char name_buf[32];
	int dir;

	//same deal as handle_preop, just with directives instead
	bool valid_directive = false;
	unsigned name_len = 0;
	while (ptr[name_len] != 0 && !isspace(ptr[name_len])) {
		name_len++;
	}

	// If longer than name_buf, it can't be a valid directive.
	if (name_len < sizeof(name_buf)) {
		// Copy string for comparing against
		memcpy(name_buf, ptr, name_len);
		name_buf[name_len] = 0;

		dir = 0;
		while (dirs[dir]) {
			if (!strcasecmp(dirs[dir], name_buf)) {
				valid_directive = true;
				break;
			}
			dir++;
		}
	}

	if (!valid_directive)
		return handle_opcode_or_macro ((char *) ptr - 1);

	ptr = skip_whitespace(&ptr[name_len]);

	switch (dir) {
		case 0: //DB
		case 4: //BYTE
		{
			ptr = parse_emit_string (ptr, ES_BYTE, NULL);
			break;
		}
		case 1: //DW
		case 5: //WORD
		{
			ptr = parse_emit_string (ptr, ES_WORD, NULL);
			break;
		}
		case 18: //DL
		case 19: //LONG
		{
			ptr = parse_emit_string (ptr, ES_LONG, NULL);
			break;
		}
		case 3: //ORG
		{
			int value;
			char value_str[256] = "";
			bool fResult = read_expr(&ptr, value_str, "");
			if (fResult == true)
			{
				if (parse_num(value_str, &value) == true)
				{
					if (value < 0)
					{
						SetLastSPASMError(SPASM_ERR_INVALID_ADDRESS, skip_whitespace(value_str));
					}
					else
					{
						program_counter = value;
					}
				}
			}
			if ((fResult == false) || (strlen(skip_whitespace(value_str)) == 0))
			{
				SetLastSPASMError(SPASM_ERR_VALUE_EXPECTED);
			}
			break;
		}
		case 6: //FILL
		case 7: //BLOCK
		{
			int size, fill_value;
			char szSize[256], szFill[256];
			bool old_listing_on = listing_on;
			//listing_on = false;

			read_expr (&ptr, szSize, ",");
			parse_num (szSize, &size);
			ptr = skip_whitespace (ptr);
			if (*ptr == ',')
				ptr++;

			if (read_expr (&ptr, szFill, "")) {
				//if there's a value to fill the block with, then handle that
				parse_num (szFill, &fill_value);
			} else {
				//otherwise use 0
				fill_value = 0;
			}

			if (size < 0) {
				SetLastSPASMError(SPASM_ERR_SIZE_MUST_BE_POSITIVE, szSize);
				listing_on = old_listing_on;
				break;
			}

			if (fill_value < -128 || fill_value > 255)
			{
				SetLastSPASMWarning(SPASM_WARN_TRUNCATING_8);
			}

			program_counter += size;
			stats_datasize += size;

			while (size-- > 0)
				write_out (fill_value & 0xFF);

			//listing_on = old_listing_on;
			break;
		}
		case 8: //ADDINSTR
		{
			instr *instr = (struct _instr *) malloc (sizeof (struct _instr));
			char word[256];
			int result;
			char *mnemonic;
			size_t i, base = 0, size_left;
			int j;
			opcode *last_opcode = NULL, *curr_opcode = all_opcodes, *new_opcode;

			memset (instr, 0, sizeof (struct _instr));

			// Mnemonic
			if (!read_expr (&ptr, word, " \t")) goto addinstr_fail;
			mnemonic = strdup (word);

			// Args
			if (!read_expr (&ptr, word, " \t")) goto addinstr_fail;
			reduce_string (word);
			instr->args = strdup (word);

			// Instruction data
			if (!read_expr (&ptr, word, " \t")) goto addinstr_fail;
	        conv_hex (word, word + strlen (word), &result);
	        instr->instr_size = strlen (word) / 2;

	        for (j = instr->instr_size - 1; j >= 0; j--)
	        	instr->instr_data[instr->instr_size - j - 1] = (result >> (j * 8)) & 0xFF;


			// Size
			if (!read_expr (&ptr, word, " \t")) goto addinstr_fail;
			if (!parse_num (word, &instr->size)) goto addinstr_fail;

			// Class
			read_expr (&ptr, word, " \t");

			// Extended
			read_expr (&ptr, word, " \t");

			// End data ...
			if (read_expr (&ptr, word, " \t")) {
				int output;
				conv_hex (word, word + strlen (word), &output);
				instr->end_data = (unsigned char) output;
				instr->has_end_data = true;
			}

			size_left = instr->size - instr->instr_size;
			while ((i = strcspn (&instr->args[base], "*")) + base != strlen (instr->args)) {
				switch (size_left - instr->has_end_data) {
					case 2:	((char *) instr->args)[base+i] = '*'; break;
					case 1: ((char *) instr->args)[base+i] = '&'; break;
					default:
						((char *) instr->args)[base+i] = '&'; break;
						//show_error ("Invalid wildcard type in ADDRINSTR");
						//goto addinstr_fail;
						break;
				}
				size_left -= 2;
				base += i + 1;
			}

			new_opcode = (opcode *)  malloc (sizeof (opcode));
			new_opcode->name = mnemonic;
			new_opcode->num_instrs = 1;
			new_opcode->use_count = 0;
			new_opcode->instrs = instr;
			new_opcode->is_added = true;

			while (curr_opcode) {
				if (strcasecmp (mnemonic, curr_opcode->name) == 0)
					break;
				last_opcode = curr_opcode;
				curr_opcode = curr_opcode->next;
			}

			if (curr_opcode == NULL) {
				last_opcode->next = new_opcode;
				new_opcode->next = NULL;
			} else {
				new_opcode->next = curr_opcode;
				if (last_opcode)
					last_opcode->next = new_opcode;
				else
					all_opcodes = new_opcode;
			}

			// You can ignore class, etc
			ptr = skip_to_line_end (ptr);
			break;
addinstr_fail:
			SetLastSPASMError(SPASM_ERR_INVALID_ADDINSTR);
			if (instr && instr->args) free ((void *) instr->args);
			if (instr) free (instr);
			ptr = skip_to_line_end(ptr);
			break;
		}
		case 9: //ECHO
		{
			if (ptr[0] == '>')
			{
				char target_format[2] = "w";
				FILE *echo_target;
				char filename[MAX_PATH];
				char temp_filename[MAX_PATH];
				define_t *define;

				if ((++ptr)[0] == '>')
					target_format[0] = 'a';

				ptr = skip_whitespace (ptr + 1);
				if (is_end_of_code_line (ptr)) {
					SetLastSPASMError(SPASM_ERR_FILENAME_EXPECTED);
					return NULL;
				}

				read_expr (&ptr, filename, " \t");

				// Is the filename given a macro?
				if ((define = search_defines (filename)))
					strncpy (filename, skip_whitespace(define->contents), sizeof (filename));
					
				reduce_string(filename);

				if (is_abs_path(filename)) {
					strncpy(temp_filename, skip_whitespace (filename), sizeof (temp_filename));
				} else {
					strncpy(temp_filename, temp_path, sizeof (temp_filename));
					strncat(temp_filename, "/", sizeof (temp_filename) - 1);
					strncat(temp_filename, skip_whitespace (filename), sizeof (temp_filename) - 1);
				}
				echo_target = fopen (fix_filename (temp_filename), target_format);
				if (echo_target == NULL) {
					SetLastSPASMError(SPASM_ERR_NO_ACCESS, filename);
					return NULL;
				}

				//if the output's redirected to a file, process it now
				WORD orig_attributes = save_console_attributes();
				set_console_attributes (COLOR_GREEN);
				ptr = parse_emit_string (ptr, ES_ECHO, echo_target);
				restore_console_attributes(orig_attributes);
			} else {
				char expr[256];
				read_expr (&ptr, expr, "");

				// If it craps out for some reason, save it for the next pass
				int session = StartSPASMErrorSession();
				parse_emit_string (expr, ES_ECHO, NULL);

				if (IsSPASMErrorSessionFatal(session) == true)
				{
					add_pass_two_output (expr, OUTPUT_ECHO);
				}
				else if (GetSPASMErrorSessionErrorCount(session) > 0)
				{
					WORD orig_attributes = save_console_attributes();
					set_console_attributes(COLOR_GREEN);
					int internal_session = StartSPASMErrorSession();
					parse_emit_string (expr, ES_ECHO, stdout);
					restore_console_attributes(orig_attributes);
					EndSPASMErrorSession(internal_session);

					ReplaySPASMErrorSession(session);
				}
				else
				{
					expand_buf_t *echo = eb_init(256);
					parse_emit_string (expr, ES_FCREATE, echo);

					char *echo_string = eb_extract(echo);
					eb_free(echo);

					char *expanded_string = escape_string(echo_string);
					free(echo_string);

					add_pass_two_output (expanded_string, OUTPUT_ECHO);
					free(expanded_string);
				}
				EndSPASMErrorSession(session);
			}
			break;
		}
		case 10: //ERROR
		{
			expand_buf_t *eb = eb_init(64);
			ptr = parse_emit_string(ptr, ES_FCREATE, eb);

			char *error_str = eb_extract(eb);
			eb_free(eb);

			SetLastSPASMError(SPASM_ERR_CUSTOM, error_str);
			free(error_str);
			break;
		}
		case 11: //LIST
		{
			//if listing was off already, then the listing
			// for the start of this line wouldn't have been
			// written, so make sure the end doesn't get
			// written either
			if (!listing_on)
				listing_for_line_done = true;
			listing_on = true;
			break;
		}
		case 12: //NOLIST
		{
			//if listing is on, then it would've written
			// the starting stuff for this line already,
			// so take that out
			if ((mode & MODE_LIST) && listing_on)
				listing_offset -= 14;
			listing_on = false;
			break;
		}
		case 13: //EQU
		{
			// Finally, a proper .equ!
			int value;
			char value_str[256];

			read_expr (&ptr, value_str, "");
			if (!parse_num (value_str, &value) && parser_forward_ref_err) {
			} else {
				if (last_label == NULL)
					SetLastSPASMError(SPASM_ERR_EQUATE_MISSING_LABEL);
				else
					last_label->value = value;
			}
			break;
		}
		case 14: //SHOW
		{
			char name[256];
			define_t *define;

			//get the name
			read_expr (&ptr, name, "");
			define = search_defines (name);
			if (define == NULL) {
				//if it doesn't exist yet, save it for the second pass
				add_pass_two_output (name, OUTPUT_SHOW);
			} else {
				//otherwise, show it now
				show_define (define);
			}
			break;
		}
		case 15: //OPTION
		{
			char *word = NULL;
			arg_context_t context = ARG_CONTEXT_INITIALIZER;
			while ((word = extract_arg_string(&ptr, &context)) != NULL)
			{
				char name[256], *expr = word;
				char *define_name;
				define_t *define;

				read_expr(&expr, name, "=");
				if (*expr == '=')
				{
					expr++;
				}
				
				if (!(isalpha(name[0]))) {
					SetLastSPASMError(SPASM_ERR_INVALID_OPTION, name);
					return (char *) ptr;
				}
				
				if (is_end_of_code_line (skip_whitespace (expr)))
					expr = strdup ("1");
				else {
					//if (!parse_num (expr, NULL))
					//	return NULL;
					expr = strdup (expr);
				}

				if (strlen (name) == 0) {
					show_error ("Invalid option statement");
					return NULL;
				}

				define_name = (char *) malloc (strlen (name) + 3);
				strcat (strcpy (define_name, "__"), name);

				define = add_define (define_name, NULL);
				set_define (define, expr, -1, false);
				free(expr);
			}
			break;
		}
		case 16: //SEEK
		{
			int value;
			char value_str[256];

			read_expr (&ptr, value_str, "");
			parse_num (value_str, (int *) &value);

			//printf("value_str: %s\npc: %d\n", value_str, program_counter);

			if (value > program_counter && (value - program_counter > output_buf_size - (out_ptr - output_contents)))
				show_fatal_error ("Seek location %d out of bounds", value);
			else if (value < program_counter && (value - (int) program_counter + (out_ptr - output_contents) < 0))
				show_fatal_error ("Seek value %d too small", value);
		
			out_ptr += value - ((int) program_counter);
			//printf("base: %p; ptr: %p\n", output_contents, out_ptr);
			program_counter = value;
			break;
		}
		case 17: //ASSUME
		{
			char args[256];
			read_expr(&ptr, args, "");

			char word[256];
			char *value_str = args;
			read_expr(&value_str, word, "=");

			int value = 1;
			bool success = true;
			if (*value_str == '=') {
				success = parse_num(value_str+1, &value);
			}

			if (!(mode & MODE_EZ80) || strcasecmp(word, "adl") || !success) {
				SetLastSPASMError(SPASM_ERR_INVALID_OPTION, args);
				return (char *)ptr;
			}

			adl_mode = (value != 0);
			break;
		}
	}

	return (char *) ptr;
}
Esempio n. 7
0
static int get_value(struct parse_opt_ctx_t *p,
		     const struct option *opt, int flags)
{
	const char *s, *arg;
	const int unset = flags & OPT_UNSET;
	int err;

	if (unset && p->opt)
		return opterror(opt, "takes no value", flags);
	if (unset && (opt->flags & PARSE_OPT_NONEG))
		return opterror(opt, "isn't available", flags);

	if (!(flags & OPT_SHORT) && p->opt) {
		switch (opt->type) {
		case OPTION_CALLBACK:
			if (!(opt->flags & PARSE_OPT_NOARG))
				break;
			/* FALLTHROUGH */
		case OPTION_BOOLEAN:
		case OPTION_BIT:
		case OPTION_NEGBIT:
		case OPTION_SET_INT:
		case OPTION_SET_PTR:
			return opterror(opt, "takes no value", flags);
		default:
			break;
		}
	}

	switch (opt->type) {
	case OPTION_BIT:
		if (unset)
			*(int *)opt->value &= ~opt->defval;
		else
			*(int *)opt->value |= opt->defval;
		return 0;

	case OPTION_NEGBIT:
		if (unset)
			*(int *)opt->value |= opt->defval;
		else
			*(int *)opt->value &= ~opt->defval;
		return 0;

	case OPTION_BOOLEAN:
		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
		return 0;

	case OPTION_SET_INT:
		*(int *)opt->value = unset ? 0 : opt->defval;
		return 0;

	case OPTION_SET_PTR:
		*(void **)opt->value = unset ? NULL : (void *)opt->defval;
		return 0;

	case OPTION_STRING:
		if (unset)
			*(const char **)opt->value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			*(const char **)opt->value = (const char *)opt->defval;
		else
			return get_arg(p, opt, flags, (const char **)opt->value);
		return 0;

	case OPTION_FILENAME:
		err = 0;
		if (unset)
			*(const char **)opt->value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			*(const char **)opt->value = (const char *)opt->defval;
		else
			err = get_arg(p, opt, flags, (const char **)opt->value);

		if (!err)
			fix_filename(p->prefix, (const char **)opt->value);
		return err;

	case OPTION_CALLBACK:
		if (unset)
			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
		if (opt->flags & PARSE_OPT_NOARG)
			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
		if (get_arg(p, opt, flags, &arg))
			return -1;
		return (*opt->callback)(opt, arg, 0) ? (-1) : 0;

	case OPTION_INTEGER:
		if (unset) {
			*(int *)opt->value = 0;
			return 0;
		}
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			*(int *)opt->value = opt->defval;
			return 0;
		}
		if (get_arg(p, opt, flags, &arg))
			return -1;
		*(int *)opt->value = strtol(arg, (char **)&s, 10);
		if (*s)
			return opterror(opt, "expects a numerical value", flags);
		return 0;

	default:
		die("should not happen, someone must be hit on the forehead");
	}
}
Esempio n. 8
0
/**
 * Does a source file.
 *
 * @param filename_in  the file to read
 * @param filename_out NULL (stdout) or the file to write
 * @param parsed_file  NULL or the filename for the parsed debug info
 * @param no_backup    don't create a backup, if filename_out == filename_in
 * @param keep_mtime   don't change the mtime (dangerous)
 */
static void do_source_file(const char *filename_in,
                           const char *filename_out,
                           const char *parsed_file,
                           bool       no_backup,
                           bool       keep_mtime)
{
   FILE     *pfout;
   bool     did_open    = false;
   bool     need_backup = false;
   file_mem fm;
   string   filename_tmp;

   /* Do some simple language detection based on the filename extension */
   if (!cpd.lang_forced || (cpd.lang_flags == 0))
   {
      cpd.lang_flags = language_from_filename(filename_in);
   }

   /* Try to read in the source file */
   if (load_mem_file(filename_in, fm) < 0)
   {
      LOG_FMT(LERR, "Failed to load (%s)\n", filename_in);
      cpd.error_count++;
      return;
   }

   LOG_FMT(LSYS, "Parsing: %s as language %s\n",
           filename_in, language_to_string(cpd.lang_flags));

   if (filename_out == NULL)
   {
      pfout = stdout;
   }
   else
   {
      /* If the out file is the same as the in file, then use a temp file */
      filename_tmp = filename_out;
      if (strcmp(filename_in, filename_out) == 0)
      {
         /* Create 'outfile.uncrustify' */
         filename_tmp = fix_filename(filename_out);

         if (!no_backup)
         {
            if (backup_copy_file(filename_in, fm.raw) != SUCCESS)
            {
               LOG_FMT(LERR, "%s: Failed to create backup file for %s\n",
                       __func__, filename_in);
               cpd.error_count++;
               return;
            }
            need_backup = true;
         }
      }
      make_folders(filename_tmp);

      pfout = fopen(filename_tmp.c_str(), "wb");
      if (pfout == NULL)
      {
         LOG_FMT(LERR, "%s: Unable to create %s: %s (%d)\n",
                 __func__, filename_tmp.c_str(), strerror(errno), errno);
         cpd.error_count++;
         return;
      }
      did_open = true;
      //LOG_FMT(LSYS, "Output file %s\n", filename_out);
   }

   cpd.filename = filename_in;
   uncrustify_file(fm, pfout, parsed_file);

   if (did_open)
   {
      fclose(pfout);

      if (need_backup)
      {
         backup_create_md5_file(filename_in);
      }

      if (filename_tmp != filename_out)
      {
         /* We need to compare and then do a rename */
         if (file_content_matches(filename_tmp, filename_out))
         {
            /* No change - remove tmp file */
            (void)unlink(filename_tmp.c_str());
         }
         else
         {
#ifdef WIN32

            /* windows can't rename a file if the target exists, so delete it
             * first. This may cause data loss if the tmp file gets deleted
             * or can't be renamed.
             */
            (void)unlink(filename_out);
#endif
            /* Change - rename filename_tmp to filename_out */
            if (rename(filename_tmp.c_str(), filename_out) != 0)
            {
               LOG_FMT(LERR, "%s: Unable to rename '%s' to '%s'\n",
                       __func__, filename_tmp.c_str(), filename_out);
               cpd.error_count++;
            }
         }
      }

#ifdef HAVE_UTIME_H
      if (keep_mtime)
      {
         /* update mtime -- don't care if it fails */
         fm.utb.actime = time(NULL);
         (void)utime(filename_in, &fm.utb);
      }
#endif
   }
}