int getPosition(t_list *list, t_list *element) { int counter; /* preconditions */ if (list == NULL || element == NULL) return -1; /* initialize the local variable `counter' */ counter = 0; if (list == element) return counter; /* update values */ counter++; list = LNEXT(list); while (list != NULL) { if (list == element) return counter; counter++; list = LNEXT(list); } return -1; }
KHMEXP khm_int32 KHMAPI khui_cfg_get_next_release(khui_config_node * pvnode) { khui_config_node_i * node; khui_config_node_i * nxt_node; if (!pvnode || !cfgui_is_valid_node_handle(*pvnode)) return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(*pvnode)) { node = cfgui_node_i_from_handle(*pvnode); for(nxt_node = LNEXT(node); nxt_node && (((node->reg.flags ^ nxt_node->reg.flags) & KHUI_CNFLAG_SUBPANEL) || (nxt_node->flags & KHUI_CN_FLAG_DELETED)); nxt_node = LNEXT(nxt_node)); if (nxt_node) cfgui_hold_node(nxt_node); cfgui_release_node(node); } else { nxt_node = NULL; } LeaveCriticalSection(&cs_cfgui); *pvnode = cfgui_handle_from_node_i(nxt_node); if (nxt_node) return KHM_ERROR_SUCCESS; else return KHM_ERROR_NOT_FOUND; }
void printGraphInfos(t_cflow_Graph *graph, FILE *fout, int verbose) { int counter; t_list *current_element; t_basic_block *current_bblock; /* preconditions */ if (graph == NULL) return; if (fout == NULL) return; /* initialization of the local variables */ counter = 1; fprintf(fout,"NOTE : Temporary registers are considered as\n" " variables of the intermediate language. \n"); #if CFLOW_ALWAYS_LIVEIN_R0 == (1) fprintf(fout," Variable \'R0\' (that refers to the \n" " physical register \'RO\') is always \n" " considered LIVE-IN for each node of \n" " a basic block. \n" " Thus, in the following control flow graph, \n" " \'R0\' will never appear as LIVE-IN or LIVE-OUT\n" " variable for a statement.\n\n" " If you want to consider \'R0\' as\n" " a normal variable, you have to set\n" " to 0 the value of the macro CFLOW_ALWAYS_LIVEIN_R0\n" " defined in \"cflow_constants.h\".\n\n"); #endif fprintf(fout,"\n"); fprintf(fout,"**************************\n"); fprintf(fout," CONTROL FLOW GRAPH \n"); fprintf(fout,"**************************\n"); fprintf(fout,"NUMBER OF BASIC BLOCKS : %d \n" , getLength(graph->blocks)); fprintf(fout,"NUMBER OF USED VARIABLES : %d \n" , getLength(graph->cflow_variables)); fprintf(fout,"--------------------------\n"); fprintf(fout,"START BASIC BLOCK INFOS. \n"); fprintf(fout,"--------------------------\n"); /* initialize `current_block' */ current_element = graph->blocks; while(current_element != NULL) { current_bblock = (t_basic_block *) LDATA(current_element); fprintf(fout,"[BLOCK %d] \n", counter); printBBlockInfos(current_bblock, fout, verbose); if (LNEXT(current_element) != NULL) fprintf(fout,"--------------------------\n"); else fprintf(fout,"**************************\n"); counter++; current_element = LNEXT(current_element); } fprintf(fout,"\n\n"); }
KHMEXP khm_int32 KHMAPI khui_cfg_get_next(khui_config_node vnode, khui_config_node * result) { khui_config_node_i * node; khui_config_node_i * nxt_node; if (!cfgui_is_valid_node_handle(vnode) || !result) return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(vnode)) { node = cfgui_node_i_from_handle(vnode); for(nxt_node = LNEXT(node); nxt_node && ((node->reg.flags ^ nxt_node->reg.flags) & KHUI_CNFLAG_SUBPANEL); nxt_node = LNEXT(nxt_node)); if (nxt_node) cfgui_hold_node(nxt_node); } else { nxt_node = NULL; } LeaveCriticalSection(&cs_cfgui); *result = cfgui_handle_from_node_i(nxt_node); if (nxt_node) return KHM_ERROR_SUCCESS; else return KHM_ERROR_NOT_FOUND; }
void kmqint_dump_consumer(FILE * f) { kmq_message_ref * r; kmq_msg_subscription * s; int n_free = 0; int n_adhoc = 0; EnterCriticalSection(&cs_kmq_msg_ref); fprintf(f, "qc0\t*** Free Message References ***\n"); fprintf(f, "qc1\tAddress\n"); r = kmq_msg_ref_free; while(r) { n_free ++; fprintf(f, "qc2\t0x%p\n", r); r = LNEXT(r); } fprintf(f, "qc3\tTotal free message references : %d\n", n_free); fprintf(f, "qc4\t--- End ---\n"); LeaveCriticalSection(&cs_kmq_msg_ref); EnterCriticalSection(&cs_kmq_global); fprintf(f, "qc5\t*** Adhoc Message Subscriptions ***\n"); fprintf(f, "qc6\tAddress\tMsg Type\tRcpt Type\tRcpt\tQueue\n"); s = kmq_adhoc_subs; while(s) { n_adhoc ++; fprintf(f, "qc7\t0x%p\t%d\t%s\t0x%p\t0x%p\n", s, s->type, (s->rcpt_type == KMQ_RCPTTYPE_CB)?"CALLBACK":"HWND", (s->rcpt_type == KMQ_RCPTTYPE_CB)? s->recipient.cb: (void *) s->recipient.hwnd, s->queue); s = LNEXT(s); } fprintf(f, "qc8\tTotal ad-hoc subscriptions : %d\n", n_adhoc); fprintf(f, "qc9\t--- End ---\n"); LeaveCriticalSection(&cs_kmq_global); }
/* remove a link from the list `list' */ extern t_list * removeElementLink(t_list *list, t_list *element) { t_list *current_elem; /* preconditions */ if (list == NULL || element == NULL) return list; if ((LPREV(element) == NULL) && (element != list)) return list; /* intialize the value of `current_elem' */ current_elem = list; while( (LDATA(current_elem) != LDATA(element)) || (LPREV(current_elem) != LPREV(element)) || (LNEXT(current_elem) != LNEXT(element)) ) { /* retrieve the next element from the list */ current_elem = LNEXT(current_elem); /* test if we reached the end of the list */ if (current_elem == NULL) return list; } if (LPREV(element) == NULL) { assert(list == element); if (LNEXT(element) != NULL) { list = LNEXT(element); SET_PREV(LNEXT(element), NULL); } else list = NULL; /* remove the allocated memory of element */ _FREE_FUNCTION(element); return list; } /* we found the element */ if (LPREV(element) != NULL) { /* we found the element, and it is the top of the list */ SET_NEXT(LPREV(element), LNEXT(element)); } if (LNEXT(element) != NULL) SET_PREV(LNEXT(element), LPREV(element)); /* remove the allocated memory of element */ _FREE_FUNCTION(element); /* return the new top of the list */ return list; }
void kmqint_dump_publisher(FILE * f) { int n_free = 0; int n_active = 0; kmq_message * m; EnterCriticalSection(&cs_kmq_msg); fprintf(f, "qp0\t*** Free Messages ***\n"); fprintf(f, "qp1\tAddress\n"); m = msg_free; while(m) { n_free++; fprintf(f, "qp2\t0x%p\n", m); m = LNEXT(m); } fprintf(f, "qp3\tTotal free messages : %d\n", n_free); fprintf(f, "qp4\t*** Active Messages ***\n"); fprintf(f, "qp5\tAddress\tType\tSubtype\tuParam\tvParam\tnSent\tnCompleted\tnFailed\twait_o\trefcount\n"); m = msg_active; while(m) { n_active++; fprintf(f, "qp6\t0x%p\t%d\t%d\t0x%x\t0x%p\t%d\t%d\t%d\t0x%p\t%d\n", m, (int) m->type, (int) m->subtype, (unsigned int) m->uparam, m->vparam, (int) m->nSent, (int) m->nCompleted, (int) m->nFailed, (void *) m->wait_o, (int) m->refcount); m = LNEXT(m); } fprintf(f, "qp7\tTotal number of active messages = %d\n", n_active); fprintf(f, "qp8\t--- End ---\n"); LeaveCriticalSection(&cs_kmq_msg); }
KHMEXP khm_int32 KHMAPI kmm_get_next_plugin(kmm_plugin p, kmm_plugin * p_next) { khm_int32 rv = KHM_ERROR_SUCCESS; kmm_plugin_i * pi; kmm_plugin_i * pi_next = NULL; kmm_module_i * m; EnterCriticalSection(&cs_kmm); if (p == NULL) { if (kmm_listed_plugins) pi_next = kmm_listed_plugins; else { for (m = kmm_all_modules; m; m = LNEXT(m)) { if (m->plugins) { pi_next = m->plugins; break; } } } } else if (kmm_is_plugin(p)) { pi = kmm_plugin_from_handle(p); pi_next = LNEXT(pi); if (!pi_next) { /* we have either exhausted the listed plugins or we are at the end of the module's plugin list */ if (pi->module) { m = LNEXT(pi->module); } else { m = kmm_all_modules; } for(; m; m = LNEXT(m)) { if (m->plugins) { pi_next = m->plugins; break; } } } } if (pi_next) { *p_next = kmm_handle_from_plugin(pi_next); kmm_hold_plugin(*p_next); } else { *p_next = NULL; rv = KHM_ERROR_NOT_FOUND; } LeaveCriticalSection(&cs_kmm); return rv; }
t_list * getLastElement(t_list *list) { /* preconditions */ if (list == NULL) return NULL; /* test if the current element is the last element of the list */ if (LNEXT(list) == NULL) return list; /* recursively call the getLastElement on the next item of the list */ return getLastElement(LNEXT(list)); }
t_list * addList(t_list *list, t_list *elements) { t_list *current_element; void *current_data; /* if the list of elements is null, this function * will return `list' unmodified */ if (elements == NULL) return list; /* initialize the value of `current_element' */ current_element = elements; while (current_element != NULL) { /* retrieve the data associated with the current element */ current_data = LDATA(current_element); list = addElement(list, current_data, -1); /* retrieve the next element in the list */ current_element = LNEXT(current_element); } /* return the new list */ return list; }
void finalizeVariables(t_list *variables) { t_list *current_element; t_axe_variable *current_var; if (variables == NULL) return; /* initialize the `current_element' */ current_element = variables; while(current_element != NULL) { current_var = (t_axe_variable *) LDATA(current_element); if (current_var != NULL) { if (current_var->ID != NULL) free(current_var->ID); _AXE_FREE_FUNCTION(current_var); } current_element = LNEXT(current_element); } /* free the list of variables */ freeList(variables); }
static void free_event(kherr_event * e) { EnterCriticalSection(&cs_error); assert(IS_KHERR_EVENT(e)); #ifdef DEBUG assert(LNEXT(e) == NULL); assert(LPREV(e) == NULL); #endif if(e->flags & KHERR_RF_FREE_SHORT_DESC) { assert(e->short_desc); PFREE((void *) e->short_desc); } if(e->flags & KHERR_RF_FREE_LONG_DESC) { assert(e->long_desc); PFREE((void *) e->long_desc); } if(e->flags & KHERR_RF_FREE_SUGGEST) { assert(e->suggestion); PFREE((void *) e->suggestion); } free_event_params(e); ZeroMemory(e, sizeof(*e)); LPUSH(&evt_free_list, e); LeaveCriticalSection(&cs_error); }
/*! \internal \brief Publish a message \note Obtains ::cs_kmq_types, ::cs_kmq_msg_ref, kmq_queue::cs, ::cs_kmq_msg */ khm_int32 kmqint_msg_publish(kmq_message * m, khm_boolean try_send) { khm_int32 rv = KHM_ERROR_SUCCESS; if(msg_types[m->type]) { kmq_msg_type *t; kmq_msg_subscription * s; EnterCriticalSection(&cs_kmq_types); EnterCriticalSection(&cs_kmq_msg); t = msg_types[m->type]; s = t->subs; while(s) { kmqint_post(s, m, try_send); s = LNEXT(s); } if(m->nCompleted + m->nFailed == m->nSent) { kmqint_put_message(m); } LeaveCriticalSection(&cs_kmq_msg); LeaveCriticalSection(&cs_kmq_types); } else { EnterCriticalSection(&cs_kmq_msg); kmqint_put_message(m); LeaveCriticalSection(&cs_kmq_msg); } return rv; }
KHMEXP void * perf_realloc(const char * file, int line, void * data, size_t s) { void * n_data; allocation * a; size_t h; if (data == NULL) return perf_malloc(file, line, s); perf_once(); h = HASHPTR(data); n_data = realloc(data, s); assert(n_data); EnterCriticalSection(&cs_alloc); for (a = ht[h]; a; a = LNEXT(a)) { if (a->ptr == data) break; } assert(a); LDELETE(&ht[h], a); a->size = s; a->ptr = n_data; h = HASHPTR(n_data); LPUSH(&ht[h], a); LeaveCriticalSection(&cs_alloc); return n_data; }
/*! \internal \brief Adds a subscription to a message type \note Obtains ::cs_kmq_types */ void kmqint_msg_type_add_sub(int t, kmq_msg_subscription *s) { kmq_msg_subscription * ts; if(t < 0 || t > KMQ_MSG_TYPE_MAX) return; if(!msg_types[t]) kmqint_msg_type_create(t); EnterCriticalSection(&cs_kmq_types); s->type = t; /* check if we already have this subscription */ ts = msg_types[t]->subs; while(ts) { if((ts->rcpt_type == s->rcpt_type) && (((ts->rcpt_type == KMQ_RCPTTYPE_CB) && (ts->recipient.cb == s->recipient.cb)) || ((ts->rcpt_type == KMQ_RCPTTYPE_HWND) && (ts->recipient.hwnd == s->recipient.hwnd)))) break; ts = LNEXT(ts); } /* add it if we didn't find it */ if(!ts) { LPUSH(&msg_types[t]->subs, s); } LeaveCriticalSection(&cs_kmq_types); }
/* finalize an instance of `t_axe_label_manager' */ void finalize_label_manager(t_axe_label_manager *lmanager) { t_list *current_element; t_axe_label *current_label; /* preconditions */ if (lmanager == NULL) return; /* initialize `current_element' to the head of the list * of labels */ current_element = lmanager->labels; while (current_element != NULL) { /* retrieve the current label */ current_label = (t_axe_label *) LDATA(current_element); assert(current_label != NULL); /* free the memory associated with the current label */ _AXE_FREE_FUNCTION(current_label); /* fetch the next label */ current_element = LNEXT(current_element); } /* free the memory associated to the list of labels */ freeList(lmanager->labels); _AXE_FREE_FUNCTION(lmanager); }
/* add sorted */ t_list * addSorted(t_list *list, void * data , int (*compareFunc)(void *a, void *b)) { t_list *current_element; void *current_data; int counter; /* preconditions */ if (list == NULL) return addFirst(list, data); counter = 0; current_element = list; while(current_element != NULL) { /* get the current interval informations */ current_data = LDATA(current_element); assert(current_data != NULL); if (compareFunc(current_data, data) >= 0) { list = addElement(list, data, counter); return list; } /* retrieve the next element */ current_element = LNEXT(current_element); /* update the value of counter */ counter++; } return addElement(list, data, -1); }
t_list * addListToSet(t_list *list, t_list *elements , int (*compareFunc)(void *a, void *b), int *modified) { t_list *current_element; void *current_data; /* if the list of elements is NULL returns the current list */ if (elements == NULL) return list; /* initialize the value of `current_element' */ current_element = elements; while (current_element != NULL) { /* retrieve the data associated with the current element */ current_data = LDATA(current_element); /* Test if the element was already inserted. */ if (CustomfindElement(list, current_data, compareFunc) == NULL) { list = addElement(list, current_data, -1); if (modified != NULL) (* modified) = 1; } /* retrieve the next element in the list */ current_element = LNEXT(current_element); } /* return the new list */ return list; }
t_list * cloneList(t_list *list) { t_list *result; t_list *current_element; /* initialize the local variables */ result = NULL; current_element = list; /* preconditions */ if (current_element == NULL) return result; while(current_element != NULL) { /* add an element to the new list */ result = addElement(result, LDATA(current_element), -1); /* retrieve the next element of the list */ current_element = LNEXT(current_element); } /* return the new list */ return result; }
/* find an element inside the list `list'. */ t_list * CustomfindElement(t_list *list, void *data , int (*compareFunc)(void *a, void *b)) { t_list *current_elem; /* preconditions */ if (compareFunc == NULL) return findElement(list, data); if (list == NULL) return NULL; /* intialize the value of `current_elem' */ current_elem = list; while (current_elem != NULL) { void *other_Data; other_Data = LDATA(current_elem); if (compareFunc(other_Data, data)) break; current_elem = LNEXT(current_elem); } /* postconditions */ return current_elem; }
/*! \internal \brief Delete a callback from a message type \note Obtains ::cs_kmq_types, ::cs_kmq_global */ kmq_msg_subscription * kmqint_msg_type_del_sub_cb(khm_int32 t, kmq_callback_t cb) { kmq_msg_subscription *s; kmq_queue *q; if(t < 0 || t > KMQ_MSG_TYPE_MAX) return NULL; if(!msg_types[t]) return NULL; q = kmqint_get_thread_queue(); EnterCriticalSection(&cs_kmq_types); s = msg_types[t]->subs; while(s) { kmq_msg_subscription * n = LNEXT(s); if(s->rcpt_type == KMQ_RCPTTYPE_CB && s->recipient.cb == cb && s->queue == q) { /*TODO: do more here? */ LDELETE(&msg_types[t]->subs, s); break; } s = n; } LeaveCriticalSection(&cs_kmq_types); return s; }
/* free the memory associated with a given basic block */ void finalizeBasicBlock(t_basic_block *block) { t_list *current_element; t_cflow_Node *current_node; if (block == NULL) return; if (block->pred != NULL) freeList(block->pred); if (block->succ != NULL) freeList(block->succ); /* initialize current_element */ current_element = block->nodes; while (current_element != NULL) { /* retrieve the current node */ current_node = (t_cflow_Node *) LDATA(current_element); /* free the memory associated with the current node */ finalizeNode(current_node); /* retrieve the next node in the list */ current_element = LNEXT(current_element); } freeList(block->nodes); /* free the memory associated with this basic block */ _AXE_FREE_FUNCTION(block); }
/* finalize the memory associated with the given control flow graph */ void finalizeGraph(t_cflow_Graph *graph) { t_list *current_element; t_basic_block *current_block; if (graph == NULL) return; current_element = graph->blocks; while (current_element != NULL) { /* retrieve the current node */ current_block = (t_basic_block *) LDATA(current_element); assert(current_block != NULL); finalizeBasicBlock(current_block); current_element = LNEXT(current_element); } if (graph->blocks != NULL) freeList(graph->blocks); if (graph->endingBlock != NULL) finalizeBasicBlock(graph->endingBlock); if (graph->cflow_variables != NULL) { t_list *current_element; t_cflow_var *current_variable; current_element = graph->cflow_variables; while (current_element != NULL) { current_variable = (t_cflow_var *) LDATA(current_element); if (current_variable != NULL) _AXE_FREE_FUNCTION(current_variable); /* retrieve the next variable in the list */ current_element = LNEXT(current_element); } freeList(graph->cflow_variables); } _AXE_FREE_FUNCTION(graph); }
KHMEXP void KHMAPI kmm_exit(void) { kmm_module_i * m; kmm_plugin_i * p; EnterCriticalSection(&cs_kmm); p = kmm_listed_plugins; while(p) { kmm_plugin_i * pn; pn = LNEXT(p); /* plugins that were never resolved should be kicked off the list. Flipping the refcount will do that if no other references exist for the plugin. The plugins that were waiting for unresolved dependencies will automatically get freed when the placeholders and other plugins get freed. */ if(p->state == KMM_PLUGIN_STATE_PLACEHOLDER) { kmm_hold_plugin(kmm_handle_from_plugin(p)); kmm_release_plugin(kmm_handle_from_plugin(p)); } p = pn; } m = kmm_all_modules; while(m) { kmm_unload_module(kmm_handle_from_module(m)); m = LNEXT(m); } LeaveCriticalSection(&cs_kmm); WaitForSingleObject(evt_exit, INFINITE); EnterCriticalSection(&cs_kmm); kmq_post_thread_quit_message(tid_registrar, 0, NULL); hash_del_hashtable(hash_plugins); hash_del_hashtable(hash_modules); LeaveCriticalSection(&cs_kmm); TlsFree(tls_kmm); tls_kmm = 0; }
/* finalization of the `infos' structure */ int finalizeStructures(t_translation_infos *infos) { if (infos == NULL) return ASM_NOT_INITIALIZED_INFO; if (infos->code != NULL) { t_list *current_element; t_asm_instruction *current_instr; /* initialize `data' */ current_element = infos->code; while ((current_element != NULL) && (infos->codesize > 0) ) { current_instr = (t_asm_instruction *) LDATA(current_element); /* free memory associated with the current instruction */ freeInstruction(current_instr); /* update the value of `current_element' */ current_element = LNEXT(current_element); infos->codesize --; } while (current_element != NULL) { /* free memory associated with the current data info. */ freeData((t_asm_data *) LDATA(current_element)); /* update the value of `current_element' */ current_element = LNEXT(current_element); } /* free the code and data segment infos */ freeList(infos->code); } /* remove labels */ finalizeLabels(infos->labels); /* free the memory block associated with `infos' */ _ASM_FREE_FUNCTION(infos); return ASM_OK; }
static edge_ref connect(edge_ref a, edge_ref b) { edge_ref e = make_edge(); ODATA(e) = DEST(a); DDATA(e) = ORG(b); splice(e, LNEXT(a)); splice(SYM(e), b); return e; }
void printListOfVariables(t_list *variables, FILE *fout) { t_list *current_element; t_cflow_var *current_variable; if (variables == NULL) return; if (fout == NULL) return; current_element = variables; while(current_element != NULL) { current_variable = (t_cflow_var *) LDATA(current_element); fprintf(fout, "R%d", current_variable->ID); if (LNEXT(current_element) != NULL) fprintf(fout, ", "); current_element = LNEXT(current_element); } }
/* remove all the elements of a list */ void freeList(t_list *list) { /* verify the preconditions */ if (list == NULL) return; /* recursively call the freeList */ freeList(LNEXT(list)); /* deallocate memory for the current element of the list */ _FREE_FUNCTION(list); }
void printBBlockInfos(t_basic_block *block, FILE *fout, int verbose) { t_list *current_element; t_cflow_Node *current_node; int count; /* preconditions */ if (block == NULL) return; if (fout == NULL) return; fprintf(fout,"NUMBER OF PREDECESSORS : %d \n" , getLength(block->pred) ); fprintf(fout,"NUMBER OF SUCCESSORS : %d \n" , getLength(block->succ) ); fprintf(fout,"NUMBER OF INSTRUCTIONS : %d \n" , getLength(block->nodes) ); count = 1; current_element = block->nodes; while(current_element != NULL) { current_node = (t_cflow_Node *) LDATA(current_element); fprintf(fout,"\t%d. ", count); debug_printInstruction(current_node->instr, fout); if (verbose != 0) { if (current_node->def != NULL) fprintf(fout, "\n\t\t\tDEF = [R%d]", (current_node->def)->ID); if (current_node->uses[0] != NULL) { fprintf(fout, "\n\t\t\tUSES = [R%d", ((current_node->uses)[0])->ID); if (current_node->uses[1] != NULL) fprintf(fout, ", R%d", ((current_node->uses)[1])->ID); if (current_node->uses[2] != NULL) fprintf(fout, ", R%d", ((current_node->uses)[2])->ID); fprintf(fout, "]"); } fprintf(fout, "\n\t\t\tLIVE IN = ["); printListOfVariables(current_node->in, fout); fprintf(fout, "]"); fprintf(fout, "\n\t\t\tLIVE OUT = ["); printListOfVariables(current_node->out, fout); fprintf(fout, "]"); } fprintf(fout, "\n"); count++; current_element = LNEXT(current_element); } }
/* called with cs_cfgui held */ static void recalc_node_flags(khui_config_node vnode, khm_boolean plural) { khui_config_node_i * node; khui_config_node_i * parent; khui_config_node_i * subpanel; cfg_node_data * data; khm_int32 flags; #ifdef DEBUG assert(cfgui_is_valid_node_handle(vnode)); #endif node = cfgui_node_i_from_handle(vnode); if (plural) parent = TPARENT(node); else parent = node; #ifdef DEBUG assert(parent); #endif flags = 0; for(subpanel = TFIRSTCHILD(parent); subpanel; subpanel = LNEXT(subpanel)) { if (!(subpanel->reg.flags & KHUI_CNFLAG_SUBPANEL) || (plural && !(subpanel->reg.flags & KHUI_CNFLAG_PLURAL)) || (!plural && (subpanel->reg.flags & KHUI_CNFLAG_PLURAL))) continue; data = get_node_data(subpanel, vnode, FALSE); if (data) { flags |= data->flags; } } flags &= KHUI_CNFLAGMASK_DYNAMIC; if ((node->flags & KHUI_CNFLAGMASK_DYNAMIC) == flags) return; node->flags = (node->flags & ~KHUI_CNFLAGMASK_DYNAMIC) | flags; if (hwnd_cfgui) PostMessage(hwnd_cfgui, KHUI_WM_CFG_NOTIFY, MAKEWPARAM((WORD) node->flags, WMCFG_UPDATE_STATE), (LPARAM) vnode); }