blob: c285ab9e8b1f40a8f7c0f5a7f01b7618dacc5087 [file] [log] [blame] [edit]
// This file is manually written. It tries to match exactly the same language interface
// between Cogent and C.
// Simplifications made:
// 1. Multiple arguments to functions are allowed
// 2. Not using bool_t type in cogent-defns.h
// 3. Using NULLable pointer instead of variant type
// 4. Using break in a for-loop
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <cogent-defns.h>
typedef void *SysState;
// *****************************************************************
// Cogent part.
// *****************************************************************
struct get_block_ret {
SysState *p1;
char *p2;
};
typedef struct get_block_ret get_block_ret_t;
struct Stuff {
u32 a;
u32 b;
u32 c;
};
typedef struct Stuff Stuff_t;
struct Entry {
u32 len;
Stuff_t stuff;
char* name;
};
typedef struct Entry Entry_t;
get_block_ret_t get_block (SysState);
Entry_t *get_entry_at_offset (char*, u64);
int is_entry (char*, Entry_t*);
int cstring_cmp(char*, char*);
Stuff_t *stuff_ptr(Entry_t *);
struct findStuff_ret {
SysState *p1;
Stuff_t *p2;
};
typedef struct findStuff_ret findStuff_ret_t;
findStuff_ret_t findStuff (SysState *sys, char *name) {
get_block_ret_t ret_block = get_block(sys);
sys = ret_block.p1;
char *blk = ret_block.p2;
u64 offset = 0;
for (;;) {
Entry_t *e = get_entry_at_offset (blk, offset);
if (e->len == 0 || !is_entry(blk, e))
break;
if (cstring_cmp(name, e->name))
return (findStuff_ret_t){ .p1 = sys, .p2 = stuff_ptr(e) };
offset = offset + e->len;
}
return (findStuff_ret_t){ .p1 = sys, .p2 = NULL};
}
// *****************************************************************
// Below is the same as the main.ac file, with minor difference.
// *****************************************************************
#define SIZE 4096
char block[SIZE]; // Contains Entry's jammed together; terminated by
// len==0.
get_block_ret_t get_block (SysState args) {
return (get_block_ret_t){ .p1 = args, .p2 = block };
}
Entry_t *get_entry_at_offset (char *block, u64 offset) {
return (Entry_t*)((uintptr_t)block + offset);
}
int is_entry (char *block, Entry_t *e) {
return ((uintptr_t)e - (uintptr_t)block) < SIZE;
}
int cstring_cmp(char *s1, char *s2) {
return !strcmp(s1, s2);
}
Stuff_t *stuff_ptr(Entry_t *e) {
return &e->stuff;
}
int in_range(Entry_t *e, unsigned long nlen) {
unsigned long p;
p = (uintptr_t)e + offsetof(Entry_t, name) + nlen;
return (p - (uintptr_t)block) < SIZE;
}
/* Initialise our block of entries. */
/* Not translated into Cogent. */
void init(void) {
FILE *fp;
Entry_t *e;
int a, b, c, len;
char buf[80];
memset(block, 0, SIZE);
if ((fp = fopen("entries.txt", "r")) != NULL) {
e = (Entry_t *)block;
while (fscanf(fp, "%s%d%d%d\n", buf, &a, &b, &c) == 4) {
len = strlen(buf)+1;
if (!in_range(e, len)) {
break;
}
// Point to the next location
e->name = (char*)((uintptr_t)e + offsetof(Entry_t, name) + sizeof(char*));
strcpy(e->name, buf);
e->stuff.a = a;
e->stuff.b = b;
e->stuff.c = c;
e->len = ((uintptr_t)e->name + len) - (uintptr_t)e;
e = (Entry_t *) ((uintptr_t)e + e->len);
}
fclose(fp);
}
}
int main(void){
struct findStuff_ret ret;
init();
char *str = {"wombat"};
ret = findStuff(NULL, str);
if (ret.p2) {
printf("Wombat's b is %d.\n", ret.p2->b);
} else {
printf("Wombat was not found.\n");
}
return 0;
}