LibC: Implement getdelim and getline
This commit is contained in:
parent
9fb161c320
commit
b9da6a4a5d
|
@ -558,6 +558,57 @@ int getchar_unlocked(void)
|
||||||
return getc_unlocked(stdin);
|
return getc_unlocked(stdin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t getdelim(char** __restrict lineptr, size_t* __restrict n, int delimeter, FILE* __restrict stream)
|
||||||
|
{
|
||||||
|
if (n == nullptr || lineptr == nullptr)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopeLock _(stream);
|
||||||
|
|
||||||
|
size_t capacity = *lineptr ? *n : 0;
|
||||||
|
size_t length = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (length + 2 > capacity)
|
||||||
|
{
|
||||||
|
const size_t new_capacity = BAN::Math::max(capacity * 2, length + 2);
|
||||||
|
void* temp = realloc(*lineptr, new_capacity);
|
||||||
|
if (temp == nullptr)
|
||||||
|
return -1;
|
||||||
|
*lineptr = static_cast<char*>(temp);
|
||||||
|
capacity = new_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ch = getc_unlocked(stream);
|
||||||
|
if (ch == EOF)
|
||||||
|
{
|
||||||
|
(*lineptr)[length] = '\0';
|
||||||
|
*n = length;
|
||||||
|
if (ferror(stream) || length == 0)
|
||||||
|
return -1;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*lineptr)[length++] = ch;
|
||||||
|
|
||||||
|
if (ch == delimeter)
|
||||||
|
{
|
||||||
|
(*lineptr)[length] = '\0';
|
||||||
|
*n = length;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t getline(char** __restrict lineptr, size_t* __restrict n, FILE* __restrict stream)
|
||||||
|
{
|
||||||
|
return getdelim(lineptr, n, '\n', stream);
|
||||||
|
}
|
||||||
|
|
||||||
char* gets(char* buffer)
|
char* gets(char* buffer)
|
||||||
{
|
{
|
||||||
if (stdin->eof)
|
if (stdin->eof)
|
||||||
|
|
Loading…
Reference in New Issue