diff --git a/APP/main.c b/APP/main.c index f1d8cf4..690f59e 100644 --- a/APP/main.c +++ b/APP/main.c @@ -2,7 +2,13 @@ #include #include #include -#include + +// Кроссплатформенная совместимость +#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,11 +132,13 @@ uint32_t calculate_file_crc32_without_last4(const char *filename, int verbose) { } // Выделяем память под данные - buffer = (uint8_t*)malloc(data_size); - if (buffer == NULL && data_size > 0) { - perror("Failed to allocate memory"); - fclose(file); - return 0; + if (data_size > 0) { + buffer = (uint8_t*)malloc(data_size); + if (buffer == NULL) { + perror("Failed to allocate memory"); + fclose(file); + return 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': - options->write_crc = 1; - break; - case 'c': - options->verify_crc = 1; - break; - case 's': - options->show_only = 1; - break; - case 'v': - options->verbose = 1; - break; - case 'h': - print_usage(argv[0]); + // Ручной разбор аргументов + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--write") == 0) { + options->write_crc = 1; + } + else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--check") == 0) { + options->verify_crc = 1; + } + else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--show-only") == 0) { + options->show_only = 1; + } + else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) { + options->verbose = 1; + } + else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + print_usage(argv[0]); + return -1; + } + 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; - 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 '?': + } + // Поддержка шестнадцатеричных чисел + 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");