static void sort_words(WordList **words_by_length, const WordList *unsorted_words) { int length_counts[MAX_WORD_LENGTH - 2] = { 0 }; for (size_t i = 0; i < unsorted_words->count; i++) { const char *word = GET_WORD(unsorted_words, i); size_t length = strlen(word); assert((length >= 3) && (length <= MAX_WORD_LENGTH)); length_counts[length - 3]++; } for (size_t i = 0; i < MAX_WORD_LENGTH - 2; i++) { WordList *word_list = make_word_list(length_counts[i], i + 4); words_by_length[i] = word_list; } for (size_t i = 0; i < unsorted_words->count; i++) { const char *word = GET_WORD(unsorted_words, i); size_t length = strlen(word); WordList *word_list = words_by_length[length - 3]; memcpy(GET_WORD(word_list, word_list->count), word, length); word_list->count++; } for (size_t i = 0; i < MAX_WORD_LENGTH - 2; i++) { WordList *word_list = words_by_length[i]; qsort(word_list->words, word_list->count, word_list->elem_size, (int (*)(const void *, const void *))strcmp); } }
static int execute_bash_trampoline(ffi_cif *cif, void *retval, void **args, char **proto) { SHELL_VAR *function; WORD_LIST *params; char *result; // Decode parameters // callback hello pointer pointer int int // FIXME this is really ugly, do it properly and check cif->argtypes // if (!(function = find_function(*proto))) { fprintf(stderr, "error: unable to resolve function %s in thunk", *proto); return -1; } params = NULL; for (unsigned i = 0; i < cif->nargs; i++) { char parameter[1024]; ffi_raw *p = args[i]; // Decode the parameters snprintf(parameter, sizeof parameter, proto[i+1], p->ptr); params = make_word_list(make_word(parameter), params); } // The first parameter should be the return location asprintf(&result, "pointer:%p", retval); params = make_word_list(make_word(result), params); params = make_word_list(make_word(*proto), params); execute_shell_function(function, params); free(result); return 0; }
/* Invoke a bash builtin command (list of tokens ending in NULL). * Return EXECUTION_SUCCESS or EXECUTION_FAILURE. */ int mpibash_invoke_bash_command(char *funcname, ...) { static char *mpibash_so = NULL; /* Path to mpibash.so */ sh_builtin_func_t *func; /* Pointer to the function corresponding to funcname */ WORD_LIST *arg_list = NULL; /* Function and arguments. */ char *one_arg; /* A single argument to invoke_bash_command */ va_list args; /* All arguments to invoke_bash_command */ /* Find our .so file name. */ if (mpibash_so == NULL) { Dl_info self_info; if (dladdr(mpibash_invoke_bash_command, &self_info) == 0 || self_info.dli_fname == NULL) { fprintf(stderr, _("mpi_init: failed to find the MPI-Bash .so file\n")); return EXECUTION_FAILURE; } mpibash_so = strdup(self_info.dli_fname); } /* Find the given command, even if it's disabled. */ func = builtin_address(funcname); if (func == NULL) { fprintf(stderr, _("mpi_init: failed to find the %s builtin\n"), funcname); return EXECUTION_FAILURE; } /* Construct a list of arguments. */ va_start(args, funcname); for (one_arg = va_arg(args, char *); one_arg != NULL; one_arg = va_arg(args, char *)) arg_list = make_word_list(make_bare_word(one_arg), arg_list); va_end(args); arg_list = REVERSE_LIST(arg_list, WORD_LIST *); /* Invoke the specified command with its arguments. */ if (func(arg_list) == EXECUTION_FAILURE) { fprintf(stderr, _("mpi_init: failed to get execute bash function %s\n"), funcname); dispose_words(arg_list); return EXECUTION_FAILURE; } dispose_words(arg_list); return EXECUTION_SUCCESS; }
void new_level(Game *game) { char *word = strdup(random_word(game->all_words_array, MAX_WORD_LENGTH)); printf("word is %s\n", word); shuffle(word); printf("word is %s\n", word); game->anagrams = find_all_anagrams(game->all_words_tree, word); printf("%zu anagrams:\n", game->anagrams->count); WordList **anagrams_by_length = malloc(sizeof(*anagrams_by_length) * (MAX_WORD_LENGTH - 2)); sort_words(anagrams_by_length, game->anagrams); for (size_t i = 0; i < MAX_WORD_LENGTH - 2; i++) { printf("%zu: %zu words\n", i + 3, anagrams_by_length[i]->count); for (size_t j = 0; j < anagrams_by_length[i]->count; j++) printf("\t%s\n", GET_WORD(anagrams_by_length[i], j)); } game->anagrams_by_length = anagrams_by_length; game->column_sizes = compute_layout(game); game->guessed_words = make_word_list(game->anagrams->count, MAX_WORD_LENGTH + 1); SDL_Color white = { 0xFF, 0xFF, 0xFF, 0xFF }; game->guessed_words_texture = render_empty_words(game, white); SDL_DestroyTexture(game->message_box); game->message_box = NULL; game->chars_entered = 0; memset(game->curr_input, 0, MAX_WORD_LENGTH + 1); memcpy(game->remaining_chars, word, MAX_WORD_LENGTH + 1); if (game->second_timer != 0) SDL_RemoveTimer(game->second_timer); game->second_timer = SDL_AddTimer(1000, timer_handler, game); game->time_left = 180; game->state = IN_LEVEL; }