libpkgconf: fileio: rework to use pkgconf_buffer, allowing larger than 64KB lines
Fixes: 130907d
("fileio: add routine for portably yanking lines out of a FILE stream")
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
master
parent
83a2ae0434
commit
d0f8f3f228
|
@ -2,7 +2,7 @@
|
||||||
* fileio.c
|
* fileio.c
|
||||||
* File reading utilities
|
* File reading utilities
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 pkgconf authors (see AUTHORS).
|
* Copyright (c) 2012, 2025 pkgconf authors (see AUTHORS).
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -17,17 +17,12 @@
|
||||||
#include <libpkgconf/libpkgconf.h>
|
#include <libpkgconf/libpkgconf.h>
|
||||||
|
|
||||||
char *
|
char *
|
||||||
pkgconf_fgetline(char *line, size_t size, FILE *stream)
|
pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream)
|
||||||
{
|
{
|
||||||
char *s = line;
|
|
||||||
char *end = line + size - 2;
|
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
int c = '\0', c2;
|
int c = '\0', c2;
|
||||||
|
|
||||||
if (s == NULL)
|
while ((c = getc(stream)) != EOF)
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while (s < end && (c = getc(stream)) != EOF)
|
|
||||||
{
|
{
|
||||||
if (c == '\\' && !quoted)
|
if (c == '\\' && !quoted)
|
||||||
{
|
{
|
||||||
|
@ -41,11 +36,11 @@ pkgconf_fgetline(char *line, size_t size, FILE *stream)
|
||||||
do {
|
do {
|
||||||
c = getc(stream);
|
c = getc(stream);
|
||||||
} while (c != '\n' && c != EOF);
|
} while (c != '\n' && c != EOF);
|
||||||
*s++ = c;
|
pkgconf_buffer_push_byte(buffer, c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*s++ = c;
|
pkgconf_buffer_push_byte(buffer, c);
|
||||||
|
|
||||||
quoted = false;
|
quoted = false;
|
||||||
continue;
|
continue;
|
||||||
|
@ -66,14 +61,14 @@ pkgconf_fgetline(char *line, size_t size, FILE *stream)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*s++ = c;
|
pkgconf_buffer_push_byte(buffer, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (c == '\r')
|
else if (c == '\r')
|
||||||
{
|
{
|
||||||
*s++ = '\n';
|
pkgconf_buffer_push_byte(buffer, '\n');
|
||||||
|
|
||||||
if ((c2 = getc(stream)) == '\n')
|
if ((c2 = getc(stream)) == '\n')
|
||||||
{
|
{
|
||||||
|
@ -99,26 +94,24 @@ pkgconf_fgetline(char *line, size_t size, FILE *stream)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (quoted) {
|
if (quoted) {
|
||||||
*s++ = '\\';
|
pkgconf_buffer_push_byte(buffer, '\\');
|
||||||
quoted = false;
|
quoted = false;
|
||||||
}
|
}
|
||||||
*s++ = c;
|
pkgconf_buffer_push_byte(buffer, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == EOF && (s == line || ferror(stream)))
|
|
||||||
|
if (c == EOF && ((!buffer->base || !*buffer->base) || ferror(stream)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*s = '\0';
|
|
||||||
|
|
||||||
/* Remove newline character. */
|
/* Remove newline character. */
|
||||||
if (s > line && *(--s) == '\n') {
|
if (pkgconf_buffer_lastc(buffer) == '\n')
|
||||||
*s = '\0';
|
pkgconf_buffer_trim_byte(buffer);
|
||||||
|
|
||||||
if (s > line && *(--s) == '\r')
|
if (pkgconf_buffer_lastc(buffer) == '\r')
|
||||||
*s = '\0';
|
pkgconf_buffer_trim_byte(buffer);
|
||||||
}
|
|
||||||
|
|
||||||
return line;
|
return pkgconf_buffer_str(buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,9 +379,6 @@ PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *b
|
||||||
PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
|
PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
|
||||||
PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
|
PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
|
||||||
|
|
||||||
/* fileio.c */
|
|
||||||
PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
|
|
||||||
|
|
||||||
/* tuple.c */
|
/* tuple.c */
|
||||||
PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags);
|
PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags);
|
||||||
PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
|
PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
|
||||||
|
|
|
@ -33,20 +33,20 @@
|
||||||
void
|
void
|
||||||
pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename)
|
pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename)
|
||||||
{
|
{
|
||||||
char readbuf[PKGCONF_BUFSIZE];
|
pkgconf_buffer_t readbuf = PKGCONF_BUFFER_INITIALIZER;
|
||||||
size_t lineno = 0;
|
size_t lineno = 0;
|
||||||
|
|
||||||
while (pkgconf_fgetline(readbuf, PKGCONF_BUFSIZE, f) != NULL)
|
while (pkgconf_fgetline(&readbuf, f) != NULL)
|
||||||
{
|
{
|
||||||
char op, *p, *key, *value;
|
char op, *p, *key, *value;
|
||||||
bool warned_key_whitespace = false, warned_value_whitespace = false;
|
bool warned_key_whitespace = false, warned_value_whitespace = false;
|
||||||
|
|
||||||
lineno++;
|
lineno++;
|
||||||
|
|
||||||
p = readbuf;
|
p = readbuf.base;
|
||||||
while (*p && isspace((unsigned char)*p))
|
while (*p && isspace((unsigned char)*p))
|
||||||
p++;
|
p++;
|
||||||
if (*p && p != readbuf)
|
if (*p && p != readbuf.base)
|
||||||
{
|
{
|
||||||
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n",
|
warnfunc(data, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n",
|
||||||
filename, lineno);
|
filename, lineno);
|
||||||
|
@ -100,6 +100,8 @@ pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *o
|
||||||
}
|
}
|
||||||
if (ops[(unsigned char) op])
|
if (ops[(unsigned char) op])
|
||||||
ops[(unsigned char) op](data, lineno, key, value);
|
ops[(unsigned char) op](data, lineno, key, value);
|
||||||
|
|
||||||
|
pkgconf_buffer_reset(&readbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
Loading…
Reference in New Issue