Init
This commit is contained in:
parent
87fa30640f
commit
c337f34aaf
156
APP/main.c
156
APP/main.c
|
|
@ -2,7 +2,13 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
// Кроссплатформенная совместимость
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define strdup _strdup
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
// Таблица CRC32 для полинома 0xEDB88320 (IEEE 802.3)
|
||||
static const uint32_t crc32_table[256] = {
|
||||
|
|
@ -126,12 +132,14 @@ uint32_t calculate_file_crc32_without_last4(const char *filename, int verbose) {
|
|||
}
|
||||
|
||||
// Выделяем память под данные
|
||||
if (data_size > 0) {
|
||||
buffer = (uint8_t*)malloc(data_size);
|
||||
if (buffer == NULL && data_size > 0) {
|
||||
if (buffer == NULL) {
|
||||
perror("Failed to allocate memory");
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Возвращаемся в начало
|
||||
if (fseek(file, 0, SEEK_SET) != 0) {
|
||||
|
|
@ -144,7 +152,7 @@ uint32_t calculate_file_crc32_without_last4(const char *filename, int verbose) {
|
|||
// Читаем данные (все, кроме последних 4 байт)
|
||||
if (data_size > 0) {
|
||||
size_t bytes_read = fread(buffer, 1, data_size, file);
|
||||
if (bytes_read != data_size) {
|
||||
if (bytes_read != (size_t)data_size) {
|
||||
fprintf(stderr, "Failed to read file data. Read %zu bytes, expected %ld bytes\n",
|
||||
bytes_read, data_size);
|
||||
free(buffer);
|
||||
|
|
@ -155,7 +163,7 @@ uint32_t calculate_file_crc32_without_last4(const char *filename, int verbose) {
|
|||
|
||||
// Вычисляем CRC
|
||||
if (data_size > 0) {
|
||||
crc = calculate_crc32(buffer, data_size);
|
||||
crc = calculate_crc32(buffer, (uint32_t)data_size);
|
||||
} else {
|
||||
crc = calculate_crc32(NULL, 0);
|
||||
}
|
||||
|
|
@ -214,14 +222,14 @@ uint32_t calculate_file_crc32_full(const char *filename, int verbose) {
|
|||
}
|
||||
|
||||
size_t bytes_read = fread(buffer, 1, file_size, file);
|
||||
if (bytes_read != file_size) {
|
||||
if (bytes_read != (size_t)file_size) {
|
||||
fprintf(stderr, "Failed to read entire file\n");
|
||||
free(buffer);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
crc = calculate_crc32(buffer, file_size);
|
||||
crc = calculate_crc32(buffer, (uint32_t)file_size);
|
||||
|
||||
free(buffer);
|
||||
fclose(file);
|
||||
|
|
@ -349,12 +357,9 @@ int verify_crc32(const char *filename, int verbose) {
|
|||
}
|
||||
|
||||
// Всегда выводим значения CRC при проверке
|
||||
printf("\n╔════════════════════════════════════════╗\n");
|
||||
printf("║ CRC32 Verification ║\n");
|
||||
printf("╠════════════════════════════════════════╣\n");
|
||||
printf("║ Stored CRC : 0x%08X (%10u) ║\n", stored_crc, stored_crc);
|
||||
printf("║ Calculated CRC : 0x%08X (%10u) ║\n", calculated_crc, calculated_crc);
|
||||
printf("╚════════════════════════════════════════╝\n");
|
||||
printf("\nCRC32 Verification:\n");
|
||||
printf("Stored CRC : 0x%08X (%u)\n", stored_crc, stored_crc);
|
||||
printf("Calculated CRC : 0x%08X (%u)\n", calculated_crc, calculated_crc);
|
||||
|
||||
if (calculated_crc == stored_crc) {
|
||||
printf("\n✓ VERIFIED: CRC matches! File integrity check passed.\n");
|
||||
|
|
@ -460,7 +465,7 @@ int split_bin_file(const char *input_file, long offset, const char *output1, con
|
|||
long next_progress = progress_step;
|
||||
|
||||
while (remaining > 0) {
|
||||
size_t to_read = (remaining < buffer_size) ? remaining : buffer_size;
|
||||
size_t to_read = (remaining < (long)buffer_size) ? (size_t)remaining : buffer_size;
|
||||
bytes_read = fread(buffer, 1, to_read, fin);
|
||||
if (bytes_read != to_read) {
|
||||
fprintf(stderr, "Error reading input file (first part)\n");
|
||||
|
|
@ -475,7 +480,7 @@ int split_bin_file(const char *input_file, long offset, const char *output1, con
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
remaining -= bytes_read;
|
||||
remaining -= (long)bytes_read;
|
||||
|
||||
if (verbose && progress_step > 0 && remaining <= next_progress) {
|
||||
int percent = (int)((bytes_to_copy1 - remaining) * 100 / bytes_to_copy1);
|
||||
|
|
@ -494,7 +499,7 @@ int split_bin_file(const char *input_file, long offset, const char *output1, con
|
|||
next_progress = bytes_to_copy2 - progress_step;
|
||||
|
||||
while (remaining > 0) {
|
||||
size_t to_read = (remaining < buffer_size) ? remaining : buffer_size;
|
||||
size_t to_read = (remaining < (long)buffer_size) ? (size_t)remaining : buffer_size;
|
||||
bytes_read = fread(buffer, 1, to_read, fin);
|
||||
if (bytes_read != to_read) {
|
||||
fprintf(stderr, "Error reading input file (second part)\n");
|
||||
|
|
@ -509,7 +514,7 @@ int split_bin_file(const char *input_file, long offset, const char *output1, con
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
remaining -= bytes_read;
|
||||
remaining -= (long)bytes_read;
|
||||
|
||||
if (verbose && progress_step > 0 && remaining <= next_progress) {
|
||||
int percent = (int)((bytes_to_copy2 - remaining) * 100 / bytes_to_copy2);
|
||||
|
|
@ -576,20 +581,7 @@ void print_usage(const char *program_name) {
|
|||
* @brief Разбирает аргументы командной строки
|
||||
*/
|
||||
int parse_arguments(int argc, char *argv[], ProgramOptions *options) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"write", no_argument, 0, 'w'},
|
||||
{"check", no_argument, 0, 'c'},
|
||||
{"show-only", no_argument, 0, 's'},
|
||||
{"split", required_argument, 0, 1000},
|
||||
{"output1", required_argument, 0, 1001},
|
||||
{"output2", required_argument, 0, 1002},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int i;
|
||||
|
||||
memset(options, 0, sizeof(ProgramOptions));
|
||||
|
||||
|
|
@ -598,58 +590,79 @@ int parse_arguments(int argc, char *argv[], ProgramOptions *options) {
|
|||
options->output2 = NULL;
|
||||
options->split_offset = 0;
|
||||
|
||||
// Поддержка коротких опций: -1 и -2 для output1/output2
|
||||
while ((c = getopt_long(argc, argv, "wcsvh1:2:", long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 'w':
|
||||
// Ручной разбор аргументов
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--write") == 0) {
|
||||
options->write_crc = 1;
|
||||
break;
|
||||
case 'c':
|
||||
}
|
||||
else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--check") == 0) {
|
||||
options->verify_crc = 1;
|
||||
break;
|
||||
case 's':
|
||||
}
|
||||
else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--show-only") == 0) {
|
||||
options->show_only = 1;
|
||||
break;
|
||||
case 'v':
|
||||
}
|
||||
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
|
||||
options->verbose = 1;
|
||||
break;
|
||||
case 'h':
|
||||
}
|
||||
else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||
print_usage(argv[0]);
|
||||
return -1;
|
||||
case '1': // Короткая опция -1 для output1
|
||||
options->output1 = strdup(optarg);
|
||||
break;
|
||||
case '2': // Короткая опция -2 для output2
|
||||
options->output2 = strdup(optarg);
|
||||
break;
|
||||
case 1000: // --split
|
||||
options->split = 1;
|
||||
// Поддержка шестнадцатеричных чисел
|
||||
if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X')) {
|
||||
options->split_offset = strtol(optarg, NULL, 16);
|
||||
} else {
|
||||
options->split_offset = strtol(optarg, NULL, 10);
|
||||
}
|
||||
break;
|
||||
case 1001: // --output1
|
||||
options->output1 = strdup(optarg);
|
||||
break;
|
||||
case 1002: // --output2
|
||||
options->output2 = strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
else if (strcmp(argv[i], "--split") == 0) {
|
||||
options->split = 1;
|
||||
i++;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "Error: --split requires an offset argument\n");
|
||||
return -1;
|
||||
}
|
||||
// Поддержка шестнадцатеричных чисел
|
||||
if (argv[i][0] == '0' && (argv[i][1] == 'x' || argv[i][1] == 'X')) {
|
||||
options->split_offset = strtol(argv[i], NULL, 16);
|
||||
}
|
||||
else {
|
||||
options->split_offset = strtol(argv[i], NULL, 10);
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[i], "-1") == 0 || strcmp(argv[i], "--output1") == 0) {
|
||||
i++;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "Error: -1/--output1 requires a filename argument\n");
|
||||
return -1;
|
||||
}
|
||||
options->output1 = strdup(argv[i]);
|
||||
}
|
||||
else if (strcmp(argv[i], "-2") == 0 || strcmp(argv[i], "--output2") == 0) {
|
||||
i++;
|
||||
if (i >= argc) {
|
||||
fprintf(stderr, "Error: -2/--output2 requires a filename argument\n");
|
||||
return -1;
|
||||
}
|
||||
options->output2 = strdup(argv[i]);
|
||||
}
|
||||
else if (argv[i][0] == '-') {
|
||||
fprintf(stderr, "Error: Unknown option %s\n", argv[i]);
|
||||
print_usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
// Это должно быть имя файла
|
||||
if (options->filename == NULL) {
|
||||
options->filename = argv[i];
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Error: Multiple filenames specified\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
// Проверяем, что имя файла указано
|
||||
if (options->filename == NULL) {
|
||||
fprintf(stderr, "Error: No filename specified.\n");
|
||||
print_usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
options->filename = argv[optind];
|
||||
|
||||
// Подсчет количества выбранных режимов
|
||||
int mode_count = options->write_crc + options->verify_crc + options->show_only + options->split;
|
||||
if (mode_count > 1) {
|
||||
|
|
@ -671,13 +684,13 @@ int parse_arguments(int argc, char *argv[], ProgramOptions *options) {
|
|||
|
||||
// Генерация имен выходных файлов, если не указаны
|
||||
if (options->output1 == NULL) {
|
||||
char *default_name = malloc(strlen(options->filename) + 10);
|
||||
char *default_name = (char*)malloc(strlen(options->filename) + 10);
|
||||
sprintf(default_name, "%s_part1.bin", options->filename);
|
||||
options->output1 = default_name;
|
||||
}
|
||||
|
||||
if (options->output2 == NULL) {
|
||||
char *default_name = malloc(strlen(options->filename) + 10);
|
||||
char *default_name = (char*)malloc(strlen(options->filename) + 10);
|
||||
sprintf(default_name, "%s_part2.bin", options->filename);
|
||||
options->output2 = default_name;
|
||||
}
|
||||
|
|
@ -724,11 +737,8 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// Всегда выводим вычисленное CRC при записи
|
||||
printf("\n╔════════════════════════════════════════╗\n");
|
||||
printf("║ CRC32 Calculation ║\n");
|
||||
printf("╠════════════════════════════════════════╣\n");
|
||||
printf("║ Calculated CRC : 0x%08X (%10u) ║\n", crc_value, crc_value);
|
||||
printf("╚════════════════════════════════════════╝\n");
|
||||
printf("\nCRC32 Calculation:\n");
|
||||
printf("Calculated CRC : 0x%08X (%u)\n", crc_value, crc_value);
|
||||
|
||||
if (options.verbose) {
|
||||
printf("\nStep 2: Writing CRC to last 4 bytes...\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue