failing test noentry; good
This commit is contained in:
parent
1a2fbccf23
commit
745e7c3167
@ -10,7 +10,7 @@ union date32 {
|
|||||||
};
|
};
|
||||||
void date32_to_string(const union date32 d, char (*const a)[12]);
|
void date32_to_string(const union date32 d, char (*const a)[12]);
|
||||||
union line64 {
|
union line64 {
|
||||||
struct { union date32 date; uint32_t line; }; /* C11, endian? */
|
struct { uint32_t line; union date32 date; }; /* C11, little-endian */
|
||||||
uint64_t u64; /* C99 optional */
|
uint64_t u64; /* C99 optional */
|
||||||
};
|
};
|
||||||
#endif /* base --> */
|
#endif /* base --> */
|
||||||
|
@ -32,6 +32,13 @@ int pair_is_equal(struct pair x, struct pair y) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pair_is_string(struct pair x, const char *y) {
|
||||||
|
assert(x.a <= x.b);
|
||||||
|
if(!x.a) return !y;
|
||||||
|
while(x.a < x.b) { if(*x.a != *y || !*y) return 0; x.a++, y++; }
|
||||||
|
return !*y;
|
||||||
|
}
|
||||||
|
|
||||||
/** djb2 <http://www.cse.yorku.ca/~oz/hash.html> */
|
/** djb2 <http://www.cse.yorku.ca/~oz/hash.html> */
|
||||||
uint32_t pair_djb2(struct pair p) {
|
uint32_t pair_djb2(struct pair p) {
|
||||||
uint32_t hash = 5381, c;
|
uint32_t hash = 5381, c;
|
||||||
|
@ -4,4 +4,5 @@ struct pair { const char *a, *b; };
|
|||||||
struct pair pair(const char *const a, const char *const b);
|
struct pair pair(const char *const a, const char *const b);
|
||||||
int pair_to_natural(const char *, const char *, uint32_t *);
|
int pair_to_natural(const char *, const char *, uint32_t *);
|
||||||
int pair_is_equal(struct pair, struct pair);
|
int pair_is_equal(struct pair, struct pair);
|
||||||
|
int pair_is_string(struct pair, const char *);
|
||||||
uint32_t pair_djb2(const struct pair p);
|
uint32_t pair_djb2(const struct pair p);
|
||||||
|
@ -40,7 +40,8 @@ struct source *sources_add(struct sources *, const union line64);
|
|||||||
struct sources sources(struct journal *);
|
struct sources sources(struct journal *);
|
||||||
void sources_(struct sources *);
|
void sources_(struct sources *);
|
||||||
const char *sources_to_string(const struct sources *);
|
const char *sources_to_string(const struct sources *);
|
||||||
/* And some query... */
|
const struct source *source_lookup(const struct sources *s,
|
||||||
|
const union line64 range);
|
||||||
#endif /* proto --> */
|
#endif /* proto --> */
|
||||||
|
|
||||||
#ifdef BASE
|
#ifdef BASE
|
||||||
|
@ -50,6 +50,7 @@ static int source_compare(const union line64 a, const union line64 b)
|
|||||||
#define TREE_VALUE size_t /* Index into source list. */
|
#define TREE_VALUE size_t /* Index into source list. */
|
||||||
#define TREE_COMPARE
|
#define TREE_COMPARE
|
||||||
#define TREE_TO_STRING
|
#define TREE_TO_STRING
|
||||||
|
#define TREE_DEFAULT 0
|
||||||
#include "../src/tree.h"
|
#include "../src/tree.h"
|
||||||
|
|
||||||
|
|
||||||
@ -93,14 +94,18 @@ static int scan(union date32 date, const char *const buffer,
|
|||||||
|
|
||||||
<source> * { why = "default source unrecognized"; goto catch; }
|
<source> * { why = "default source unrecognized"; goto catch; }
|
||||||
<source> @s0 keyword @s1 / "\n" => skip { also_add_to_tree: {
|
<source> @s0 keyword @s1 / "\n" => skip { also_add_to_tree: {
|
||||||
struct pair p = pair(s0, s1);
|
const struct pair keyword = pair(s0, s1);
|
||||||
size_t i;
|
const union line64 key = { { (uint32_t)line, date } };
|
||||||
//const union line64 key = { ... };
|
size_t i, *pi;
|
||||||
if(!(i = sourcemap_table_get(&s->map, p)))
|
if(line > UINT32_MAX)
|
||||||
|
{ errno = ERANGE; why = "too many lines of text"; goto catch; }
|
||||||
|
if(!(i = sourcemap_table_get(&s->map, keyword)))
|
||||||
{ why = "keyword not introduced"; goto catch; }
|
{ why = "keyword not introduced"; goto catch; }
|
||||||
/*switch(source_tree_assign(&s->source, )) {
|
switch(source_tree_try(&s->dates, key, &pi)) {
|
||||||
...
|
case TREE_PRESENT: why = "duplicate key"; /* _Sic_. */
|
||||||
}*/
|
case TREE_ERROR: goto catch;
|
||||||
|
case TREE_ABSENT: *pi = i; break;
|
||||||
|
}
|
||||||
date32_to_string(date, &datestr);
|
date32_to_string(date, &datestr);
|
||||||
printf("%s: <%.*s>\n", datestr, (int)(s1 - s0), s0);
|
printf("%s: <%.*s>\n", datestr, (int)(s1 - s0), s0);
|
||||||
continue;
|
continue;
|
||||||
@ -113,9 +118,8 @@ static int scan(union date32 date, const char *const buffer,
|
|||||||
switch(sourcemap_table_assign(&s->map, keyword, &idx)) {
|
switch(sourcemap_table_assign(&s->map, keyword, &idx)) {
|
||||||
case TABLE_PRESENT: errno = EDOM; why = "new keyword already used";
|
case TABLE_PRESENT: errno = EDOM; why = "new keyword already used";
|
||||||
case TABLE_ERROR: goto catch; /* /\ _Sic_. */
|
case TABLE_ERROR: goto catch; /* /\ _Sic_. */
|
||||||
case TABLE_ABSENT: break; /* Good. */
|
case TABLE_ABSENT: *idx = 0; break; /* Good. */
|
||||||
}
|
}
|
||||||
*idx = 0; /* Clean. */
|
|
||||||
if(!(source = sourcelist_array_new(&s->list))) goto catch;
|
if(!(source = sourcelist_array_new(&s->list))) goto catch;
|
||||||
*idx = (size_t)(source - s->list.data);
|
*idx = (size_t)(source - s->list.data);
|
||||||
source->name.a = s0, source->name.b = s1;
|
source->name.a = s0, source->name.b = s1;
|
||||||
@ -165,3 +169,14 @@ catch:
|
|||||||
finally:
|
finally:
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Lookup the last source in `range` in sources `s`. They are invalidated on
|
||||||
|
adding a source, (probably fine.) */
|
||||||
|
const struct source *source_lookup(const struct sources *const s,
|
||||||
|
const union line64 range) {
|
||||||
|
struct source *looked;
|
||||||
|
assert(s);
|
||||||
|
looked = s->list.data + source_tree_left(&s->dates, range);
|
||||||
|
/* verify ... */
|
||||||
|
return looked;
|
||||||
|
}
|
||||||
|
@ -11,6 +11,27 @@ int main(void) {
|
|||||||
struct journal j = journal();
|
struct journal j = journal();
|
||||||
struct sources s = sources(&j);
|
struct sources s = sources(&j);
|
||||||
if(errno) goto catch;
|
if(errno) goto catch;
|
||||||
|
|
||||||
|
const union line64 agenda = {{4,{{20,04,1996}}}},
|
||||||
|
before = {{1,{{1,1,1900}}}},
|
||||||
|
noentry = {{3,{{1,6,1995}}}};
|
||||||
|
const struct source *source;
|
||||||
|
|
||||||
|
source = source_lookup(&s, agenda);
|
||||||
|
printf("agenda: <%.*s>\n",
|
||||||
|
(int)(source->name.b - source->name.a), source->name.a);
|
||||||
|
assert(pair_is_string(source->name, "1995agenda"));
|
||||||
|
|
||||||
|
source = source_lookup(&s, before);
|
||||||
|
printf("before: <%.*s>\n",
|
||||||
|
(int)(source->name.b - source->name.a), source->name.a);
|
||||||
|
assert(pair_is_string(source->name, 0));
|
||||||
|
|
||||||
|
source = source_lookup(&s, noentry);
|
||||||
|
printf("noentry: <%.*s>\n",
|
||||||
|
(int)(source->name.b - source->name.a), source->name.a);
|
||||||
|
assert(pair_is_string(source->name, 0));
|
||||||
|
|
||||||
goto finally;
|
goto finally;
|
||||||
catch:
|
catch:
|
||||||
success = EXIT_FAILURE, perror("source");
|
success = EXIT_FAILURE, perror("source");
|
||||||
|
Loading…
Reference in New Issue
Block a user