void list_names_that_must_be_looped(Block* contents, Value* names) { // Find all names within 'contents' that must be looped. A name must be looped when // a term inside the loop binds a name that was already used outside the loop. Value namesMap; set_hashtable(&namesMap); for (BlockIteratorFlat it(contents); it; ++it) { Term* term = it.current(); if (has_empty_name(term)) continue; Value termVal; termVal.set_term(contents->owningTerm); Term* outsideName = find_name_at(&termVal, term_name(term)); // Don't look at names outside the major block. if (outsideName != NULL && !is_under_same_major_block(term, outsideName)) outsideName = NULL; if (outsideName != NULL) set_bool(hashtable_insert(&namesMap, term_name(term)), true); } hashtable_get_keys(&namesMap, names); list_sort(names, NULL, NULL); }
/* `optlist' should contain only one unknown key - the server tag. returns NULL if there was unknown -option */ static int cmd_options_get_signal(const char *cmd, GHashTable *optlist) { GSList *list, *tmp, *next; char *signame; int signum; /* get all the options, then remove the known ones. there should be only one left - the signal */ list = hashtable_get_keys(optlist); if (cmd != NULL) { for (tmp = list; tmp != NULL; tmp = next) { char *option = tmp->data; next = tmp->next; if (command_have_option(cmd, option)) list = g_slist_remove(list, option); } } if (list == NULL) return -1; signame = list->data; signum = -1; signum = is_numeric(signame, 0) ? atol(signame) : signal_name_to_id(signame); if (signum == -1 || list->next != NULL) { /* unknown option (not a signal) */ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN), signum == -1 ? list->data : list->next->data); signal_stop(); return -2; } g_slist_free(list); return signum; }
/* `optlist' should contain only one unknown key - the server tag. returns NULL if there was unknown -option */ SERVER_REC *cmd_options_get_server(const char *cmd, GHashTable *optlist, SERVER_REC *defserver) { SERVER_REC *server; GSList *list, *tmp, *next; /* get all the options, then remove the known ones. there should be only one left - the server tag. */ list = hashtable_get_keys(optlist); if (cmd != NULL) { for (tmp = list; tmp != NULL; tmp = next) { char *option = tmp->data; next = tmp->next; if (command_have_option(cmd, option)) list = g_slist_remove(list, option); } } if (list == NULL) return defserver; server = server_find_tag(list->data); if (server == NULL || list->next != NULL) { /* unknown option (not server tag) */ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN), server == NULL ? list->data : list->next->data); signal_stop(); server = NULL; } g_slist_free(list); return server; }
/* Only unknown keys in `optlist' should be levels. Returns -1 if unknown option was given. */ int cmd_options_get_level(const char *cmd, GHashTable *optlist) { GSList *list, *tmp, *next; int level, retlevel; /* get all the options, then remove the known ones. there should be only one left - the server tag. */ list = hashtable_get_keys(optlist); if (cmd != NULL) { for (tmp = list; tmp != NULL; tmp = next) { char *option = tmp->data; next = tmp->next; if (command_have_option(cmd, option)) list = g_slist_remove(list, option); } } retlevel = 0; while (list != NULL) { level = level_get(list->data); if (level == 0) { /* unknown option */ signal_emit("error command", 2, GINT_TO_POINTER(CMDERR_OPTION_UNKNOWN), list->data); retlevel = -1; break; } retlevel |= level; list = g_slist_remove(list, list->data); } return retlevel; }