| 87 |
{ |
{ |
| 88 |
struct parser_result *res; |
struct parser_result *res; |
| 89 |
struct parser_res *entry; |
struct parser_res *entry; |
| 90 |
char ch, *cp, *t, *buf; |
char ch, *cp, *t, *buf, *buf_base; |
| 91 |
size_t len, n; |
size_t len, n; |
| 92 |
struct stat sb; |
struct stat sb; |
| 93 |
|
|
| 102 |
== MAP_FAILED) |
== MAP_FAILED) |
| 103 |
err(255, "cannot mmap %zu bytes", len); |
err(255, "cannot mmap %zu bytes", len); |
| 104 |
/* make a nice NUL-terminated copy (malloc'd) */ |
/* make a nice NUL-terminated copy (malloc'd) */ |
| 105 |
buf = str_nsave(cp, len); |
buf = buf_base = str_nsave(cp, len); |
| 106 |
if (munmap(cp, len)) |
if (munmap(cp, len)) |
| 107 |
err(255, "cannot munmap"); |
err(255, "cannot munmap"); |
| 108 |
/* don't need the file any more */ |
/* don't need the file any more */ |
| 109 |
close(fd); |
close(fd); |
| 110 |
|
|
| 111 |
/* now we can operate on the NUL-terminated R/W string “buf” */ |
/* now we can operate on the NUL-terminated R/W string “buf” */ |
| 112 |
|
if (buf[len - 1] != '\n') |
| 113 |
|
errx(1, "syntax error: file does not end with a newline!"); |
| 114 |
|
|
| 115 |
|
loop_newline: |
| 116 |
|
/* completely new line buffer */ |
| 117 |
|
cp = NULL; |
| 118 |
|
|
| 119 |
|
loop_getline: |
| 120 |
|
/* get a line and add it to line buffer */ |
| 121 |
|
if (*buf == '\0') |
| 122 |
|
goto eof; |
| 123 |
|
if (*buf == '\n') { |
| 124 |
|
++buf; |
| 125 |
|
goto loop_getline; |
| 126 |
|
} |
| 127 |
|
if (*buf == '#') { |
| 128 |
|
while (*buf != '\n') |
| 129 |
|
++buf; |
| 130 |
|
goto loop_getline; |
| 131 |
|
} |
| 132 |
|
if (*buf == '\t') { |
| 133 |
|
if (cp == NULL) |
| 134 |
|
errx(1, "syntax error: expected lead line," |
| 135 |
|
" got trail line!"); |
| 136 |
|
t = ++buf; |
| 137 |
|
loop_storeline: |
| 138 |
|
while (*t != '\n') |
| 139 |
|
++t; |
| 140 |
|
t = str_nsave(buf, t - buf + /* NL */ 1); |
| 141 |
|
goto loop_addline; |
| 142 |
|
} |
| 143 |
|
if (cp != NULL) |
| 144 |
|
goto process_line; |
| 145 |
|
if ((*buf >= 'A' && *buf <= 'Z') || |
| 146 |
|
(*buf >= 'a' && *buf <= 'z') || *buf == '_') { |
| 147 |
|
t = buf; |
| 148 |
|
goto loop_storeline; |
| 149 |
|
} |
| 150 |
|
errx(1, "syntax error: line must begin with letter or underscore!"); |
| 151 |
|
loop_addline: |