void add_record(char *word, char *filename) { struct Record *r; int record_id = djb2((unsigned char *) word); HASH_FIND_INT(records, &record_id, r); // linear probing to resolve collisions while (r != NULL) { // found word if (strcmp(r->word, word) == 0) { break; } record_id++; HASH_FIND_INT(records, &record_id, r); } if (r == NULL) { // found empty spot, proceed to add r = (struct Record *)malloc(sizeof(struct Record)); r->id = record_id; r->word = word; r->filenames = SLCreate(compareStrings, destroyStrings); SLInsert(r->filenames, filename); HASH_ADD_INT(records, id, r); } else { SLInsert(r->filenames, filename); } }
Sint8 hash_test(hashp h, Uint8 *query) { hashindex *o; Uint32 sum; if ((sum = djb2(query)) == -1) { // Too long, invalid. return -1; } o = h->list[__mindex(query[0])]; if (o == NULL) { // It can't be in an empty list. return -1; } // Find it. for ( ; o != NULL; o = o->next) { if (o->sum == sum) { // Last test; djb2 isn't perfect. if(!strcmp(query, o->data)) { return 1; } } } return 0; }
int hash_add (hashp h, Uint8 *data, void *info) { hashindex *n; Uint32 sum; int pos; if ((sum = djb2(data)) == -1) { // Too Long. Invalid information. return -1; } pos = __mindex(data[0]); n = (hashindex *)malloc(sizeof(hashindex)); n->sum = sum; n->data = (char *)malloc(strlen(data)+1); n->prev = NULL; // Insert onto the front. strcpy(n->data, data); n->info = info; // Inserting onto the front is a threefold optimization. // * It takes fewer operations (don't have to seek the end). // * It's a fair assumption that a new entry will soon be used. // * It's fair to assume that new additions will be temporaries. n->next = h->list[pos]; if(n->next != NULL) { n->next->prev = n; } h->list[pos] = n; return 1; }
void printVMT(FILE* file, VMT* vmt) { while(!vmt->isEmpty) { fprintf(file, ".addr\t%s_%s_%lx\n", vmt->className, symToString(vmt->name), djb2(vmt->fileName)); vmt = vmt->next; } fprintf(file, "\n"); }
// Insert an item in the hash table file_data_t* insert(const char* filename) { unsigned long hash = djb2(filename); file_data_t* entry = table[hash]; file_data_t* prev = NULL; // Traverse to the end of the linked list to insert while (entry) { // Don't allow duplicate entries if (strcmp(entry->filename, filename) == 0) return entry; prev = entry; entry = entry->next; } // Create a new table entry, filled with 0 entry = (file_data_t*)calloc(1, sizeof(file_data_t)); // Every entry must have a filename entry->filename = strdup(filename); // Fix up our previous/next links entry->prev = prev; if (prev) prev->next = entry; else table[hash] = entry; return entry; }
void Aplicacion6::mostrarDetallesCiudad(Dispersion<StructPost> &disp, string nombreCiudad) { unsigned long int clave; clave = djb2(nombreCiudad); StructPost* c = disp.buscar(clave); if(c == 0){ cout << "Ciudad " << nombreCiudad<<" no encontrada." << endl; return; } EEDD::Iterador<CodigoPost*>* itLineas; itLineas = c->getListadoCodigos().iteradorIni(); cout << "Zipcode\tZipCodeType\tCity\t\tState\tLocationType\tLat\tLong\tLocation\tDecommisioned\tTaxReturnsFiled\tEstimatedPopulation\tTotalWages" << endl; while(itLineas->haySiguiente()){ cout << itLineas->dato()->getZipCode() << "\t"; cout << itLineas->dato()->getZipCodeType() << "\t"; cout << itLineas->dato()->getCity() << "\t\t"; cout << itLineas->dato()->getState() << "\t"; cout << itLineas->dato()->getLocationType() << "\t"; cout << itLineas->dato()->getLat() << "\t"; cout << itLineas->dato()->getLon() << "\t"; cout << itLineas->dato()->getLocation() << "\t"; cout << itLineas->dato()->getDecommisioned() << "\t"; cout << itLineas->dato()->getTaxReturnsFiled() << "\t"; cout << itLineas->dato()->getEstimatedPopulation() << "\t"; cout << itLineas->dato()->getTotalWages() << endl; itLineas->siguiente(); } }
static char *idt_test(){ Map *idt = idtCreate(); mu_assert("idt == NULL", idt != NULL); Instr a; fprintf(stderr, "%d\n", (int)djb2((void *)"ADD") % 32); char *key = "ADD"; int get_status = mapGet(idt, key, &a); mu_assert("couldn't find ADD in IDT", get_status == 0); mu_assert("ins_type != real (ADD)", a.type == ins_t_real); mu_assert("ADD's opcode != 8", a.data.real.opcode == 8); get_status = mapGet(idt, "WORD", &a); mu_assert("couldn't find WORD in IDT", get_status == 0); mu_assert("ins_type != pseudo (WORD)", a.type == ins_t_pseudo); mu_assert("num_ops != 1 (WORD)", a.data.pseudo.num_ops == 1); idtDestroy(idt); return 0; }
bool readEntry(struct entry *entry) { if(scanf("%128s", entry->line) == EOF) { return false; } entry->hash = djb2(entry->line); entry->counter = 0; return true; }
void *hash_del(hashp h, Uint8 *query) { hashindex *o; void *i; Uint32 sum; int pos; if ((sum = djb2(query)) == -1) { // Too long, invalid. return NULL; } pos = __mindex(query[0]); o = h->list[pos]; if (o == NULL) { // It can't be in an empty list. return NULL; } // Find it. for ( ; o != NULL; o = o->next) { if (o->sum == sum) { // Last test; djb2 isn't perfect. printf("Possible match for deletion!\n"); if (!strcmp(query, o->data)) { i = o->info; free(o->data); // Patch up the list if (o->prev == NULL && o->next == NULL) { h->list[pos] = NULL; } else if (o->prev == NULL && o->next != NULL) { h->list[pos] = o->next; h->list[pos]->prev = NULL; } else if (o->prev != NULL && o->next == NULL) { o->prev->next = NULL; } else if (o->prev != NULL && o->next != NULL) { o->prev->next = o->next; o->next->prev = o->prev; } free(o); return i; } } } return NULL; }
/** * This is so far the optimal algorithm as far as * speed and lack of collisions is concerned: * * Compute key using one-at-a-time algorithm, compute * step using FNV-1a 32 bit hash. */ int insert_dh1(Hashtable *ht, char *val) { u32 key = hash(val) % ht->size; u32 step = djb2(val) % (ht->size - 1) + 1; while (ht->table[key] != NULL) { collisions++; key = (key + step) % ht->size; } ht->table[key] = malloc(30); strcpy(ht->table[key], val); return 1; }
static bool checksum_bitmap(flow_c * c, struct flow_bitmap_bgra * bitmap, char * checksum_buffer, size_t checksum_buffer_length) { char info_buffer[256]; flow_snprintf(&info_buffer[0], sizeof(info_buffer), "%dx%d fmt=%d alpha=%d", bitmap->w, bitmap->h, bitmap->fmt, bitmap->alpha_meaningful); int64_t printed_chars = (flow_snprintf(checksum_buffer, checksum_buffer_length, "%016X_%016X", djb2_buffer((uint8_t *)bitmap->pixels, bitmap->stride * bitmap->h), djb2((unsigned const char *)&info_buffer[0]))); return printed_chars != -1; }
// Look up an item in the hash table file_data_t* lookup(const char* filename) { unsigned long hash = djb2(filename); file_data_t* entry = table[hash]; // Loop through the linked list at the hash value until // we find a matching entry while (entry && strcmp(entry->filename, filename) != 0) entry = entry->next; return entry; }
int main(int argc, char ** argv) { int hash_size = 0, i = 0; string * key = NULL; if (argc > 3) { hash_size = atoi(argv[1]); for (i = 2; i < argc; i += 1){ key = new string(argv[i]); cout << djb2(*key, hash_size) << "\n"; delete key; } } }
/** * Find value inserted using one-at-a-time hashing with * FNV-1a 32 bit. */ int find_dh1(Hashtable *ht, char *val) { u32 key = hash(val) % ht->size; u32 step = djb2(val) % (ht->size - 1) + 1; printf("Original key: %u\n", key); while (ht->table[key] != NULL) { if (strcmp(val, ht->table[key]) == 0) { printf("Found \"%s\" with key %u\n", val, key); return 1; } key = (key + step) % ht->size; } return 0; }
static void parse_map( pr_state_t* parser, int skip, int isrom ) { pr_node_t dummy; pr_node_t* node; unsigned hash; const char* key; unsigned keylen; if ( skip ) { node = &dummy; dummy.count = 0; } else node = parser->node; match( parser, LX_LPAREN ); while ( parser->lexer.token != LX_RPAREN ) { if ( parser->lexer.token != LX_TAG ) longjmp( parser->env, PR_UNEXPECTED_TOKEN ); key = parser->lexer.start; keylen = parser->lexer.len; hash = djb2( key, keylen ); match_any( parser ); switch ( hash ) { case 0x0b88a693U: /* rom */ parse_map( parser, skip, 1 ); break; default: parse_value( parser, key, keylen, node, isrom ); break; } } match_any( parser ); }
rl_entry_t* rl_find_entry( void* data, const char* name ) { rl_header_t* header = (rl_header_t*)data; if ( !( header->runtime_flags & RL_ENDIAN_CONVERTED ) ) { if ( isle() ) { header->num_entries = be32( header->num_entries ); for ( uint32_t i = 0; i < header->num_entries; i++ ) { header->entries[ i ].name_hash = be32( header->entries[ i ].name_hash ); header->entries[ i ].name_offset = be32( header->entries[ i ].name_offset ); header->entries[ i ].data_offset = be32( header->entries[ i ].data_offset ); header->entries[ i ].data_size = be32( header->entries[ i ].data_size ); header->entries[ i ].runtime_flags = 0; } } header->runtime_flags = RL_ENDIAN_CONVERTED; } uint32_t name_hash = djb2( name ); for ( uint32_t i = 0; i < header->num_entries - 1; i++ ) { uint32_t ndx = ( name_hash + i ) % header->num_entries; rl_entry_t* entry = header->entries + ndx; if ( entry->name_hash == name_hash ) { const char* entry_name = (char*)data + entry->name_offset; if ( !strcmp( name, entry_name ) ) { return entry; } } } return NULL; }
// return NULL if not found struct Record * find_record(char *word) { struct Record *r; int record_id = djb2((unsigned char *) word); HASH_FIND_INT(records, &record_id, r); // possible collision, linear probing while (r != NULL) { // found word if (strcmp(r->word, word) == 0) { break; } record_id++; HASH_FIND_INT(records, &record_id, r); } return r; }
void VM::recordProfile(State *state) { if (!s_profile) return; struct timespec profileTime; long long nsDifference = getClockDifference(&profileTime, &state->m_shared->m_profileState.m_lastTime); if (nsDifference > (long long)(s_profile_sample_size * k1MS)) { state->m_shared->m_profileState.m_lastTime = profileTime; const int cycleCount = state->m_shared->m_cycleCount; Table *directTable = &state->m_shared->m_profileState.m_directTable; Table *indirectTable = &state->m_shared->m_profileState.m_indirectTable; int innerRange = 0; for (State *currentState = state; currentState; currentState = currentState->m_parent) { for (CallFrame *currentFrame = currentState->m_frame; currentFrame; currentFrame = currentFrame->m_above, ++innerRange) { Instruction *currentInstruction = currentFrame->m_instructions; const char *keyData = (char *)¤tInstruction->m_belongsTo; const size_t keyLength = sizeof currentInstruction->m_belongsTo; const size_t keyHash = djb2(keyData, keyLength); if (innerRange == 0) { Field *free = nullptr; Field *find = Table::lookupAllocWithHash(directTable, keyData, keyLength, keyHash, &free); if (find) find->m_value = (void *)((size_t)find->m_value + 1); else free->m_value = (void *)1; } else if (currentInstruction->m_belongsTo->m_lastCycleSeen != cycleCount) { Field *free = nullptr; Field *find = Table::lookupAllocWithHash(indirectTable, keyData, keyLength, keyHash, &free); if (find) find->m_value = (void *)((size_t)find->m_value + 1); else free->m_value = (void *)1; } currentInstruction->m_belongsTo->m_lastCycleSeen = cycleCount; } // TODO backoff profiling samples if it's slowing us down too much // and adding noise } } }
static char *map_test(){ int map_len = 8; // Initialization test Map *m = mapCreate(sizeof(int), map_len, (unsigned int (*)(void *))djb2, (int(*)(void *a, void *b))strcmp); mu_assert("m == NULL", m != NULL); mu_assert("m->len != 8", m->len == 8); // Insertion tests char *key = "sprite"; int val = 33; mapInsert(m, key, strlen(key) + 1, &val); unsigned int bucket_id = djb2((unsigned char *)key) % map_len; Bucket *b = m->bs[bucket_id]; mu_assert("bucket is empty", b->tail != b->head); mu_assert("bucket->last->data != val", *(int *)b->tail->data == val); // Retrieval tests int x = 12, get_status; get_status = mapGet(m, key, &x); mu_assert("x has the wrong value", x == val); mu_assert("get_status != 0", get_status == 0); // Removal tests int y = 44, pop_status; pop_status = mapPop(m, key, &y, free); mu_assert("c has the wrong value", y == val); mu_assert("pop_status != 0", pop_status == 0); mu_assert("bucket is not empty", b->tail == b->head); mapDestroy(m, free); return 0; }
void Aplicacion6::cargarTablaDispersion(Dispersion<StructPost> &disp) { cout << "Iniciando carga de la tabla de Dispersión." << endl; long int tIni = time(0); CargadorDatos cd; CodigoPost* d; unsigned long clave = 0; d=cd.siguienteDetalle(); while(d != 0){ clave = djb2(d->getCity()); //si la ciudad no está aún en el árbol la creo. if (disp.buscar(clave) == 0){ StructPost c; c.setNombreCiudad(d->getCity()); disp.insertar(clave,c); } disp.buscar(clave)->getListadoCodigos().insertarFin(d); d=cd.siguienteDetalle(); } long int tFin = time(0); cout << "Número máximo de colisiones: " << disp.maxI << endl; cout << "Tabla de dispersión cargada(" << (tFin-tIni) << " segs)."<< endl; }
int hash_string(void *str) { return (int) djb2((unsigned char *) str); }
// hashing function int Hashmap::hash(string key) { return djb2(key, size); }
// scoring update void rf2plugin::YAMLupdate(const ScoringInfoV01 &info) { // WeekendInfo strncpy(weekendinfo.TrackName, info.mTrackName, sizeof(info.mTrackName)); weekendinfo.WeekendOptions.NumStarters = info.mNumVehicles; weekendinfo.TrackLength = (float)info.mLapDist/1000; weekendinfo.TrackID = djb2((unsigned char *)&info.mTrackName) & 0xFFFFFF; if(info.mDarkCloud < 0.25) strcpy (weekendinfo.TrackSkies, "Clear"); else if(info.mDarkCloud < 0.5) strcpy (weekendinfo.TrackSkies, "Partly Cloudy"); else if(info.mDarkCloud < 0.5) strcpy (weekendinfo.TrackSkies, "Mostly Cloudy"); else strcpy (weekendinfo.TrackSkies, "Overcast"); // mRaining not used weekendinfo.TrackAirTemp = (float)info.mAmbientTemp; weekendinfo.TrackSurfaceTemp = (float)info.mTrackTemp; // Wind isn't actually enabled, meh... weekendinfo.TrackWindVel = sqrtf((info.mWind.x * info.mWind.x) + (info.mWind.y * info.mWind.y)); // direction A·B = ||A|| ||B|| cos theta if(weekendinfo.TrackWindVel > 0.0) weekendinfo.TrackWindDir = acosf((info.mWind.x + info.mWind.y) / (sqrtf((info.mWind.x * info.mWind.x) + (info.mWind.y * info.mWind.y)) * sqrtf(1))); else { weekendinfo.TrackWindDir = 0.0; } // mOnPathWetness not used // mOffPathWetness not used // SessionInfo sessioninfo.Sessions[info.mSession].SessionNum = info.mSession; sessioninfo.Sessions[info.mSession].SessionTime = (float)info.mEndET; switch (info.mSession) // (0=testday 1-4=practice 5-8=qual 9=warmup 10-13=race) { case 0: case 1: case 2: case 3: case 4: strcpy (sessioninfo.Sessions[info.mSession].SessionType, "Practice"); break; case 5: case 6: case 7: case 8: strcpy (sessioninfo.Sessions[info.mSession].SessionType, "Qualify"); break; case 9: strcpy (sessioninfo.Sessions[info.mSession].SessionType, "Warmup"); break; case 10: case 11: case 12: case 13: strcpy (sessioninfo.Sessions[info.mSession].SessionType, "Race"); break; default: break; } if(info.mMaxLaps >= 2147483647) strcpy(sessioninfo.Sessions[info.mSession].SessionLaps, "unlimited"); else sprintf(sessioninfo.Sessions[info.mSession].SessionLaps, "%i", info.mMaxLaps); sessioninfo.Sessions[info.mSession].ResultsFastestLap.FastestTime = 999999.9f; // DriverInfo for( long i = 0; i < info.mNumVehicles; ++i ) { VehicleScoringInfoV01 &vinfo = info.mVehicle[i]; if((float)vinfo.mBestLapTime < sessioninfo.Sessions[info.mSession].ResultsFastestLap.FastestTime) { sessioninfo.Sessions[info.mSession].ResultsFastestLap.CarIdx = vinfo.mID; sessioninfo.Sessions[info.mSession].ResultsFastestLap.FastestTime = (float)vinfo.mBestLapTime; //sessioninfo.Sessions[info.mSession].ResultsFastestLap.FastestLap = ; dunno } sessioninfo.Sessions[info.mSession].ResultsPositions[i].CarIdx = vinfo.mID+1; sessioninfo.Sessions[info.mSession].ResultsPositions[i].Position = vinfo.mPlace; sessioninfo.Sessions[info.mSession].ResultsPositions[i].ClassPosition = vinfo.mPlace; // TODO sessioninfo.Sessions[info.mSession].ResultsPositions[i].FastestTime = (float)vinfo.mBestLapTime; sessioninfo.Sessions[info.mSession].ResultsPositions[i].Lap = vinfo.mTotalLaps; sessioninfo.Sessions[info.mSession].ResultsPositions[i].LastTime = (float)vinfo.mLastLapTime; sessioninfo.Sessions[info.mSession].ResultsPositions[i].LapsComplete = vinfo.mTotalLaps; sessioninfo.Sessions[info.mSession].ResultsPositions[i].LapsDriven = vinfo.mTotalLaps; //(float)((double)vinfo.mTotalLaps + (vinfo.mLapDist/info.mLapDist)); sessioninfo.Sessions[info.mSession].ResultsPositions[i].ReasonOutId = (int)vinfo.mFinishStatus; switch (vinfo.mFinishStatus) // 0=none, 1=finished, 2=dnf, 3=dq { case 0: strcpy(sessioninfo.Sessions[info.mSession].ResultsPositions[i].ReasonOutStr, "Running"); break; case 1: strcpy(sessioninfo.Sessions[info.mSession].ResultsPositions[i].ReasonOutStr, "Finished"); break; case 2: strcpy(sessioninfo.Sessions[info.mSession].ResultsPositions[i].ReasonOutStr, "DNF"); break; case 3: strcpy(sessioninfo.Sessions[info.mSession].ResultsPositions[i].ReasonOutStr, "Disqualified"); break; default: break; } driverinfo.Drivers[i].CarIdx = vinfo.mID+1; driverinfo.Drivers[i].UserID = djb2((unsigned char *)&vinfo.mDriverName) & 0xFFFFFF; driverinfo.Drivers[i].CarID = djb2((unsigned char *)&vinfo.mVehicleName) & 0xFFFFFF; driverinfo.Drivers[i].CarClassID = djb2((unsigned char *)&vinfo.mVehicleClass) & 0xFFFFFF; strcpy(driverinfo.Drivers[i].UserName, vinfo.mDriverName); strcpy(driverinfo.Drivers[i].CarPath, vinfo.mVehicleName); strcpy(driverinfo.Drivers[i].CarClassShortName, vinfo.mVehicleClass); if(vinfo.mIsPlayer) { driverinfo.DriverCarIdx = vinfo.mID+1; } } YAMLgenerate(); }
int main(int argc, char **argv) { if (argc > 1) while (++argv, --argc) { if (!strcmp("-c", argv[0])) color_on = 1; else if (!strcmp("-h", argv[0])) printf("liblisp unit tests\n\tusage ./%s (-c)? (-h)?\n", argv[0]); else printf("unknown argument '%s'\n", argv[0]); } unit_test_start("liblisp"); { print_note("util.c"); test(is_number("0xfAb")); test(is_number("-01234567")); test(is_number("+1000000000000000000000000000003")); test(!is_number("")); test(!is_number("+")); test(!is_number("-")); test(unbalanced("(((", '(', ')') > 0); test(unbalanced("))", '(', ')') < 0); test(unbalanced("", '(', ')') == 0); test(unbalanced("\"(", '(', ')') == 0); test(unbalanced("( \"))))(()()()(()\\\"())\")", '(', ')') == 0); test(unbalanced("(a (b) c (d (e (f) \")\" g)))", '(', ')') == 0); test(unbalanced("((a b) c", '(', ')') > 0); test(!is_fnumber("")); test(!is_fnumber("1e")); test(!is_fnumber("-1e")); test(!is_fnumber("1-e")); test(is_fnumber("+0.")); test(is_fnumber("123")); /*this passes, see header */ test(is_fnumber("1e-3")); test(is_fnumber("1.003e+34")); test(is_fnumber("1e34")); test(is_fnumber("93.04")); test(match("", "")); test(match("abc", "abc")); test(!match("abC", "abc")); test(match("aaa*", "aaaXX")); test(!match("aaa*", "XXaaaXX")); test(match(".bc", "abc")); test(match("a.c", "aXc")); test(!match("a\\.c", "aXc")); test(match("a\\.c", "a.c")); char *s = NULL; state(s = vstrcatsep(",", "a", "b", "c", "", "foo", "bar", NULL)); test(!sstrcmp("a,b,c,,foo,bar", s)); free(s); char *t = NULL, *s1 = "Hello,", *s2 = " World!"; state(t = calloc(16, 1)); state(strcpy(t, s1)); test(((size_t) (lstrcatend(t, s2) - t)) == (strlen(s1) + strlen(s2))); free(t); /*test tr, or translate, functionality */ size_t trinsz = 0; uint8_t trout[128] = { 0 }, *trin = (uint8_t *) "aaabbbcdaacccdeeefxxxa"; tr_state_t *tr1; state(tr1 = tr_new()); state(trinsz = strlen((char *)trin)); test(tr_init(tr1, "", (uint8_t *) "abc", (uint8_t *) "def") == TR_OK); test(tr_block(tr1, trin, trout, trinsz) == trinsz); test(!strcmp((char *)trout, "dddeeefdddfffdeeefxxxd")); test(tr_init(tr1, "s", (uint8_t *) "abc", (uint8_t *) "def") == TR_OK); state(memset(trout, 0, 128)); test(tr_block(tr1, trin, trout, trinsz) <= trinsz); test(!strcmp((char *)trout, "defddfdeeefxxxd")); state(tr_delete(tr1)); /*know collisions for the djb2 hash algorithm */ test(djb2("heliotropes", strlen("heliotropes")) == djb2("neurospora", strlen("neurospora"))); test(djb2("depravement", strlen("depravement")) == djb2("serafins", strlen("serafins"))); /*should not collide */ test(djb2("heliotropes", strlen("heliotropes")) != djb2("serafins", strlen("serafins"))); } { /*io.c test */ io_t *in, *out; print_note("io.c"); /*string input */ static const char hello[] = "Hello\n"; /**@note io_sin currently duplicates "hello" internally*/ state(in = io_sin(hello, strlen(hello))); test(io_is_in(in)); test(io_getc(in) == 'H'); test(io_getc(in) == 'e'); test(io_getc(in) == 'l'); test(io_getc(in) == 'l'); test(io_getc(in) == 'o'); test(io_getc(in) == '\n'); test(io_getc(in) == EOF); test(io_getc(in) == EOF); test(!io_error(in)); test(io_seek(in, 0, SEEK_SET) >= 0); test(io_getc(in) == 'H'); test(io_seek(in, 3, SEEK_SET) >= 0); test(io_getc(in) == 'l'); test(io_ungetc('x', in) == 'x'); test(io_getc(in) == 'x'); test(io_getc(in) == 'o'); state(io_close(in)); /*string output */ char *s = NULL; static const char hello_world[] = "Hello,\n\tWorld!\n"; /**@note io_sin currently duplicates hello_world internally*/ state(in = io_sin(hello_world, strlen(hello_world))); test(!strcmp(s = io_getline(in), "Hello,")); s = (free(s), NULL); test(!strcmp(s = io_getline(in), "\tWorld!")); s = (free(s), NULL); test(!io_getline(in)); test(io_seek(in, 0, SEEK_SET) >= 0); test(!strcmp(s = io_getdelim(in, EOF), "Hello,\n\tWorld!\n")); s = (free(s), NULL); state(io_close(in)); state(out = io_sout(1)); test(io_puts("Hello, World", out) != EOF); test(!strcmp("Hello, World", io_get_string(out))); test(io_putc('\n', out) != EOF); test(!strcmp("Hello, World\n", io_get_string(out))); test(io_seek(out, -6, SEEK_CUR) >= 0); test(io_puts("Mars\n", out) != EOF); test(!strcmp("Hello, Mars\n\n", io_get_string(out))); free(io_get_string(out)); state(io_close(out)); static const char block_in[16] = {1, 3, 4, 6}; static char block_out[16] = {0}; state((in = io_sin(block_in, 16))); test(io_getc(in) == 1); test(io_read(block_out, 15, in) == 15); test(!memcmp(block_out, block_in+1, 15)); state(io_close(in)); } { /* hash.c hash table tests */ hash_table_t *h = NULL; print_note("hash.c"); state(h = hash_create(1)); return_if(!h); test(!hash_insert(h, "key1", "val1")); test(!hash_insert(h, "key2", "val2")); /* assuming the hash algorithm is djb2, then * "heliotropes" collides with "neurospora" * "depravement" collides with "serafins" * "playwright" collides with "snush" (for djb2a) * See: * <https://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed> */ test(!hash_insert(h, "heliotropes", "val3")); test(!hash_insert(h, "neurospora", "val4")); test(!hash_insert(h, "depravement", "val5")); test(!hash_insert(h, "serafins", "val6")); test(!hash_insert(h, "playwright", "val7")); test(!hash_insert(h, "snush", "val8")); test(!hash_insert(h, "", "val9")); test(!hash_insert(h, "nil", "")); test(!hash_insert(h, "a", "x")); test(!hash_insert(h, "a", "y")); test(!hash_insert(h, "a", "z")); test(!sstrcmp("val1", hash_lookup(h, "key1"))); test(!sstrcmp("val2", hash_lookup(h, "key2"))); test(!sstrcmp("val3", hash_lookup(h, "heliotropes"))); test(!sstrcmp("val4", hash_lookup(h, "neurospora"))); test(!sstrcmp("val5", hash_lookup(h, "depravement"))); test(!sstrcmp("val6", hash_lookup(h, "serafins"))); test(!sstrcmp("val7", hash_lookup(h, "playwright"))); test(!sstrcmp("val8", hash_lookup(h, "snush"))); test(!sstrcmp("val9", hash_lookup(h, ""))); test(!sstrcmp("", hash_lookup(h, "nil"))); test(!sstrcmp("z", hash_lookup(h, "a"))); test(hash_get_load_factor(h) <= 0.75f); state(hash_destroy(h)); } { /* lisp.c (and the lisp interpreter in general) */ lisp_t *l; print_note("lisp.c"); /*while unit testing eschews state being held across tests it is makes *little sense in this case*/ state(l = lisp_init()); state(io_close(lisp_get_logging(l))); test(!lisp_set_logging(l, io_nout())); return_if(!l); test(!lisp_eval_string(l, "")); test(is_int(lisp_eval_string(l, "2"))); test(get_int(lisp_eval_string(l, "(+ 2 2)")) == 4); test(get_int(lisp_eval_string(l, "(* 3 2)")) == 6); lisp_cell_t *x = NULL, *y = NULL, *z = NULL; char *t = NULL; state(x = lisp_intern(l, lstrdup_or_abort("foo"))); state(y = lisp_intern(l, t = lstrdup_or_abort("foo"))); /*this one needs freeing! */ state(z = lisp_intern(l, lstrdup_or_abort("bar"))); test(x == y && x != NULL); test(x != z); free(t); /*free the non-interned string */ test(is_proc(lisp_eval_string(l, "(define square (lambda (x) (* x x)))"))); test(get_int(lisp_eval_string(l, "(square 4)")) == 16); test(!is_list(cons(l, gsym_tee(), gsym_tee()))); test(is_list(cons(l, gsym_tee(), gsym_nil()))); test(!is_list(cons(l, gsym_nil(), cons(l, gsym_tee(), gsym_tee())))); test(is_list(mk_list(l, gsym_tee(), gsym_nil(), gsym_tee(), NULL))); test(gsym_error() == lisp_eval_string(l, "(> 'a 1)")); test(is_sym(x)); test(is_asciiz(x)); test(!is_str(x)); test(gsym_error() == lisp_eval_string(l, "(eval (cons quote 0))")); char *serial = NULL; test(!strcmp((serial = lisp_serialize(l, cons(l, gsym_tee(), gsym_error()))), "(t . error)")); state(free(serial)); state(lisp_destroy(l)); } return unit_test_end("liblisp"); /*should be zero! */ }
unsigned long hash(unsigned char *str) { return djb2(str); }