.
This commit is contained in:
commit
55385f8857
69 changed files with 1125 additions and 0 deletions
6
strff/strff_close.c
Normal file
6
strff/strff_close.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "../strff.h"
|
||||
|
||||
void strff_close(struct strff *strff)
|
||||
{
|
||||
buffer_close(&strff->b);
|
||||
}
|
||||
8
strff/strff_get.c
Normal file
8
strff/strff_get.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "../strff.h"
|
||||
|
||||
int strff_get(struct strff *strff, char *key, stralloc *sa)
|
||||
{
|
||||
if (!strff_seek(strff, key))
|
||||
return 0;
|
||||
return strff_read_sa(strff, sa);
|
||||
}
|
||||
8
strff/strff_open.c
Normal file
8
strff/strff_open.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "../strff.h"
|
||||
#include <libowfat/byte.h>
|
||||
|
||||
void strff_open(struct strff *strff, int fd)
|
||||
{
|
||||
byte_zero(strff, sizeof *strff);
|
||||
strff->fd = fd;
|
||||
}
|
||||
44
strff/strff_read.c
Normal file
44
strff/strff_read.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "../strff.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int strff_read(struct strff *strff, size_t buflen, char buf[buflen])
|
||||
{
|
||||
size_t nread;
|
||||
int r;
|
||||
char c;
|
||||
int isnewline;
|
||||
if (strff->fieldtype == STRFF_TYPE_NONE) {
|
||||
errno = EINVAL; /* cannot read NONE field */
|
||||
return -1;
|
||||
}
|
||||
|
||||
isnewline = 1;
|
||||
nread = 0;
|
||||
while (nread < buflen) {
|
||||
r = buffer_peekc(&strff->b, &c);
|
||||
if (r < 0) return -1;
|
||||
if (r == 0) {
|
||||
if (isnewline && nread > 0)
|
||||
nread--; /* remove last \n */
|
||||
break;
|
||||
}
|
||||
|
||||
if (strff->fieldtype == STRFF_TYPE_EQUAL && c == '\n')
|
||||
break;
|
||||
else if (strff->fieldtype == STRFF_TYPE_BRACKET) {
|
||||
if (isnewline && c == '[') {
|
||||
if (nread > 0)
|
||||
nread--; /* remove last \n */
|
||||
break;
|
||||
}
|
||||
isnewline = 0;
|
||||
if (c == '\n')
|
||||
isnewline = 1;
|
||||
}
|
||||
|
||||
buf[nread++] = c;
|
||||
strff->b.p++;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
15
strff/strff_read_sa.c
Normal file
15
strff/strff_read_sa.c
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include "../strff.h"
|
||||
#include <libowfat/stralloc.h>
|
||||
|
||||
int strff_read_sa(struct strff *strff, stralloc *sa)
|
||||
{
|
||||
int n;
|
||||
char buf[1024];
|
||||
for (;;) {
|
||||
n = strff_read(strff, sizeof buf, buf);
|
||||
if (n == 0) break;
|
||||
if (n < 0) return 0;
|
||||
if (!stralloc_catb(sa, buf, n)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
124
strff/strff_seek.c
Normal file
124
strff/strff_seek.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include "../strff.h"
|
||||
|
||||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/stralloc.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
#include <libowfat/str.h>
|
||||
#include <libowfat/byte.h>
|
||||
#include <unistd.h>
|
||||
#include <alloca.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
keys can be defined either with key= or with [key].
|
||||
The first is the equalform, the second the bracketform.
|
||||
There can be no keyforms after the bracketform.
|
||||
*/
|
||||
|
||||
static int skip_to_next_line(buffer *b)
|
||||
{
|
||||
int r;
|
||||
char c;
|
||||
for (;;) {
|
||||
r = buffer_getc(b, &c);
|
||||
if (r == 0 || c == '\n') break;
|
||||
if (r < 0) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* advances the cursor until it is positioned at the value of a
|
||||
* field. It will look for both the equalform and bracketform of
|
||||
* the field, and returns STRFF_TYPE_BRACKET or STRFF_TYPE_EQUAL
|
||||
* accordingly. If no such field is found, it returns STRFF_TYPE_NONE.
|
||||
* On error, -1 is returned.
|
||||
*/
|
||||
static int seek_field(buffer *b, char *equalform, char *bracketform)
|
||||
{
|
||||
size_t linemax, linelen;
|
||||
char *line;
|
||||
int r;
|
||||
/* bracketform is longer */
|
||||
linemax = str_len(bracketform) + 1;
|
||||
line = alloca(linemax);
|
||||
linelen = 0;
|
||||
|
||||
for (;;) {
|
||||
r = buffer_getc(b, line + linelen);
|
||||
if (r < 0) return -1;
|
||||
if (r == 0) break;
|
||||
linelen++;
|
||||
|
||||
if (byte_starts(line, linelen, bracketform)) {
|
||||
return STRFF_TYPE_BRACKET;
|
||||
}
|
||||
if (line[0] == '[') {
|
||||
/* equalform cannot come after a bracketform */
|
||||
equalform = NULL;
|
||||
}
|
||||
if (equalform && byte_starts(line, linelen, equalform)){
|
||||
return STRFF_TYPE_EQUAL;
|
||||
}
|
||||
|
||||
if (line[linelen-1] == '\n') {
|
||||
/* reset line */
|
||||
linelen = 0;
|
||||
continue;
|
||||
}
|
||||
if (linelen == linemax) {
|
||||
if (!skip_to_next_line(b))
|
||||
return -1;
|
||||
linelen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found */
|
||||
return STRFF_TYPE_NONE;
|
||||
}
|
||||
|
||||
static int to_equalform(char *key, char *result)
|
||||
{
|
||||
size_t l;
|
||||
l = str_copy(result, key);
|
||||
result[l++] = '=';
|
||||
result[l++] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int to_bracketform(char *key, char *result)
|
||||
{
|
||||
size_t l;
|
||||
l = 0;
|
||||
result[l++] = '[';
|
||||
l += str_copy(result + l, key);
|
||||
result[l++] = ']';
|
||||
result[l++] = '\n';
|
||||
result[l++] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int strff_seek(struct strff *strff, char *key) {
|
||||
char *equalform, *bracketform;
|
||||
int fieldtype;
|
||||
if (str_chr(key, '[') != str_len(key)) {
|
||||
errno = EINVAL; /* key cannot contain '[' */
|
||||
return 0;
|
||||
}
|
||||
|
||||
equalform = alloca(str_len(key) + 2);
|
||||
to_equalform(key, equalform);
|
||||
bracketform = alloca(str_len(key) + 4);
|
||||
to_bracketform(key, bracketform);
|
||||
|
||||
buffer_init(&strff->b, read, strff->fd, strff->buf, sizeof strff->buf);
|
||||
lseek(strff->fd, 0, SEEK_SET);
|
||||
fieldtype = seek_field(&strff->b, equalform, bracketform);
|
||||
if (fieldtype < 0) return 0;
|
||||
strff->fieldtype = fieldtype;
|
||||
if (fieldtype == STRFF_TYPE_NONE) {
|
||||
errno = ENOKEY;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue