view src/main.c @ 81:c06dcab17923 v2.1

*: change license to BSD, update README for Unicode src/gui: use tchar.h for unicode instead of our own macros
author Paper <paper@paper.us.eu.org>
date Fri, 22 Mar 2024 22:04:16 -0400
parents 8f90d5addda9
children 1acd477da42f
line wrap: on
line source

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <getopt.h>
#include <libgen.h>

#include "common.h"

/* non-portable functions */
static inline char* msvpvf_internal_strdup(const char* str) {
	size_t len = strlen(str) + 1;

	char* copy = malloc(len);
	if (!copy)
		return NULL;

	memcpy(copy, str, len);
	return copy;
}

/* source needs read permissions, target needs write permissions, both must be in binary mode */
static inline int copy_file(FILE* source, FILE* target) {
	char ch[4096];

	while (!feof(source)) {
		size_t b = fread(ch, 1, sizeof(ch), source);
		if (b)
			fwrite(ch, 1, b, target);
	}

	return 0;
}

static inline const char* type_to_string(enum types type) {
	switch (type) {
		case TYPES_VF: return "Movie Studio";
		case TYPES_VEG: return "Vegas Pro";
		case TYPES_UNKNOWN:
		default: return "Unknown";
	}
}

static inline const char* type_to_extension(enum types type) {
	switch (type) {
		case TYPES_VF: return "vf";
		case TYPES_VEG:
		case TYPES_UNKNOWN:
		default: return "veg";
	}
}

#ifndef ARRAYSIZE
#define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif

static const char* help_text =
	"msvpvf by Paper\n"
	"usage: %s <input>... (arguments)\n"
	"\n"
	"arguments:\n"
	"  -t, --type       one of [vf,veg] (required)\n"
	"  -v, --version    version to convert to (required)\n"
	"  -h, --help       show this screen (optional)\n";

static struct option options_long[] = {
	{"version", required_argument, NULL, 'v'},
	{"type", required_argument, NULL, 't'},
	{"help", 0, NULL, 'h'}
};

int main(int argc, char *argv[]) {
	uint8_t version = 0;
	enum types type = TYPES_UNKNOWN;

	int c;
	int option_index = 0;
	while ((c = getopt_long(argc, argv, "v:t:h", options_long, &option_index)) != -1) {
		/* option argument */
		switch (c) {
			case 'v':
				version = atoi(optarg);
				break;
			case 't':
				if (!strcmp(optarg, "vf")) {
					type = TYPES_VF;
				} else if (!strcmp(optarg, "veg")) {
					type = TYPES_VEG;
				} else {
					fprintf(stderr, "[ERROR]: Received an invalid type parameter!\n");
					printf(help_text, argv[0]);
				}

				break;
			case 'h':
			default:
				printf(help_text, argv[0]);
				break;
		}
	}

	if (argc <= optind) {
		fprintf(stderr, "[ERROR]: Missing input file!\n");
		printf(help_text, argv[0]);
		return 1;
	}

	if (!version || !type) {
		printf(help_text, (argc > 0) ? argv[0] : "msvpvf");
		return 1;
	}

	/* this progressively */
	while (optind < argc) {
		const char* input = argv[optind++];
		FILE* output_file = NULL;

		{
			uint8_t file_version = 0;
			enum types file_type = TYPES_UNKNOWN;

			printf("Input file name: %s\n", input);
			/* print information about the input file */
			FILE* input_file = fopen(input, "rb");
			if (!input_file) {
				fprintf(stderr, "[ERROR]: Error opening input file %s!\n\n", input);
				continue;
			}

			if (fgetc(input_file) == EOF) {
				fprintf(stderr, "[ERROR]: Input file \"%s\" is empty.\n", input);
				fclose(input_file);
				continue;
			}

			if (get_file_information(input_file, &file_version, &file_type)) {
				fprintf(stderr, "[ERROR]: Failed to get file information for input file \"%s\"!\n", input);
				fclose(input_file);
				continue;
			}

			printf("Input file version: %u\n", file_version);
			printf("Input file type: %s\n\n", type_to_string(file_type));

			{
				/* open the output file... */
				char* basec = msvpvf_internal_strdup(input);
				char* bname = basename(basec);
				int ext = strrchr(bname, '.') - bname;

				/* create the output filename */
				int needed_size = snprintf(NULL, 0, "V%u_%.*s.%s", version, ext, bname, type_to_extension(type));
				char* output = malloc((needed_size + 1) * sizeof(char));
				if (!output) {
					fprintf(stderr, "[ERROR]: Failed to allocate memory for output string!\n");
					free(basec);
					return 1;
				}

				snprintf(output, needed_size + 1, "V%u_%.*s.%s", version, ext, bname, type_to_extension(type));
				printf("Output filename: %s\n", output);

				output_file = fopen(output, "w+b");
				if (!output_file) {
					fprintf(stderr, "[ERROR]: Failed to open output file %s! Do you have write permissions?\n", output);
					free(basec);
					free(output);
					continue;
				}
				free(basec);
				free(output);
			}

			copy_file(input_file, output_file);

			fflush(stdout);
			fclose(input_file);
		}

		set_file_information(output_file, version, type);
		fclose(output_file);
	}

	return 0;
}