diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7a0bf6b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.0) + +# Define the project and executable +project(EasyCodeIt C) +add_executable(eci eci.c utils.c) + +# Enable warnings +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + add_compile_options(-Wall -Wno-maybe-uninitialized -Wno-parentheses -Wpedantic) +endif() diff --git a/eci.c b/eci.c new file mode 100644 index 0000000..aec9a59 --- /dev/null +++ b/eci.c @@ -0,0 +1,50 @@ +/* + * This file is part of EasyCodeIt. + * + * Copyright (C) 2020 TheDcoder + * + * EasyCodeIt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include "utils.h" + +noreturn void die(char *msg) { + fputs(msg, stderr); + if (*msg != '\0') fputs("\n", stderr); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) { + if (argc < 2) die("No arguments!"); + + // Open the source file + FILE *source_file = fopen(argv[1], "r"); + if (!source_file) die("Can't open source file! :("); + + // Read the source file + char *code = readfile(source_file); + if (!code) die("Failed to read from source file!"); + + // Output the code + fputs(code, stdout); + + // Free the resources + free(code); + fclose(source_file); + + return EXIT_SUCCESS; +} diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..e510ab0 --- /dev/null +++ b/utils.c @@ -0,0 +1,86 @@ +/* + * This file is part of EasyCodeIt. + * + * Copyright (C) 2020 TheDcoder + * + * EasyCodeIt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include "utils.h" + +char *readfile(FILE *file) { + // Define the final buffer + char *final_buffer = NULL; + size_t final_size = 0; + + // Define and allocate the initial node + struct ReadFileBufferNode *initial_node = malloc(sizeof(struct ReadFileBufferNode)); + if (!initial_node) return NULL; + + // Read the contents of file in chunks + struct ReadFileBufferNode *curr_node = initial_node; + struct ReadFileBufferNode *next_node; + while (true) { + // Copy the current chunk + size_t bytes_read = fread(curr_node->buffer, 1, READ_FILE_BUFFER_SIZE, file); + curr_node->data_len = bytes_read; + final_size += bytes_read; + if (bytes_read < READ_FILE_BUFFER_SIZE) { + // Check if we have an error + if (ferror(file)) goto cleanup; + + // Mark this node as final + curr_node->next = NULL; + + // Break the loop + break; + } + + // Allocate the next buffer node + next_node = malloc(sizeof(struct ReadFileBufferNode)); + if (!next_node) goto cleanup; + curr_node->next = next_node; + curr_node = next_node; + } + + // Allocate the buffer + final_buffer = malloc(final_size + 1); + if (!final_buffer) goto cleanup; + final_buffer[final_size] = '\0'; + + // Copy data into the final buffer + curr_node = initial_node; + char *curr_chunk = final_buffer; + do { + memcpy(curr_chunk, curr_node->buffer, curr_node->data_len); + curr_chunk += curr_node->data_len; + curr_node = curr_node->next; + } while (curr_node); + + // Free all nodes + cleanup: + curr_node = initial_node; + do { + next_node = curr_node->next; + free(curr_node); + curr_node = next_node; + } while (curr_node); + + // Return the final buffer + return final_buffer; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..409c944 --- /dev/null +++ b/utils.h @@ -0,0 +1,35 @@ +/* + * This file is part of EasyCodeIt. + * + * Copyright (C) 2020 TheDcoder + * + * EasyCodeIt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UTILS_H +#define UTILS_H + +#ifndef READ_FILE_BUFFER_SIZE +#define READ_FILE_BUFFER_SIZE 1024 +#endif + +struct ReadFileBufferNode { + char buffer[READ_FILE_BUFFER_SIZE]; + size_t data_len; + struct ReadFileBufferNode *next; +}; + +char *readfile(FILE *file); + +#endif