comparison src/main.c @ 85:1acd477da42f

posix: improvements
author Paper <paper@paper.us.eu.org>
date Mon, 17 Jun 2024 21:18:37 -0400
parents c06dcab17923
children
comparison
equal deleted inserted replaced
84:7d4db3e24487 85:1acd477da42f
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdint.h> 2 #include <stdint.h>
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <stdarg.h>
4 #include <string.h> 5 #include <string.h>
5 6
6 #include <getopt.h> 7 #include <getopt.h>
7 #include <libgen.h> 8 #include <libgen.h>
8 9
9 #include "common.h" 10 #include "common.h"
10 11
11 /* non-portable functions */ 12 /* non-portable functions */
12 static inline char* msvpvf_internal_strdup(const char* str) { 13 static char* msvpvf_internal_strdup(const char* str) {
13 size_t len = strlen(str) + 1; 14 size_t len = strlen(str) + 1;
14 15
15 char* copy = malloc(len); 16 char* copy = malloc(len);
16 if (!copy) 17 if (!copy)
17 return NULL; 18 return NULL;
18 19
19 memcpy(copy, str, len); 20 memcpy(copy, str, len);
20 return copy; 21 return copy;
21 } 22 }
22 23
24 static char *msvpvf_internal_asnprintf(const char *format, ...) {
25 va_list args;
26 int needed_size;
27 char *output = NULL;
28
29 va_start(args, format);
30
31 needed_size = vsnprintf(NULL, 0, format, args);
32 if (needed_size < 0)
33 return NULL;
34
35 va_end(args);
36
37 output = malloc((needed_size + 1) * sizeof(char));
38 if (!output)
39 return NULL;
40
41 va_start(args, format);
42
43 needed_size = vsnprintf(output, needed_size + 1, format, args);
44 if (needed_size < 0) {
45 free(output);
46 return NULL;
47 }
48
49 va_end(args);
50
51 return output;
52 }
53
23 /* source needs read permissions, target needs write permissions, both must be in binary mode */ 54 /* source needs read permissions, target needs write permissions, both must be in binary mode */
24 static inline int copy_file(FILE* source, FILE* target) { 55 static int copy_file(FILE* source, FILE* target) {
25 char ch[4096]; 56 char ch[4096];
26 57
27 while (!feof(source)) { 58 while (!feof(source)) {
28 size_t b = fread(ch, 1, sizeof(ch), source); 59 size_t b = fread(ch, 1, sizeof(ch), source);
29 if (b) 60 if (b)
31 } 62 }
32 63
33 return 0; 64 return 0;
34 } 65 }
35 66
36 static inline const char* type_to_string(enum types type) { 67 static const char* type_names[] = {
37 switch (type) { 68 [TYPES_VF] = "Movie Studio",
38 case TYPES_VF: return "Movie Studio"; 69 [TYPES_VEG] = "Vegas Pro",
39 case TYPES_VEG: return "Vegas Pro"; 70 [TYPES_UNKNOWN] = "Unknown",
40 case TYPES_UNKNOWN: 71 };
41 default: return "Unknown"; 72
42 } 73 static const char* type_extensions[] = {
43 } 74 [TYPES_VF] = "vf",
44 75 [TYPES_VEG] = "veg",
45 static inline const char* type_to_extension(enum types type) { 76 };
46 switch (type) {
47 case TYPES_VF: return "vf";
48 case TYPES_VEG:
49 case TYPES_UNKNOWN:
50 default: return "veg";
51 }
52 }
53 77
54 #ifndef ARRAYSIZE 78 #ifndef ARRAYSIZE
55 #define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0])) 79 #define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
56 #endif 80 #endif
57 81
58 static const char* help_text = 82 static const char* help_text =
59 "msvpvf by Paper\n" 83 "msvpvf help text\n"
84 "author: Paper <paper@paper.us.eu.org>\n"
60 "usage: %s <input>... (arguments)\n" 85 "usage: %s <input>... (arguments)\n"
61 "\n" 86 "\n"
62 "arguments:\n" 87 "arguments:\n"
63 " -t, --type one of [vf,veg] (required)\n" 88 " -t, --type one of [vf,veg] (required)\n"
64 " -v, --version version to convert to (required)\n" 89 " -v, --version version to convert to (required)\n"
65 " -h, --help show this screen (optional)\n"; 90 " -h, --help show this screen (optional)\n";
66 91
67 static struct option options_long[] = { 92 static struct option options_long[] = {
68 {"version", required_argument, NULL, 'v'}, 93 {"version", required_argument, NULL, 'v'},
69 {"type", required_argument, NULL, 't'}, 94 {"type", required_argument, NULL, 't'},
70 {"help", 0, NULL, 'h'} 95 {"help", 0, NULL, 'h'},
71 }; 96 };
72 97
73 int main(int argc, char *argv[]) { 98 int main(int argc, char *argv[]) {
74 uint8_t version = 0; 99 uint8_t version = 0;
75 enum types type = TYPES_UNKNOWN; 100 enum types type = TYPES_VEG; /* ...? */
76 101
77 int c; 102 int c;
78 int option_index = 0; 103 int option_index = 0;
79 while ((c = getopt_long(argc, argv, "v:t:h", options_long, &option_index)) != -1) { 104 while ((c = getopt_long(argc, argv, "v:t:h", options_long, &option_index)) != -1) {
80 /* option argument */ 105 /* option argument */
99 break; 124 break;
100 } 125 }
101 } 126 }
102 127
103 if (argc <= optind) { 128 if (argc <= optind) {
104 fprintf(stderr, "[ERROR]: Missing input file!\n"); 129 fprintf(stderr, "[ERROR]: Missing input file(s)!\n");
105 printf(help_text, argv[0]); 130 printf(help_text, argv[0]);
106 return 1; 131 return 1;
107 } 132 }
108 133
109 if (!version || !type) { 134 if (!version || !type) {
110 printf(help_text, (argc > 0) ? argv[0] : "msvpvf"); 135 printf(help_text, (argc > 0) ? argv[0] : "msvpvf");
111 return 1; 136 return 1;
112 } 137 }
113 138
114 /* this progressively */
115 while (optind < argc) { 139 while (optind < argc) {
116 const char* input = argv[optind++]; 140 const char* input = argv[optind++];
117 FILE* output_file = NULL; 141 FILE *input_file, *output_file = NULL;
142 uint8_t file_version = 0;
143 enum types file_type = TYPES_UNKNOWN;
144
145 printf("Input file name: %s\n", input);
146
147 /* print information about the input file */
148 input_file = fopen(input, "rb");
149 if (!input_file) {
150 fprintf(stderr, "[ERROR]: Error opening input file %s!\n\n", input);
151 continue;
152 }
153
154 if (fgetc(input_file) == EOF) {
155 fprintf(stderr, "[ERROR]: Input file \"%s\" is empty.\n", input);
156 fclose(input_file);
157 continue;
158 }
159
160 if (get_file_information(input_file, &file_version, &file_type)) {
161 fprintf(stderr, "[ERROR]: Failed to get file information for input file \"%s\"!\n", input);
162 fclose(input_file);
163 continue;
164 }
165
166 printf("Input file version: %u\n", file_version);
167 printf("Input file type: %s\n\n", type_names[file_type]);
118 168
119 { 169 {
120 uint8_t file_version = 0; 170 /* open the output file... */
121 enum types file_type = TYPES_UNKNOWN; 171 char* basec = msvpvf_internal_strdup(input);
122 172 char* bname = basename(basec);
123 printf("Input file name: %s\n", input); 173 int ext = strrchr(bname, '.') - bname;
124 /* print information about the input file */ 174
125 FILE* input_file = fopen(input, "rb"); 175 char *output = msvpvf_internal_asnprintf("V%u_%.*s.%s", version, ext, bname, type_extensions[type]);
126 if (!input_file) { 176 if (!output) {
127 fprintf(stderr, "[ERROR]: Error opening input file %s!\n\n", input); 177 fprintf(stderr, "[ERROR]: msvpvf_internal_asnprintf failed!\n");
128 continue; 178 free(basec);
129 } 179 free(output);
130
131 if (fgetc(input_file) == EOF) {
132 fprintf(stderr, "[ERROR]: Input file \"%s\" is empty.\n", input);
133 fclose(input_file); 180 fclose(input_file);
134 continue; 181 continue;
135 } 182 }
136 183
137 if (get_file_information(input_file, &file_version, &file_type)) { 184 output_file = fopen(output, "w+b");
138 fprintf(stderr, "[ERROR]: Failed to get file information for input file \"%s\"!\n", input); 185 if (!output_file) {
186 fprintf(stderr, "[ERROR]: Failed to open output file %s! Do you have write permissions?\n", output);
187 free(basec);
188 free(output);
139 fclose(input_file); 189 fclose(input_file);
140 continue; 190 continue;
141 } 191 }
142 192
143 printf("Input file version: %u\n", file_version); 193 free(basec);
144 printf("Input file type: %s\n\n", type_to_string(file_type)); 194 free(output);
145 195 }
146 { 196
147 /* open the output file... */ 197 copy_file(input_file, output_file);
148 char* basec = msvpvf_internal_strdup(input); 198
149 char* bname = basename(basec); 199 fflush(stdout);
150 int ext = strrchr(bname, '.') - bname; 200 fclose(input_file);
151
152 /* create the output filename */
153 int needed_size = snprintf(NULL, 0, "V%u_%.*s.%s", version, ext, bname, type_to_extension(type));
154 char* output = malloc((needed_size + 1) * sizeof(char));
155 if (!output) {
156 fprintf(stderr, "[ERROR]: Failed to allocate memory for output string!\n");
157 free(basec);
158 return 1;
159 }
160
161 snprintf(output, needed_size + 1, "V%u_%.*s.%s", version, ext, bname, type_to_extension(type));
162 printf("Output filename: %s\n", output);
163
164 output_file = fopen(output, "w+b");
165 if (!output_file) {
166 fprintf(stderr, "[ERROR]: Failed to open output file %s! Do you have write permissions?\n", output);
167 free(basec);
168 free(output);
169 continue;
170 }
171 free(basec);
172 free(output);
173 }
174
175 copy_file(input_file, output_file);
176
177 fflush(stdout);
178 fclose(input_file);
179 }
180 201
181 set_file_information(output_file, version, type); 202 set_file_information(output_file, version, type);
182 fclose(output_file); 203 fclose(output_file);
183 } 204 }
184 205