Datum g_int_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int4 i; ArrayType *res; int totlen = 0, *ptr; for (i = 0; i < entryvec->n; i++) totlen += ARRNELEMS(GETENTRY(entryvec, i)); res = new_intArrayType(totlen); ptr = ARRPTR(res); for (i = 0; i < entryvec->n; i++) { memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4)); ptr += ARRNELEMS(GETENTRY(entryvec, i)); } QSORT(res, 1); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); }
void mkfiles(){ getcwd(cwd, 1024); int size = 0; int usize = 0; { GETENTRY(ind, file_index); GETENTRY(content, file_content); while(!ENDENTRY(ind, file_index) && !ENDENTRY(content, file_content)){ handlers[ind->type](ind, content); size += content->size; ind = NEXTENTRY(ind); content = NEXTENTRY(content); } } { GETENTRY(ind, file_index); GETENTRY(content, file_content); while(!ENDENTRY(ind, file_index) && !ENDENTRY(content, file_content)){ handlers[ind->type](ind, content); usize += content->size; printf("%.2lf%% (%d / %d) %s\r", usize * 10000.0 / size / 100.0, usize, size, ind->content); ind = NEXTENTRY(ind); content = NEXTENTRY(content); } } puts(""); }
Datum g_int_union(PG_FUNCTION_ARGS) { bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int4 i, len = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); ArrayType *res; int totlen = 0, *ptr; for (i = 0; i < len; i++) totlen += ARRNELEMS(GETENTRY(entryvec, i)); res = new_intArrayType(totlen); ptr = ARRPTR(res); for (i = 0; i < len; i++) { memcpy(ptr, ARRPTR(GETENTRY(entryvec, i)), ARRNELEMS(GETENTRY(entryvec, i)) * sizeof(int4)); ptr += ARRNELEMS(GETENTRY(entryvec, i)); } QSORT(res, 1); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); }
void Redirect(AMX * amx, char const * const from, ucell to, AMX_NATIVE * store) { int num, idx; // Operate on the raw AMX file, don't use the amx_ functions to avoid issues // with the fact that we've not actually finished initialisation yet. Based // VERY heavilly on code from "amx.c" in the PAWN runtime library. AMX_HEADER * hdr = (AMX_HEADER *)amx->base; AMX_FUNCSTUB * func; num = NUMENTRIES(hdr, natives, libraries); //logprintf("Redirect 1"); for (idx = 0; idx != num; ++idx) { func = GETENTRY(hdr, natives, idx); //logprintf("Redirect 2 \"%s\" \"%s\"", from, GETENTRYNAME(hdr, func)); if (!strcmp(from, GETENTRYNAME(hdr, func))) { //logprintf("Redirect 3"); // Intercept the call! if (store) { *store = (AMX_NATIVE)func->address; } func->address = to; break; } } }
void runstring(){ GETENTRY(cmd, strings); while(!ENDENTRY(cmd, strings)){ if(cmd->type == 9) run(cmd->content); cmd = NEXTENTRY(cmd); } }
PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX * amx) { int num, idx; // Operate on the raw AMX file, don't use the amx_ functions to avoid issues // with the fact that we've not actually finished initialisation yet. Based // VERY heavilly on code from "amx.c" in the PAWN runtime library. AMX_HEADER * hdr = (AMX_HEADER *)amx->base; AMX_FUNCSTUB * func; num = NUMENTRIES(hdr, natives, libraries); for (idx = 0; idx != num; ++idx) { func = GETENTRY(hdr, natives, idx); if (!strcmp("SetPlayerName", GETENTRYNAME(hdr, func))) { // Intercept the call! SetPlayerName = (AMX_NATIVE)func->address; func->address = (ucell)n_SSCANF_SetPlayerName; break; } } return amx_Register(amx, sscanfNatives, -1); }
Datum gmol_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int32 i,j; int signlen; bytea *result, *key; unsigned char *s, *k; key = GETENTRY(entryvec, 0); if (ISALLTRUE(key)) { *size = VARHDRSZ; result = palloc(VARHDRSZ); SET_VARSIZE(result, VARHDRSZ); PG_RETURN_POINTER(result); } signlen = SIGLEN(key); *size = VARHDRSZ + signlen; result = palloc(VARHDRSZ + signlen); SET_VARSIZE(result, VARHDRSZ + signlen); memcpy( VARDATA(result), VARDATA(key), signlen ); s = (unsigned char *)VARDATA(result); for (i = 1; i < entryvec->n; i++) { key = GETENTRY(entryvec, i); k = (unsigned char *)VARDATA(key); if (ISALLTRUE(key)) { *size = VARHDRSZ; SET_VARSIZE(result, VARHDRSZ); PG_RETURN_POINTER(result); } if (SIGLEN(key) != signlen) elog(ERROR, "All fingerprints should be the same length"); for(j=0;j<signlen;j++) s[j] |= k[j]; } PG_RETURN_POINTER(result); }
Datum gmol_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int i, signlen; bytea *result, *key; unsigned char *s, *k; int numentries = entryvec->n; for (i = 0; i < numentries; ++i) { key = GETENTRY(entryvec, i); if (ISALLTRUE(key)) { *size = VARHDRSZ; result = palloc(VARHDRSZ); SET_VARSIZE(result, VARHDRSZ); PG_RETURN_POINTER(result); } } key = GETENTRY(entryvec, 0); signlen = SIGLEN(key); *size = VARHDRSZ + signlen; result = palloc(*size); SET_VARSIZE(result, *size); memcpy(VARDATA(result), VARDATA(key), signlen); s = (uint8 *)VARDATA(result); for (i = 1; i < entryvec->n; ++i) { key = GETENTRY(entryvec, i); k = (uint8 *)VARDATA(key); if (SIGLEN(key) != signlen) { elog(ERROR, "All fingerprints should be the same length"); } bitstringUnion(signlen, s, k); } PG_RETURN_POINTER(result); }
Datum g_int_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); int4 i, *ptr; ArrayType *res; int totlen = 0; for (i = 0; i < entryvec->n; i++) { ArrayType *ent = GETENTRY(entryvec, i); CHECKARRVALID(ent); totlen += ARRNELEMS(ent); } res = new_intArrayType(totlen); ptr = ARRPTR(res); for (i = 0; i < entryvec->n; i++) { ArrayType *ent = GETENTRY(entryvec, i); int nel; nel = ARRNELEMS(ent); memcpy(ptr, ARRPTR(ent), nel * sizeof(int4)); ptr += nel; } QSORT(res, 1); res = _int_unique(res); *size = VARSIZE(res); PG_RETURN_POINTER(res); }
Datum gtsquery_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); TSQuerySign *sign = (TSQuerySign *) palloc(sizeof(TSQuerySign)); int i; memset(sign, 0, sizeof(TSQuerySign)); for (i = 0; i < entryvec->n; i++) *sign |= *GETENTRY(entryvec, i); *size = sizeof(TSQuerySign); PG_RETURN_POINTER(sign); }
Datum gtsquery_union(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int *size = (int *) PG_GETARG_POINTER(1); TSQuerySign sign; int i; sign = 0; for (i = 0; i < entryvec->n; i++) sign |= GETENTRY(entryvec, i); *size = sizeof(TSQuerySign); PG_RETURN_TSQUERYSIGN(sign); }
/* ** The GiST PickSplit method for _intments ** We use Guttman's poly time split algorithm */ Datum g_int_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber i, j; ArrayType *datum_alpha, *datum_beta; ArrayType *datum_l, *datum_r; ArrayType *union_d, *union_dl, *union_dr; ArrayType *inter_d; bool firsttime; float size_alpha, size_beta, size_union, size_inter; float size_waste, waste; float size_l, size_r; int nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; OffsetNumber maxoff; SPLITCOST *costvector; #ifdef GIST_DEBUG elog(DEBUG3, "--------picksplit %d", entryvec->n); #endif maxoff = entryvec->n - 2; nbytes = (maxoff + 2) * sizeof(OffsetNumber); v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); firsttime = true; waste = 0.0; for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) { datum_alpha = GETENTRY(entryvec, i); for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) { datum_beta = GETENTRY(entryvec, j); /* compute the wasted space by unioning these guys */ /* size_waste = size_union - size_inter; */ union_d = inner_int_union(datum_alpha, datum_beta); rt__int_size(union_d, &size_union); inter_d = inner_int_inter(datum_alpha, datum_beta); rt__int_size(inter_d, &size_inter); size_waste = size_union - size_inter; pfree(union_d); if (inter_d != (ArrayType *) NULL) pfree(inter_d); /* * are these a more promising split that what we've already seen? */ if (size_waste > waste || firsttime) { waste = size_waste; seed_1 = i; seed_2 = j; firsttime = false; } } } left = v->spl_left; v->spl_nleft = 0; right = v->spl_right; v->spl_nright = 0; if (seed_1 == 0 || seed_2 == 0) { seed_1 = 1; seed_2 = 2; } datum_alpha = GETENTRY(entryvec, seed_1); datum_l = copy_intArrayType(datum_alpha); rt__int_size(datum_l, &size_l); datum_beta = GETENTRY(entryvec, seed_2); datum_r = copy_intArrayType(datum_beta); rt__int_size(datum_r, &size_r); maxoff = OffsetNumberNext(maxoff); /* * sort entries */ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { costvector[i - 1].pos = i; datum_alpha = GETENTRY(entryvec, i); union_d = inner_int_union(datum_l, datum_alpha); rt__int_size(union_d, &size_alpha); pfree(union_d); union_d = inner_int_union(datum_r, datum_alpha); rt__int_size(union_d, &size_beta); pfree(union_d); costvector[i - 1].cost = Abs((size_alpha - size_l) - (size_beta - size_r)); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); /* * Now split up the regions between the two seeds. An important property * of this split algorithm is that the split vector v has the indices of * items to be split in order in its left and right vectors. We exploit * this property by doing a merge in the code that actually splits the * page. * * For efficiency, we also place the new index tuple in this loop. This is * handled at the very end, when we have placed all the existing tuples * and i == maxoff + 1. */ for (j = 0; j < maxoff; j++) { i = costvector[j].pos; /* * If we've already decided where to place this item, just put it on * the right list. Otherwise, we need to figure out which page needs * the least enlargement in order to store the item. */ if (i == seed_1) { *left++ = i; v->spl_nleft++; continue; } else if (i == seed_2) { *right++ = i; v->spl_nright++; continue; } /* okay, which page needs least enlargement? */ datum_alpha = GETENTRY(entryvec, i); union_dl = inner_int_union(datum_l, datum_alpha); union_dr = inner_int_union(datum_r, datum_alpha); rt__int_size(union_dl, &size_alpha); rt__int_size(union_dr, &size_beta); /* pick which page to add it to */ if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.01)) { if (datum_l) pfree(datum_l); if (union_dr) pfree(union_dr); datum_l = union_dl; size_l = size_alpha; *left++ = i; v->spl_nleft++; } else { if (datum_r) pfree(datum_r); if (union_dl) pfree(union_dl); datum_r = union_dr; size_r = size_beta; *right++ = i; v->spl_nright++; } } pfree(costvector); *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); PG_RETURN_POINTER(v); }
Datum gtsquery_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber maxoff = entryvec->n - 2; OffsetNumber k, j; TSQuerySign *datum_l, *datum_r; int4 size_alpha, size_beta; int4 size_waste, waste = -1; int4 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; SPLITCOST *costvector; nbytes = (maxoff + 2) * sizeof(OffsetNumber); left = v->spl_left = (OffsetNumber *) palloc(nbytes); right = v->spl_right = (OffsetNumber *) palloc(nbytes); v->spl_nleft = v->spl_nright = 0; for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { size_waste = hemdist(*GETENTRY(entryvec, j), *GETENTRY(entryvec, k)); if (size_waste > waste) { waste = size_waste; seed_1 = k; seed_2 = j; } } if (seed_1 == 0 || seed_2 == 0) { seed_1 = 1; seed_2 = 2; } datum_l = (TSQuerySign *) palloc(sizeof(TSQuerySign)); *datum_l = *GETENTRY(entryvec, seed_1); datum_r = (TSQuerySign *) palloc(sizeof(TSQuerySign)); *datum_r = *GETENTRY(entryvec, seed_2); maxoff = OffsetNumberNext(maxoff); costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) { costvector[j - 1].pos = j; size_alpha = hemdist(*GETENTRY(entryvec, seed_1), *GETENTRY(entryvec, j)); size_beta = hemdist(*GETENTRY(entryvec, seed_2), *GETENTRY(entryvec, j)); costvector[j - 1].cost = abs(size_alpha - size_beta); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); for (k = 0; k < maxoff; k++) { j = costvector[k].pos; if (j == seed_1) { *left++ = j; v->spl_nleft++; continue; } else if (j == seed_2) { *right++ = j; v->spl_nright++; continue; } size_alpha = hemdist(*datum_l, *GETENTRY(entryvec, j)); size_beta = hemdist(*datum_r, *GETENTRY(entryvec, j)); if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.05)) { *datum_l |= *GETENTRY(entryvec, j); *left++ = j; v->spl_nleft++; } else { *datum_r |= *GETENTRY(entryvec, j); *right++ = j; v->spl_nright++; } } *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); PG_RETURN_POINTER(v); }
Datum gmol_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber k, j; bytea *datum_l, *datum_r; int32 size_alpha, size_beta; int32 size_waste, waste = -1; int32 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; OffsetNumber maxoff; int i, signlen = 0; SPLITCOST *costvector; maxoff = entryvec->n - 1; nbytes = (maxoff + 2) * sizeof(OffsetNumber); v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) { if (signlen == 0) { signlen = SIGLEN(GETENTRY(entryvec, k)); } for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { size_waste = hemdist(GETENTRY(entryvec, j), GETENTRY(entryvec, k)); if (size_waste > waste) { waste = size_waste; seed_1 = k; seed_2 = j; } } } if (signlen == 0) { signlen = SIGLEN(GETENTRY(entryvec, maxoff)); } left = v->spl_left; v->spl_nleft = 0; right = v->spl_right; v->spl_nright = 0; if (signlen == 0 || waste == 0) { /* all entries a alltrue or all the same */ for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k)) { if (k <= (maxoff - FirstOffsetNumber + 1) / 2) { v->spl_left[v->spl_nleft] = k; v->spl_nleft++; } else { v->spl_right[v->spl_nright] = k; v->spl_nright++; } } signlen = VARSIZE(GETENTRY(entryvec, FirstOffsetNumber)); datum_l = palloc(signlen); memcpy(datum_l, GETENTRY(entryvec, FirstOffsetNumber), signlen); v->spl_ldatum = PointerGetDatum(datum_l); datum_r = palloc(signlen); memcpy(datum_r, GETENTRY(entryvec, FirstOffsetNumber), signlen); v->spl_rdatum = PointerGetDatum(datum_r); Assert( v->spl_nleft + v->spl_nright == maxoff ); PG_RETURN_POINTER(v); } if (seed_1 == 0 || seed_2 == 0) { seed_1 = 1; seed_2 = 2; } /* form initial .. */ if (ISALLTRUE(GETENTRY(entryvec, seed_1))) { datum_l = palloc(VARHDRSZ); SET_VARSIZE(datum_l, VARHDRSZ); } else { datum_l = palloc(signlen + VARHDRSZ); memcpy(datum_l , GETENTRY(entryvec, seed_1) , signlen + VARHDRSZ); } if (ISALLTRUE(GETENTRY(entryvec, seed_2))) { datum_r = palloc(VARHDRSZ); SET_VARSIZE(datum_r, VARHDRSZ); } else { datum_r = palloc(signlen + VARHDRSZ); memcpy(datum_r , GETENTRY(entryvec, seed_2) , signlen + VARHDRSZ); } /* sort before ... */ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) { costvector[j - 1].pos = j; size_alpha = hemdist(datum_l, GETENTRY(entryvec, j)); size_beta = hemdist(datum_r, GETENTRY(entryvec, j)); costvector[j - 1].cost = Abs(size_alpha - size_beta); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); for (k = 0; k < maxoff; k++) { j = costvector[k].pos; if (j == seed_1) { *left++ = j; v->spl_nleft++; continue; } else if (j == seed_2) { *right++ = j; v->spl_nright++; continue; } size_alpha = hemdist(GETENTRY(entryvec, j), datum_l); size_beta = hemdist(GETENTRY(entryvec, j), datum_r); if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1)) { if (!ISALLTRUE(datum_l)) { if (ISALLTRUE(GETENTRY(entryvec, j))) { datum_l = palloc(VARHDRSZ); SET_VARSIZE(datum_l, VARHDRSZ); } else { unsigned char *as = (unsigned char *)VARDATA(datum_l), *bs = (unsigned char *)VARDATA(GETENTRY(entryvec, j)); for (i=0;i<signlen;i++) { as[i] |= bs[i]; } } } *left++ = j; v->spl_nleft++; } else { if (!ISALLTRUE(datum_r)) { if (ISALLTRUE(GETENTRY(entryvec, j))) { datum_r = palloc(VARHDRSZ); SET_VARSIZE(datum_r, VARHDRSZ); } else { unsigned char *as = (unsigned char *)VARDATA(datum_r), *bs = (unsigned char *)VARDATA(GETENTRY(entryvec, j)); for (i=0;i<signlen;i++) { as[i] |= bs[i]; } } } *right++ = j; v->spl_nright++; } } *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); Assert( v->spl_nleft + v->spl_nright == maxoff ); PG_RETURN_POINTER(v); }
static int foreach(struct dbengine *db, const char *prefix, size_t prefixlen, foreach_p *goodp, foreach_cb *cb, void *rock, struct txn **mytid) { int r = CYRUSDB_OK; int offset; unsigned long len; const char *p, *pend; const char *dataend; /* for use inside the loop, but we need the values to be retained * from loop to loop */ struct buf keybuf = BUF_INITIALIZER; int dontmove = 0; /* For when we have a transaction running */ struct buf savebuf = BUF_INITIALIZER; /* for the local iteration so that the db can change out from under us */ const char *dbbase = NULL; size_t dblen = 0; int dbfd = -1; struct buf prefixbuf = BUF_INITIALIZER; r = starttxn_or_refetch(db, mytid); if (r) return r; if (!mytid) { /* No transaction, use the fast method to avoid stomping on our * memory map if changes happen */ dbfd = dup(db->fd); if(dbfd == -1) return CYRUSDB_IOERROR; map_refresh(dbfd, 1, &dbbase, &dblen, db->size, db->fname, 0); /* drop our read lock on the file, since we don't really care * if it gets replaced out from under us, our mmap stays on the * old version */ lock_unlock(db->fd, db->fname); } else { /* use the same variables as in the no transaction case, just to * get things set up */ dbbase = db->base; dblen = db->len; } if (prefix) { encode(prefix, prefixlen, &prefixbuf); offset = bsearch_mem_mbox(prefixbuf.s, dbbase, db->size, 0, &len); } else { offset = 0; } p = dbbase + offset; pend = dbbase + db->size; while (p < pend) { if (!dontmove) { GETENTRY(p) } else dontmove = 0; /* does it still match prefix? */ if (keybuf.len < (size_t) prefixbuf.len) break; if (prefixbuf.len && memcmp(keybuf.s, prefixbuf.s, prefixbuf.len)) break; if (!goodp || goodp(rock, keybuf.s, keybuf.len, DATA(db), DATALEN(db))) { unsigned long ino = db->ino; unsigned long sz = db->size; if(mytid) { /* transaction present, this means we do the slow way */ buf_copy(&savebuf, &keybuf); } /* make callback */ r = cb(rock, keybuf.s, keybuf.len, DATA(db), DATALEN(db)); if (r) break; if (mytid) { /* reposition? (we made a change) */ if (!(ino == db->ino && sz == db->size)) { /* something changed in the file; reseek */ buf_cstring(&savebuf); offset = bsearch_mem_mbox(savebuf.s, db->base, db->size, 0, &len); p = db->base + offset; GETENTRY(p); /* 'key' might not equal 'savebuf'. if it's different, we want to stay where we are. if it's the same, we should move on to the next one */ if (!buf_cmp(&savebuf, &keybuf)) { p = dataend + 1; } else { /* 'savebuf' got deleted, so we're now pointing at the right thing */ dontmove = 1; } } } } p = dataend + 1; } if (!mytid) { /* cleanup the fast method */ map_free(&dbbase, &dblen); close(dbfd); } buf_free(&savebuf); buf_free(&keybuf); buf_free(&prefixbuf); return r; }
int loadprogram(const char *filename, char *error, size_t error_size) { FIL *file = &amx_file; FRESULT status = f_open(file, filename, FA_READ); if (status != FR_OK) { snprintf(error, error_size, "Could not open file %s: %d", filename, status); return AMX_ERR_NOTFOUND; } /* Read file header */ memset(&amx, 0, sizeof(amx)); AMX_HEADER hdr; UINT read_count; f_read(file, &hdr, sizeof hdr, &read_count); if (read_count != sizeof hdr || hdr.magic != AMX_MAGIC) return AMX_ERR_FORMAT; if (hdr.flags & AMX_FLAG_OVERLAY) { // Read the header f_lseek(file, 0); f_read(file, vm_data, hdr.cod, &read_count); // Read the data block f_lseek(file, hdr.dat); unsigned dat_size = hdr.hea - hdr.dat; f_read(file, vm_data + hdr.cod, dat_size, &read_count); if (read_count != dat_size) return AMX_ERR_FORMAT; unsigned static_size = (hdr.stp - hdr.dat) + hdr.cod; amx_poolinit(vm_data + static_size, sizeof(vm_data) - static_size); amx.base = vm_data; amx.data = vm_data + hdr.cod; overlay_init(&amx, amx_filename, &amx_file); } else { if (hdr.stp > sizeof(vm_data)) return AMX_ERR_MEMORY; /* Read the actual file, including the header (again) */ f_lseek(file, 0); f_read(file, vm_data, hdr.size, &read_count); if (read_count != hdr.size) return AMX_ERR_FORMAT; } AMXERRORS(amx_Init(&amx, vm_data)); amxinit_display(&amx); amx_CoreInit(&amx); amxinit_string(&amx); amxinit_fixed(&amx); amxinit_wavein(&amx); amxinit_waveout(&amx); amxinit_menu(&amx); amxinit_file(&amx); amxinit_buttons(&amx); amxinit_fourier(&amx); amxinit_time(&amx); amxinit_device(&amx); amxinit_fpga(&amx); // Check that everything has been registered int regstat = amx_Register(&amx, NULL, -1); if (regstat != 0) { // Find out what is missing for (int i = 0; i < NUMENTRIES((AMX_HEADER*)amx.base,natives,libraries); i++) { AMX_FUNCSTUB *func = GETENTRY((AMX_HEADER*)amx.base,natives,i); if (func->address == 0) { snprintf(error, error_size, "Native function not found: %s", GETENTRYNAME((AMX_HEADER*)amx.base,func)); return AMX_ERR_NOTFOUND; } } snprintf(error, error_size, "Error registering native functions"); return regstat; } return 0; }