/*! * \brief Register dialplan switches for our pbx_lua contexs. * * In the event of an error, an error string will be pushed onto the lua stack. * * \retval 0 success * \retval 1 failure */ static int lua_register_switches(lua_State *L) { int extensions; struct ast_context *con = NULL; /* create the hash table for our contexts */ /* XXX do we ever need to destroy this? pbx_config does not */ if (!local_table) local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); /* load the 'extensions' table */ lua_getglobal(L, "extensions"); extensions = lua_gettop(L); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); return 1; } /* iterate through the extensions table and register a context and * dialplan switch for each lua context */ for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { int context = lua_gettop(L); int context_name = context - 1; const char *context_str = lua_tostring(L, context_name); /* find or create this context */ con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar); if (!con) { /* remove extensions table and context key and value */ lua_pop(L, 3); lua_pushstring(L, "Failed to find or create context\n"); return 1; } /* register the switch */ if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) { /* remove extensions table and context key and value */ lua_pop(L, 3); lua_pushstring(L, "Unable to create switch for context\n"); return 1; } } /* remove the extensions table */ lua_pop(L, 1); return 0; }
static int pbx_load_module(void) { int errs=0, sem_err=0, sem_warn=0, sem_note=0; char *rfilename; struct ast_context *local_contexts=NULL, *con; struct ast_hashtab *local_table=NULL; struct pval *parse_tree; ast_log(LOG_NOTICE, "Starting AEL load process.\n"); if (config[0] == '/') rfilename = (char *)config; else { rfilename = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2); sprintf(rfilename, "%s/%s", ast_config_AST_CONFIG_DIR, config); } if (access(rfilename,R_OK) != 0) { ast_log(LOG_NOTICE, "File %s not found; AEL declining load\n", rfilename); return AST_MODULE_LOAD_DECLINE; } parse_tree = ael2_parse(rfilename, &errs); ast_log(LOG_NOTICE, "AEL load process: parsed config file name '%s'.\n", rfilename); ael2_semantic_check(parse_tree, &sem_err, &sem_warn, &sem_note); if (errs == 0 && sem_err == 0) { ast_log(LOG_NOTICE, "AEL load process: checked config file name '%s'.\n", rfilename); local_table = ast_hashtab_create(11, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); ast_compile_ael2(&local_contexts, local_table, parse_tree); ast_log(LOG_NOTICE, "AEL load process: compiled config file name '%s'.\n", rfilename); ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); local_table = NULL; /* it's the dialplan global now */ local_contexts = NULL; ast_log(LOG_NOTICE, "AEL load process: merged config file name '%s'.\n", rfilename); for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con)) ast_context_verify_includes(con); ast_log(LOG_NOTICE, "AEL load process: verified config file name '%s'.\n", rfilename); } else { ast_log(LOG_ERROR, "Sorry, but %d syntax errors and %d semantic errors were detected. It doesn't make sense to compile.\n", errs, sem_err); destroy_pval(parse_tree); /* free up the memory */ return AST_MODULE_LOAD_DECLINE; } destroy_pval(parse_tree); /* free up the memory */ return AST_MODULE_LOAD_SUCCESS; }
static void run_hashtest(int numthr) { pthread_t thr[numthr]; void *thrres[numthr]; int i, biggest, resize_cnt, numobjs, numbuckets; /* init a single global hashtab, then... */ glob_hashtab = ast_hashtab_create(180000, hashtab_compare_strings_nocase, ast_hashtab_resize_java, ast_hashtab_newsize_java, hashtab_hash_string_nocase, 1); printf("starting with %d elements in the hashtable...\n", ast_hashtab_capacity(glob_hashtab)); /* set a random seed */ glob_seed = (unsigned int)time(0); srand(glob_seed); /* create threads, each running hashtest */ for(i=0;i<numthr;i++) { unsigned long z = rand(); printf("starting hashtest thread %d....\n",i+1); if (ast_pthread_create(&thr[i], NULL, hashtest, (void*)z)) { printf("Sorry, couldn't create thread #%d\n", i+1); } printf("hashtest thread spawned.... \n"); } /* collect threads, each running hashtest */ for(i=0;i<numthr;i++) { printf("waiting for thread %d....\n", i+1); if (pthread_join(thr[i], &thrres[i])) { printf("Sorry, couldn't join thread #%d\n", i+1); } printf("hashtest thread %d done.... \n",i+1); } /* user has to kill/intr the process to stop the test? */ ast_hashtab_get_stats(glob_hashtab, &biggest, &resize_cnt, &numobjs, &numbuckets); printf("Some stats: longest bucket chain: %d; number of resizes: %d; number of objects: %d; capacity: %d\n", biggest, resize_cnt, numobjs, numbuckets); }
void read_dict(void) { struct stat dict_stat; FILE *dict_file; char *cptr, *ncptr; /* since the hashtab package provides all the funcs we'll need to implement this common and simple sort of hash table, let's use them... */ dict = ast_hashtab_create(600000, ast_hashtab_compare_strings, ast_hashtab_resize_none, ast_hashtab_newsize_none, ast_hashtab_hash_string, 0); /* get the size of the dict file, allocate that much mem, read it in */ stat(DICT, &dict_stat); dict_file_size = dict_stat.st_size; dict_file_buffer = malloc(dict_file_size+1); dict_file = fopen(DICT,"r"); if( !dict_file ) { printf("uh-oh! can't open the dictionary (%s) for reading. Check out the proper path and perhaps fix and recompile this source\n", DICT); exit(13); } fread(dict_file_buffer, 1, dict_file_size, dict_file); fclose(dict_file); /* we are now done with this file pointer */ /* now, people, we go thru the dictionary, and turn each linefeed into a null, and enter each word into the hash table */ cptr = dict_file_buffer; /* start it out */ while( (ncptr=strchr(cptr,'\n')) ) { *ncptr = 0; if (!ast_hashtab_insert_safe(dict, cptr)) printf("Could not insert %s into the hash table; ignoring it.\n", cptr); cptr = ncptr+1; /* next line! */ } printf("Entered %d entries from the dictionary into the hash table.\n", ast_hashtab_size(dict)); }
int main(int argc,char **argv) { char linebuffer[300]; FILE *ifile = fopen("/tmp/refs", "r"); char *t; unsigned int un; struct rc_obj *curr_obj, *count1_obj; struct rc_obj lookup; struct ast_hashtab_iter *it; struct ast_hashtab *objhash; if (!ifile) { printf("Sorry, Cannot open /tmp/refs!\n"); exit(10); } objhash = ast_hashtab_create(9000, hashtab_compare_rc, ast_hashtab_resize_java, ast_hashtab_newsize_java, hashtab_hash_rc, 1); while (fgets(linebuffer, sizeof(linebuffer), ifile)) { /* collect data about the entry */ un = strtoul(linebuffer, &t, 16); lookup.addr = un; lookup.count = 1; count1_obj = ast_hashtab_lookup(objhash, &lookup); if (count1_obj) { /* there IS a count1 obj, so let's see which one we REALLY want */ if (*(t+1) == '=') { /* start a new object! */ curr_obj = alloc_obj(un, ++count1_obj->last_count); /* put it in the hashtable */ ast_hashtab_insert_safe(objhash, curr_obj); } else { if (count1_obj->last_count > 1) { lookup.count = count1_obj->last_count; curr_obj = ast_hashtab_lookup(objhash, &lookup); } else { curr_obj = count1_obj; } } } else { /* NO obj at ALL? -- better make one! */ if (*(t+1) != '=') { printf("BAD: object %x appears without previous allocation marker!\n", un); } curr_obj = count1_obj = alloc_obj(un, 1); /* put it in the hashtable */ ast_hashtab_insert_safe(objhash, curr_obj); } if (*(t+1) == '+' || *(t+1) == '-' ) { curr_obj->total_refcount += strtol(t+1, NULL, 10); } else if (*(t+1) == '*') { curr_obj->destroy_count++; } add_to_hist(linebuffer, curr_obj); } fclose(ifile); /* traverse the objects and check for problems */ it = ast_hashtab_start_traversal(objhash); while ((curr_obj = ast_hashtab_next(it))) { if (curr_obj->total_refcount != 0 || curr_obj->destroy_count != 1) { struct rc_hist *h; if (curr_obj->total_refcount != 0) printf("Problem: net Refcount not zero for object %x\n", curr_obj->addr); if (curr_obj->destroy_count > 1 ) printf("Problem: Object %x destroyed more than once!\n", curr_obj->addr); printf("Object %x history:\n", curr_obj->addr); for(h=curr_obj->hist;h;h=h->next) { printf(" %s", h->desc); } printf("==============\n"); } } ast_hashtab_end_traversal(it); return 0; }
/*! * \brief Register dialplan hints for our pbx_lua contexs. * * In the event of an error, an error string will be pushed onto the lua stack. * * \retval 0 success * \retval 1 failure */ static int lua_register_hints(lua_State *L) { int hints; struct ast_context *con = NULL; /* create the hash table for our contexts */ /* XXX do we ever need to destroy this? pbx_config does not */ if (!local_table) local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); /* load the 'hints' table */ lua_getglobal(L, "hints"); hints = lua_gettop(L); if (lua_isnil(L, -1)) { /* hints table not found, move along */ lua_pop(L, 1); return 0; } /* iterate through the hints table and register each context and * the hints that go along with it */ for (lua_pushnil(L); lua_next(L, hints); lua_pop(L, 1)) { int context = lua_gettop(L); int context_name = context - 1; const char *context_str = lua_tostring(L, context_name); /* find or create this context */ con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar); if (!con) { /* remove hints table and context key and value */ lua_pop(L, 3); lua_pushstring(L, "Failed to find or create context\n"); return 1; } /* register each hint */ for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) { const char *hint_value = lua_tostring(L, -1); const char *hint_name; /* the hint value is not a string, ignore it */ if (!hint_value) { continue; } /* copy the name then convert it to a string */ lua_pushvalue(L, -2); if (!(hint_name = lua_tostring(L, -1))) { /* ignore non-string value */ lua_pop(L, 1); continue; } if (ast_add_extension2(con, 0, hint_name, PRIORITY_HINT, NULL, NULL, hint_value, NULL, NULL, registrar)) { /* remove hints table, hint name, hint value, * key copy, context name, and contex table */ lua_pop(L, 6); lua_pushstring(L, "Error creating hint\n"); return 1; } /* pop the name copy */ lua_pop(L, 1); } } /* remove the hints table */ lua_pop(L, 1); return 0; }
main(int argc,char **argv) { int len = 12; /* this val says we are permuting 12 items */ int set[20], currset[20]; /* set is a list of the 12 items to permute. currset is a work area where we generate all the permutations */ char *vals[20]; /* vals is a set of up to 20 string pointers */ char *vals2[20][20]; /* and here is where we can store those strings of up to 20 chars each */ int i; /* a temp working var */ /* find all the n-digit numbers that have each digit mentioned only once. */ /* all the numbers including only the numbers 1-n; */ /* set up the arrays */ for(i=0;i<len;i++) { /* now, this code was adapted from a previous program that permuted letters in a word. The idea was to take a scrambled word, and generate all the permutations of that set of letters, and look each one up in the dictionary, and output just the permutations that resulted in a valid word. Well, this code can handle not just individual letters, but whole strings to permute. For instance, you could permut apples, oranges, and grapefruit; you would get these sets of 3: apples, oranges, grapefruit apples, grapefruit, oranges oranges, apples, grapefruit oranges, grapefruit, apples grapefruit, apples, oranges grapefruit, oranges, apples Well, that's fine and good, but this time all we want to permute is the numbers 1 thru 12. so, we put one letter in each string, the letters with values 1 thru 12. We won't be printing them as letters, thank goodness, because they'd just be control characters and not very visible. But a char is 8 bits, and we can store the numbers 0-255 in those 8 bits, which is more than enough to handle 1-12. */ vals[i] = (char *)vals2[i]; /* now remember, vals is a set of char pointers. So make them point to the real storage area, vals2 */ vals[i][0] = (char)i+1; /* here is where we stick the vals 1 to 12 into vals2 via the pointers in vals */ vals[i][1] = 0; /* not really necessary, but done out of habit: strings are null terminated */ } /* the initial set */ /* now, we don't play around with the vals arrays. Instead, we play around with the indexes into the val array. */ for(i=0;i<len;i++) { set[i] = i; } /* set up the hash table of the solutions found, and the 5 rotations of each solution, to find just a set of 'unique' solutions */ solutions = ast_hashtab_create(7109, ast_hashtab_compare_strings, ast_hashtab_resize_none, ast_hashtab_newsize_none, ast_hashtab_hash_string, 0); /* now, everything is all set up. Fire up the permute engine */ permute(set, len, (char **)vals, 0, currset, print_result); /* approximately 16 minutes later on my gutless 3 Ghz machine, permute completes, and we can output the totals kept in global vars */ /* now, in this case, 12 items will result in just over 479 million permutations. This puzzle yields 960 solutions, of which only 160 are really unique. The remaining 800 solutions are simply rotations of previously found solutions. This is due to the symmetry of the puzzle. I don't look at reflections (mirror images). Hadn't thought of that till now. Might be, that the rotations will cover the reflections. This is a further puzzle left to the reader. */ printf("\nDone. That's been %d permutations; %d unique solutions, %d non-unique solutions.\n", permutation_count, solution_count, non_unique_solutions_count); /* we can free up that hashtab now, it's done. Yeah, I know, it's like rearranging deck chairs on the sinking Titanic... */ ast_hashtab_destroy(solutions, free); }