1
0
mirror of https://gitlab.com/80486DX2-66/gists synced 2024-12-27 14:50:23 +05:30

C: add freadln.*

This commit is contained in:
Intel A80486DX2-66 2024-02-20 01:38:45 +03:00
parent 714d32b4b4
commit 73257b0c55
Signed by: 80486DX2-66
GPG Key ID: 83631EF27054609B
2 changed files with 95 additions and 0 deletions

62
c-programming/freadln.c Normal file
View File

@ -0,0 +1,62 @@
/*
* freadln.c
*
* The `freadln` function reads a line from STDIN into a string, allocating
* memory for it.
*
* Author: Intel A80486DX2-66
* License: Creative Commons Zero 1.0 Universal
*
* To-Do: figure out potential problems
*/
#include "freadln.h"
ssize_t freadln(char** output, size_t* length_out) {
/*
* The length of STDIN line is counted without any terminating characters.
*
* return value:
* freadln_OK: no errors, the length of STDIN line has been stored in
* `length_out`
* freadln_ERROR: an error occurred (see errno)
* >= 0: length of stdin line
*/
if (output == NULL)
return freadln_ERROR;
freadln_length_type length = 0;
*output = malloc((length + 1) * sizeof(char));
if (*output == NULL)
return freadln_ERROR;
int character;
while ((character = fgetc(stdin)) != EOF
/* stop on a newline character: */ && character != '\n') {
(*output)[length] = (char) character;
// integer overflow and integer limit check, to keep array boundaries
if ((freadln_length_type) (length + 2) <= (freadln_length_type) length)
{
errno = ERANGE;
freadln_success_epilogue
} else
length++;
char* temp = realloc(*output, (length + 1) * sizeof(char));
// If the function fails to allocate new memory, return the string that
// has already been accumulated.
if (temp == NULL) {
// keep errno;
freadln_success_epilogue
}
*output = temp;
}
errno = 0;
freadln_success_epilogue
}

33
c-programming/freadln.h Normal file
View File

@ -0,0 +1,33 @@
/*
* freadln.h
*
* Author: Intel A80486DX2-66
* License: Creative Commons Zero 1.0 Universal
*/
#ifndef _FREADLN_H
#define _FREADLN_H
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
typedef size_t freadln_length_type;
enum freadln_status {
freadln_OK = -2,
freadln_ERROR
};
#define freadln_success_epilogue do { \
(*output)[length] = '\0'; \
if (length_out == NULL) \
return length; \
else { \
*length_out = length; \
return freadln_OK; \
} \
} while (0);
ssize_t freadln(char** output);
#endif /* _FREADLN_H */