void HashSetEnter(hashset *h, const void *elemAddr){ assert(elemAddr != NULL && "elemAddr can't be NULL"); int hashCode = h->hashfn(elemAddr, h->numBuckets); vector *vAddress; assert(hashCode >= 0 && hashCode < h->numBuckets && "not possible to insert the specified element into the specified hashset"); vAddress = h->buckets + hashCode; int position = VectorSearch(vAddress, elemAddr, h->comparefn, 0, false); if (position == -1) VectorAppend(vAddress, elemAddr); else VectorReplace(vAddress, elemAddr, position); }
static void TestReplace(vector *alphabet) { int found = 0; char toFind = 's', toReplace = '*'; while (found < VectorLength(alphabet)) { found = VectorSearch(alphabet, &toFind, CompareChar, found, false); if (found == -1) break; VectorReplace(alphabet, &toReplace, found); } fprintf(stdout, "\nAfter changing all %c to %c: ", toFind, toReplace); VectorMap(alphabet, PrintChar, stdout); }
/* * Pattern Rule Grammar * -------------------- * * line := blank | "#" comment | rule * * rule := pattern *[ whitespace ] actions * * whitespace := SPACE | TAB * * pattern := "/" extended_regex "/" * * actions := action [ ";" actions ] * * action := thread | limit | report | on_exceed | on_expire * * quote := "'" | '"' * * index := number | quote text quote * * indices := index [ "," index ] * * thread := "t=" indices * * limit := "l=" indices "," max "/" period [ unit ] * * report := "r=" mail *[ "," mail ] * * on_exceed := "c=" quoted_shell_command * * on_expire := "C=" quoted_shell_command * * quoted_shell_command := quote text quote */ static int init_rule(char *line) { Vector fields; const char *next; struct pattern_rule *rule; int i, rc = -1, err; char *field, error[128]; if (*line != '/') goto error0; if ((rule = calloc(1, sizeof (*rule))) == NULL) goto error0; if ((rule->pattern = TokenNext(line, &next, "/", TOKEN_KEEP_ASIS)) == NULL) goto error1; if ((fields = TextSplit(next, ";", TOKEN_KEEP_ASIS)) == NULL) goto error1; if ((err = regcomp(&rule->re, rule->pattern, REG_EXTENDED|REG_NEWLINE)) != 0) { (void) regerror(err, &rule->re, error, sizeof (error)); (void) fprintf(stderr, "pattern /%s/: %s (%d)\n", rule->pattern, error, err); goto error2; } /* Assume new previously unknown pattern. */ if ((err = sqlite3_bind_text(ctx.insert_pattern, 1, rule->pattern, -1, SQLITE_STATIC)) != SQLITE_OK) { sql_error(__FILE__, __LINE__, ctx.insert_pattern); goto error2; } if ((err = sql_step(ctx.db, ctx.insert_pattern)) != SQLITE_DONE) { sql_error(__FILE__, __LINE__, ctx.insert_pattern); goto error2; } rule->id_pattern = sqlite3_last_insert_rowid(ctx.db); (void) sqlite3_clear_bindings(ctx.insert_pattern); sqlite3_reset(ctx.insert_pattern); /* Last insert rowid is zero if no row was inserted, thus it * already exists and we need to find the pattern number (OID). */ if (rule->id_pattern == 0) { if ((err = sqlite3_bind_text(ctx.find_pattern, 1, rule->pattern, -1, SQLITE_STATIC)) != SQLITE_OK) { sql_error(__FILE__, __LINE__, ctx.find_pattern); goto error2; } if ((err = sql_step(ctx.db, ctx.find_pattern)) != SQLITE_ROW) { sql_error(__FILE__, __LINE__, ctx.find_pattern); goto error2; } if ((rule->id_pattern = sqlite3_column_int64(ctx.find_pattern, 0)) == 0) { sql_error(__FILE__, __LINE__, ctx.find_pattern); goto error2; } (void) sqlite3_clear_bindings(ctx.find_pattern); sqlite3_reset(ctx.find_pattern); } for (i = 0; i < VectorLength(fields); i++) { field = VectorGet(fields, i); field += strspn(field, " \t"); switch (*field) { case 'c': if (field[1] == '=') { free(rule->on_exceed); rule->on_exceed = VectorReplace(fields, i, NULL); } break; case 'C': if (field[1] == '=') { free(rule->on_expire); rule->on_expire = VectorReplace(fields, i, NULL); } break; case 'r': if (field[1] == '=') { free(rule->report); rule->report = VectorReplace(fields, i, NULL); } break; case 't': if (field[1] == '=') rule->thread = strtol(field+2, NULL, 10); break; case 'l': if (field[1] == '=') continue; } (void) VectorRemove(fields, i--); } field[strcspn(field, "\r\n")] = '\0'; /* What remains of fields should be an empty vector or an array of l= actions. */ rule->limits = (char **) VectorBase(fields); fields = NULL; rule->node.data = rule; rule->node.free = free_rule; listInsertAfter(&pattern_rules, NULL, &rule->node); rc = 0; error2: VectorDestroy(fields); error1: if (rc != 0) free_rule(rule); error0: return rc; }