1// This file is manually written. It tries to match exactly the same language interface 2// between Cogent and C. 3 4// Simplifications made: 5// 1. Multiple arguments to functions are allowed 6// 2. Not using bool_t type in cogent-defns.h 7// 3. Using NULLable pointer instead of variant type 8// 4. Using break in a for-loop 9 10 11#include <stdio.h> 12#include <string.h> 13#include <stdint.h> 14#include <stddef.h> 15#include <cogent-defns.h> 16 17typedef void *SysState; 18 19// ***************************************************************** 20// Cogent part. 21// ***************************************************************** 22 23struct get_block_ret { 24 SysState *p1; 25 char *p2; 26}; 27typedef struct get_block_ret get_block_ret_t; 28 29struct Stuff { 30 u32 a; 31 u32 b; 32 u32 c; 33}; 34typedef struct Stuff Stuff_t; 35 36struct Entry { 37 u32 len; 38 Stuff_t stuff; 39 char* name; 40}; 41typedef struct Entry Entry_t; 42 43 44get_block_ret_t get_block (SysState); 45Entry_t *get_entry_at_offset (char*, u64); 46int is_entry (char*, Entry_t*); 47int cstring_cmp(char*, char*); 48Stuff_t *stuff_ptr(Entry_t *); 49 50 51struct findStuff_ret { 52 SysState *p1; 53 Stuff_t *p2; 54}; 55typedef struct findStuff_ret findStuff_ret_t; 56 57findStuff_ret_t findStuff (SysState *sys, char *name) { 58 get_block_ret_t ret_block = get_block(sys); 59 sys = ret_block.p1; 60 char *blk = ret_block.p2; 61 62 u64 offset = 0; 63 for (;;) { 64 Entry_t *e = get_entry_at_offset (blk, offset); 65 if (e->len == 0 || !is_entry(blk, e)) 66 break; 67 68 if (cstring_cmp(name, e->name)) 69 return (findStuff_ret_t){ .p1 = sys, .p2 = stuff_ptr(e) }; 70 offset = offset + e->len; 71 } 72 return (findStuff_ret_t){ .p1 = sys, .p2 = NULL}; 73} 74 75 76// ***************************************************************** 77// Below is the same as the main.ac file, with minor difference. 78// ***************************************************************** 79 80 81#define SIZE 4096 82 83 84char block[SIZE]; // Contains Entry's jammed together; terminated by 85 // len==0. 86 87 88get_block_ret_t get_block (SysState args) { 89 return (get_block_ret_t){ .p1 = args, .p2 = block }; 90} 91 92Entry_t *get_entry_at_offset (char *block, u64 offset) { 93 return (Entry_t*)((uintptr_t)block + offset); 94} 95 96int is_entry (char *block, Entry_t *e) { 97 return ((uintptr_t)e - (uintptr_t)block) < SIZE; 98} 99 100int cstring_cmp(char *s1, char *s2) { 101 return !strcmp(s1, s2); 102} 103 104Stuff_t *stuff_ptr(Entry_t *e) { 105 return &e->stuff; 106} 107 108int in_range(Entry_t *e, unsigned long nlen) { 109 unsigned long p; 110 111 p = (uintptr_t)e + offsetof(Entry_t, name) + nlen; 112 113 return (p - (uintptr_t)block) < SIZE; 114} 115 116/* Initialise our block of entries. */ 117/* Not translated into Cogent. */ 118void init(void) { 119 FILE *fp; 120 Entry_t *e; 121 int a, b, c, len; 122 char buf[80]; 123 124 memset(block, 0, SIZE); 125 126 if ((fp = fopen("entries.txt", "r")) != NULL) { 127 e = (Entry_t *)block; 128 while (fscanf(fp, "%s%d%d%d\n", buf, &a, &b, &c) == 4) { 129 len = strlen(buf)+1; 130 if (!in_range(e, len)) { 131 break; 132 } 133 // Point to the next location 134 e->name = (char*)((uintptr_t)e + offsetof(Entry_t, name) + sizeof(char*)); 135 strcpy(e->name, buf); 136 e->stuff.a = a; 137 e->stuff.b = b; 138 e->stuff.c = c; 139 e->len = ((uintptr_t)e->name + len) - (uintptr_t)e; 140 e = (Entry_t *) ((uintptr_t)e + e->len); 141 } 142 fclose(fp); 143 } 144} 145 146int main(void){ 147 struct findStuff_ret ret; 148 init(); 149 char *str = {"wombat"}; 150 ret = findStuff(NULL, str); 151 if (ret.p2) { 152 printf("Wombat's b is %d.\n", ret.p2->b); 153 } else { 154 printf("Wombat was not found.\n"); 155 } 156 return 0; 157} 158 159 160