/* Find all squares with a single digit allowed -- do not mutate board */ static void singles( int el, int (*idx_fn)( int, int ), int hintcode ) { int i, j, idx; count_set_digits( el, idx_fn ); for( i = 0 ; i < 9 ; ++i ) { if( 1 == counts[ i ] ) { /* Digit 'i+1' appears just once in the element */ for( j = 0 ; j < 9 ; ++j ) { idx = (*idx_fn)( el, j ); if( !DISALLOWED( idx, i + 1 ) && idx_possible < 81 ) possible[ idx_possible++ ] = SET_INDEX( idx ) | SET_DIGIT( i + 1 ) | hintcode; } } if( 8 == digits[ i ] ) { /* 8 digits are masked at this position - just one remaining */ idx = (*idx_fn)( el, i ); for( j = 1 ; j <= 9 ; ++j ) if( 0 == ( STATE( idx ) & DIGIT_STATE( j ) ) && idx_possible < 81 ) possible[ idx_possible++ ] = SET_INDEX( idx ) | SET_DIGIT( j ) | hintcode; } } }
static int choice( void ) { int i, n; rb->yield(); for( n = i = 0 ; i < 81 ; ++i ) if( IS_EMPTY( i ) ) { possible[ n ] = SET_INDEX( i ) | SET_DIGIT( numset( board[ i ] ) ); /* Inconsistency if square unknown, but nothing possible */ if( 9 == GET_DIGIT( possible[ n ] ) ) return -2; ++n; } if( 0 == n ) return -1; /* All squares known */ rb->qsort( possible, n, sizeof( possible[ 0 ] ), cmp ); return GET_INDEX( possible[ 0 ] ); }
static DPOINT *get_point_location(int random_path) { static int current = 0; int i = 0, ri = 0; /* ri: random index */ DPOINT *pt = NULL; if (current == val_data->n_list) { current = 0; /* reset for next run */ return NULL; } if (current == 0 && random_path) { /* first time: randomize list order */ for (i = 0; i < val_data->n_list; i++) { ri = floor(r_uniform() * (val_data->n_list)); if (ri >= val_data->n_list) /* obsolete, but anyway... */ ri = val_data->n_list - 1; /* now swap list pointers i and ri: */ pt = val_data->list[i]; val_data->list[i] = val_data->list[ri]; val_data->list[ri] = pt; } } if (DEBUG_TRACE) printf("[cell %d]\n", current); pt = val_data->list[current]; print_progress(current, val_data->n_list); SET_INDEX(pt, current); current++; return pt; }
/* Management of the move history - adding a move */ static void add_move( int idx, int digit, int choice ) { int i; if( sizeof( history ) / sizeof( int ) == idx_history ) compress( 81 ); /* Never ignore the last move */ history[ idx_history++ ] = SET_INDEX( idx ) | SET_DIGIT( digit ) | choice; /* Ignore all previous references to idx */ for( i = idx_history - 2 ; 0 <= i ; --i ) if( GET_INDEX( history[ i ] ) == idx ) { history[ i ] |= IGNORED; break; } }
/* pointerreversed_handle_reference marks the given object as well as any objects pointed to by it using pointer-reversal. */ void pointerreversed_handle_reference(jobject_unwrapped *ref) { jobject_unwrapped prev = NULL; jobject_unwrapped curr = *ref; jobject_unwrapped next; int done = 0; // in pointer-reversal, the mark has 3 possible states. // when an object has not yet been visited, it is // unmarked. after an object has been visited and all // its roots traced, it is marked as reachable. after // an object has been visited and before all its roots // have been traced, its mark encodes the field or // array element that is currently being examined. while (!done) { // follow pointers down while (curr != NULL) { jobject_unwrapped obj = PTRMASK(curr); struct block *bl = (void *)obj - BLOCK_HEADER_SIZE; if (!IN_MARKSWEEP_HEAP(obj, heap)) { error_gc("%p not allocated by marksweep.\n", obj); if (prev == NULL) done = 1; break; } debug_verify_object(obj); // these objects are untouched if (NOT_MARKED(bl)) { ptroff_t next_index; jobject_unwrapped *elements_and_fields; error_gc("%p is unmarked.\n", obj); elements_and_fields = (jobject_unwrapped *)obj; // we know the header does not contain heap pointers next_index = get_next_index(obj, OBJ_HEADER_SIZE/SIZEOF_VOID_P); if (next_index == NO_POINTERS) { // does not contain pointers, mark as done error_gc("%p does not contain pointers.\n", obj); MARK_AS_REACHABLE(bl); if (prev == NULL) done = 1; break; } else { // the indices returned by next_index // is off by one; do fix up next_index -= INDEX_OFFSET; assert(next_index >= 0); error_gc("next_index = %d\n", next_index); // look at the next index SET_INDEX(bl, next_index); next = elements_and_fields[next_index]; elements_and_fields[next_index] = prev; prev = curr; error_gc("Setting prev = %p.\n", prev); curr = next; } } else { // these are references we're done with or that // we are already looking at somewhere in the chain if (prev == NULL) done = 1; break; } } // retreat! curr should point to the last thing we looked at, and prev to its parent while (prev != NULL) { // these objects are in the middle of being examined jobject_unwrapped obj = PTRMASK(prev); struct block *bl = (void *)obj - BLOCK_HEADER_SIZE; ptroff_t last_index; ptroff_t next_index; jobject_unwrapped *elements_and_fields; error_gc("Starting prev loop with prev = %p.\n", prev); last_index = GET_INDEX(bl); elements_and_fields = (jobject_unwrapped *)obj; next_index = get_next_index(obj, last_index+1); if (next_index == NO_POINTERS) { // does not contain any more pointers, mark as done error_gc("None of the rest of the fields/elements in this object contains a ptr.\n", ""); MARK_AS_REACHABLE(bl); // restore pointers next = prev; prev = elements_and_fields[last_index]; error_gc("Setting prev = %p.\n", prev); elements_and_fields[last_index] = curr; curr = next; if (prev == NULL) done = 1; } else { // the indices returned by next_array_index // and next_field_index are off by one; do fix up next_index -= INDEX_OFFSET; assert(next_index > 0); error_gc("last_index = %d\n", last_index); error_gc("next_index = %d\n", next_index); SET_INDEX(bl, next_index); next = elements_and_fields[next_index]; elements_and_fields[next_index] = elements_and_fields[last_index]; elements_and_fields[last_index] = curr; curr = next; break; } } } }
int verify(const char *command, int argc, char **argv) { int ret = 1; unsigned char signature[sizeof(ecdsa_signature_t)]; set pubkeys, signatures; set_init(&pubkeys, sizeof(ecc_25519_work_t), 5); set_init(&signatures, sizeof(signature), 5); size_t min_good_signatures = 1; int opt; while ((opt = getopt(argc, argv, "s:p:n:")) != -1) { ecc_int256_t pubkey_packed; ecc_25519_work_t pubkey; switch (opt) { case 's': if (!parsehex(signature, optarg, sizeof(signature))) { fprintf(stderr, "Error while reading signature %s\n", optarg); break; } if (!set_add(&signatures, signature)) { fprintf(stderr, "Error in array_add\n"); goto out; } break; case 'p': if (!parsehex(pubkey_packed.p, optarg, 32)) { fprintf(stderr, "Error while reading pubkey %s\n", optarg); break; } int ok = ecc_25519_load_packed_legacy(&pubkey, &pubkey_packed); if (!ok || !ecdsa_is_valid_pubkey(&pubkey)) { fprintf(stderr, "Invalid pubkey %s\n", optarg); break; } if (!set_add(&pubkeys, &pubkey)) { fprintf(stderr, "Error in array_add\n"); goto out; } break; case 'n': min_good_signatures = atoi(optarg); } } if (optind > argc) { fprintf(stderr, "Usage: %s [-s signature ...] [-p pubkey ...] [-n num] file\n", command); goto out; } ecc_int256_t hash; if (!sha256_file((optind <= argc) ? argv[optind] : NULL, hash.p)) { fprintf(stderr, "Error while hashing file\n"); goto out; } { ecdsa_verify_context_t ctxs[signatures.size]; for (size_t i = 0; i < signatures.size; i++) ecdsa_verify_prepare_legacy(&ctxs[i], &hash, SET_INDEX(signatures, i)); size_t good_signatures = ecdsa_verify_list_legacy(ctxs, signatures.size, pubkeys.content, pubkeys.size); if (good_signatures >= min_good_signatures) ret = 0; } out: set_destroy(&pubkeys); set_destroy(&signatures); return ret; }
void push_point(DATA *d, const DPOINT *p) { int i; /* * add one point p to the data structure d * [counts on the fact that erealloc(NULL,size) calls malloc(size)] */ if (d->prob < 1.0) { ErrMsg(ER_IMPOSVAL, "sample in R, not in gstat"); } else if (d->every > 1) { /* EJP: WAS if ((d->n_list + d->offset) % d->every != 0) */ if ((d->n_list + d->skip + 1 - d->offset) % d->every != 0) { d->skip++; return; } } if (d->n_list < 0) { message("push_point: n_list < 0: %d (%s)\n", d->n_list, d->fname); ErrMsg(ER_NULL, "push_point(): n_list < 0"); } if (d->n_max < 0) { message("push_point: n_max < 0: %d (%s)\n", d->n_max, d->fname); ErrMsg(ER_NULL, "push_point(): n_max < 0"); } /* * use rather large blocks of memory for points: */ if (d->n_list == d->n_max) { /* increase memory: */ /* resize d->n_max: */ if (d->list == NULL) { if (d->init_max > 0) d->n_max = d->init_max; else d->n_max = MAX_DATA; } else { d->n_max += MAX_DATA; /* or else: d->n_max *= 2; */ if (d->init_max > 0 && DEBUG_DUMP) pr_warning("exceeding nmax, now %d", d->n_max); } /* resize blocked memory bases P_base and X_base, and list: */ d->P_base = (DPOINT *) erealloc(d->P_base, d->n_max * sizeof(DPOINT)); if (d->n_X > 0) { if (intercept_only(d)) { /* create a single instance of the X row: */ if (d->X_base == NULL) { /* first time */ d->X_base = (double *) emalloc(sizeof(double)); d->X_base[0] = 1.0; } } else /* each point needs it's own X row: */ d->X_base = (double *) erealloc(d->X_base, d->n_max * d->n_X * sizeof(double)); } d->list = (DPOINT **) erealloc(d->list, d->n_max * sizeof(DPOINT *)); /* * realloc'ing may have moved P_base or X_base, so reset all pointers: */ for (i = 0; i < d->n_list; i++) { d->list[i] = &(d->P_base[i]); if (d->n_X) { if (intercept_only(d)) /* d->P_base[i].X = d->X_base; */ d->list[i]->X = d->X_base; else /* d->P_base[i].X = &(d->X_base[d->n_X * i]); */ d->list[i]->X = &(d->X_base[d->n_X * i]); } else /* d->P_base[i].X = NULL; */ d->list[i]->X = NULL; } for (i = d->n_list; i < d->n_max; i++) d->list[i] = NULL; /* for savety */ /* rebuild qtree_root: this is avoided by setting nmax */ qtree_rebuild(d); datagrid_rebuild(d, 0); } /* * copy information on current point into P_base and X_base arrays: */ #ifdef SLOW d->P_base[d->n_list] = *p; #else memcpy(&(d->P_base[d->n_list]), p, sizeof(DPOINT)); #endif if (d->n_X > 0 && !intercept_only(d)) { #define SLOW 1 #ifdef SLOW /* slow... copy X row */ for (i = 0; i < d->n_X; i++) d->X_base[d->n_X * d->n_list + i] = p->X[i]; #else memcpy(&(d->X_base[d->n_X * d->n_list]), p->X, d->n_X * sizeof(double)); #endif } /* * adjust list and X pointer to this copy: */ d->list[d->n_list] = &(d->P_base[d->n_list]); if (intercept_only(d)) d->list[d->n_list]->X = d->X_base; else d->list[d->n_list]->X = &(d->X_base[d->n_X * d->n_list]); SET_INDEX(d->list[d->n_list], d->n_list); qtree_push_point(d, d->list[d->n_list]); grid_push_point(d, d->list[d->n_list], 0); /* * this will be ignored during read_gstat_data(), the tree structure will * be filled only during the first call to qtree_quick_select(). * Later on, it does have effect if simulated points are pushed. */ d->n_list++; return; }