folly::Optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name) { SystraceSection s("getConfig", "module", name); // Initialize modulesByName_ if (modulesByName_.empty() && !modules_.empty()) { moduleNames(); } auto it = modulesByName_.find(name); if (it == modulesByName_.end()) { return nullptr; } CHECK(it->second < modules_.size()); NativeModule* module = modules_[it->second].get(); // string name, object constants, array methodNames (methodId is index), [array promiseMethodIds], [array syncMethodIds] folly::dynamic config = folly::dynamic::array(name); { SystraceSection s_("getConstants"); config.push_back(module->getConstants()); } { SystraceSection s_("getMethods"); std::vector<MethodDescriptor> methods = module->getMethods(); folly::dynamic methodNames = folly::dynamic::array; folly::dynamic promiseMethodIds = folly::dynamic::array; folly::dynamic syncMethodIds = folly::dynamic::array; for (auto& descriptor : methods) { // TODO: #10487027 compare tags instead of doing string comparison? methodNames.push_back(std::move(descriptor.name)); if (descriptor.type == "promise") { promiseMethodIds.push_back(methodNames.size() - 1); } else if (descriptor.type == "sync") { syncMethodIds.push_back(methodNames.size() - 1); } } if (!methodNames.empty()) { config.push_back(std::move(methodNames)); if (!promiseMethodIds.empty() || !syncMethodIds.empty()) { config.push_back(std::move(promiseMethodIds)); if (!syncMethodIds.empty()) { config.push_back(std::move(syncMethodIds)); } } } } if (config.size() == 2 && config[1].empty()) { // no constants or methods return nullptr; } else { return ModuleConfig({it->second, config}); } }
int ModInit( void ) { SET_SEGV_LOCATION(); ModuleConfig( ss_settings ); if( StatServ.html && StatServ.htmlpath[0] == 0 ) { nlog( LOG_NOTICE, "HTML stats disabled as HTML_PATH is not set" ); StatServ.html = 0; } InitNetworkStats(); if( InitChannelStats() == NS_FAILURE ) return NS_FAILURE; if( InitServerStats() == NS_FAILURE ) return NS_FAILURE; if( InitVersionStats() == NS_FAILURE ) return NS_FAILURE; if( InitTLDStatistics() == NS_FAILURE ) return NS_FAILURE; InitUserStats(); return NS_SUCCESS; }
static void __execute_function( cond_rc_t *cond_rc, const exec_context_t *exc, char *action, FUNC_FLAGS_TYPE exec_flags, char *args[], Bool has_ref_window_moved) { static int func_depth = 0; cond_rc_t *func_rc = NULL; cond_rc_t dummy_rc; Window w; int j; char *function; char *taction; char *trash; char *trash2; char *expaction = NULL; char *arguments[11]; const func_t *bif; Bool set_silent; Bool must_free_string = False; Bool must_free_function = False; Bool do_keep_rc = False; /* needed to be able to avoid resize to use moved windows for base */ extern Window PressedW; Window dummy_w; if (!action) { return; } /* ignore whitespace at the beginning of all config lines */ action = SkipSpaces(action, NULL, 0); if (!action || action[0] == 0) { /* impossibly short command */ return; } if (action[0] == '#') { /* a comment */ return; } func_depth++; if (func_depth > MAX_FUNCTION_DEPTH) { fvwm_msg( ERR, "__execute_function", "Function '%s' called with a depth of %i, " "stopping function execution!", action, func_depth); func_depth--; return; } if (args) { for (j = 0; j < 11; j++) { arguments[j] = args[j]; } } else { for (j = 0; j < 11; j++) { arguments[j] = NULL; } } if (exc->w.fw == NULL || IS_EWMH_DESKTOP(FW_W(exc->w.fw))) { if (exec_flags & FUNC_IS_UNMANAGED) { w = exc->w.w; } else { w = Scr.Root; } } else { FvwmWindow *tw; w = GetSubwindowFromEvent(dpy, exc->x.elast); if (w == None) { w = exc->x.elast->xany.window; } tw = NULL; if (w != None) { if (XFindContext( dpy, w, FvwmContext, (caddr_t *)&tw) == XCNOENT) { tw = NULL; } } if (w == None || tw != exc->w.fw) { w = FW_W(exc->w.fw); } } set_silent = False; if (action[0] == '-') { exec_flags |= FUNC_DONT_EXPAND_COMMAND; action++; } taction = action; /* parse prefixes */ trash = PeekToken(taction, &trash2); while (trash) { if (StrEquals(trash, PRE_SILENT)) { if (Scr.flags.are_functions_silent == 0) { set_silent = 1; Scr.flags.are_functions_silent = 1; } taction = trash2; trash = PeekToken(taction, &trash2); } else if (StrEquals(trash, PRE_KEEPRC)) { do_keep_rc = True; taction = trash2; trash = PeekToken(taction, &trash2); } else { break; } } if (taction == NULL) { if (set_silent) { Scr.flags.are_functions_silent = 0; } func_depth--; return; } if (cond_rc == NULL || do_keep_rc == True) { condrc_init(&dummy_rc); func_rc = &dummy_rc; } else { func_rc = cond_rc; } GetNextToken(taction, &function); if (function) { char *tmp = function; function = expand_vars( function, arguments, False, False, func_rc, exc); free(tmp); } if (function && function[0] != '*') { #if 1 /* DV: with this piece of code it is impossible to have a * complex function with embedded whitespace that begins with a * builtin function name, e.g. a function "echo hello". */ /* DV: ... and without it some of the complex functions will * fail */ char *tmp = function; while (*tmp && !isspace(*tmp)) { tmp++; } *tmp = 0; #endif bif = find_builtin_function(function); must_free_function = True; } else { bif = NULL; if (function) { free(function); } function = ""; } if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor && (!bif || !(bif->flags & FUNC_DECOR))) { fvwm_msg( ERR, "__execute_function", "Command can not be added to a decor; executing" " command now: '%s'", action); } if (!(exec_flags & FUNC_DONT_EXPAND_COMMAND)) { expaction = expand_vars( taction, arguments, (bif) ? !!(bif->flags & FUNC_ADD_TO) : False, (taction[0] == '*'), func_rc, exc); if (func_depth <= 1) { must_free_string = set_repeat_data( expaction, REPEAT_COMMAND, bif); } else { must_free_string = True; } } else { expaction = taction; } #ifdef FVWM_COMMAND_LOG fvwm_msg(INFO, "LOG", "%c: %s", (char)exc->type, expaction); #endif /* Note: the module config command, "*" can not be handled by the * regular command table because there is no required white space after * the asterisk. */ if (expaction[0] == '*') { if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) { fvwm_msg( WARN, "__execute_function", "Command can not be added to a decor;" " executing command now: '%s'", expaction); } /* process a module config command */ ModuleConfig(expaction); } else { const exec_context_t *exc2; exec_context_changes_t ecc; exec_context_change_mask_t mask; mask = (w != exc->w.w) ? ECC_W : 0; ecc.w.fw = exc->w.fw; ecc.w.w = w; ecc.w.wcontext = exc->w.wcontext; if (bif && bif->func_t != F_FUNCTION) { char *runaction; Bool rc = False; runaction = SkipNTokens(expaction, 1); if ((bif->flags & FUNC_NEEDS_WINDOW) && !(exec_flags & FUNC_DONT_DEFER)) { rc = DeferExecution( &ecc, &mask, bif->cursor, exc->x.elast->type, (bif->flags & FUNC_ALLOW_UNMANAGED)); } else if ((bif->flags & FUNC_NEEDS_WINDOW) && !__context_has_window( exc, bif->flags & FUNC_ALLOW_UNMANAGED)) { /* no context window and not allowed to defer, * skip command */ rc = True; } if (rc == False) { exc2 = exc_clone_context(exc, &ecc, mask); if (has_ref_window_moved && (bif->func_t == F_ANIMATED_MOVE || bif->func_t == F_MOVE || bif->func_t == F_RESIZE || bif->func_t == F_RESIZEMOVE || bif->func_t == F_RESIZE_MAXIMIZE || bif->func_t == F_RESIZEMOVE_MAXIMIZE)) { dummy_w = PressedW; PressedW = None; bif->action(func_rc, exc2, runaction); PressedW = dummy_w; } else { bif->action(func_rc, exc2, runaction); } exc_destroy_context(exc2); } } else { Bool desperate = 1; char *runaction; if (bif) { /* strip "function" command */ runaction = SkipNTokens(expaction, 1); } else { runaction = expaction; } exc2 = exc_clone_context(exc, &ecc, mask); execute_complex_function( func_rc, exc2, runaction, &desperate, has_ref_window_moved); if (!bif && desperate) { if (executeModuleDesperate( func_rc, exc, runaction) == NULL && *function != 0 && !set_silent) { fvwm_msg( ERR, "__execute_function", "No such command '%s'", function); } } exc_destroy_context(exc2); } } if (set_silent) { Scr.flags.are_functions_silent = 0; } if (cond_rc != NULL) { cond_rc->break_levels = func_rc->break_levels; } if (must_free_string) { free(expaction); } if (must_free_function) { free(function); } func_depth--; return; }
/*********************************************************************** * * Procedure: * ExecuteFunction - execute a fvwm built in function * * Inputs: * Action - the menu action to execute * tmp_win - the fvwm window structure * eventp - pointer to the event that caused the function * context - the context in which the button was pressed * ***********************************************************************/ void ExecuteFunction(char *Action, FvwmWindow *tmp_win, XEvent *eventp, unsigned long context, int Module) { Window w; int matched,j; char *function; char *action, *taction; char *arguments[10]; struct functions *bif; if (!Action || Action[0] == 0 || Action[1] == 0) { /* impossibly short command */ return; /* done */ } if (Action[0] == '#') { /* a comment */ return; /* done */ } /* Note: the module config command, "*" can not be handled by the regular command table because there is no required white space after the asterisk. */ if (Action[0] == '*') { /* a module config command */ ModuleConfig(NULL,0,0,0,Action,0); /* process the command */ return; /* done */ } for(j=0;j<10;j++) arguments[j] = NULL; if(tmp_win == NULL) w = Scr.Root; else w = tmp_win->w; if((tmp_win) &&(eventp)) w = eventp->xany.window; if((tmp_win)&&(eventp->xbutton.subwindow != None)&& (eventp->xany.window != tmp_win->w)) w = eventp->xbutton.subwindow; taction = expand(Action,arguments,tmp_win); action = GetNextToken(taction,&function); if (!function) return; j=0; matched = FALSE; bif = FindBuiltinFunction(function); if (bif) { matched = TRUE; bif->action(eventp,w,tmp_win,context,action,&Module); } if(!matched) { desperate = 1; ComplexFunction(eventp,w,tmp_win,context,taction, &Module); if(desperate) executeModule(eventp,w,tmp_win,context,taction, &Module); desperate = 0; } /* Only wait for an all-buttons-up condition after calls from * regular built-ins, not from complex-functions or modules. */ if(Module == -1) WaitForButtonsUp(); if (function) free(function); if(taction != NULL) free(taction); return; }