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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (stdin->eof)
|
||||
|
|
Loading…
Reference in New Issue