
3 changed files with 128 additions and 1 deletions
@ -0,0 +1,111 @@ |
|||
#include "prefs.h" |
|||
#include <ctype.h> |
|||
|
|||
ORCA_FORCE_NO_INLINE |
|||
Readprefs_result prefs_read_line(FILE* file, char* buf, Usz bufsize, |
|||
Usz* out_strlen, char** out_left, |
|||
Usz* out_leftsize, char** out_right, |
|||
Usz* out_rightsize) { |
|||
Usz len, a0, a1, b0, b1; |
|||
char* s; |
|||
*out_strlen = 0; |
|||
if (bufsize < 2) |
|||
goto insufficient_buffer; |
|||
#if SIZE_MAX > INT_MAX |
|||
if (bufsize > (Usz)INT_MAX) |
|||
exit(1); // he boot too big
|
|||
#endif |
|||
s = fgets(buf, (int)bufsize, file); |
|||
if (!s) { |
|||
if (feof(file)) |
|||
goto eof; |
|||
goto ioerror; |
|||
} |
|||
len = strlen(buf); |
|||
if (len == bufsize - 1 && buf[len - 1] != '\n' && !feof(file)) |
|||
goto insufficient_buffer; |
|||
*out_strlen = len - 1; |
|||
a0 = 0; // start of left
|
|||
for (;;) { |
|||
if (a0 == len) |
|||
goto ignore; |
|||
char c = s[a0]; |
|||
if (c == ';' || c == '#') // comment line, ignore
|
|||
goto ignore; |
|||
if (c == '=') // '=' before any other char, bad
|
|||
goto ignore; |
|||
if (!isspace(c)) |
|||
break; |
|||
a0++; |
|||
} |
|||
a1 = a0; // end of left
|
|||
for (;;) { |
|||
a1++; |
|||
if (a1 == len) |
|||
goto ignore; |
|||
char c = s[a1]; |
|||
Usz x = a1; |
|||
while (isspace(c)) { |
|||
x++; |
|||
if (x == len) |
|||
goto ignore; |
|||
c = s[x]; |
|||
} |
|||
if (c == '=') { |
|||
b0 = x; |
|||
break; |
|||
} |
|||
a1 = x; |
|||
} |
|||
for (;;) { |
|||
b0++; |
|||
if (b0 == len) |
|||
goto ignore; |
|||
char c = s[b0]; |
|||
if (!isspace(c)) |
|||
break; |
|||
} |
|||
b1 = b0; // end of right
|
|||
for (;;) { |
|||
b1++; |
|||
if (b1 == len) |
|||
goto ok; |
|||
char c = s[b1]; |
|||
Usz x = b1; |
|||
while (isspace(c)) { |
|||
x++; |
|||
if (x == len) |
|||
goto ok; |
|||
c = s[x]; |
|||
} |
|||
b1 = x; |
|||
} |
|||
Readprefs_result err; |
|||
insufficient_buffer: |
|||
err = Readprefs_buffer_too_small; |
|||
goto fail; |
|||
eof: |
|||
err = Readprefs_eof; |
|||
goto fail; |
|||
ioerror: |
|||
err = Readprefs_io_error; |
|||
goto fail; |
|||
ignore: |
|||
s[len - 1] = '\0'; |
|||
err = Readprefs_irrelevant; |
|||
goto fail; |
|||
fail: |
|||
*out_left = NULL; |
|||
*out_leftsize = 0; |
|||
*out_right = NULL; |
|||
*out_rightsize = 0; |
|||
return err; |
|||
ok: |
|||
s[a1] = '\0'; |
|||
s[b1] = '\0'; |
|||
*out_left = s + a0; |
|||
*out_leftsize = a1 - a0; |
|||
*out_right = s + b0; |
|||
*out_rightsize = b1 - b0; |
|||
return Readprefs_left_and_right; |
|||
} |
@ -0,0 +1,16 @@ |
|||
#pragma once |
|||
#include "base.h" |
|||
#include <stdio.h> // FILE cannot be forward declared |
|||
|
|||
typedef enum { |
|||
Readprefs_left_and_right = 0, |
|||
Readprefs_irrelevant, |
|||
Readprefs_buffer_too_small, |
|||
Readprefs_eof, |
|||
Readprefs_io_error, |
|||
} Readprefs_result; |
|||
|
|||
Readprefs_result prefs_read_line(FILE* file, char* buf, Usz bufsize, |
|||
Usz* out_linelen, char** out_left, |
|||
Usz* out_leftlen, char** out_right, |
|||
Usz* out_rightlen); |
Loading…
Reference in new issue