void sdl_mount_fbfs() { fs_mount_builtin("/framebuffer", fbfs_open, fbfs_read, fbfs_write, 0, fbfs_mmap); insert_global_symbol(alloc_sym("screen-width"),alloc_int(WIDTH)); insert_global_symbol(alloc_sym("screen-height"),alloc_int(HEIGHT)); insert_global_symbol(alloc_sym("screen-bpp"),alloc_int(BPP)); }
ReaderState* read_char(char c, ReaderState* rs) { Cell* cell = rs->cell; Cell* new_cell; if (!cell) { // make a root cell = alloc_nil(); cell->next = alloc_nil(); *rs->stack = cell; } if (rs->state == PST_ATOM) { if (c==' ' || c==13 || c==10) { // skip whitespace } else if (c==';') { // comment rs->state = PST_COMMENT; } else if (c>='0' && c<='9') { rs->state = PST_NUM; rs->valuestate = VST_DEFAULT; new_cell = alloc_int(0); new_cell->value = c-'0'; cell->addr = new_cell; } else if (c=='(') { // start list new_cell = alloc_nil(); cell->addr = new_cell; *rs->stack = cell; cell = new_cell; rs->stack++; rs->level++; rs->state = PST_ATOM; } else if (c==')') { // end of list cell = reader_end_list(cell, rs); } else if (c=='[') { // bytes (hex notation) rs->state = PST_BYTES; rs->sym_len = 0; new_cell = alloc_bytes(); cell->addr = new_cell; } else if (c=='"') { // string rs->state = PST_STR; rs->sym_len = 0; new_cell = alloc_string(); cell->addr = new_cell; } else { // symbol rs->state = PST_SYM; rs->sym_len = 1; new_cell = alloc_sym(0); new_cell->addr = cell_malloc(SYM_INIT_BUFFER_SIZE); memset(new_cell->addr, 0, SYM_INIT_BUFFER_SIZE); ((char*)new_cell->addr)[0] = c; new_cell->size = SYM_INIT_BUFFER_SIZE; // buffer space cell->addr = new_cell; } } else if (rs->state == PST_COMMENT) { //printf("c[%c]\n",c); if (c=='\n' || c=='0') { rs->state = PST_ATOM; } } else if (rs->state == PST_NUM || rs->state == PST_NUM_NEG) { if (c>='0' && c<='9' || ((rs->valuestate == VST_HEX && c>='a' && c<='f'))) { // build number Cell* vcell = (Cell*)cell->addr; int mul = 10; if (rs->valuestate == VST_HEX) mul = 16; int d = 0; if (c>='a') { d = 10+(c-'a'); } else { d = c-'0'; } if (rs->state == PST_NUM_NEG) { vcell->value = vcell->value*mul - d; } else { vcell->value = vcell->value*mul + d; } } else if (c==' ' || c==13 || c==10) { cell = reader_next_list_cell(cell, rs); } else if (c==')') { cell = reader_end_list(cell, rs); } else if (c=='x') { rs->valuestate = VST_HEX; } else { rs->state = PST_ERR_UNEXP_JUNK_IN_NUMBER; } } else if (rs->state == PST_SYM || rs->state == PST_STR) { int append = 0; if (rs->state == PST_STR) { if (c=='"') { // string is over Cell* vcell = (Cell*)cell->addr; vcell->size = (rs->sym_len); cell = reader_next_list_cell(cell, rs); } else { append = 1; } } else { if (c==')') { cell = reader_end_list(cell, rs); } else if (c==' ' || c==13 || c==10) { cell = reader_next_list_cell(cell, rs); } else if (rs->state == PST_SYM && (c>='0' && c<='9')) { Cell* vcell = (Cell*)cell->addr; // detect negative number if (((char*)vcell->addr)[0] == '-') { // we're actually not a symbol, correct the cell. rs->state = PST_NUM_NEG; vcell->tag = TAG_INT; vcell->value = -(c-'0'); } } else { append = 1; } } if (append) { // build symbol/string Cell* vcell = (Cell*)cell->addr; int idx = rs->sym_len; rs->sym_len++; if (rs->sym_len>=vcell->size-1) { // grow buffer vcell->addr = cell_realloc(vcell->addr, vcell->size, 2*vcell->size); memset(vcell->addr+vcell->size, 0, vcell->size); vcell->size = 2*vcell->size; } ((char*)vcell->addr)[idx] = c; } } else if (rs->state == PST_BYTES) { if (c==']') { Cell* vcell = (Cell*)cell->addr; vcell->size = (rs->sym_len)/2; cell = reader_next_list_cell(cell, rs); } else if ((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F')) { int n = c; if (n>='a') n-=('a'-'9'-1); // hex 'a' to 10 offset if (n>='A') n-=('A'-'9'-1); // hex 'a' to 10 offset n-='0'; // char to value Cell* vcell = (Cell*)cell->addr; int idx = rs->sym_len; rs->sym_len++; if (rs->sym_len>=(vcell->size/2)-1) { // grow buffer vcell->addr = cell_realloc(vcell->addr, vcell->size, 2*vcell->size); // TODO: check the math memset(vcell->addr+vcell->size, 0, vcell->size); vcell->size = 2*vcell->size; } if (idx%2==0) { // even digit ((byte*)vcell->addr)[idx/2] = n<<4; // high nybble } else { // odd digit ((byte*)vcell->addr)[idx/2] |= n; } } else if (c==' ' || c==13 || c==10) { // skip } else { rs->state = PST_ERR_UNEXP_JUNK_IN_BYTES; } } rs->cell = cell; return rs; }
static void symbol_handler (zebra_image_scanner_t *iscn, int x, int y) { zebra_symbol_type_t type = zebra_decoder_get_type(iscn->dcode); /* FIXME assert(type == ZEBRA_PARTIAL) */ /* FIXME debug flag to save/display all PARTIALs */ if(type <= ZEBRA_PARTIAL) return; const char *data = zebra_decoder_get_data(iscn->dcode); /* FIXME deprecate - instead check (x, y) inside existing polygon */ zebra_symbol_t *sym; for(sym = iscn->img->syms; sym; sym = sym->next) if(sym->type == type && !strcmp(sym->data, data)) { /* add new point to existing set */ /* FIXME should be polygon */ sym_add_point(sym, x, y); return; } sym = alloc_sym(iscn, type, data); /* timestamp symbol */ struct timeval abstime; gettimeofday(&abstime, NULL); sym->time = (abstime.tv_sec * 1000) + ((abstime.tv_usec / 500) + 1) / 2; /* initialize first point */ sym->npts = 0; sym_add_point(sym, x, y); /* attach to current root image */ sym->next = iscn->img->syms; iscn->img->syms = sym; iscn->img->nsyms++; if(iscn->enable_cache) { zebra_symbol_t *entry = cache_lookup(iscn, sym); if(!entry) { entry = alloc_sym(iscn, sym->type, sym->data); entry->time = sym->time - CACHE_HYSTERESIS; entry->cache_count = -CACHE_CONSISTENCY; /* add to cache */ entry->next = iscn->cache; iscn->cache = entry; } /* consistency check and hysteresis */ uint32_t age = sym->time - entry->time; entry->time = sym->time; int near = (age < CACHE_PROXIMITY); int far = (age >= CACHE_HYSTERESIS); int dup = (entry->cache_count >= 0); if((!dup && !near) || far) entry->cache_count = -CACHE_CONSISTENCY; else if(dup || near) entry->cache_count++; sym->cache_count = entry->cache_count; } else sym->cache_count = 0; if(iscn->handler) iscn->handler(iscn->img, iscn->userdata); }