Bonus files, invalid unfortunately since it's too late now i guess.

This commit is contained in:
Midou 2025-04-05 18:21:59 +00:00
parent 53a181c5d7
commit 80022d2f9d
Signed by: midou
GPG Key ID: 1D134A95FE521A7A
3 changed files with 349 additions and 0 deletions

View File

@ -0,0 +1,41 @@
// INFO: INVALID SINCE SUBMISSION IS OVER
#include "tome_utils_bonus.h"
#ifndef OPEN_MAX // If the GCC compiler does not define any value
#define OPEN_MAX 5 // Give it a default one (lines)
#endif // This should make clangd shut up about it
int main(int argc, char *argv[]) {
char *data;
int fd[OPEN_MAX];
// INFO: I'm sorry, I don't have much time left to implement a pipe input.
if (argc < 2) {
printer("Usage: ./tome_reader <file1> <file2> ...");
exit(1);
} else {
for (int i = 1; i < argc; i++) {
fd[i - 1] = get_fd(argv[i], O_RDONLY);
if (fd[i] == ERR) {
printer("Error: Unable to open file\n");
exit(1);
}
}
}
for (int i = 0; i < argc - 1; i++) {
printer("--------------");
// Loop until we get nothing
while ((data = tome_reader(fd[i])) != NULL) {
printer("\n");
printer("New line: ");
printer(data);
printer("--------------");
free(data);
}
printer("\n");
if (fd[i] != 0)
close(fd[i]); // Close the file descriptor
}
return 0;
}

286
phase2/tome_utils_bonus.c Normal file
View File

@ -0,0 +1,286 @@
// INFO: INVALID SINCE SUBMISSION IS OVER
#include "tome_utils_bonus.h"
#define strlen invalid // make sure that the built-in strlen is not used
#ifndef BUFFER_SIZE // If the GCC compiler does not define any value
#define BUFFER_SIZE 40 // Give it a default one (lines)
#endif // This should make clangd shut up about it
#ifndef OPEN_MAX // If the GCC compiler does not define any value
#define OPEN_MAX 5 // Give it a default one (lines)
#endif // This should make clangd shut up about it
#ifndef DEBUG
#define DEBUG FALSE
#endif
// INFO: THINGS TO KEEP IN MIND:
// printf is not used in this challenge, by default it's not being used unless
// it's for debugging for simplicity sake.
/*
* @info This is a simple implementation of the strlen function
*
* @brief Returns the length of a string
* @param str The string to measure
* @return The length of the string
* @error Returns 0 if str is NULL
*/
int strlen(const char *str) {
if (str == NULL) {
return 0;
}
int i = 0;
while (str[i] != '\0') {
i++;
}
return i;
}
/*
* @info crude and basic implementation of "print"
*
* @brief Writes a string to STDOUT
* @param str The string to write
* @error does nothing if str is NULL
*/
void printer(const char *str, ...) {
// screw me i guess
// va_list args;
if (str == NULL) {
return;
}
write(1, str, strlen(str));
}
/*
* @info Convenience function to get the file descriptor
*
* @brief Returns the file descriptor of a file
* @param filename The name of the file
* @param mode The mode to open the file in
* @return The file descriptor of the file
* @error Returns -1 if the file cannot be opened
*/
int get_fd(char *filename, int mode) {
if (filename == NULL)
return ERR;
int fd = open(filename, mode);
if (fd == ERR)
return ERR;
return fd;
}
/*
* @info This function checks if a string contains a newline character
*
* @brief Returns TRUE (1) if the string contains a newline character, FALSE (0)
* otherwise
* @param str The string to check
* @error Returns ERR (-1) if str is NULL
*/
int newlineexists(const char *str) {
if (str == NULL)
return ERR;
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == '\n') {
return TRUE;
}
}
return FALSE;
}
/*
* @info This function concatenates two strings
*
* @brief Returns a new string that is the concatenation of str1 and str2
* @param str1 The first string
* @param str2 The second string
* @return The concatenated string
* @error Returns NULL if str1 or str2 is NULL, or if memory allocation fails
*/
char *concat(char const *str1, char const *str2) {
char *result;
int i, j;
// Sanity check
if (!str1 || !str2)
return NULL;
result = malloc(strlen(str1) + strlen(str2) + 1); // +1 for eof
if (result == NULL)
return NULL;
for (i = 0; str1[i] != '\0'; i++) {
result[i] = str1[i];
}
if (DEBUG)
printf("[DEBUG]: Concatenating: [%s] + [%s]\n", str1, str2);
for (j = 0; str2[j] != '\0'; j++, i++) {
result[i] = str2[j];
}
result[i] = '\0';
return result;
}
/*
* @info This function reads from a file descriptor and stores the content in a
* string
*
* @brief Reads from a file descriptor and stores the content in a string
* @param fd The file descriptor to read from
* @param buf The buffer to store the content
* @param str The string to store the content
* @return The string containing the content read from the file descriptor
* @error Returns NULL if there is an error reading from the file descriptor or
* if memory allocation fails
*/
char *read_content(int fd, char *buf, char *temp, char *str) {
int bytes;
while (TRUE) {
bytes = read(fd, buf, BUFFER_SIZE);
if (bytes == ERR) {
return NULL;
}
if (DEBUG)
printf("[DEBUG]: Bytes gives : [%d]\n", bytes);
buf[bytes] = '\0';
if (DEBUG)
printf("[DEBUG]: Buffer is: [%s]\n", buf);
if (DEBUG)
printf("[DEBUG]: read %d bytes: \"%s\"\n", bytes, buf);
temp = str; // move the temporary data to str
if (temp == NULL) {
temp = malloc(sizeof(char));
if (temp == NULL) {
return NULL;
}
temp[0] = '\0';
}
if (DEBUG)
printf("[DEBUG]:We got a [%s] and [%s]\n", temp, buf);
str = concat(temp, buf); // concatenate the temporary data with the buffer
if (DEBUG)
printf("[DEBUG]:Variable temp: (%s), buf: (%s)\n", temp, buf);
if (DEBUG)
printf("[DEBUG]: Concatenated str is: [%s]\n", str);
free(temp);
if (newlineexists(str) == TRUE || bytes == 0) {
break;
}
}
free(buf);
return str;
}
/*
* @info This function returns a string up to the first newline character
*
* @brief Returns a string up to the first newline character
* @param str The string to search
* @return A string up to the first newline character
* @error Returns NULL if str is NULL or if there is no newline character in the
* string
* @details
* This function allocates memory for the new string, so it is the
* responsibility of the caller to free it when it is no longer needed.
*/
char *before_nl(const char *str) {
int i;
char *ptr = NULL;
// Sanity check
if (str == NULL || str[0] == '\0')
return NULL; // We got nothing or it's already EOF, we don't need this.
for (i = 0; str[i] != '\n' && str[i] != '\0';
i++) { // Count up until we reach a newline or EOF
continue;
}
ptr = malloc(
(i + 1 + 1) * // The str count plus the newline plus the null terminator
sizeof(char)); // Dynamically allocate *just enough* space for the str
if (ptr == NULL) {
return NULL;
}
for (i = 0; str[i] != '\n' && str[i] != '\0'; i++) { // Same thing here.
ptr[i] = str[i];
}
if (str[i] == '\n') {
ptr[i] = '\n';
i++;
}
ptr[i] = '\0';
return ptr;
}
/*
* @info This function returns what's after the first newline character
*
* @brief I'm not repeating this ^
* @param str The string to search
* @return What's after the first newline character
* @error Returns NULL if str is NULL, or malloc is going funky
*/
char *after_nl(char *str) {
int i, j;
char *ptr;
if (str == NULL)
return NULL;
for (i = 0; str[i] != '\n' && str[i] != '\0'; i++)
continue;
if (str[i] == '\n') { // Consume the \n by skipping it
i++;
}
if (str[i] == '\0') { // It's empty, might aswell drop it.
free(str);
return NULL;
}
if (DEBUG)
printf("[DEBUG]: strlen(str) = %d\n", strlen(str));
ptr = malloc((strlen(str) - i + 1) * sizeof(char));
if (ptr == NULL)
return NULL;
j = 0;
while (str[i] != '\0')
ptr[j++] = str[i++];
ptr[j] = '\0';
free(str);
return ptr;
}
/*
* @info This is similar to the get_next_line function homework I found on
* GitHub ( src: https://github.com/pvaladares/42cursus-01-get_next_line )
* Youtube ( url: https://www.youtube.com/watch?v=-Mt2FdJjVno )
* (Heavily inspired, but not copied, I can explain what I wrote ;) )
* @function tome_reader
* @brief Reads a line from a file descriptor
* @param fd The file descriptor to read from
* @return The line read from the file descriptor
*
* @details
* Here we start by defining a static variable str, which is used to store the
* content read from the file descriptor.
* We then proceed to actually get and return the line that is before the \n
* Then we just take the same string and we chop everything before the first \n
* and keep everything after.
*/
char *tome_reader(int fd) {
// INFO: technically static is a global variable, but I hope it's allowed for
// this one, removing static does the exact same thing. It's just for
// cleanness sake.
static char *str[OPEN_MAX];
char *buf, *line;
char *temp = NULL;
if (fd == ERR || read(fd, 0, 0) == ERR) // Check if nothing wrong happened.
return NULL;
buf = malloc((BUFFER_SIZE + 1) * sizeof(char));
if (buf == NULL)
return NULL;
str[fd] = read_content(fd, buf, temp, str[fd]);
if (str[fd] == NULL)
return NULL;
line = before_nl(str[fd]);
str[fd] = after_nl(str[fd]);
return line;
}

22
phase2/tome_utils_bonus.h Normal file
View File

@ -0,0 +1,22 @@
// INFO: INVALID SINCE SUBMISSION IS OVER
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// BOOLEAN VALUES
enum {
TRUE = 1,
FALSE = 0,
ERR = -1,
};
void printer(const char *str, ...);
int get_fd(char *filename, int mode);
int newlineexists(const char *str);
char *tome_reader(int fd);
char *before_nl(const char *str);
char *after_nl(char *str);
char *read_content(int fd, char *buf, char *temp, char *str);
char *concat(char const *string1, char const *string2);