A couple of small changes for master: 0001: Makes the code in log.c easiert to read. 0002: Ignore emacs backup files. 0003: Clean up a header file. 0004: Remove the unused dependency from libs/vpacket.h to fvwm/fvwm.h. 0005: Your NEW-PARSEER.md patch without the reindentation. 0006: Remove the -D command line option. I'm not sure if we should really delete this. Should probably rather be a "bugopts" option.
parser branch on top of master: 0007-0009: Current cleaned up version of the parser parches Ciao Dominik ^_^ ^_^ -- Dominik Vogt
From 3f61e78201a452a69c74ccde036e371391e0dfd3 Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Sat, 20 Nov 2021 14:39:54 +0100 Subject: [PATCH 1/9] Clean up log.c. --- libs/log.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/libs/log.c b/libs/log.c index 23f28dcb..877a9f74 100644 --- a/libs/log.c +++ b/libs/log.c @@ -55,35 +55,36 @@ void log_open(const char *fvwm_userdir) { char *path, *file_name; + char *expanded_path; if (lib_log_level == 0) return; - if (log_file_name != NULL && - log_file_name[0] == '-' && log_file_name[1] == 0) { + /* determine file name or file path to use */ + file_name = log_file_name; + if (file_name == NULL) + { + file_name = getenv("FVWM3_LOGFILE"); + } + if (file_name == NULL) + { + file_name = FVWM3_LOGFILE_DEFAULT; + } + /* handle stderr logging */ + if (log_file_name[0] == '-' && log_file_name[1] == 0) + { log_file = stderr; return; } - if ((file_name = log_file_name) == NULL) - file_name = getenv("FVWM3_LOGFILE"); - - if (file_name != NULL) + /* handle file logging */ + expanded_path = expand_path(file_name); + if (expanded_path[0] == '/') { - char *expanded_path; - - expanded_path = expand_path(file_name); - if (expanded_path[0] == '/') - { - path = expanded_path; - } - else - { - xasprintf(&path, "%s/%s", fvwm_userdir, expanded_path); - free((char *)expanded_path); - } + path = expanded_path; } else { - xasprintf(&path, "%s/%s", fvwm_userdir, FVWM3_LOGFILE_DEFAULT); + xasprintf(&path, "%s/%s", fvwm_userdir, expanded_path); + free((char *)expanded_path); } log_close(); -- 2.30.2
From 7ff0553f89bf5b767a5f67d8bcbdc1c63363a01d Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Sat, 20 Nov 2021 11:04:03 +0100 Subject: [PATCH 2/9] .gitignore: Ignore emacs backups. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7ec13d8d..6c538bee 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ *.o *.patch *~ +*# +.#* Makefile Makefile.in aclocal.m4 -- 2.30.2
From 2021ba60dc174b9508f87d4ee7ffb800792cd0ab Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Sat, 20 Nov 2021 12:12:13 +0100 Subject: [PATCH 3/9] Header cleanup. --- libs/vpacket.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/libs/vpacket.h b/libs/vpacket.h index d0d88b2d..bd549fab 100644 --- a/libs/vpacket.h +++ b/libs/vpacket.h @@ -16,7 +16,6 @@ This is the same packet as the M_ADD_WINDOW packet, the only difference being the type. */ -/* RBW- typedef struct config_win_packet */ typedef struct ConfigWinPacket { /*** Alignment notes ***/ @@ -33,14 +32,7 @@ typedef struct ConfigWinPacket unsigned long desk; unsigned long monitor_id; unsigned long monitor_name; - /* - Temp word for alignment - old flags used to be here. - - remove before next release. - RBW - 05/01/2000 - layer has usurped this slot. - unsigned long dummy; - */ unsigned long layer; - unsigned long hints_base_width; unsigned long hints_base_height; unsigned long hints_width_inc; @@ -56,8 +48,6 @@ typedef struct ConfigWinPacket unsigned long hints_win_gravity; unsigned long TextPixel; unsigned long BackPixel; - - /* Everything below this is post-GSFR */ unsigned long ewmh_hint_layer; unsigned long ewmh_hint_desktop; unsigned long ewmh_window_type; -- 2.30.2
From 500e6f4b2c532d76581ba055d216a5d63cc93a03 Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Sat, 20 Nov 2021 11:50:52 +0100 Subject: [PATCH 4/9] Remove libs/vpacket.h depending on fvwm.h. --- libs/vpacket.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/vpacket.h b/libs/vpacket.h index bd549fab..98eb590c 100644 --- a/libs/vpacket.h +++ b/libs/vpacket.h @@ -3,7 +3,6 @@ #ifndef FVWMLIB_VPACKET_H #define FVWMLIB_VPACKET_H #include "fvwm_x11.h" -#include "fvwm/fvwm.h" /* All new-style module packets (i.e., those that are not simply arrays @@ -70,7 +69,7 @@ typedef struct MiniIconPacket { Window w; Window frame; - FvwmWindow *fvwmwin; + void *fvwmwin; unsigned long width; unsigned long height; unsigned long depth; -- 2.30.2
From 01686e05071f7fbd460c73e4e70462136b50eb29 Mon Sep 17 00:00:00 2001 From: Thomas Adam <tho...@fvwm.org> Date: Thu, 18 Nov 2021 22:47:15 +0000 Subject: [PATCH 5/9] doc: NEW-PARSER.md --- dev-docs/NEW-PARSER.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 dev-docs/NEW-PARSER.md diff --git a/dev-docs/NEW-PARSER.md b/dev-docs/NEW-PARSER.md new file mode 100644 index 00000000..c176b245 --- /dev/null +++ b/dev-docs/NEW-PARSER.md @@ -0,0 +1,4 @@ +New Parser +========== + + -- 2.30.2
From 1f1c1e811174bba008286022e4e9758e747a70dd Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Sat, 20 Nov 2021 14:40:12 +0100 Subject: [PATCH 6/9] Remove -D option. --- doc/fvwm3_manpage_source.adoc | 5 ----- fvwm/externs.h | 1 - fvwm/fvwm3.c | 11 ----------- 3 files changed, 17 deletions(-) diff --git a/doc/fvwm3_manpage_source.adoc b/doc/fvwm3_manpage_source.adoc index d78b5d22..42187d14 100644 --- a/doc/fvwm3_manpage_source.adoc +++ b/doc/fvwm3_manpage_source.adoc @@ -71,11 +71,6 @@ fvwm -c "AddToFunc StartFunction I Module FvwmPager" Manage the display called _displayname_ instead of the name obtained from the environment variable _$DISPLAY_. -*-D* | *--debug*:: - -Puts X transactions in synchronous mode, which dramatically slows things -down, but guarantees that fvwm's internal error messages are correct. - *-f* _config-file_:: Causes fvwm to read _config-file_ instead of _~/.fvwm/config_ as its diff --git a/fvwm/externs.h b/fvwm/externs.h index 1fcb1597..37719341 100644 --- a/fvwm/externs.h +++ b/fvwm/externs.h @@ -46,7 +46,6 @@ extern int x_fd; extern XContext FvwmContext; extern Bool fFvwmInStartup; extern Bool DoingCommandLine; -extern Bool debugging; extern Bool debugging_stack_ring; extern int GrabPointerState; extern Window JunkRoot, JunkChild; diff --git a/fvwm/fvwm3.c b/fvwm/fvwm3.c index fb6e8c87..d4aa8838 100644 --- a/fvwm/fvwm3.c +++ b/fvwm/fvwm3.c @@ -149,7 +149,6 @@ Window JunkRoot, JunkChild; /* junk window */ int JunkWidth, JunkHeight, JunkBW, JunkDepth; unsigned int JunkMask; -Bool debugging = False; Bool debugging_stack_ring = False; Window bad_window = None; @@ -1812,12 +1811,6 @@ int main(int argc, char **argv) { debugging_stack_ring = True; } - else if (strcmp(argv[i], "-D") == 0 || - strcmp(argv[i], "-debug") == 0 || - strcmp(argv[i], "--debug") == 0) - { - debugging = True; - } else if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "-clientid") == 0 || strcmp(argv[i], "--clientid") == 0 || @@ -2378,10 +2371,6 @@ int main(int argc, char **argv) frame_init(); XFlush(dpy); - if (debugging) - { - sync_server(1); - } SetupICCCM2(replace_wm); XSetIOErrorHandler(CatchFatal); -- 2.30.2
From eb39cff44bfb04996d09055e3189d6e364c82c73 Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Wed, 17 Nov 2021 20:03:57 +0100 Subject: [PATCH 7/9] Rewrite parser framework. --- fvwm/Makefile.am | 4 +- fvwm/add_window.c | 9 +- fvwm/builtins.c | 4 +- fvwm/cmdparser.h | 65 ++++ fvwm/cmdparser_hooks.h | 74 ++++ fvwm/cmdparser_old.c | 425 +++++++++++++++++++++ fvwm/cmdparser_old.h | 11 + fvwm/colorset.c | 2 +- fvwm/conditional.c | 21 +- fvwm/conditional.h | 42 +++ fvwm/events.c | 40 +- fvwm/ewmh.c | 7 +- fvwm/ewmh_events.c | 33 +- fvwm/expand.c | 48 ++- fvwm/expand.h | 2 +- fvwm/functable.c | 66 +++- fvwm/functable.h | 25 +- fvwm/functable_complex.c | 157 ++++++++ fvwm/functable_complex.h | 55 +++ fvwm/functions.c | 792 ++++++++++++++------------------------- fvwm/functions.h | 41 +- fvwm/fvwm.h | 49 +-- fvwm/fvwm3.c | 14 +- fvwm/menucmd.c | 3 +- fvwm/menus.c | 4 +- fvwm/misc.c | 1 + fvwm/module_interface.c | 3 +- fvwm/move_resize.c | 29 +- fvwm/placement.c | 5 +- fvwm/read.c | 14 +- fvwm/read.h | 4 +- fvwm/repeat.c | 6 +- fvwm/schedule.c | 3 +- fvwm/update.c | 7 +- fvwm/virtual.c | 24 +- fvwm/windowlist.c | 3 +- 36 files changed, 1380 insertions(+), 712 deletions(-) create mode 100644 fvwm/cmdparser.h create mode 100644 fvwm/cmdparser_hooks.h create mode 100644 fvwm/cmdparser_old.c create mode 100644 fvwm/cmdparser_old.h create mode 100644 fvwm/functable_complex.c create mode 100644 fvwm/functable_complex.h diff --git a/fvwm/Makefile.am b/fvwm/Makefile.am index a4bb6a0b..9ae456f9 100644 --- a/fvwm/Makefile.am +++ b/fvwm/Makefile.am @@ -19,6 +19,7 @@ fvwm3_SOURCES = \ placement.h read.h repeat.h execcontext.h schedule.h screen.h \ session.h stack.h style.h update.h virtual.h window_flags.h frame.h \ infostore.h \ + cmdparser.h cmdparser_hooks.h cmdparser_old.h functable_complex.h \ \ menus.c style.c borders.c events.c move_resize.c builtins.c \ add_window.c icons.c fvwm3.c frame.c placement.c virtual.c \ @@ -28,7 +29,8 @@ fvwm3_SOURCES = \ menubindings.c decorations.c ewmh_icons.c update.c bindings.c misc.c \ cursor.c colormaps.c modconf.c ewmh_conf.c read.c schedule.c \ menucmd.c ewmh_names.c icccm2.c windowshade.c focus_policy.c repeat.c \ - execcontext.c menugeometry.c menudim.c condrc.c infostore.c + execcontext.c menugeometry.c menudim.c condrc.c infostore.c \ + cmdparser_old.c functable_complex.c fvwm3_DEPENDENCIES = $(top_builddir)/libs/libfvwm3.a diff --git a/fvwm/add_window.c b/fvwm/add_window.c index dbd062e2..95a18600 100644 --- a/fvwm/add_window.c +++ b/fvwm/add_window.c @@ -2495,7 +2495,7 @@ FvwmWindow *AddWindow( char *cmd; xasprintf(&cmd, "GotoDesk %s 0 %d", tm->si->name, fw->Desk); - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); free(cmd); /* read the requested absolute geometry */ @@ -2695,7 +2695,8 @@ FvwmWindow *AddWindow( SET_STICKY_ACROSS_PAGES(fw, 0); SET_STICKY_ACROSS_DESKS(fw, 0); handle_stick( - NULL, exc2, "", stick_page, stick_desk, 1, 0); + NULL, exc2, "", NULL, stick_page, stick_desk, + 1, 0); exc_destroy_context(exc2); } } @@ -2727,7 +2728,7 @@ FvwmWindow *AddWindow( ecc.w.wcontext = C_WINDOW; exc2 = exc_clone_context( exc, &ecc, ECC_ETRIGGER | ECC_FW | ECC_WCONTEXT); - CMD_Resize(NULL, exc2, ""); + CMD_Resize(NULL, exc2, "", NULL); exc_destroy_context(exc2); } @@ -2796,7 +2797,7 @@ FvwmWindow *AddWindow( EWMH_STATE_HAS_HINT) ? 100 : 0; sprintf(cmd,"Maximize on %i %i", h, v); execute_function_override_window( - NULL, NULL, cmd, 0, fw); + NULL, NULL, cmd, NULL, 0, fw); } } if (HAS_EWMH_INIT_FULLSCREEN_STATE(fw) == EWMH_STATE_HAS_HINT) diff --git a/fvwm/builtins.c b/fvwm/builtins.c index 4065051d..5c6e4eba 100644 --- a/fvwm/builtins.c +++ b/fvwm/builtins.c @@ -544,7 +544,7 @@ static void __remove_window_decors(F_CMD_ARGS, FvwmDecor *d) exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_WCONTEXT); execute_function( - cond_rc, exc2, "ChangeDecor Default", 0); + cond_rc, exc2, "ChangeDecor Default", pc, 0); exc_destroy_context(exc2); } } @@ -2166,7 +2166,7 @@ void AddToDecor(F_CMD_ARGS, FvwmDecor *decor) return; } Scr.cur_decor = decor; - execute_function(cond_rc, exc, action, 0); + execute_function(F_PASS_ARGS, 0); Scr.cur_decor = NULL; return; diff --git a/fvwm/cmdparser.h b/fvwm/cmdparser.h new file mode 100644 index 00000000..53e1d2e6 --- /dev/null +++ b/fvwm/cmdparser.h @@ -0,0 +1,65 @@ +/* -*-c-*- */ + +#ifndef FVWM_CMDPARSER_H +#define FVWM_CMDPARSER_H + +/* ---------------------------- included header files ---------------------- */ + +/* ---------------------------- global definitions ------------------------- */ + +/* $0 through to $9 */ +#define CMDPARSER_NUM_POS_ARGS 10 + +/* ---------------------------- global macros ------------------------------ */ + +/* ---------------------------- type definitions --------------------------- */ + +/* Enum for all the possible prefixes. */ +typedef enum +{ + CP_PREFIX_NONE = 0, + CP_PREFIX_MINUS = 0x1, + CP_PREFIX_SILENT = 0x2, + CP_PREFIX_KEEPRC = 0x4 +} cmdparser_prefix_flags_t; + +/* Enum for types of things to execute. */ +typedef enum +{ + CP_EXECTYPE_UNKNOWN = 0, + CP_EXECTYPE_BUILTIN_FUNCTION, + CP_EXECTYPE_COMPLEX_FUNCTION, + CP_EXECTYPE_COMPLEX_FUNCTION_DOES_NOT_EXIST, + CP_EXECTYPE_MODULECONFIG +} cmdparser_execute_type_t; + +/* move this to the implementation file and use void* instead??? */ + +typedef struct +{ + /* !!!note: need to define which bits in here may be accessed by the + * user and which are internal */ + unsigned char is_created : 1; + /* the original command line */ + char *line; + /* the current command line */ + char *cline; + /* the expanded command line */ + char *expline; + unsigned char do_free_expline : 1; + /* the command name */ + char *command; + /* name of the complex function if present */ + char *complex_function_name; + /* current function nesting depth */ + int call_depth; + /* A string with all positional arguments of a complex function. May + * be NULL if not in the context of a complex function. */ + char *all_pos_args_string; + /* An array of the first CMDPARSER_NUM_POS_ARGS positional arguments up + * to and excluding the first NULL pointer. Must (not) all be NULL if + * all_pos_args_string is (not) NULL. */ + char *pos_arg_tokens[CMDPARSER_NUM_POS_ARGS]; +} cmdparser_context_t; + +#endif /* FVWM_CMDPARSER_H */ diff --git a/fvwm/cmdparser_hooks.h b/fvwm/cmdparser_hooks.h new file mode 100644 index 00000000..42330246 --- /dev/null +++ b/fvwm/cmdparser_hooks.h @@ -0,0 +1,74 @@ +/* -*-c-*- */ + +#ifndef FVWM_CMDPARSER_HOOKS_H +#define FVWM_CMDPARSER_HOOKS_H + +/* ---------------------------- included header files ---------------------- */ + +/* ---------------------------- global definitions ------------------------- */ + +/* ---------------------------- global macros ------------------------------ */ + +/* ---------------------------- type definitions --------------------------- */ + +typedef struct +{ + /* in general, functions in this structure that return int return + * 0: success + * > 0: unsuccessful but not an error condition + * < 0: unsuccessful, error + */ + int (*create_context)( + /* context structure to initialise */ + cmdparser_context_t *dest_context, + /* context structure of the caller or NULL */ + cmdparser_context_t *caller_context, + /* input command line */ + char *line, + /* A string with all positional arguments of a complex + * function. May be NULL if not in the context of a complex + * function. */ + char *all_pos_args_string, + /* An array of the first CMDPARSER_NUM_POS_ARGS positional + * arguments up to and excluding the first NULL pointer. Must + * (not) all be NULL if all_pos_args_string is (not) NULL. */ + char *pos_arg_tokens[] + ); + int (*handle_line_start)(cmdparser_context_t *context); + /* Returns a set of or'ed flags of which prefixes are present on the + * command line. The prefixes are stripped. */ + cmdparser_prefix_flags_t (*handle_line_prefix)( + cmdparser_context_t *context); + /* parses and returns the command name or returns a NULL pointer if not + * possible */ + const char *(*parse_command_name)( + cmdparser_context_t *context, void *func_rc, const void *exc); + /* returns 1 if the stored command is a module configuration command + * and 0 otherwise */ + int (*is_module_config)(cmdparser_context_t *context); + /* expands the command line */ + void (*expand_command_line)( + cmdparser_context_t *context, int is_addto, void *func_rc, + const void *exc); + /* Release the expline field from the context structure and return it. + * It is then the responsibility of the caller to free() it. */ + void (*release_expanded_line)(cmdparser_context_t *context); + /* Tries to find a builtin function, a complex function or a module + * config line to execute and returns the type found or + * CP_EXECTYPE_UNKNOWN if none of the above were identified. For a + * builtin or a complex function, the pointer to the description is + * returned in *ret_builtin or *ret_complex_function. Consumes the + * the "Module" or the "Function" command from the input. Does not + * consider builtin functions if *ret_builtin is != NULL when the + * function is called. */ + cmdparser_execute_type_t (*find_something_to_execute)( + cmdparser_context_t *context, + const func_t **ret_builtin, + FvwmFunction **ret_complex_function); + /* Release the context initialised with create_context(). */ + void (*destroy_context)(cmdparser_context_t *context); + /* Print the contents of the context. */ + void (*debug)(cmdparser_context_t *context, const char *msg); +} cmdparser_hooks_t; + +#endif /* FVWM_CMDPARSER_HOOKS_H */ diff --git a/fvwm/cmdparser_old.c b/fvwm/cmdparser_old.c new file mode 100644 index 00000000..21c2074e --- /dev/null +++ b/fvwm/cmdparser_old.c @@ -0,0 +1,425 @@ +/* -*-c-*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ---------------------------- included header files ---------------------- */ + +#include "config.h" +#include "libs/defaults.h" +#include "libs/Parse.h" + +#include <assert.h> +#include <stdio.h> + +#include "fvwm.h" +#include "execcontext.h" +#include "conditional.h" +#include "functable.h" +#include "commands.h" +#include "functable_complex.h" +#include "cmdparser.h" +#include "cmdparser_hooks.h" +#include "cmdparser_old.h" +#include "misc.h" +#include "expand.h" + +/* ---------------------------- local definitions -------------------------- */ + +#if 0 /*!!!*/ +#define OCP_DEBUG 1 +#else +#define OCP_DEBUG 0 +#endif + +/* ---------------------------- local macros ------------------------------- */ + +/* ---------------------------- imports ------------------------------------ */ + +/* ---------------------------- included code files ------------------------ */ + +/* ---------------------------- local types -------------------------------- */ + +/* ---------------------------- forward declarations ----------------------- */ + +/* ---------------------------- local variables ---------------------------- */ + +/* ---------------------------- exported variables (globals) --------------- */ + +/* ---------------------------- local functions ---------------------------- */ + +static void ocp_debug(cmdparser_context_t *c, const char *msg) +{ + int i; + + if (!OCP_DEBUG) + { + return; + } + fprintf(stderr, "%s: %p: %s\n", __func__, c, (msg != NULL) ? msg : ""); + if (!c->is_created) + { + fprintf(stderr, " not created\n"); + return; + } + fprintf(stderr, " depth : %d\n", c->call_depth); + fprintf(stderr, " orig line: '%s'\n", c->line ? c->line : "(nil)"); + fprintf(stderr, " curr line: '%s'\n", c->cline ? c->cline : "(nil)"); + fprintf( + stderr, " exp line: (do_free = %d) '%s'\n", + c->do_free_expline, c->expline ? c->expline : "(nil)"); + fprintf( + stderr, " command : '%s'\n", + c->command ? c->command : "(nil)"); + fprintf( + stderr, " complexf : '%s'\n", + c->complex_function_name ? c->complex_function_name : "(nil)"); + if (c->all_pos_args_string == NULL) + { + return; + } + fprintf( + stderr, " all args : '%s'\n", + c->all_pos_args_string ? c->all_pos_args_string: "(nil)"); + fprintf(stderr, " pos args :"); + for ( + i = 0; i < CMDPARSER_NUM_POS_ARGS && + c->pos_arg_tokens[i] != NULL; i++) + { + fprintf(stderr, " %d:'%s'", i, + c->pos_arg_tokens[i] ? c->pos_arg_tokens[i]: "(nil)"); + } + fprintf(stderr, "\n"); + + return; +} + +static int ocp_create_context( + cmdparser_context_t *dest_c, cmdparser_context_t *caller_c, char *line, + char *all_pos_args_string, char *pos_arg_tokens[]) +{ + /* allocate the necessary resources */ + memset(dest_c, 0, sizeof(*dest_c)); + dest_c->line = line; + /*!!!should this be in handle_line_start instead???*/ + if (caller_c != NULL) + { + if (caller_c->call_depth >= MAX_FUNCTION_DEPTH) + { + fvwm_debug( + __func__, + "called with a depth of %i, " + "stopping function execution!", + caller_c->call_depth); + + return -1; + } + dest_c->call_depth = caller_c->call_depth + 1; + } + else + { + dest_c->call_depth = 1; + } + if (all_pos_args_string != NULL) + { + int i; + + dest_c->all_pos_args_string = all_pos_args_string; + for ( + i = 0; i < CMDPARSER_NUM_POS_ARGS && + pos_arg_tokens[i] != NULL; i++) + { + dest_c->pos_arg_tokens[i] = pos_arg_tokens[i]; + } + } + /*!!!allocate stuff*/ + dest_c->is_created = 1; + + return 0; +} + +static void ocp_destroy_context(cmdparser_context_t *c) +{ + /* free the resources allocated in the create function */ + if (!c->is_created) + { + return; + } + if (c->command != NULL) + { + free(c->command); + } + if (c->expline != NULL && c->do_free_expline) + { + free(c->expline); + } + c->is_created = 0; + + return; +} + +static int ocp_handle_line_start(cmdparser_context_t *c) +{ + /*!!! remove assertion later*/ + assert(c->cline == NULL); + if (!c->line) + { + /* nothing to do */ + return 1; + } + /* ignore whitespace at the beginning of all config lines */ + c->cline = SkipSpaces(c->line, NULL, 0); + if (!c->cline || c->cline[0] == 0) + { + /* impossibly short command */ + return -1; + } + if (c->cline[0] == '#') + { + /* a comment */ + return 1; + } + + return 0; +} + +static cmdparser_prefix_flags_t ocp_handle_line_prefix(cmdparser_context_t *c) +{ + cmdparser_prefix_flags_t flags; + char *token; + char *restofline; + + if (OCP_DEBUG) + { + fprintf(stderr, "%s: '%s'\n", __func__, c->cline); + } + flags = CP_PREFIX_NONE; + if (c->cline[0] == '-') + { + c->cline++; + flags |= CP_PREFIX_MINUS; + if (OCP_DEBUG) + { + fprintf(stderr, "minus -> '%s'\n", c->cline); + } + } + token = PeekToken(c->cline, &restofline); + if (OCP_DEBUG) + { + fprintf( + stderr, "cl '%s', tok '%s', rl '%s'\n", c->cline, + token, restofline); + } + while (token != NULL) + { + if (OCP_DEBUG) + { + fprintf(stderr, "loop: token '%s'\n", token); + } + if (StrEquals(token, PRE_SILENT)) + { + flags |= CP_PREFIX_SILENT; + c->cline = restofline; + token = PeekToken(c->cline, &restofline); + if (OCP_DEBUG) + { + fprintf( + stderr, + "-> silent: cl '%s', tok '%s'\n", + c->cline, token); + } + } + else if (StrEquals(token, PRE_KEEPRC)) + { + flags |= CP_PREFIX_KEEPRC; + c->cline = restofline; + token = PeekToken(c->cline, &restofline); + if (OCP_DEBUG) + { + fprintf( + stderr, + "-> keeprc: cl '%s', tok '%s'\n", + c->cline, token); + } + } + else + { + break; + } + } + if (OCP_DEBUG) + { + fprintf(stderr, "done: flags 0x%x\n", flags); + } + + return flags; +} + +static int ocp_is_module_config(cmdparser_context_t *c) +{ + return (c->command != NULL && *c->command == '*') ? 1 : 0; +} + +static const char *ocp_parse_command_name( + cmdparser_context_t *c, void *func_rc, const void *exc) +{ + GetNextToken(c->cline, &c->command); + if (c->command != NULL) + { + char *tmp = c->command; + + c->command = expand_vars( + c->command, c, False, False, func_rc, exc); + free(tmp); + } + if (c->command && !ocp_is_module_config(c)) + { +#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 = c->command; + + while (*tmp && !isspace(*tmp)) + { + tmp++; + } + *tmp = 0; +#endif + return c->command; + } + else + { + return NULL; + } +} + +static void ocp_expand_command_line( + cmdparser_context_t *c, int is_addto, void *func_rc, const void *exc) +{ + c->expline = expand_vars( + c->cline, c, is_addto, ocp_is_module_config(c), func_rc, exc); + c->cline = c->expline; + c->do_free_expline = 1; + + return; +} + +static void ocp_release_expanded_line(cmdparser_context_t *c) +{ + c->do_free_expline = 0; + + return; +} + +static cmdparser_execute_type_t ocp_find_something_to_execute( + cmdparser_context_t *c, const func_t **ret_builtin, + FvwmFunction **ret_complex_function) +{ + int is_function_builtin; + + *ret_complex_function = NULL; + /* 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 (ocp_is_module_config(c)) + { + /*!!!strip asterisk??? */ + return CP_EXECTYPE_MODULECONFIG; + } + if (*ret_builtin == NULL) + { + /* in a new parser we would look for a builtin function here, + * but in the old parser this has already been done */ + } + is_function_builtin = 0; + if (*ret_builtin != NULL) + { + if ((*ret_builtin)->func_c == F_FUNCTION) + { + c->cline = SkipNTokens(c->cline, 1); + if (OCP_DEBUG) + { + fprintf(stderr, "func cline '%s'\n", c->cline); + } + free(c->command); + c->command = NULL; + is_function_builtin = 1; + *ret_builtin = NULL; + } + else + { + c->cline = SkipNTokens(c->cline, 1); + return CP_EXECTYPE_BUILTIN_FUNCTION; + } + } +#if 1 /*!!!*/ + assert(*ret_builtin == NULL); +#endif + do + { + char *complex_function_name; + char *rest_of_line; + + /* find_complex_function expects a token, not just a quoted + * string */ + complex_function_name = PeekToken(c->cline, &rest_of_line); + if (complex_function_name == NULL) + { + break; + } + *ret_complex_function = + find_complex_function(complex_function_name); + if (*ret_complex_function != NULL) + { + c->cline = rest_of_line; + c->complex_function_name = complex_function_name; + return CP_EXECTYPE_COMPLEX_FUNCTION; + } + if (is_function_builtin) + { + c->cline = rest_of_line; + c->complex_function_name = complex_function_name; + return CP_EXECTYPE_COMPLEX_FUNCTION_DOES_NOT_EXIST; + } + } while (0); + + return CP_EXECTYPE_UNKNOWN; +} + +/* ---------------------------- local variables ---------------------------- */ + +static cmdparser_hooks_t old_parser_hooks = +{ + ocp_create_context, + ocp_handle_line_start, + ocp_handle_line_prefix, + ocp_parse_command_name, + ocp_is_module_config, + ocp_expand_command_line, + ocp_release_expanded_line, + ocp_find_something_to_execute, + ocp_destroy_context, + ocp_debug +}; + +/* ---------------------------- interface functions ------------------------ */ + +/* return the hooks structure of the old parser */ +const cmdparser_hooks_t *cmdparser_old_get_hooks(void) +{ + return &old_parser_hooks; +} diff --git a/fvwm/cmdparser_old.h b/fvwm/cmdparser_old.h new file mode 100644 index 00000000..d2b11b47 --- /dev/null +++ b/fvwm/cmdparser_old.h @@ -0,0 +1,11 @@ +/* -*-c-*- */ + +#ifndef FVWM_CMDPARSER_OLD_H +#define FVWM_CMDPARSER_OLD_H + +/* ---------------------------- interface functions ------------------------ */ + +/* return the hooks structure of the old parser */ +const cmdparser_hooks_t *cmdparser_old_get_hooks(void); + +#endif /* FVWM_CMDPARSER_OLD_H */ diff --git a/fvwm/colorset.c b/fvwm/colorset.c index 48f59c8c..5aa9bc8d 100644 --- a/fvwm/colorset.c +++ b/fvwm/colorset.c @@ -250,7 +250,7 @@ static void add_to_junk(Pixmap pixmap) const exec_context_t *exc; exc = exc_create_null_context(); - CMD_Schedule(NULL, exc, "3000 CleanupColorsets"); + CMD_Schedule(NULL, exc, "3000 CleanupColorsets", NULL); exc_destroy_context(exc); cleanup_scheduled = True; } diff --git a/fvwm/conditional.c b/fvwm/conditional.c index e64cabf6..30bf14a3 100644 --- a/fvwm/conditional.c +++ b/fvwm/conditional.c @@ -28,6 +28,7 @@ #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "execcontext.h" #include "functions.h" #include "conditional.h" @@ -201,7 +202,7 @@ static void circulate_cmd( ecc.w.wcontext = new_context; exc2 = exc_clone_context( exc, &ecc, ECC_FW | ECC_W | ECC_WCONTEXT); - execute_function(cond_rc, exc2, restofline, flags); + execute_function(cond_rc, exc2, restofline, pc, flags); exc_destroy_context(exc2); } @@ -240,7 +241,7 @@ static void select_cmd(F_CMD_ARGS) cond_rc->rc = COND_RC_OK; } execute_function_override_wcontext( - cond_rc, exc, restofline, 0, C_WINDOW); + cond_rc, exc, restofline, pc, 0, C_WINDOW); } else if (cond_rc != NULL) { @@ -1423,7 +1424,7 @@ static void direction_cmd(F_CMD_ARGS, Bool is_scan) cond_rc->rc = COND_RC_OK; } execute_function_override_window( - cond_rc, exc, restofline, 0, fw_best); + cond_rc, exc, restofline, pc, 0, fw_best); } else if (cond_rc != NULL) { @@ -1664,7 +1665,7 @@ void CMD_All(F_CMD_ARGS) for (i = num-1; i >= 0; i--) { execute_function_override_window( - cond_rc, exc, restofline, 0, g[i]); + cond_rc, exc, restofline, pc, 0, g[i]); } } else @@ -1672,7 +1673,7 @@ void CMD_All(F_CMD_ARGS) for (i = 0; i < num; i++) { execute_function_override_window( - cond_rc, exc, restofline, 0, g[i]); + cond_rc, exc, restofline, pc, 0, g[i]); } } if (cond_rc != NULL && cond_rc->rc != COND_RC_BREAK) @@ -1792,7 +1793,7 @@ void CMD_WindowId(F_CMD_ARGS) cond_rc->rc = COND_RC_OK; } execute_function_override_window( - cond_rc, exc, action, 0, t); + cond_rc, exc, action, pc, 0, t); } else if (cond_rc != NULL) { @@ -1836,7 +1837,7 @@ void CMD_WindowId(F_CMD_ARGS) ECC_FW | ECC_W | ECC_WCONTEXT); execute_function( cond_rc, exc2, action, - FUNC_IS_UNMANAGED); +pc, FUNC_IS_UNMANAGED); exc_destroy_context(exc2); } } @@ -1873,7 +1874,7 @@ void CMD_TestRc(F_CMD_ARGS) { /* execute the command in root window context; overwrite the * return code with the return code of the command */ - execute_function(cond_rc, exc, rest, 0); + execute_function(cond_rc, exc, rest, pc, 0); } return; @@ -1899,7 +1900,7 @@ void CMD_Break(F_CMD_ARGS) void CMD_NoWindow(F_CMD_ARGS) { - execute_function_override_window(cond_rc, exc, action, 0, NULL); + execute_function_override_window(cond_rc, exc, action, pc, 0, NULL); return; } @@ -2321,7 +2322,7 @@ void CMD_Test(F_CMD_ARGS) } if (!error && match) { - execute_function(cond_rc, exc, restofline, 0); + execute_function(cond_rc, exc, restofline, pc, 0); } if (cond_rc != NULL) { diff --git a/fvwm/conditional.h b/fvwm/conditional.h index c993ae8b..c58f2030 100644 --- a/fvwm/conditional.h +++ b/fvwm/conditional.h @@ -12,6 +12,48 @@ /* ---------------------------- type definitions --------------------------- */ +/* Window mask for Circulate and Direction functions */ +typedef struct WindowConditionMask +{ + struct + { + unsigned do_accept_focus : 1; + unsigned do_check_desk : 1; + unsigned do_check_screen : 1; + unsigned do_check_cond_desk : 1; + unsigned do_check_desk_and_global_page : 1; + unsigned do_check_desk_and_page : 1; + unsigned do_check_global_page : 1; + unsigned do_check_overlapped : 1; + unsigned do_check_page : 1; + unsigned do_not_check_screen : 1; + unsigned needs_current_desk : 1; + unsigned needs_current_desk_and_global_page : 1; + unsigned needs_current_desk_and_page : 1; + unsigned needs_current_global_page : 1; + unsigned needs_current_page : 1; +#define NEEDS_ANY 0 +#define NEEDS_TRUE 1 +#define NEEDS_FALSE 2 + unsigned needs_focus : 2; + unsigned needs_overlapped : 2; + unsigned needs_pointer : 2; + unsigned needs_same_layer : 1; + unsigned use_circulate_hit : 1; + unsigned use_circulate_hit_icon : 1; + unsigned use_circulate_hit_shaded : 1; + unsigned use_do_accept_focus : 1; + } my_flags; + window_flags flags; + window_flags flag_mask; + struct name_condition *name_condition; + int layer; + int desk; + struct monitor *screen; + int placed_by_button_mask; + int placed_by_button_set_mask; +} WindowConditionMask; + /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- exported variables (globals) --------------- */ diff --git a/fvwm/events.c b/fvwm/events.c index 01102968..b490b404 100644 --- a/fvwm/events.c +++ b/fvwm/events.c @@ -70,6 +70,7 @@ #include "libs/FEvent.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "cursor.h" #include "functions.h" #include "commands.h" @@ -1622,7 +1623,7 @@ static Bool __handle_bpress_action( /* release the pointer since it can't do harm over an icon */ XAllowEvents(dpy, AsyncPointer, CurrentTime); } - execute_function(NULL, exc, action, 0); + execute_function(NULL, exc, action, NULL, 0); if (exc->w.wcontext != C_WINDOW && exc->w.wcontext != C_NO_CONTEXT) { WaitForButtonsUp(True); @@ -1660,7 +1661,7 @@ static void __handle_bpress_on_root(const exec_context_t *exc) ecc.w.wcontext = C_ROOT; exc2 = exc_clone_context(exc, &ecc, ECC_WCONTEXT); - execute_function(NULL, exc2, action, 0); + execute_function(NULL, exc2, action, NULL, 0); exc_destroy_context(exc2); WaitForButtonsUp(True); } @@ -1824,27 +1825,30 @@ monitor_emit_broadcast(void) TAILQ_FOREACH (m, &monitor_q, entry) { if (m->emit & MONITOR_CHANGED) { - BroadcastName(MX_MONITOR_CHANGED, -1, -1, -1, m->si->name); + BroadcastName( + MX_MONITOR_CHANGED, -1, -1, -1, m->si->name); m->emit &= ~MONITOR_ALL; m->flags &= ~MONITOR_CHANGED; /* Run the RandRFunc in case a user has set it. */ - execute_function_override_window(NULL, NULL, randrfunc, - 0, NULL); + execute_function_override_window( + NULL, NULL, randrfunc, NULL, 0, NULL); } if (m->emit & MONITOR_ENABLED) { - BroadcastName(MX_MONITOR_ENABLED, -1, -1, -1, m->si->name); + BroadcastName( + MX_MONITOR_ENABLED, -1, -1, -1, m->si->name); /* Run the RandRFunc in case a user has set it. */ - execute_function_override_window(NULL, NULL, randrfunc, - 0, NULL); + execute_function_override_window( + NULL, NULL, randrfunc, NULL, 0, NULL); } if (m->emit & MONITOR_DISABLED) { - BroadcastName(MX_MONITOR_DISABLED, -1, -1, -1, m->si->name); + BroadcastName( + MX_MONITOR_DISABLED, -1, -1, -1, m->si->name); /* Run the RandRFunc in case a user has set it. */ - execute_function_override_window(NULL, NULL, randrfunc, - 0, NULL); + execute_function_override_window( + NULL, NULL, randrfunc, NULL, 0, NULL); } } } @@ -1895,7 +1899,7 @@ void HandleClientMessage(const evh_args_t *ea) ecc.w.wcontext = C_WINDOW; exc = exc_clone_context(ea->exc, &ecc, ECC_WCONTEXT); - execute_function(NULL, exc, "Iconify", 0); + execute_function(NULL, exc, "Iconify", NULL, 0); exc_destroy_context(exc); return; } @@ -2260,7 +2264,7 @@ void HandleEnterNotify(const evh_args_t *ea) else if (edge_command) { fvwm_debug(__func__, "EC is: %s", edge_command); - execute_function(NULL, ea->exc, edge_command, 0); + execute_function(NULL, ea->exc, edge_command, NULL, 0); } else { @@ -2677,7 +2681,7 @@ void __handle_key(const evh_args_t *ea, Bool is_press) exc = exc_clone_context( ea->exc, &ecc, ECC_FW | ECC_WCONTEXT); } - execute_function(NULL, exc, action, 0); + execute_function(NULL, exc, action, NULL, 0); if (is_second_binding == False) { exc_destroy_context(exc); @@ -2821,7 +2825,8 @@ void HandleLeaveNotify(const evh_args_t *ea) } else if (edge_command_leave) { - execute_function(NULL, ea->exc, edge_command_leave, 0); + execute_function( + NULL, ea->exc, edge_command_leave, NULL, 0); } } @@ -3192,7 +3197,8 @@ void HandleMapRequestKeepRaised( { execute_function_override_window( NULL, ea->exc, - (char *)initial_map_command, 0, fw); + (char *)initial_map_command, NULL, 0, + fw); } MyXUngrabServer(dpy); @@ -3635,7 +3641,7 @@ void HandlePropertyNotify(const evh_args_t *ea) ecc.w.wcontext = C_WINDOW; exc = exc_clone_context( ea->exc, &ecc, ECC_FW | ECC_WCONTEXT); - execute_function(NULL, exc, urgency_action, 0); + execute_function(NULL, exc, urgency_action, NULL, 0); exc_destroy_context(exc); } break; diff --git a/fvwm/ewmh.c b/fvwm/ewmh.c index e4e84800..3983ded4 100644 --- a/fvwm/ewmh.c +++ b/fvwm/ewmh.c @@ -58,6 +58,7 @@ #include "libs/fvwm_x11.h" #include "libs/fvwmlib.h" #include "fvwm.h" +#include "cmdparser.h" #include "execcontext.h" #include "functions.h" #include "commands.h" @@ -2036,7 +2037,7 @@ void EWMH_fullscreen(FvwmWindow *fw) { fw->fullscreen.is_iconified = 1; execute_function_override_window( - NULL, NULL, "Iconify off", 0, fw); + NULL, NULL, "Iconify off", NULL, 0, fw); } if (IS_SHADED(fw)) { @@ -2045,7 +2046,7 @@ void EWMH_fullscreen(FvwmWindow *fw) fw->fullscreen.is_shaded = 1; fw->shade_anim_steps = 0; execute_function_override_window( - NULL, NULL, "WindowShade off", 0, fw); + NULL, NULL, "WindowShade off", NULL, 0, fw); fw->shade_anim_steps = sas; } SET_EWMH_FULLSCREEN(fw,True); @@ -2079,7 +2080,7 @@ void EWMH_fullscreen(FvwmWindow *fw) if (cmd[0] != 0) { SET_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw, 1); - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); SET_DISABLE_CONSTRAIN_SIZE_FULLSCREEN(fw, 0); } diff --git a/fvwm/ewmh_events.c b/fvwm/ewmh_events.c index 65b730c2..5989f40d 100644 --- a/fvwm/ewmh_events.c +++ b/fvwm/ewmh_events.c @@ -24,6 +24,7 @@ #include "fvwm.h" #include "externs.h" #include "execcontext.h" +#include "cmdparser.h" #include "functions.h" #include "misc.h" #include "screen.h" @@ -92,7 +93,7 @@ int ewmh_DesktopGeometry( return -1; } sprintf(action, "DesktopSize %ld %ld", width, height); - execute_function_override_window(NULL, NULL, action, 0, NULL); + execute_function_override_window(NULL, NULL, action, NULL, 0, NULL); return -1; } @@ -169,7 +170,7 @@ int ewmh_ActiveWindow( return 0; } execute_function_override_window( - NULL, NULL, "EWMHActivateWindowFunc", 0, fw); + NULL, NULL, "EWMHActivateWindowFunc", NULL, 0, fw); return 0; } @@ -185,7 +186,7 @@ int ewmh_CloseWindow( { return 0; } - execute_function_override_window(NULL, NULL, "Close", 0, fw); + execute_function_override_window(NULL, NULL, "Close", NULL, 0, fw); return 0; } @@ -290,7 +291,7 @@ int ewmh_WMDesktop( if (d == (unsigned long)-2 || d == (unsigned long)-1) { execute_function_override_window( - NULL, NULL, "Stick on", 0, fw); + NULL, NULL, "Stick on", NULL, 0, fw); } else if (d >= 0) { @@ -298,7 +299,7 @@ int ewmh_WMDesktop( IS_STICKY_ACROSS_DESKS(fw)) { execute_function_override_window( - NULL, NULL, "Stick off", 0, fw); + NULL, NULL, "Stick off", NULL, 0, fw); } if (fw->Desk != d) { @@ -449,18 +450,18 @@ int ewmh_MoveResize( if (!move) { sprintf(cmd, "WarpToWindow %i %i",x_warp,y_warp); - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); } if (move) { execute_function_override_window( - NULL, NULL, "Move", 0, fw); + NULL, NULL, "Move", NULL, 0, fw); } else { execute_function_override_window( - NULL, NULL, "Resize", 0, fw); + NULL, NULL, "Resize", NULL, 0, fw); } return 0; @@ -558,7 +559,7 @@ int ewmh_WMState( } sprintf(cmd,"Maximize on %i %i", max_horiz, max_vert); } - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); } return 0; } @@ -628,7 +629,7 @@ int ewmh_WMStateFullScreen( /* unmaximize will restore is_ewmh_fullscreen, * layer and apply_decor_change */ execute_function_override_window( - NULL, NULL, "Maximize off", 0, fw); + NULL, NULL, "Maximize off", NULL, 0, fw); } if ((IS_EWMH_FULLSCREEN(fw) && !DO_EWMH_USE_STACKING_HINTS(fw)) || @@ -638,7 +639,7 @@ int ewmh_WMStateFullScreen( /* On: if not raised by a layer cmd raise * Off: if lowered by a layer cmd raise */ execute_function_override_window( - NULL, NULL, "Raise", 0, fw); + NULL, NULL, "Raise", NULL, 0, fw); } } @@ -720,7 +721,7 @@ int ewmh_WMStateHidden( /* deiconify */ sprintf(cmd, "Iconify off"); } - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); } return 0; } @@ -1042,7 +1043,7 @@ int ewmh_WMStateShaded( cmd_arg == NET_WM_STATE_ADD)) { execute_function_override_window( - NULL, NULL, "Windowshade on", 0, fw); + NULL, NULL, "Windowshade on", NULL, 0, fw); } else if ( IS_SHADED(fw) && @@ -1050,7 +1051,7 @@ int ewmh_WMStateShaded( cmd_arg == NET_WM_STATE_REMOVE)) { execute_function_override_window( - NULL, NULL, "Windowshade off", 0, fw); + NULL, NULL, "Windowshade off", NULL, 0, fw); } } return 0; @@ -1441,7 +1442,7 @@ int ewmh_WMStateSticky( bool_arg == NET_WM_STATE_ADD) { execute_function_override_window( - NULL, NULL, "Stick on", 0, fw); + NULL, NULL, "Stick on", NULL, 0, fw); } else if ((IS_STICKY_ACROSS_PAGES(fw) || IS_STICKY_ACROSS_DESKS(fw)) && @@ -1449,7 +1450,7 @@ int ewmh_WMStateSticky( bool_arg == NET_WM_STATE_REMOVE)) { execute_function_override_window( - NULL, NULL, "Stick off", 1, fw); + NULL, NULL, "Stick off", NULL, 1, fw); } } return 0; diff --git a/fvwm/expand.c b/fvwm/expand.c index 3d366bb5..4d9e6b19 100644 --- a/fvwm/expand.c +++ b/fvwm/expand.c @@ -28,7 +28,9 @@ #include "fvwm.h" #include "externs.h" #include "cursor.h" +#include "cmdparser.h" #include "functions.h" +#include "expand.h" #include "misc.h" #include "move_resize.h" #include "screen.h" @@ -1206,7 +1208,7 @@ GOT_STRING: /* ---------------------------- interface functions ------------------------ */ char *expand_vars( - char *input, char *arguments[], Bool addto, Bool ismod, + char *input, cmdparser_context_t *pc, Bool addto, Bool ismod, cond_rc_t *cond_rc, const exec_context_t *exc) { int l, i, l2, n, k, j, m; @@ -1280,12 +1282,12 @@ char *expand_vars( if (name_has_dollar) { var = expand_vars( - var, arguments, addto, - ismod, cond_rc, exc); + var, pc, addto, ismod, + cond_rc, exc); } xlen = expand_args_extended( - var, arguments ? arguments[0] : - NULL, NULL); + var, pc->all_pos_args_string, + NULL); if (xlen < 0) { xlen = expand_vars_extended( @@ -1315,20 +1317,26 @@ char *expand_vars( case '8': case '9': case '*': + { + char *s; + if (input[i + 1] == '*') { - n = 0; + s = pc->all_pos_args_string; } else { - n = input[i + 1] - '0' + 1; + n = input[i + 1] - '0'; + s = pc->pos_arg_tokens[n]; } - if (arguments[n] != NULL) + n = input[i + 1] - '0'; + if (s != NULL) { - l2 += strlen(arguments[n]) - 2; + l2 += strlen(s) - 2; i++; } break; + } case '.': string = get_current_read_dir(); break; @@ -1459,12 +1467,11 @@ char *expand_vars( if (name_has_dollar) { var = expand_vars( - var, arguments, addto, - ismod, cond_rc, exc); + var, pc, addto, ismod, + cond_rc, exc); } xlen = expand_args_extended( - var, arguments ? - arguments[0] : NULL, + var, pc->all_pos_args_string, &out[j]); if (xlen < 0) { @@ -1509,19 +1516,23 @@ char *expand_vars( case '8': case '9': case '*': + { + char *s; + if (input[i + 1] == '*') { - n = 0; + s = pc->all_pos_args_string; } else { - n = input[i + 1] - '0' + 1; + n = input[i + 1] - '0'; + s = pc->pos_arg_tokens[n]; } - if (arguments[n] != NULL) + if (s != NULL) { - for (k = 0; arguments[n][k]; k++) + for (k = 0; s[k]; k++) { - out[j++] = arguments[n][k]; + out[j++] = s[k]; } i++; } @@ -1534,6 +1545,7 @@ char *expand_vars( i++; } break; + } case '.': string = get_current_read_dir(); is_string = True; diff --git a/fvwm/expand.h b/fvwm/expand.h index 087c3723..b1ec03fa 100644 --- a/fvwm/expand.h +++ b/fvwm/expand.h @@ -18,7 +18,7 @@ /* ---------------------------- interface functions ------------------------ */ char *expand_vars( - char *input, char *arguments[], Bool addto, Bool ismod, + char *input, cmdparser_context_t *pc, Bool addto, Bool ismod, cond_rc_t *cond_rc, const exec_context_t *exc); #endif /* FVWM_EXPAND_H */ diff --git a/fvwm/functable.c b/fvwm/functable.c index aa53a045..f003184b 100644 --- a/fvwm/functable.c +++ b/fvwm/functable.c @@ -84,7 +84,7 @@ const func_t func_table[] = /* - Operate on all windows matching the given condition */ CMD_ENT("animatedmove", CMD_AnimatedMove, F_ANIMATED_MOVE, - FUNC_NEEDS_WINDOW, CRS_MOVE), + FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, CRS_MOVE), /* - Like Move, but uses animation to move windows */ CMD_ENT("any", CMD_Any, F_ANY, 0, 0), @@ -381,7 +381,7 @@ const func_t func_table[] = /* - Bind or unbind a mouse button press to an fvwm action */ CMD_ENT("move", CMD_Move, F_MOVE, - FUNC_NEEDS_WINDOW, CRS_MOVE), + FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, CRS_MOVE), /* - Move a window */ CMD_ENT("movethreshold", CMD_MoveThreshold, F_MOVE_THRESHOLD, 0, 0), @@ -479,19 +479,20 @@ const func_t func_table[] = /* - Repeat (very unreliably) the last command, don't use */ CMD_ENT("resize", CMD_Resize, F_RESIZE, - FUNC_NEEDS_WINDOW, CRS_RESIZE), + FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, CRS_RESIZE), /* - Cause a window to be resized */ CMD_ENT("resizemaximize", CMD_ResizeMaximize, F_RESIZE_MAXIMIZE, - FUNC_NEEDS_WINDOW, CRS_RESIZE), + FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, CRS_RESIZE), /* - Resize a window and mark window as maximized */ CMD_ENT("resizemove", CMD_ResizeMove, F_RESIZEMOVE, - FUNC_NEEDS_WINDOW, CRS_RESIZE), + FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, CRS_RESIZE), /* - Resize and move in one operation */ CMD_ENT("resizemovemaximize", CMD_ResizeMoveMaximize, - F_RESIZEMOVE_MAXIMIZE, FUNC_NEEDS_WINDOW, CRS_RESIZE), + F_RESIZEMOVE_MAXIMIZE, FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, + CRS_RESIZE), /* - Resize and move in one operation and mark maximized */ CMD_ENT("restacktransients", CMD_RestackTransients, F_RESTACKTRANSIENTS, @@ -651,3 +652,56 @@ const func_t func_table[] = { "", 0, 0, 0, 0 } }; + +/* ---------------------------- local functions ---------------------------- */ + +/* + * do binary search on func list + */ +static int func_comp(const void *a, const void *b) +{ + return (strcmp((char *)a, ((func_t *)b)->keyword)); +} + +/* ---------------------------- interface functions ------------------------ */ + +const func_t *find_builtin_function(const char *func) +{ + static int nfuncs = 0; + func_t *ret_func; + char *temp; + char *s; + + if (!func || func[0] == 0) + { + return NULL; + } + + /* since a lot of lines in a typical rc are probably menu/func + * continues: */ + if (func[0]=='+' || (func[0] == ' ' && func[1] == '+')) + { + return &(func_table[0]); + } + + temp = fxstrdup(func); + for (s = temp; *s != 0; s++) + { + if (isupper(*s)) + { + *s = tolower(*s); + } + } + if (nfuncs == 0) + { + for ( ; (func_table[nfuncs]).action != NULL; nfuncs++) + { + /* nothing to do here */ + } + } + ret_func = (func_t *)bsearch( + temp, func_table, nfuncs, sizeof(func_t), func_comp); + free(temp); + + return ret_func; +} diff --git a/fvwm/functable.h b/fvwm/functable.h index 8f0ba7fb..c5bf6b9b 100644 --- a/fvwm/functable.h +++ b/fvwm/functable.h @@ -4,22 +4,39 @@ #define FVWM_FUNCTABLE_H /* ---------------------------- included header files ---------------------- */ -#include "functions.h" /* ---------------------------- global definitions ------------------------- */ -#define PRE_KEEPRC "keeprc" -#define PRE_REPEAT "repeat" -#define PRE_SILENT "silent" +#define PRE_KEEPRC "keeprc" +#define PRE_REPEAT "repeat" +#define PRE_SILENT "silent" /* ---------------------------- global macros ------------------------------ */ /* ---------------------------- type definitions --------------------------- */ +typedef unsigned int func_flags_t; + +/* used for parsing commands*/ +typedef struct +{ + char *keyword; +#ifdef __STDC__ + void (*action)(F_CMD_ARGS); +#else + void (*action)(); +#endif + short func_c; + func_flags_t flags; + int cursor; +} func_t; + /* ---------------------------- exported variables (globals) --------------- */ extern const func_t func_table[]; /* ---------------------------- interface functions ------------------------ */ +const func_t *find_builtin_function(const char *func); + #endif /* FVWM_FUNCTABLE_H */ diff --git a/fvwm/functable_complex.c b/fvwm/functable_complex.c new file mode 100644 index 00000000..34539014 --- /dev/null +++ b/fvwm/functable_complex.c @@ -0,0 +1,157 @@ +/* -*-c-*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ---------------------------- included header files ---------------------- */ + +#include "config.h" + +#include "libs/fvwmlib.h" +#include "libs/Picture.h" +#include "libs/Strings.h" + +#include "fvwm.h" +#include "cmdparser.h" +#include "execcontext.h" +#include "functable.h" +#include "functable.h" +#include "functable_complex.h" +#include "misc.h" +#include "screen.h" + +/* ---------------------------- local definitions -------------------------- */ + +/* ---------------------------- local macros ------------------------------- */ + +/* ---------------------------- imports ------------------------------------ */ + +/* ---------------------------- included code files ------------------------ */ + +/* ---------------------------- local types -------------------------------- */ + +/* ---------------------------- local variables ---------------------------- */ + +/* ---------------------------- exported variables (globals) --------------- */ + +/* ---------------------------- local functions ---------------------------- */ + +FvwmFunction *NewFvwmFunction(const char *name) +{ + FvwmFunction *tmp; + + tmp = fxmalloc(sizeof *tmp); + tmp->next_func = Scr.functions; + tmp->first_item = NULL; + tmp->last_item = NULL; + tmp->name = stripcpy(name); + tmp->use_depth = 0; + Scr.functions = tmp; + + return tmp; +} + +void DestroyFunction(FvwmFunction *func) +{ + FunctionItem *fi,*tmp2; + FvwmFunction *tmp, *prev; + + if (func == NULL) + { + return; + } + + tmp = Scr.functions; + prev = NULL; + while (tmp && tmp != func) + { + prev = tmp; + tmp = tmp->next_func; + } + if (tmp != func) + { + return; + } + + if (func->use_depth != 0) + { + fvwm_debug( + "Function %s is in use (depth %d)", func->name, + func->use_depth); + return; + } + + if (prev == NULL) + { + Scr.functions = func->next_func; + } + else + { + prev->next_func = func->next_func; + } + + free(func->name); + + fi = func->first_item; + while (fi != NULL) + { + tmp2 = fi->next_item; + if (fi->action != NULL) + { + free(fi->action); + } + free(fi); + fi = tmp2; + } + free(func); + + return; +} + +/* ---------------------------- interface functions ------------------------ */ + +/* find_complex_function expects a token as the input. Make sure you have used + * GetNextToken before passing a function name to remove quotes */ +FvwmFunction *find_complex_function(const char *function_name) +{ + FvwmFunction *func; + + if (function_name == NULL || *function_name == 0) + { + return NULL; + } + func = Scr.functions; + while (func != NULL) + { + if (func->name != NULL) + { + if (strcasecmp(function_name, func->name) == 0) + { + return func; + } + } + func = func->next_func; + } + + return NULL; +} +Bool functions_is_complex_function(const char *function_name) +{ + if (find_complex_function(function_name) != NULL) + { + return True; + } + + return False; +} diff --git a/fvwm/functable_complex.h b/fvwm/functable_complex.h new file mode 100644 index 00000000..f3d50483 --- /dev/null +++ b/fvwm/functable_complex.h @@ -0,0 +1,55 @@ +/* -*-c-*- */ + +#ifndef FVWM_FUNCTABLE_COMPLEX_H +#define FVWM_FUNCTABLE_COMPLEX_H + +/* ---------------------------- included header files ---------------------- */ + +/* ---------------------------- global definitions ------------------------- */ + +/* ---------------------------- global macros ------------------------------ */ + +/* ---------------------------- type definitions --------------------------- */ + +typedef struct FunctionItem +{ + struct FvwmFunction *func; /* the function this item is in */ + struct FunctionItem *next_item; /* next function item */ + char condition; /* the character string displayed on + * left*/ + char *action; /* action to be performed */ + short type; /* type of built in function */ + func_flags_t flags; +} FunctionItem; + +typedef struct FvwmFunction +{ + struct FvwmFunction *next_func; /* next in list of root menus */ + FunctionItem *first_item; /* first item in function */ + FunctionItem *last_item; /* last item in function */ + char *name; /* function name */ + int use_depth; +} FvwmFunction; + +/* Types of events for the FUNCTION builtin */ +typedef enum +{ + CF_IMMEDIATE = 'i', + CF_LATE_IMMEDIATE = 'j', + CF_MOTION = 'm', + CF_HOLD = 'h', + CF_CLICK = 'c', + CF_DOUBLE_CLICK = 'd', + CF_TIMEOUT = '-' +} cfunc_action_t; + +/* ---------------------------- exported variables (globals) --------------- */ + +/* ---------------------------- interface functions ------------------------ */ + +FvwmFunction *NewFvwmFunction(const char *name); +void DestroyFunction(FvwmFunction *func); +FvwmFunction *find_complex_function(const char *function_name); +Bool functions_is_complex_function(const char *function_name); + +#endif /* FVWM_FUNCTABLE_COMPLEX_H */ diff --git a/fvwm/functions.c b/fvwm/functions.c index a40718cd..060eaff3 100644 --- a/fvwm/functions.c +++ b/fvwm/functions.c @@ -22,6 +22,9 @@ #include "config.h" #include <stdio.h> +#if 1 /*!!!*/ +#include <assert.h> +#endif #include "libs/fvwm_x11.h" #include "libs/fvwmlib.h" @@ -36,9 +39,13 @@ #include "externs.h" #include "cursor.h" #include "execcontext.h" +#include "functable.h" +#include "functable_complex.h" +#include "cmdparser.h" +#include "cmdparser_hooks.h" +#include "cmdparser_old.h" #include "functions.h" #include "commands.h" -#include "functable.h" #include "events.h" #include "modconf.h" #include "module_list.h" @@ -58,45 +65,19 @@ /* ---------------------------- local types -------------------------------- */ -typedef struct FunctionItem -{ - struct FvwmFunction *func; /* the function this item is in */ - struct FunctionItem *next_item; /* next function item */ - char condition; /* the character string displayed on - * left*/ - char *action; /* action to be performed */ - short type; /* type of built in function */ - FUNC_FLAGS_TYPE flags; -} FunctionItem; - -typedef struct FvwmFunction -{ - struct FvwmFunction *next_func; /* next in list of root menus */ - FunctionItem *first_item; /* first item in function */ - FunctionItem *last_item; /* last item in function */ - char *name; /* function name */ - int use_depth; -} FvwmFunction; - -/* Types of events for the FUNCTION builtin */ -typedef enum -{ - CF_IMMEDIATE = 'i', - CF_LATE_IMMEDIATE = 'j', - CF_MOTION = 'm', - CF_HOLD = 'h', - CF_CLICK = 'c', - CF_DOUBLE_CLICK = 'd', - CF_TIMEOUT = '-' -} cfunc_action_t; - /* ---------------------------- forward declarations ----------------------- */ static void execute_complex_function( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - Bool *desperate, Bool has_ref_window_moved); + cond_rc_t *cond_rc, const exec_context_t *exc, cmdparser_context_t *pc, + FvwmFunction *func, Bool has_ref_window_moved); + + /* ---------------------------- local variables ---------------------------- */ -/* ---------------------------- local variables ---------------------------- */ +/* Temporary instance of the hooks functions used in this file. The goal is + * to remove all parsing and expansion from functions.c and move it into a + * separate, replaceable file. */ + +static const cmdparser_hooks_t *cmdparser_hooks = NULL; /* ---------------------------- exported variables (globals) --------------- */ @@ -294,120 +275,85 @@ static Bool DeferExecution( return False; } -/* -** do binary search on func list -*/ -static int func_comp(const void *a, const void *b) -{ - return (strcmp((char *)a, ((func_t *)b)->keyword)); -} - -static const func_t *find_builtin_function(char *func) -{ - static int nfuncs = 0; - func_t *ret_func; - char *temp; - char *s; - - if (!func || func[0] == 0) - { - return NULL; - } - - /* since a lot of lines in a typical rc are probably menu/func - * continues: */ - if (func[0]=='+' || (func[0] == ' ' && func[1] == '+')) - { - return &(func_table[0]); - } - - temp = fxstrdup(func); - for (s = temp; *s != 0; s++) - { - if (isupper(*s)) - { - *s = tolower(*s); - } - } - if (nfuncs == 0) - { - for ( ; (func_table[nfuncs]).action != NULL; nfuncs++) - { - /* nothing to do here */ - } - } - ret_func = (func_t *)bsearch( - temp, func_table, nfuncs, sizeof(func_t), func_comp); - free(temp); - - return ret_func; -} - -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 void __execute_command_line( + cond_rc_t *cond_rc, const exec_context_t *exc, char *xaction, + cmdparser_context_t *caller_pc, + func_flags_t exec_flags, char *all_pos_args_string, + char *pos_arg_tokens[], Bool has_ref_window_moved) { - static int func_depth = 0; + cmdparser_context_t pc; 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]; + char *err_cline; + const char *err_func; + cmdparser_execute_type_t exec_type; const func_t *bif; - Bool set_silent; - Bool must_free_function = False; - Bool must_free_expaction = False; - Bool do_keep_rc = False; + FvwmFunction *complex_function; + int set_silent; + int do_keep_rc = 0; /* needed to be able to avoid resize to use moved windows for base */ extern Window PressedW; Window dummy_w; + int rc; - if (!action) - { - return; - } - /* ignore whitespace at the beginning of all config lines */ - action = SkipSpaces(action, NULL, 0); - if (!action || action[0] == 0) +#if 1 /*!!!*/ + fprintf(stderr, "%s: cpc %p, xaction '%s'\n", __func__, caller_pc, xaction); +#endif + set_silent = 0; + /* generate a parsing context; this *must* be destroyed before + * returning */ + rc = cmdparser_hooks->create_context( + &pc, caller_pc, xaction, all_pos_args_string, pos_arg_tokens); + if (rc != 0) { - /* impossibly short command */ - return; + goto fn_exit; } - if (action[0] == '#') +cmdparser_hooks->debug(&pc, "!!!A"); + rc = cmdparser_hooks->handle_line_start(&pc); + if (rc != 0) { - /* a comment */ - return; + goto fn_exit; } +cmdparser_hooks->debug(&pc, "!!!B"); - func_depth++; - if (func_depth > MAX_FUNCTION_DEPTH) - { - fvwm_debug(__func__, - "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++) + cmdparser_prefix_flags_t flags; + + flags = cmdparser_hooks->handle_line_prefix(&pc); +cmdparser_hooks->debug(&pc, "!!!BA"); + if (flags & CP_PREFIX_MINUS) { - arguments[j] = args[j]; +#if 1 /*!!!*/ +fprintf(stderr, "!!!do not expand\n"); +#endif + exec_flags |= FUNC_DONT_EXPAND_COMMAND; } - } - else - { - for (j = 0; j < 11; j++) + if (flags & CP_PREFIX_SILENT) + { +#if 1 /*!!!*/ +fprintf(stderr, "!!!is silent\n"); +#endif + if (Scr.flags.are_functions_silent == 0) + { + set_silent = 1; + Scr.flags.are_functions_silent = 1; + } + } + if (flags & CP_PREFIX_KEEPRC) + { +#if 1 /*!!!*/ +fprintf(stderr, "!!!do keeprc\n"); +#endif + do_keep_rc = 1; + } + if (pc.cline == NULL) { - arguments[j] = NULL; + goto fn_exit; } + err_cline = pc.cline; } +cmdparser_hooks->debug(&pc, "!!!C"); if (exc->w.fw == NULL || IS_EWMH_DESKTOP(FW_W(exc->w.fw))) { @@ -444,50 +390,7 @@ static void __execute_function( 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) + if (cond_rc == NULL || do_keep_rc) { condrc_init(&dummy_rc); func_rc = &dummy_rc; @@ -496,42 +399,22 @@ static void __execute_function( { 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; + const char *func; - while (*tmp && !isspace(*tmp)) + func = cmdparser_hooks->parse_command_name(&pc, func_rc, exc); + if (func != NULL) { - tmp++; +cmdparser_hooks->debug(&pc, "!!!D"); + bif = find_builtin_function(func); + err_func = func; } - *tmp = 0; -#endif - bif = find_builtin_function(function); - must_free_function = True; - } - else - { - bif = NULL; - if (function) + else { - free(function); +cmdparser_hooks->debug(&pc, "!!!E"); + bif = NULL; + err_func = ""; } - function = ""; } if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor && @@ -539,177 +422,163 @@ static void __execute_function( { fvwm_debug(__func__, "Command can not be added to a decor; executing" - " command now: '%s'", action); + " command now: '%s'", err_cline); } if (!(exec_flags & FUNC_DONT_EXPAND_COMMAND)) { - expaction = expand_vars( - taction, arguments, (bif) ? - !!(bif->flags & FUNC_ADD_TO) : - False, (taction[0] == '*'), func_rc, exc); - must_free_expaction = True; - if (func_depth <= 1) + cmdparser_hooks->expand_command_line( + &pc, (bif) ? !!(bif->flags & FUNC_ADD_TO) : False, + func_rc, exc); +cmdparser_hooks->debug(&pc, "!!!F"); + if (pc.call_depth <= 1) { - must_free_expaction = set_repeat_data(expaction, REPEAT_COMMAND, bif); + Bool do_free_string_ourselves; + + do_free_string_ourselves = set_repeat_data( + pc.expline, REPEAT_COMMAND, bif); + if (do_free_string_ourselves == False) + { + cmdparser_hooks->release_expanded_line(&pc); +cmdparser_hooks->debug(&pc, "!!!F"); + } } } - else - { - expaction = taction; - must_free_expaction = False; - } +#if 1 /*!!!*/ +fprintf(stderr, "!!!pc.cline: '%s'\n", pc.cline); +#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] == '*') + exec_type = cmdparser_hooks->find_something_to_execute( + &pc, &bif, &complex_function); +cmdparser_hooks->debug(&pc, "!!!H"); +fprintf(stderr, "!!!exec_type %d\n", exec_type); + switch (exec_type) { - if (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) - { - fvwm_debug(__func__, - "Command can not be added to a decor;" - " executing command now: '%s'", expaction); - } - - /* process a module config command */ - ModuleConfig(expaction); - } - else + case CP_EXECTYPE_BUILTIN_FUNCTION: { const exec_context_t *exc2; exec_context_changes_t ecc; exec_context_change_mask_t mask; +cmdparser_hooks->debug(&pc, "!!!J"); +#if 1 /*!!!*/ + assert(bif && bif->func_c != F_FUNCTION); +#endif +#if 1 /*!!!*/ +fprintf(stderr, "!!!pc.cline: '%s'\n", pc.cline); +#endif 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) + if ( + (bif->flags & FUNC_NEEDS_WINDOW) && + !(exec_flags & FUNC_DONT_DEFER)) { - char *runaction; - Bool rc = False; + Bool rc; - 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)) + rc = DeferExecution( + &ecc, &mask, bif->cursor, exc->x.elast->type, + (bif->flags & FUNC_ALLOW_UNMANAGED)); + if (rc == True) { - /* 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); + break; } +#if 1 /*!!!*/ +fprintf(stderr, "!!!deferred: %d\n", rc); +#endif } - else + else if ( + (bif->flags & FUNC_NEEDS_WINDOW) && + !__context_has_window( + exc, bif->flags & FUNC_ALLOW_UNMANAGED)) { - 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_debug(__func__, - "No such command '%s'", - function); - } - } - exc_destroy_context(exc2); +#if 1 /*!!!*/ +fprintf(stderr, "!!!skip no-defer\n"); +#endif + /* no context window and not allowed to defer, + * skip command */ + break; } + exc2 = exc_clone_context(exc, &ecc, mask); + dummy_w = PressedW; + if ( + has_ref_window_moved && + (bif->flags & FUNC_IS_MOVE_TYPE)) + { +#if 1 /*!!!*/ +fprintf(stderr, "!!!erase PressedW\n"); +#endif + PressedW = None; + } +#if 1 /*!!!*/ +fprintf(stderr, "!!!execute '%s'\n", bif->keyword); +#endif + bif->action(func_rc, exc2, pc.cline, &pc); + PressedW = dummy_w; + exc_destroy_context(exc2); + break; } - - if (set_silent) - { - Scr.flags.are_functions_silent = 0; - } - if (cond_rc != NULL) - { - cond_rc->break_levels = func_rc->break_levels; - } - if (must_free_function) + case CP_EXECTYPE_COMPLEX_FUNCTION: { - free(function); + 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; + exc2 = exc_clone_context(exc, &ecc, mask); + execute_complex_function( + func_rc, exc2, &pc, complex_function, + has_ref_window_moved); + exc_destroy_context(exc2); + break; } - /* Free the string allocated by expand_vars earlier in this function. */ - if (must_free_expaction) - { - free(expaction); + case CP_EXECTYPE_COMPLEX_FUNCTION_DOES_NOT_EXIST: + fvwm_debug( + __func__, "No such function %s", + pc.complex_function_name); + break; + case CP_EXECTYPE_MODULECONFIG: + /* 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 (Scr.cur_decor && Scr.cur_decor != &Scr.DefaultDecor) + { + fvwm_debug( + __func__, "Command can not be added to a decor;" + " executing command now: '%s'", pc.expline); + } + /* process a module config command */ + ModuleConfig(pc.expline); + goto fn_exit; + case CP_EXECTYPE_UNKNOWN: + if (executeModuleDesperate(func_rc, exc, pc.cline, &pc) == + NULL && *err_func != 0 && !set_silent) + { + fvwm_debug(__func__, "No such command '%s'", err_func); + } + break; +#if 1 /*!!!*/ + default: + assert(!"bad exec_type"); +#endif } - func_depth--; - - return; -} - -/* find_complex_function expects a token as the input. Make sure you have used - * GetNextToken before passing a function name to remove quotes */ -static FvwmFunction *find_complex_function(const char *function_name) -{ - FvwmFunction *func; - if (function_name == NULL || *function_name == 0) + fn_exit: + if (func_rc != NULL && cond_rc != NULL) { - return NULL; + cond_rc->break_levels = func_rc->break_levels; } - func = Scr.functions; - while (func != NULL) + if (set_silent) { - if (func->name != NULL) - { - if (strcasecmp(function_name, func->name) == 0) - { - return func; - } - } - func = func->next_func; + Scr.flags.are_functions_silent = 0; } + cmdparser_hooks->destroy_context(&pc); - return NULL; + return; } /* @@ -801,7 +670,9 @@ static cfunc_action_t CheckActionType( static void __run_complex_function_items( cond_rc_t *cond_rc, char cond, FvwmFunction *func, - const exec_context_t *exc, char *args[], Bool has_ref_window_moved) + const exec_context_t *exc, cmdparser_context_t *caller_pc, + char *all_pos_args_string, char *pos_arg_tokens[], + Bool has_ref_window_moved) { char c; FunctionItem *fi; @@ -825,9 +696,10 @@ static void __run_complex_function_items( } if (c == cond) { - __execute_function( - cond_rc, exc, fi->action, FUNC_DONT_DEFER, - args, has_ref_window_moved); + __execute_command_line( + cond_rc, exc, fi->action, caller_pc, + FUNC_DONT_DEFER, all_pos_args_string, + pos_arg_tokens, has_ref_window_moved); if (!has_ref_window_moved && PressedW && XTranslateCoordinates( dpy, PressedW , Scr.Root, 0, 0, &x, &y, @@ -843,7 +715,8 @@ static void __run_complex_function_items( } static void __cf_cleanup( - int *depth, char **arguments, cond_rc_t *cond_rc) + FvwmFunction *func, int *depth, char *all_pos_args_string, + char **pos_arg_tokens, cond_rc_t *cond_rc) { int i; @@ -852,11 +725,15 @@ static void __cf_cleanup( { Scr.flags.is_executing_complex_function = 0; } - for (i = 0; i < 11; i++) + if (all_pos_args_string != NULL) + { + free(all_pos_args_string); + } + for (i = 0; i < CMDPARSER_NUM_POS_ARGS; i++) { - if (arguments[i] != NULL) + if (pos_arg_tokens[i] != NULL) { - free(arguments[i]); + free(pos_arg_tokens[i]); } } if (cond_rc->break_levels > 0) @@ -868,8 +745,8 @@ static void __cf_cleanup( } static void execute_complex_function( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - Bool *desperate, Bool has_ref_window_moved) + cond_rc_t *cond_rc, const exec_context_t *exc, cmdparser_context_t *pc, + FvwmFunction *func, Bool has_ref_window_moved) { cond_rc_t tmp_rc; cfunc_action_t type = CF_MOTION; @@ -881,14 +758,15 @@ static void execute_complex_function( Bool NeedsTarget = False; Bool ImmediateNeedsTarget = False; int has_immediate = 0; + int do_ungrab = 1; int do_run_late_immediate = 0; int do_allow_unmanaged = FUNC_ALLOW_UNMANAGED; int do_allow_unmanaged_immediate = FUNC_ALLOW_UNMANAGED; - char *arguments[11], *taction; - char *func_name; + char *all_pos_args_string; + char *pos_arg_tokens[CMDPARSER_NUM_POS_ARGS]; + char *taction; int x, y ,i; XEvent d; - FvwmFunction *func; static int depth = 0; const exec_context_t *exc2; exec_context_changes_t ecc; @@ -897,6 +775,9 @@ static void execute_complex_function( int button; XEvent *te; +#if 1 /*!!!*/ + assert(func != NULL); +#endif if (cond_rc == NULL) { condrc_init(&tmp_rc); @@ -908,54 +789,33 @@ static void execute_complex_function( ecc.w.fw = exc->w.fw; ecc.w.w = exc->w.w; ecc.w.wcontext = exc->w.wcontext; - /* find_complex_function expects a token, not just a quoted string */ - func_name = PeekToken(action, &taction); - if (!func_name) - { - return; - } - func = find_complex_function(func_name); - if (func == NULL) - { - if (*desperate == 0) - { - fvwm_debug(__func__, "No such function %s", - action); - } - return; - } - if (!depth) - { - Scr.flags.is_executing_complex_function = 1; - } + Scr.flags.is_executing_complex_function = 1; depth++; - *desperate = 0; /* duplicate the whole argument list for use as '$*' */ - if (taction) + taction = pc->cline; + if (taction && *taction) { - arguments[0] = fxstrdup(taction); + all_pos_args_string = fxstrdup(taction); /* strip trailing newline */ - if (arguments[0][0]) + if (all_pos_args_string[0]) { - int l= strlen(arguments[0]); + int l = strlen(all_pos_args_string); - if (arguments[0][l - 1] == '\n') + if (all_pos_args_string[l - 1] == '\n') { - arguments[0][l - 1] = 0; + all_pos_args_string[l - 1] = 0; } } /* Get the argument list */ - for (i = 1; i < 11; i++) + for (i = 0; i < CMDPARSER_NUM_POS_ARGS; i++) { - taction = GetNextToken(taction, &arguments[i]); + taction = GetNextToken(taction, &pos_arg_tokens[i]); } } else { - for (i = 0; i < 11; i++) - { - arguments[i] = NULL; - } + all_pos_args_string = 0; + memset(pos_arg_tokens, 0, sizeof(pos_arg_tokens)); } /* In case we want to perform an action on a button press, we * need to fool other routines */ @@ -992,11 +852,9 @@ static void execute_complex_function( { if (DeferExecution( &ecc, &mask, CRS_SELECT, trigger_evtype, - do_allow_unmanaged_immediate)) + do_allow_unmanaged_immediate) == True) { - func->use_depth--; - __cf_cleanup(&depth, arguments, cond_rc); - return; + goto ungrab_exit; } NeedsTarget = False; } @@ -1011,17 +869,18 @@ static void execute_complex_function( * button release would go to the application below. */ if (!GrabEm(CRS_NONE, GRAB_NORMAL)) { - func->use_depth--; - fvwm_debug(__func__, "Grab failed in function %s," - " unable to execute immediate action", action); - __cf_cleanup(&depth, arguments, cond_rc); - return; + fvwm_debug( + __func__, + "Grab failed, unable to execute immediate action"); + goto ungrab_exit; } + do_ungrab = 1; if (has_immediate) { exc2 = exc_clone_context(exc, &ecc, mask); __run_complex_function_items( - cond_rc, CF_IMMEDIATE, func, exc2, arguments, + cond_rc, CF_IMMEDIATE, func, exc2, pc, + all_pos_args_string, pos_arg_tokens, has_ref_window_moved); exc_destroy_context(exc2); } @@ -1054,10 +913,7 @@ static void execute_complex_function( if (!Persist || cond_rc->break_levels != 0) { - func->use_depth--; - __cf_cleanup(&depth, arguments, cond_rc); - UngrabEm(GRAB_NORMAL); - return; + goto ungrab_exit; } /* Only defer execution if there is a possibility of needing @@ -1066,12 +922,9 @@ static void execute_complex_function( { if (DeferExecution( &ecc, &mask, CRS_SELECT, trigger_evtype, - do_allow_unmanaged)) + do_allow_unmanaged) == True) { - func->use_depth--; - __cf_cleanup(&depth, arguments, cond_rc); - UngrabEm(GRAB_NORMAL); - return; + goto ungrab_exit; } } @@ -1107,7 +960,8 @@ static void execute_complex_function( { exc2 = exc_clone_context(exc, &ecc, mask); __run_complex_function_items( - cond_rc, CF_LATE_IMMEDIATE, func, exc2, arguments, + cond_rc, CF_LATE_IMMEDIATE, func, exc2, pc, + all_pos_args_string, pos_arg_tokens, has_ref_window_moved); exc_destroy_context(exc2); do_run_late_immediate = 0; @@ -1162,14 +1016,11 @@ static void execute_complex_function( } } -#ifdef BUGGY_CODE /* domivogt (11-Apr-2000): The pointer ***must not*** be ungrabbed * here. If it is, any window that the mouse enters during the * function will receive MotionNotify events with a button held down! * The results are unpredictable. E.g. rxvt interprets the * ButtonMotion as user input to select text. */ - UngrabEm(GRAB_NORMAL); -#endif fev_set_evpos(&d, x, y); fev_fake_event(&d); ecc.x.etrigger = &d; @@ -1179,135 +1030,58 @@ static void execute_complex_function( if (do_run_late_immediate) { __run_complex_function_items( - cond_rc, CF_LATE_IMMEDIATE, func, exc2, arguments, + cond_rc, CF_LATE_IMMEDIATE, func, exc2, pc, + all_pos_args_string, pos_arg_tokens, has_ref_window_moved); } __run_complex_function_items( - cond_rc, type, func, exc2, arguments, has_ref_window_moved); + cond_rc, type, func, exc2, pc, all_pos_args_string, + pos_arg_tokens, has_ref_window_moved); exc_destroy_context(exc2); - /* This is the right place to ungrab the pointer (see comment above). - */ - func->use_depth--; - __cf_cleanup(&depth, arguments, cond_rc); - UngrabEm(GRAB_NORMAL); - - return; -} - -/* - * create a new FvwmFunction - */ -static FvwmFunction *NewFvwmFunction(const char *name) -{ - FvwmFunction *tmp; - - tmp = fxmalloc(sizeof *tmp); - tmp->next_func = Scr.functions; - tmp->first_item = NULL; - tmp->last_item = NULL; - tmp->name = stripcpy(name); - tmp->use_depth = 0; - Scr.functions = tmp; - - return tmp; -} - -static void DestroyFunction(FvwmFunction *func) -{ - FunctionItem *fi,*tmp2; - FvwmFunction *tmp, *prev; - if (func == NULL) - { - return; - } - - tmp = Scr.functions; - prev = NULL; - while (tmp && tmp != func) - { - prev = tmp; - tmp = tmp->next_func; - } - if (tmp != func) - { - return; - } - - if (func->use_depth != 0) - { - fvwm_debug(__func__, - "Function %s is in use (depth %d)", func->name, - func->use_depth); - return; - } - - if (prev == NULL) + ungrab_exit: + __cf_cleanup( + func, &depth, all_pos_args_string, pos_arg_tokens, cond_rc); + if (do_ungrab) { - Scr.functions = func->next_func; - } - else - { - prev->next_func = func->next_func; - } - - free(func->name); - - fi = func->first_item; - while (fi != NULL) - { - tmp2 = fi->next_item; - if (fi->action != NULL) - { - free(fi->action); - } - free(fi); - fi = tmp2; + UngrabEm(GRAB_NORMAL); } - free(func); return; } /* ---------------------------- interface functions ------------------------ */ -Bool functions_is_complex_function(const char *function_name) +void functions_init(void) { - if (find_complex_function(function_name) != NULL) - { - return True; - } + cmdparser_hooks = cmdparser_old_get_hooks(); - return False; + return; } -void execute_function( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - FUNC_FLAGS_TYPE exec_flags) +void execute_function(F_CMD_ARGS, func_flags_t exec_flags) { - __execute_function(cond_rc, exc, action, exec_flags, NULL, False); + __execute_command_line(F_PASS_ARGS, exec_flags, NULL, NULL, False); return; } void execute_function_override_wcontext( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - FUNC_FLAGS_TYPE exec_flags, int wcontext) + F_CMD_ARGS, func_flags_t exec_flags, int wcontext) { const exec_context_t *exc2; exec_context_changes_t ecc; ecc.w.wcontext = wcontext; exc2 = exc_clone_context(exc, &ecc, ECC_WCONTEXT); - execute_function(cond_rc, exc2, action, exec_flags); + execute_function(F_PASS_ARGS_WITH_EXC(exc2), exec_flags); exc_destroy_context(exc2); return; } void execute_function_override_window( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - FUNC_FLAGS_TYPE exec_flags, FvwmWindow *fw) + F_CMD_ARGS, func_flags_t exec_flags, FvwmWindow *fw) { const exec_context_t *exc2; exec_context_changes_t ecc; @@ -1335,13 +1109,13 @@ void execute_function_override_window( exc2 = exc_create_context( &ecc, ECC_TYPE | ECC_FW | ECC_W | ECC_WCONTEXT); } - execute_function(cond_rc, exc2, action, exec_flags); + execute_function(F_PASS_ARGS_WITH_EXC(exc2), exec_flags); exc_destroy_context(exc2); return; } -void find_func_t(char *action, short *func_t, unsigned char *flags) +void find_func_t(char *action, short *ret_func_c, func_flags_t *flags) { int j, len = 0; char *endtok = action; @@ -1365,9 +1139,9 @@ void find_func_t(char *action, short *func_t, unsigned char *flags) { matched=True; /* found key word */ - if (func_t) + if (ret_func_c) { - *func_t = func_table[j].func_t; + *ret_func_c = func_table[j].func_c; } if (flags) { @@ -1382,9 +1156,9 @@ void find_func_t(char *action, short *func_t, unsigned char *flags) } /* No clue what the function is. Just return "BEEP" */ } - if (func_t) + if (ret_func_c) { - *func_t = F_BEEP; + *ret_func_c = F_BEEP; } if (flags) { diff --git a/fvwm/functions.h b/fvwm/functions.h index b127626f..b87256a8 100644 --- a/fvwm/functions.h +++ b/fvwm/functions.h @@ -6,6 +6,8 @@ /* ---------------------------- included header files ---------------------- */ #include "execcontext.h" +#include "functable.h" +#include "functable_complex.h" /* ---------------------------- global definitions ------------------------- */ @@ -17,10 +19,12 @@ typedef enum FUNC_ADD_TO = 0x04, FUNC_DECOR = 0x08, FUNC_ALLOW_UNMANAGED = 0x10, + /* only used in __execute_command_line */ + FUNC_IS_MOVE_TYPE = 0x20, /* only to be passed to execute_function() */ - FUNC_IS_UNMANAGED = 0x20, - FUNC_DONT_EXPAND_COMMAND = 0x40, - FUNC_DONT_DEFER = 0x80, + FUNC_IS_UNMANAGED = 0x40, + FUNC_DONT_EXPAND_COMMAND = 0x80, + FUNC_DONT_DEFER = 0x100, /* The values are not used internally but by external scripts parsing * functable. Hence all the values below are 0 @@ -51,36 +55,17 @@ typedef enum /* ---------------------------- type definitions --------------------------- */ -/* used for parsing commands*/ -typedef struct -{ - char *keyword; -#ifdef __STDC__ - void (*action)(F_CMD_ARGS); -#else - void (*action)(); -#endif - short func_t; - FUNC_FLAGS_TYPE flags; - int cursor; -} func_t; - /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- interface functions ------------------------ */ -void find_func_t( - char *action, short *func_t, FUNC_FLAGS_TYPE *flags); -Bool functions_is_complex_function( - const char *function_name); -void execute_function( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - FUNC_FLAGS_TYPE exec_flags); +/* needs to be called before any command line can be executed */ +void functions_init(void); +void find_func_t(char *action, short *func_t, func_flags_t *flags); +void execute_function(F_CMD_ARGS, func_flags_t exec_flags); void execute_function_override_wcontext( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - FUNC_FLAGS_TYPE exec_flags, int wcontext); + F_CMD_ARGS, func_flags_t exec_flags, int wcontext); void execute_function_override_window( - cond_rc_t *cond_rc, const exec_context_t *exc, char *action, - FUNC_FLAGS_TYPE exec_flags, FvwmWindow *fw); + F_CMD_ARGS, func_flags_t exec_flags, FvwmWindow *fw); #endif /* FVWM_FUNCTIONS_H */ diff --git a/fvwm/fvwm.h b/fvwm/fvwm.h index bdc04ee8..4013f1db 100644 --- a/fvwm/fvwm.h +++ b/fvwm/fvwm.h @@ -41,6 +41,7 @@ #include "libs/FScreen.h" #include "window_flags.h" #include "condrc.h" +#include "cmdparser.h" /* ---------------------------- global definitions ------------------------- */ @@ -59,9 +60,9 @@ /* Macro for args passed to fvwm commands... */ #define F_CMD_ARGS \ - cond_rc_t *cond_rc, const exec_context_t *exc, char *action -#define F_PASS_ARGS cond_rc, exc, action -#define FUNC_FLAGS_TYPE unsigned char + cond_rc_t *cond_rc, const exec_context_t *exc, char *action, cmdparser_context_t *pc +#define F_PASS_ARGS cond_rc, exc, action, pc +#define F_PASS_ARGS_WITH_EXC(new_exc) cond_rc, (new_exc), action, pc /* access macros */ #define FW_W_FRAME(fw) ((fw)->wins.frame) @@ -426,48 +427,6 @@ struct name_condition /* matches to namelists in this list are struct name_condition *next; }; -/* Window mask for Circulate and Direction functions */ -typedef struct WindowConditionMask -{ - struct - { - unsigned do_accept_focus : 1; - unsigned do_check_desk : 1; - unsigned do_check_screen : 1; - unsigned do_check_cond_desk : 1; - unsigned do_check_desk_and_global_page : 1; - unsigned do_check_desk_and_page : 1; - unsigned do_check_global_page : 1; - unsigned do_check_overlapped : 1; - unsigned do_check_page : 1; - unsigned do_not_check_screen : 1; - unsigned needs_current_desk : 1; - unsigned needs_current_desk_and_global_page : 1; - unsigned needs_current_desk_and_page : 1; - unsigned needs_current_global_page : 1; - unsigned needs_current_page : 1; -#define NEEDS_ANY 0 -#define NEEDS_TRUE 1 -#define NEEDS_FALSE 2 - unsigned needs_focus : 2; - unsigned needs_overlapped : 2; - unsigned needs_pointer : 2; - unsigned needs_same_layer : 1; - unsigned use_circulate_hit : 1; - unsigned use_circulate_hit_icon : 1; - unsigned use_circulate_hit_shaded : 1; - unsigned use_do_accept_focus : 1; - } my_flags; - window_flags flags; - window_flags flag_mask; - struct name_condition *name_condition; - int layer; - int desk; - struct monitor *screen; - int placed_by_button_mask; - int placed_by_button_set_mask; -} WindowConditionMask; - typedef struct pl_penalty_struct { float normal; diff --git a/fvwm/fvwm3.c b/fvwm/fvwm3.c index d4aa8838..8ac80a06 100644 --- a/fvwm/fvwm3.c +++ b/fvwm/fvwm3.c @@ -555,7 +555,7 @@ void Done(int restart, char *command) ecc.type = restart ? EXCT_TORESTART : EXCT_QUIT; ecc.w.wcontext = C_ROOT; exc = exc_create_context(&ecc, ECC_TYPE | ECC_WCONTEXT); - execute_function(NULL, exc, action, 0); + execute_function(NULL, exc, action, NULL, 0); exc_destroy_context(exc); free(action); } @@ -1402,7 +1402,7 @@ static void SetRCDefaults(void) exc = exc_create_context(&ecc, ECC_TYPE | ECC_WCONTEXT); xasprintf(&cmd, "%s%s%s", defaults[i][0], defaults[i][1], defaults[i][2]); - execute_function(NULL, exc, cmd, 0); + execute_function(NULL, exc, cmd, NULL, 0); free(cmd); exc_destroy_context(exc); } @@ -1526,7 +1526,7 @@ void StartupStuff(void) { char *action = "Function " start_func_name; - execute_function(NULL, exc, action, 0); + execute_function(NULL, exc, action, NULL, 0); } /* migo (03-Jul-1999): execute [Session]{Init|Restart}Function */ @@ -1536,7 +1536,7 @@ void StartupStuff(void) char *action; xasprintf(&action, "Function %s", init_func_name); - execute_function(NULL, exc, action, 0); + execute_function(NULL, exc, action, NULL, 0); free(action); } /* see comment above */ @@ -1739,6 +1739,7 @@ int main(int argc, char **argv) exec_context_changes_t ecc; struct monitor *m = NULL; + functions_init(); fvwmlib_init_max_fd(); /* Tell the FEvent module an event type that is not used by fvwm. */ fev_init_invalid_event_type(KeymapNotify); @@ -2457,7 +2458,8 @@ int main(int argc, char **argv) for (i = 0; i < num_config_commands; i++) { DoingCommandLine = True; - execute_function(NULL, exc, config_commands[i], 0); + execute_function( + NULL, exc, config_commands[i], NULL, 0); free(config_commands[i]); } DoingCommandLine = False; @@ -2489,7 +2491,7 @@ int main(int argc, char **argv) xasprintf(&cfg_loc[++nl], "%s/default-config/config", FVWM_DATADIR); for (nl = 0; nl < upper; nl++) { - if (!run_command_file(cfg_loc[nl], exc)) { + if (!run_command_file(cfg_loc[nl], exc, NULL)) { fvwm_debug(__func__, "couldn't find/load [%d]: %s\n", nl, cfg_loc[nl]); tries++; diff --git a/fvwm/menucmd.c b/fvwm/menucmd.c index fb7ea219..e4dfd6f9 100644 --- a/fvwm/menucmd.c +++ b/fvwm/menucmd.c @@ -27,6 +27,7 @@ #include "libs/Strings.h" #include "fvwm.h" #include "functions.h" +#include "cmdparser.h" #include "repeat.h" #include "misc.h" #include "move_resize.h" @@ -113,7 +114,7 @@ static void menu_func(F_CMD_ARGS, Bool fStaysUp) do_menu(&mp, &mret); if (mret.rc == MENU_DOUBLE_CLICKED && action) { - execute_function(cond_rc, exc2, action, 0); + execute_function(cond_rc, exc2, action, NULL, 0); } if (ret_action != NULL) { diff --git a/fvwm/menus.c b/fvwm/menus.c index 520befa0..bd7d6542 100644 --- a/fvwm/menus.c +++ b/fvwm/menus.c @@ -37,6 +37,7 @@ #include "libs/wcontext.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "execcontext.h" #include "events.h" #include "eventhandler.h" @@ -242,7 +243,7 @@ static void __menu_execute_function(const exec_context_t **pexc, char *action) exc = exc_clone_context(*pexc, &ecc, ECC_W); old_emf = Scr.flags.is_executing_menu_function; Scr.flags.is_executing_menu_function = 1; - execute_function(NULL, exc, action, FUNC_DONT_EXPAND_COMMAND); + execute_function(NULL, exc, action, NULL, FUNC_DONT_EXPAND_COMMAND); Scr.flags.is_executing_menu_function = old_emf; exc_destroy_context(exc); /* See if the window has been deleted */ @@ -5610,6 +5611,7 @@ static void menu_tear_off(MenuRoot *mr_to_copy) char *action; cond_rc_t *cond_rc = NULL; const exec_context_t *exc = NULL; + cmdparser_context_t *pc = NULL; /* keep the menu open */ if (MR_WINDOW(mr_to_copy) != None) diff --git a/fvwm/misc.c b/fvwm/misc.c index bd8e483a..a44eedeb 100644 --- a/fvwm/misc.c +++ b/fvwm/misc.c @@ -24,6 +24,7 @@ #include "libs/ftime.h" #include "libs/Parse.h" #include "libs/Target.h" +#include "libs/fvwmrect.h" #include "libs/FEvent.h" #include "fvwm.h" #include "externs.h" diff --git a/fvwm/module_interface.c b/fvwm/module_interface.c index fdcb493c..c140c59a 100644 --- a/fvwm/module_interface.c +++ b/fvwm/module_interface.c @@ -33,6 +33,7 @@ #include "libs/FEvent.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "functions.h" #include "bindings.h" #include "misc.h" @@ -727,7 +728,7 @@ void module_input_execute(struct fmodule_input *input) exc = exc_create_context( &ecc, ECC_TYPE | ECC_ETRIGGER | ECC_FW | ECC_W | ECC_WCONTEXT | ECC_MODULE); - execute_function(NULL, exc, input->command, flags); + execute_function(NULL, exc, input->command, NULL, flags); exc_destroy_context(exc); module_input_discard(input); diff --git a/fvwm/move_resize.c b/fvwm/move_resize.c index 7091a984..c10d7d35 100644 --- a/fvwm/move_resize.c +++ b/fvwm/move_resize.c @@ -33,6 +33,7 @@ #include "libs/FEvent.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "cursor.h" #include "execcontext.h" #include "commands.h" @@ -2193,7 +2194,8 @@ static void __move_window(F_CMD_ARGS, Bool do_animate, int mode) if (fWarp & !do_animate) { char *cmd = "WarpToWindow 50 50"; - execute_function_override_window(NULL, exc, cmd, 0, fw); + execute_function_override_window( + NULL, exc, cmd, NULL, 0, fw); } if (IS_MAXIMIZED(fw)) { @@ -3397,7 +3399,7 @@ void CMD_HideGeometryWindow(F_CMD_ARGS) "Converting to use: GeometryWindow hide %s", action); xasprintf(&cmd, "GeometryWindow hide %s", action); - execute_function_override_window(NULL, NULL, cmd, 0, NULL); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, NULL); free(cmd); } @@ -3415,7 +3417,7 @@ void CMD_SnapAttraction(F_CMD_ARGS) "The command SnapAttraction is obsolete. Please use the" " following command instead:\n\n%s", cmd); execute_function( - cond_rc, exc, cmd, + cond_rc, exc, cmd, pc, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); free(cmd); @@ -3436,7 +3438,7 @@ void CMD_SnapGrid(F_CMD_ARGS) "The command SnapGrid is obsolete. Please use the following" " command instead:\n\n%s", cmd); execute_function( - cond_rc, exc, cmd, + cond_rc, exc, cmd, pc, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); free(cmd); @@ -4997,7 +4999,7 @@ static void grow_to_closest_type( } static void unmaximize_fvwm_window( - FvwmWindow *fw) + FvwmWindow *fw, cmdparser_context_t *pc) { char *cmd; rectangle new_g; @@ -5016,8 +5018,9 @@ static void unmaximize_fvwm_window( * If the window was not maximized, then we use the window's normal * geometry. */ - get_relative_geometry(fw, &new_g, fw->fullscreen.was_maximized ? - &fw->fullscreen.g.max : &fw->g.normal); + get_relative_geometry( + fw, &new_g, fw->fullscreen.was_maximized ? + &fw->fullscreen.g.max : &fw->g.normal); if (fw->fullscreen.was_maximized) { @@ -5049,7 +5052,7 @@ static void unmaximize_fvwm_window( fw, new_g.x, new_g.y, new_g.width, new_g.height, True); xasprintf(&cmd, "MoveToScreen %s", fw->m->si->name); - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); free(cmd); border_draw_decorations( @@ -5058,14 +5061,14 @@ static void unmaximize_fvwm_window( if (fw->fullscreen.is_shaded) { execute_function_override_window( - NULL, NULL, "WindowShade on", 0, fw); + NULL, NULL, "WindowShade on", NULL, 0, fw); fw->fullscreen.is_shaded = 0; } if (fw->fullscreen.is_iconified) { execute_function_override_window( - NULL, NULL, "Iconify on", 0, fw); + NULL, NULL, "Iconify on", NULL, 0, fw); fw->fullscreen.is_iconified = 0; } @@ -5216,7 +5219,7 @@ void CMD_Maximize(F_CMD_ARGS) } if (toggle == 0 && IS_EWMH_FULLSCREEN(fw)) { - unmaximize_fvwm_window(fw); + unmaximize_fvwm_window(fw, pc); return; } return; @@ -5368,11 +5371,11 @@ void CMD_Maximize(F_CMD_ARGS) if (do_forget == True) { fw->g.normal = fw->g.max; - unmaximize_fvwm_window(fw); + unmaximize_fvwm_window(fw, pc); } else if (IS_MAXIMIZED(fw) && !do_force_maximize) { - unmaximize_fvwm_window(fw); + unmaximize_fvwm_window(fw, pc); } else /* maximize */ { diff --git a/fvwm/placement.c b/fvwm/placement.c index ee404906..a6cce055 100644 --- a/fvwm/placement.c +++ b/fvwm/placement.c @@ -367,14 +367,15 @@ adjust_for_shared_placement(FvwmWindow *fw, const exec_context_t *exc) xasprintf(&cmd, "GotoDesk %s 0 %d", m_style->si->name, fw->Desk); - execute_function_override_window(NULL, NULL, cmd, 0, fw); + execute_function_override_window(NULL, NULL, cmd, NULL, 0, fw); free(cmd); } done: TAILQ_FOREACH(m, &monitor_q, entry) { if (m->virtual_scr.CurrentDesk == fw->Desk) { xasprintf(&cmd, "MoveToScreen %s", m->si->name); - execute_function_override_window(NULL, exc, cmd, 0, fw); + execute_function_override_window( + NULL, exc, cmd, NULL, 0, fw); free(cmd); break; diff --git a/fvwm/read.c b/fvwm/read.c index d71a2efb..dc4d6e4b 100644 --- a/fvwm/read.c +++ b/fvwm/read.c @@ -28,6 +28,7 @@ #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "cursor.h" #include "functions.h" #include "events.h" @@ -112,7 +113,8 @@ const char *get_current_read_dir(void) * Read and execute each line from stream. */ void run_command_stream( - cond_rc_t *cond_rc, FILE *f, const exec_context_t *exc) + cond_rc_t *cond_rc, FILE *f, const exec_context_t *exc, + cmdparser_context_t *pc) { char *tline; char line[1024]; @@ -143,7 +145,7 @@ void run_command_stream( { tline[l - 1] = '\0'; } - execute_function(cond_rc, exc, tline, 0); + execute_function(cond_rc, exc, tline, pc, 0); tline = fgets(line, (sizeof line) - 1, f); } @@ -192,7 +194,7 @@ static int parse_filename( * Returns 0 if file not found **/ int run_command_file( - char *filename, const exec_context_t *exc) + char *filename, const exec_context_t *exc, cmdparser_context_t *pc) { char *full_filename; FILE *f = NULL; @@ -251,7 +253,7 @@ int run_command_file( fclose(f); return 0; } - run_command_stream(NULL, f, exc); + run_command_stream(NULL, f, exc, pc); fclose(f); pop_read_file(); @@ -317,7 +319,7 @@ void CMD_Read(F_CMD_ARGS) return; } cursor_control(True); - if (!run_command_file(filename, exc)) + if (!run_command_file(filename, exc, pc)) { if (!read_quietly) { @@ -384,7 +386,7 @@ void CMD_PipeRead(F_CMD_ARGS) } free(command); - run_command_stream(cond_rc,f, exc); + run_command_stream(cond_rc, f, exc, pc); pclose(f); cursor_control(False); diff --git a/fvwm/read.h b/fvwm/read.h index 0b7d2618..d42f9ca6 100644 --- a/fvwm/read.h +++ b/fvwm/read.h @@ -4,6 +4,7 @@ #include <stdio.h> #include "condrc.h" #include "execcontext.h" +#include "cmdparser.h" /** * Full pathname of file read in progress, or NULL. @@ -30,6 +31,7 @@ void run_command_stream( * fvwm_userdir (set in main()) or in FVWM_DATADIR. Return 1 * if the file was found and executed. **/ -int run_command_file(char *filename, const exec_context_t *exc); +int run_command_file( + char *filename, const exec_context_t *exc, cmdparser_context_t *pc); #endif diff --git a/fvwm/repeat.c b/fvwm/repeat.c index 92b02b64..3c3b24a4 100644 --- a/fvwm/repeat.c +++ b/fvwm/repeat.c @@ -21,6 +21,7 @@ #include "libs/fvwmlib.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "cursor.h" #include "functions.h" #include "repeat.h" @@ -85,6 +86,9 @@ FvwmWindow *repeat_last_fvwm_window = NULL; * from within this function have depth 2 and higher, this may be applicable * to future enhancements like menus). * + * Returns True if the caller needs to free the string himself and False if + * the repeat module will take care of freeing the string. + * * TODO: [finish and update description] */ Bool set_repeat_data(void *data, repeat_t type, const func_t *builtin) @@ -157,7 +161,7 @@ void CMD_Repeat(F_CMD_ARGS) default: action = last.command_line; execute_function( - cond_rc, exc, action, FUNC_DONT_EXPAND_COMMAND); + cond_rc, exc, action, pc, FUNC_DONT_EXPAND_COMMAND); break; } repeat_depth--; diff --git a/fvwm/schedule.c b/fvwm/schedule.c index b1f13223..33bfaf1e 100644 --- a/fvwm/schedule.c +++ b/fvwm/schedule.c @@ -25,6 +25,7 @@ #include "libs/FEvent.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "colorset.h" #include "bindings.h" #include "misc.h" @@ -189,7 +190,7 @@ static void execute_obj_func(void *object, void *args) mask |= ECC_FW; } exc = exc_create_context(&ecc, mask); - execute_function(NULL, exc, obj->command, 0); + execute_function(NULL, exc, obj->command, NULL, 0); exc_destroy_context(exc); } if (obj->period > 0) diff --git a/fvwm/update.c b/fvwm/update.c index c3399de2..8cc8ed75 100644 --- a/fvwm/update.c +++ b/fvwm/update.c @@ -147,17 +147,18 @@ static void apply_window_updates( /* stick and unstick the window to force the icon on * the current page */ handle_stick( - NULL, exc, "", + NULL, exc, "", NULL, S_IS_STICKY_ACROSS_PAGES(SCF(*pstyle)), S_IS_STICKY_ACROSS_DESKS(SCF(*pstyle)), 1, 1); - handle_stick(NULL, exc, "", 0, 0, 1, 0); + handle_stick(NULL, exc, "", NULL, 0, 0, 1, 0); } flags->do_update_icon_title = True; } else if (flags->do_update_stick) { handle_stick( - NULL, exc, "", S_IS_STICKY_ACROSS_PAGES(SCF(*pstyle)), + NULL, exc, "", NULL, + S_IS_STICKY_ACROSS_PAGES(SCF(*pstyle)), S_IS_STICKY_ACROSS_DESKS(SCF(*pstyle)), 0, 0); } exc_destroy_context(exc); diff --git a/fvwm/virtual.c b/fvwm/virtual.c index cfe1ec17..27f728cb 100644 --- a/fvwm/virtual.c +++ b/fvwm/virtual.c @@ -28,6 +28,7 @@ #include "libs/FScreen.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "execcontext.h" #include "expand.h" #include "cursor.h" @@ -64,7 +65,8 @@ do { \ char *cmd; \ xasprintf(&cmd, "GotoDesk %s 0 %d", (m)->si->name, (d)); \ - execute_function_override_window(NULL, NULL, cmd, 0, NULL); \ + execute_function_override_window( \ + NULL, NULL, cmd, NULL, 0, NULL); \ free(cmd); \ } while (0) @@ -74,7 +76,8 @@ xasprintf(&cmd, "All (!Screen %s, Desk %d, !CirculateHit) " \ "MoveToPage %s $[w.pagex] $[w.pagey]", \ (m)->si->name, (d), (m)->si->name); \ - execute_function_override_window(NULL, NULL, cmd, 0, NULL); \ + execute_function_override_window( \ + NULL, NULL, cmd, NULL, 0, NULL); \ free(cmd); \ } while (0) @@ -628,8 +631,8 @@ static void MapDesk(struct monitor *m, int desk, Bool grab) /* execute_function_override_window() * will expand cmd's variables. */ - execute_function_override_window(NULL, - NULL, cmd, 0, t); + execute_function_override_window( + NULL, NULL, cmd, NULL, 0, t); free(cmd); /* No need to map the window as it's @@ -2204,13 +2207,13 @@ void CMD_EdgeResistance(F_CMD_ARGS) " instead:\n%s\n%s\n%s\n", cmd, stylecmd, stylecmd2); execute_function( - cond_rc, exc, cmd, + cond_rc, exc, cmd, pc, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); execute_function( - cond_rc, exc, stylecmd, + cond_rc, exc, stylecmd, pc, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); execute_function( - cond_rc, exc, stylecmd2, + cond_rc, exc, stylecmd2, pc, FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); } else @@ -2249,7 +2252,8 @@ void CMD_DesktopConfiguration(F_CMD_ARGS) m->virtual_scr.Vx / monitor_get_all_widths(), m->virtual_scr.Vy / monitor_get_all_heights()); - execute_function_override_window(NULL, NULL, cmd, 0, NULL); + execute_function_override_window( + NULL, NULL, cmd, NULL, 0, NULL); free(cmd); } monitor_mode = MONITOR_TRACKING_G; @@ -2660,8 +2664,8 @@ void CMD_MoveToDesk(F_CMD_ARGS) xasprintf(&cmd, "MoveToPage %s $[w.pagex] $[w.pagey]", m->si->name); - execute_function_override_window(NULL, NULL, - cmd, 0, fw); + execute_function_override_window( + NULL, NULL, cmd, NULL, 0, fw); free(cmd); return; diff --git a/fvwm/windowlist.c b/fvwm/windowlist.c index f77cf675..d4be0dba 100644 --- a/fvwm/windowlist.c +++ b/fvwm/windowlist.c @@ -30,6 +30,7 @@ #include "libs/Strings.h" #include "fvwm.h" #include "externs.h" +#include "cmdparser.h" #include "functions.h" #include "misc.h" #include "screen.h" @@ -1085,7 +1086,7 @@ void CMD_WindowList(F_CMD_ARGS) if (mret.rc == MENU_DOUBLE_CLICKED && default_action && *default_action) { - execute_function(cond_rc, exc2, default_action, 0); + execute_function(cond_rc, exc2, default_action, pc, 0); } if (default_action != NULL) { -- 2.30.2
From 97cb16222d94a3352fbb3dec69b8003abc1992f7 Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Sat, 20 Nov 2021 15:10:36 +0100 Subject: [PATCH 8/9] Remove Repeat command prefix. --- doc/fvwm3_manpage_source.adoc | 9 -- fvwm/Makefile.am | 4 +- fvwm/commands.h | 1 - fvwm/functable.c | 23 ++--- fvwm/functable.h | 1 - fvwm/functions.c | 15 +-- fvwm/functions.h | 2 +- fvwm/menucmd.c | 6 +- fvwm/move_resize.c | 8 +- fvwm/repeat.c | 170 ---------------------------------- fvwm/repeat.h | 37 -------- fvwm/virtual.c | 9 +- 12 files changed, 19 insertions(+), 266 deletions(-) delete mode 100644 fvwm/repeat.c delete mode 100644 fvwm/repeat.h diff --git a/doc/fvwm3_manpage_source.adoc b/doc/fvwm3_manpage_source.adoc index 42187d14..6578cb2b 100644 --- a/doc/fvwm3_manpage_source.adoc +++ b/doc/fvwm3_manpage_source.adoc @@ -3655,15 +3655,6 @@ _infostore_ which prints information on all entries in the infostore, listing the key and its value. _verbose_ has no effect with this option. -*Repeat*:: - When the *Repeat* command is invoked, the last command that was - executed by fvwm is executed again. This happens regardless of whether - it was triggered by user interaction, a module or by an X event. - Commands that are executed from a function defined with the *Function* - command, from the *Read* or *PipeRead* commands or by a menu are not - repeated. Instead, the function, menu or the *Read* or *PipeRead* - command is executed again. - *Schedule* [Periodic] _delay_ms_ [_command_id_] _command_:: The _command_ is executed after about _delay_ms_ milliseconds. This may be useful in some tricky setups. The _command_ is executed in the diff --git a/fvwm/Makefile.am b/fvwm/Makefile.am index 9ae456f9..bb04b6d2 100644 --- a/fvwm/Makefile.am +++ b/fvwm/Makefile.am @@ -16,7 +16,7 @@ fvwm3_SOURCES = \ icccm2.h icons.h menubindings.h menudim.h menugeometry.h \ menuitem.h menuroot.h menuparameters.h menus.h menustyle.h misc.h \ modconf.h module_interface.h module_list.h move_resize.h \ - placement.h read.h repeat.h execcontext.h schedule.h screen.h \ + placement.h read.h execcontext.h schedule.h screen.h \ session.h stack.h style.h update.h virtual.h window_flags.h frame.h \ infostore.h \ cmdparser.h cmdparser_hooks.h cmdparser_old.h functable_complex.h \ @@ -28,7 +28,7 @@ fvwm3_SOURCES = \ windowlist.c functable.c menuitem.c expand.c module_interface.c \ menubindings.c decorations.c ewmh_icons.c update.c bindings.c misc.c \ cursor.c colormaps.c modconf.c ewmh_conf.c read.c schedule.c \ - menucmd.c ewmh_names.c icccm2.c windowshade.c focus_policy.c repeat.c \ + menucmd.c ewmh_names.c icccm2.c windowshade.c focus_policy.c \ execcontext.c menugeometry.c menudim.c condrc.c infostore.c \ cmdparser_old.c functable_complex.c diff --git a/fvwm/commands.h b/fvwm/commands.h index 4663111a..9f9739f9 100644 --- a/fvwm/commands.h +++ b/fvwm/commands.h @@ -112,7 +112,6 @@ enum F_RECAPTURE, F_RECAPTURE_WINDOW, F_REFRESH, - F_REPEAT, F_RESTART, F_SAVE_SESSION, F_SAVE_QUIT_SESSION, diff --git a/fvwm/functable.c b/fvwm/functable.c index f003184b..0d328a06 100644 --- a/fvwm/functable.c +++ b/fvwm/functable.c @@ -405,7 +405,7 @@ const func_t func_table[] = CMD_ENT("none", CMD_None, F_NONE, 0, 0), /* - Perform command if no window matches conditions */ - CMD_ENT("nop", CMD_Nop, F_NOP, FUNC_DONT_REPEAT, 0), + CMD_ENT("nop", CMD_Nop, F_NOP, 0, 0), /* - Do nothing (used internally) */ CMD_ENT("nowindow", CMD_NoWindow, F_NOP, 0, 0), @@ -475,9 +475,6 @@ const func_t func_table[] = FUNC_NEEDS_WINDOW, CRS_SELECT), /* - Cause one window to redraw itself */ - CMD_ENT(PRE_REPEAT, CMD_Repeat, F_REPEAT, FUNC_DONT_REPEAT, 0), - /* - Repeat (very unreliably) the last command, don't use */ - CMD_ENT("resize", CMD_Resize, F_RESIZE, FUNC_NEEDS_WINDOW | FUNC_IS_MOVE_TYPE, CRS_RESIZE), /* - Cause a window to be resized */ @@ -518,31 +515,27 @@ const func_t func_table[] = CMD_ENT("scroll", CMD_Scroll, F_SCROLL, 0, 0), /* - Scroll the desktop viewport */ - CMD_ENT("send_configinfo", CMD_Send_ConfigInfo, F_CONFIG_LIST, - FUNC_DONT_REPEAT, 0), + CMD_ENT("send_configinfo", CMD_Send_ConfigInfo, F_CONFIG_LIST, 0, 0), /* - Internal, used for module communication */ - CMD_ENT("send_reply", CMD_Send_Reply, F_SEND_REPLY, - FUNC_DONT_REPEAT, 0), + CMD_ENT("send_reply", CMD_Send_Reply, F_SEND_REPLY, 0, 0), /* - Internal, used for module communication */ CMD_ENT("send_windowlist", CMD_Send_WindowList, F_SEND_WINDOW_LIST, - FUNC_DONT_REPEAT, 0), + 0, 0), /* - Internal, used for module communication */ - CMD_ENT("sendtomodule", CMD_SendToModule, F_SEND_STRING, - FUNC_DONT_REPEAT, 0), + CMD_ENT("sendtomodule", CMD_SendToModule, F_SEND_STRING, 0, 0), /* - Send a string (action) to a module */ - CMD_ENT("set_mask", CMD_set_mask, F_SET_MASK, FUNC_DONT_REPEAT, 0), + CMD_ENT("set_mask", CMD_set_mask, F_SET_MASK, 0, 0), /* - Internal, used for module communication */ CMD_ENT("set_nograb_mask", CMD_set_nograb_mask, F_SET_NOGRAB_MASK, - FUNC_DONT_REPEAT, 0), + 0, 0), /* - Internal, used for module communication */ - CMD_ENT("set_sync_mask", CMD_set_sync_mask, F_SET_SYNC_MASK, - FUNC_DONT_REPEAT, 0), + CMD_ENT("set_sync_mask", CMD_set_sync_mask, F_SET_SYNC_MASK, 0, 0), /* - Internal, used for module communication */ CMD_ENT("setanimation", CMD_SetAnimation, F_SET_ANIMATION, 0, 0), diff --git a/fvwm/functable.h b/fvwm/functable.h index c5bf6b9b..e0e21da6 100644 --- a/fvwm/functable.h +++ b/fvwm/functable.h @@ -8,7 +8,6 @@ /* ---------------------------- global definitions ------------------------- */ #define PRE_KEEPRC "keeprc" -#define PRE_REPEAT "repeat" #define PRE_SILENT "silent" /* ---------------------------- global macros ------------------------------ */ diff --git a/fvwm/functions.c b/fvwm/functions.c index 060eaff3..6c4ae468 100644 --- a/fvwm/functions.c +++ b/fvwm/functions.c @@ -51,7 +51,6 @@ #include "module_list.h" #include "misc.h" #include "screen.h" -#include "repeat.h" #include "expand.h" #include "menus.h" @@ -427,22 +426,10 @@ cmdparser_hooks->debug(&pc, "!!!E"); if (!(exec_flags & FUNC_DONT_EXPAND_COMMAND)) { +cmdparser_hooks->debug(&pc, "!!!F"); cmdparser_hooks->expand_command_line( &pc, (bif) ? !!(bif->flags & FUNC_ADD_TO) : False, func_rc, exc); -cmdparser_hooks->debug(&pc, "!!!F"); - if (pc.call_depth <= 1) - { - Bool do_free_string_ourselves; - - do_free_string_ourselves = set_repeat_data( - pc.expline, REPEAT_COMMAND, bif); - if (do_free_string_ourselves == False) - { - cmdparser_hooks->release_expanded_line(&pc); -cmdparser_hooks->debug(&pc, "!!!F"); - } - } } #if 1 /*!!!*/ fprintf(stderr, "!!!pc.cline: '%s'\n", pc.cline); diff --git a/fvwm/functions.h b/fvwm/functions.h index b87256a8..9a7c7796 100644 --- a/fvwm/functions.h +++ b/fvwm/functions.h @@ -15,7 +15,7 @@ typedef enum { FUNC_NEEDS_WINDOW = 0x01, - FUNC_DONT_REPEAT = 0x02, + /*free = 0x02,*/ FUNC_ADD_TO = 0x04, FUNC_DECOR = 0x08, FUNC_ALLOW_UNMANAGED = 0x10, diff --git a/fvwm/menucmd.c b/fvwm/menucmd.c index e4dfd6f9..f6300cc9 100644 --- a/fvwm/menucmd.c +++ b/fvwm/menucmd.c @@ -28,7 +28,6 @@ #include "fvwm.h" #include "functions.h" #include "cmdparser.h" -#include "repeat.h" #include "misc.h" #include "move_resize.h" #include "screen.h" @@ -91,11 +90,10 @@ static void menu_func(F_CMD_ARGS, Bool fStaysUp) } return; } - if (menu_name && - set_repeat_data( - menu_name, (fStaysUp) ? REPEAT_MENU : REPEAT_POPUP,NULL)) + if (menu_name) { free(menu_name); + menu_name = NULL; } memset(&mp, 0, sizeof(mp)); diff --git a/fvwm/move_resize.c b/fvwm/move_resize.c index c10d7d35..ab3af0f5 100644 --- a/fvwm/move_resize.c +++ b/fvwm/move_resize.c @@ -3416,9 +3416,7 @@ void CMD_SnapAttraction(F_CMD_ARGS) fvwm_debug(__func__, "The command SnapAttraction is obsolete. Please use the" " following command instead:\n\n%s", cmd); - execute_function( - cond_rc, exc, cmd, pc, - FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); + execute_function(cond_rc, exc, cmd, pc, FUNC_DONT_EXPAND_COMMAND); free(cmd); return; @@ -3437,9 +3435,7 @@ void CMD_SnapGrid(F_CMD_ARGS) fvwm_debug(__func__, "The command SnapGrid is obsolete. Please use the following" " command instead:\n\n%s", cmd); - execute_function( - cond_rc, exc, cmd, pc, - FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); + execute_function(cond_rc, exc, cmd, pc, FUNC_DONT_EXPAND_COMMAND); free(cmd); return; diff --git a/fvwm/repeat.c b/fvwm/repeat.c deleted file mode 100644 index 3c3b24a4..00000000 --- a/fvwm/repeat.c +++ /dev/null @@ -1,170 +0,0 @@ -/* -*-c-*- */ -/* Copyright (C) 1999 Dominik Vogt */ -/* This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see: <http://www.gnu.org/licenses/> - */ - -#include "config.h" - -#include <stdio.h> - -#include "libs/fvwmlib.h" -#include "fvwm.h" -#include "externs.h" -#include "cmdparser.h" -#include "cursor.h" -#include "functions.h" -#include "repeat.h" -#include "libs/Parse.h" - - -/* If non-zero we are already repeating a function, so don't record the - * command again. */ -static int repeat_depth = 0; - -#if 0 -typedef struct -{ - char *start; - char *end; -} double_ended_string; - -static struct -{ - double_ended_string string; - double_ended_string old; - double_ended_string builtin; - double_ended_string function; - double_ended_string top_function; - double_ended_string module; - double_ended_string menu; - double_ended_string popup; - double_ended_string menu_or_popup; - int page_x; - int page_y; - int desk; - FvwmWindow *fvwm_window; -} last; -#endif - -static struct -{ - char *command_line; - char *menu_name; -} last = { - NULL, - NULL -}; - -#if 0 -char *repeat_last_function = NULL; -char *repeat_last_complex_function = NULL; -char *repeat_last_builtin_function = NULL; -char *repeat_last_module = NULL; -char *repeat_last_top_function = NULL; -char *repeat_last_menu = NULL; -FvwmWindow *repeat_last_fvwm_window = NULL; -#endif - -/* Stores the contents of the data pointer internally for the repeat command. - * The type of data is determined by the 'type' parameter. If this function is - * called to set a string value representing an fvwm builtin function the - * 'builtin' can be set to the F_... value in the function table in - * functions.c. If this value is set certain functions are not recorded. - * The 'depth' parameter indicates the recursion depth of the current data - * pointer (i.e. the first function call has a depth of one, functions called - * from within this function have depth 2 and higher, this may be applicable - * to future enhancements like menus). - * - * Returns True if the caller needs to free the string himself and False if - * the repeat module will take care of freeing the string. - * - * TODO: [finish and update description] - */ -Bool set_repeat_data(void *data, repeat_t type, const func_t *builtin) -{ - /* No history recording during startup. */ - if (fFvwmInStartup) - { - return True; - } - - switch(type) - { - case REPEAT_COMMAND: - if (last.command_line == (char *)data) - { - /* Already stored, no need to free the data pointer. */ - return False; - } - if (data == NULL || repeat_depth != 0) - { - /* Ignoring the data, must free it outside of this - * call. */ - return True; - } - if (builtin && (builtin->flags & FUNC_DONT_REPEAT)) - { - /* Dont' record functions that have the - * FUNC_DONT_REPEAT flag set. */ - return True; - } - /* Store a backup. */ - free(last.command_line); - last.command_line = (char *)data; - /* Since we stored the pointer the caller must not free it. */ - return False; - case REPEAT_MENU: - case REPEAT_POPUP: - if (last.menu_name != (char*)data) - { - free(last.menu_name); - } - last.menu_name = (char *)data; - return False; - case REPEAT_PAGE: - case REPEAT_DESK: - case REPEAT_DESK_AND_PAGE: - return True; - case REPEAT_FVWM_WINDOW: - return True; - case REPEAT_NONE: - default: - return True; - } -} - -void CMD_Repeat(F_CMD_ARGS) -{ - int index; - char *optlist[] = { - "command", - NULL - }; - - repeat_depth++; - /* Replay the backup, we don't want the repeat command recorded. */ - GetNextTokenIndex(action, optlist, 0, &index); - switch (index) - { - case 0: /* command */ - default: - action = last.command_line; - execute_function( - cond_rc, exc, action, pc, FUNC_DONT_EXPAND_COMMAND); - break; - } - repeat_depth--; - - return; -} diff --git a/fvwm/repeat.h b/fvwm/repeat.h deleted file mode 100644 index a8138b8b..00000000 --- a/fvwm/repeat.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*-c-*- */ - -#ifndef FVWM_REPEAT_H -#define FVWM_REPEAT_H -#include "functions.h" - -typedef enum -{ - REPEAT_NONE = 0, - REPEAT_COMMAND, - /* I think we don't need all these - REPEAT_BUILTIN, - REPEAT_FUNCTION, - REPEAT_TOP_FUNCTION, - REPEAT_MODULE, - */ - REPEAT_MENU, - REPEAT_POPUP, - REPEAT_PAGE, - REPEAT_DESK, - REPEAT_DESK_AND_PAGE, - REPEAT_FVWM_WINDOW -} repeat_t; - -extern char *repeat_last_function; -extern char *repeat_last_complex_function; -extern char *repeat_last_builtin_function; -extern char *repeat_last_module; -/* - extern char *repeat_last_top_function; - extern char *repeat_last_menu; - extern FvwmWindow *repeat_last_fvwm_window; -*/ - -Bool set_repeat_data(void *data, repeat_t type, const func_t *builtin); - -#endif /* FVWM_REPEAT_H */ diff --git a/fvwm/virtual.c b/fvwm/virtual.c index 27f728cb..94ad4418 100644 --- a/fvwm/virtual.c +++ b/fvwm/virtual.c @@ -2207,14 +2207,11 @@ void CMD_EdgeResistance(F_CMD_ARGS) " instead:\n%s\n%s\n%s\n", cmd, stylecmd, stylecmd2); execute_function( - cond_rc, exc, cmd, pc, - FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); + cond_rc, exc, cmd, pc, FUNC_DONT_EXPAND_COMMAND); execute_function( - cond_rc, exc, stylecmd, pc, - FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); + cond_rc, exc, stylecmd, pc, FUNC_DONT_EXPAND_COMMAND); execute_function( - cond_rc, exc, stylecmd2, pc, - FUNC_DONT_REPEAT | FUNC_DONT_EXPAND_COMMAND); + cond_rc, exc, stylecmd2, pc, FUNC_DONT_EXPAND_COMMAND); } else { -- 2.30.2
From af9bac8eed6ddf7920cff4017a84927c3e6f3a40 Mon Sep 17 00:00:00 2001 From: Dominik Vogt <dominik.v...@gmx.de> Date: Wed, 17 Nov 2021 19:53:39 +0100 Subject: [PATCH 9/9] !!!debug fprintfs --- fvwm/cmdparser_old.c | 55 ++++++++++++++++++-- fvwm/functions.c | 95 +++++++++++++++++++++++++++++++++-- fvwm/modconf.c | 17 ++++++- libs/defaults.h | 4 ++ modules/FvwmButtons/dynamic.c | 23 +++++++++ 5 files changed, 184 insertions(+), 10 deletions(-) diff --git a/fvwm/cmdparser_old.c b/fvwm/cmdparser_old.c index 21c2074e..b53ac5d6 100644 --- a/fvwm/cmdparser_old.c +++ b/fvwm/cmdparser_old.c @@ -37,7 +37,7 @@ /* ---------------------------- local definitions -------------------------- */ -#if 0 /*!!!*/ +#if 1 /*!!!*/ #define OCP_DEBUG 1 #else #define OCP_DEBUG 0 @@ -275,12 +275,28 @@ static const char *ocp_parse_command_name( cmdparser_context_t *c, void *func_rc, const void *exc) { GetNextToken(c->cline, &c->command); + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: c->command '%s'\n", __func__, + (c->command) ? c->command : "(nil)"); + } if (c->command != NULL) { char *tmp = c->command; + if (OCP_DEBUG) + { + fprintf(stderr, "%s: expand c->command\n", __func__); + } c->command = expand_vars( c->command, c, False, False, func_rc, exc); + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: c->command '%s'\n", __func__, + (c->command) ? c->command : "(nil)"); + } free(tmp); } if (c->command && !ocp_is_module_config(c)) @@ -293,11 +309,23 @@ static const char *ocp_parse_command_name( * fail */ char *tmp = c->command; + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: remove trailing spaces\n", + __func__); + } while (*tmp && !isspace(*tmp)) { tmp++; } *tmp = 0; + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: c->command '%s'\n", __func__, + (c->command) ? c->command : "(nil)"); + } #endif return c->command; } @@ -331,6 +359,12 @@ static cmdparser_execute_type_t ocp_find_something_to_execute( { int is_function_builtin; + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: c->command '%s'\n", __func__, + (c->command) ? c->command : "(nil)"); + } *ret_complex_function = NULL; /* Note: the module config command, "*" can not be handled by the * regular command table because there is no required white space after @@ -366,9 +400,10 @@ static cmdparser_execute_type_t ocp_find_something_to_execute( return CP_EXECTYPE_BUILTIN_FUNCTION; } } -#if 1 /*!!!*/ - assert(*ret_builtin == NULL); -#endif + if (OCP_DEBUG) + { + assert(*ret_builtin == NULL); + } do { char *complex_function_name; @@ -381,8 +416,20 @@ static cmdparser_execute_type_t ocp_find_something_to_execute( { break; } + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: lookup cf '%s'\n", __func__, + complex_function_name); + } *ret_complex_function = find_complex_function(complex_function_name); + if (OCP_DEBUG) + { + fprintf( + stderr, "%s: lookup cf '%s' -> %p\n", __func__, + complex_function_name, *ret_complex_function); + } if (*ret_complex_function != NULL) { c->cline = rest_of_line; diff --git a/fvwm/functions.c b/fvwm/functions.c index 6c4ae468..694a8c17 100644 --- a/fvwm/functions.c +++ b/fvwm/functions.c @@ -124,21 +124,36 @@ static Bool DeferExecution( original_w = w; wcontext = ret_ecc->w.wcontext; FinishEvent = ((fw != NULL) ? ButtonRelease : ButtonPress); +#if 1 /*!!!*/ + fprintf(stderr, "!!!%s: A wc 0x%x\n", __func__, wcontext); +#endif if (wcontext == C_UNMANAGED && do_allow_unmanaged) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Bf\n", __func__); +#endif return False; } if (wcontext != C_ROOT && wcontext != C_NO_CONTEXT && fw != NULL && wcontext != C_EWMH_DESKTOP) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: C\n", __func__); +#endif if (FinishEvent == ButtonPress || (FinishEvent == ButtonRelease && trigger_evtype != ButtonPress)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Df\n", __func__); +#endif return False; } else if (FinishEvent == ButtonRelease) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: E\n", __func__); +#endif /* We are only waiting until the user releases the * button. Do not change the cursor. */ cursor = CRS_NONE; @@ -147,16 +162,25 @@ static Bool DeferExecution( } if (Scr.flags.are_functions_silent) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Ft\n", __func__); +#endif return True; } if (!GrabEm(cursor, GRAB_NORMAL)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Gt\n", __func__); +#endif XBell(dpy, 0); return True; } MyXGrabKeyboard(dpy); while (!finished) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: H\n", __func__); +#endif done = 0; /* block until there is an event */ FMaskEvent( @@ -167,9 +191,15 @@ static Bool DeferExecution( if (e.type == KeyPress) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: I\n", __func__); +#endif KeySym keysym = XLookupKeysym(&e.xkey, 0); if (keysym == XK_Escape) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Jt\n", __func__); +#endif ret_ecc->x.etrigger = &e; *ret_mask |= ECC_ETRIGGER; UngrabEm(GRAB_NORMAL); @@ -180,33 +210,57 @@ static Bool DeferExecution( } if (e.type == FinishEvent) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: K\n", __func__); +#endif finished = 1; } switch (e.type) { case KeyPress: case ButtonPress: +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: L\n", __func__); +#endif if (e.type != FinishEvent) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: M\n", __func__); +#endif original_w = e.xany.window; } done = 1; break; case ButtonRelease: +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: N\n", __func__); +#endif done = 1; break; default: +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: O\n", __func__); +#endif break; } if (!done) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: P\n", __func__); +#endif dispatch_event(&e); } } +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Q\n", __func__); +#endif MyXUngrabKeyboard(dpy); UngrabEm(GRAB_NORMAL); if (just_waiting_for_finish) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Rf\n", __func__); +#endif return False; } w = e.xany.window; @@ -215,11 +269,17 @@ static Bool DeferExecution( if ((w == Scr.Root || w == Scr.NoFocusWin) && e.xbutton.subwindow != None) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: S\n", __func__); +#endif w = e.xbutton.subwindow; e.xany.window = w; } if (w == Scr.Root || IS_EWMH_DESKTOP(w)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Tt\n", __func__); +#endif ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); @@ -228,6 +288,9 @@ static Bool DeferExecution( *ret_mask |= ECC_FW; if (XFindContext(dpy, w, FvwmContext, (caddr_t *)&fw) == XCNOENT) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Ut\n", __func__); +#endif ret_ecc->w.fw = NULL; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; @@ -236,10 +299,16 @@ static Bool DeferExecution( } if (w == FW_W_PARENT(fw)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: V\n", __func__); +#endif w = FW_W(fw); } if (original_w == FW_W_PARENT(fw)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: W\n", __func__); +#endif original_w = FW_W(fw); } /* this ugly mess attempts to ensure that the release and press @@ -248,8 +317,14 @@ static Bool DeferExecution( original_w != None && original_w != Scr.NoFocusWin && !IS_EWMH_DESKTOP(original_w)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: X\n", __func__); +#endif if (w != FW_W_FRAME(fw) || original_w != FW_W(fw)) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Yt\n", __func__); +#endif ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; @@ -260,12 +335,18 @@ static Bool DeferExecution( if (IS_EWMH_DESKTOP(FW_W(fw))) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: Zt\n", __func__); +#endif ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } +#if 1 /*!!!*/ +fprintf(stderr, "!!!%s: @f\n", __func__); +#endif wcontext = GetContext(NULL, fw, &e, &dummy); ret_ecc->w.fw = fw; ret_ecc->w.w = w; @@ -296,9 +377,6 @@ static void __execute_command_line( Window dummy_w; int rc; -#if 1 /*!!!*/ - fprintf(stderr, "%s: cpc %p, xaction '%s'\n", __func__, caller_pc, xaction); -#endif set_silent = 0; /* generate a parsing context; this *must* be destroyed before * returning */ @@ -358,10 +436,12 @@ cmdparser_hooks->debug(&pc, "!!!C"); { if (exec_flags & FUNC_IS_UNMANAGED) { +fprintf(stderr, "!!!AAA unmanaged\n"); w = exc->w.w; } else { +fprintf(stderr, "!!!BBB root\n"); w = Scr.Root; } } @@ -406,11 +486,12 @@ cmdparser_hooks->debug(&pc, "!!!C"); { cmdparser_hooks->debug(&pc, "!!!D"); bif = find_builtin_function(func); +fprintf(stderr, "!!! --> find bif '%s' -> %p\n", func, bif); err_func = func; } else { -cmdparser_hooks->debug(&pc, "!!!E"); +cmdparser_hooks->debug(&pc, "!!!E no command name"); bif = NULL; err_func = ""; } @@ -453,6 +534,7 @@ cmdparser_hooks->debug(&pc, "!!!J"); #endif #if 1 /*!!!*/ fprintf(stderr, "!!!pc.cline: '%s'\n", pc.cline); +fprintf(stderr, "!!!bif: '%s' 0x%x\n", bif->keyword, bif->flags); #endif mask = (w != exc->w.w) ? ECC_W : 0; ecc.w.fw = exc->w.fw; @@ -469,6 +551,9 @@ fprintf(stderr, "!!!pc.cline: '%s'\n", pc.cline); (bif->flags & FUNC_ALLOW_UNMANAGED)); if (rc == True) { +#if 1 /*!!!*/ +fprintf(stderr, "!!!not deferred: %d\n", rc); +#endif break; } #if 1 /*!!!*/ @@ -499,7 +584,7 @@ fprintf(stderr, "!!!erase PressedW\n"); PressedW = None; } #if 1 /*!!!*/ -fprintf(stderr, "!!!execute '%s'\n", bif->keyword); +fprintf(stderr, "!!!execute '%s' (fw %p)\n", bif->keyword, exc2->w.fw); #endif bif->action(func_rc, exc2, pc.cline, &pc); PressedW = dummy_w; diff --git a/fvwm/modconf.c b/fvwm/modconf.c index 8726df83..ab17b9d8 100644 --- a/fvwm/modconf.c +++ b/fvwm/modconf.c @@ -90,6 +90,9 @@ void ModuleConfig(char *action) fmodule *module; struct moduleInfoList *new_entry; +#if 1 /*!!!*/ +fprintf(stderr, "%s: action '%s'\n", __func__, (action) ? action : "(nil)"); +#endif end = strlen(action) - 1; if (action[end] == '\n') action[end] = '\0'; @@ -143,8 +146,16 @@ static struct moduleInfoList *AddToModList(char *tline) { /* migo (01-Sep-2000): construct an old-style config line */ char *conf_start = alias_end + 1; +#if 1 /*!!!*/ +fprintf(stderr, "%s: conf_start '%s'\n", __func__, conf_start); +#endif while (isspace(*conf_start)) conf_start++; *alias_end = '\0'; +#if 1 /*!!!*/ +fprintf(stderr, "%s: alias '%s'\n", __func__, tline ? tline : "(nil)"); +fprintf(stderr, "%s: conf_start '%s'\n", __func__, conf_start); +#endif + xasprintf(&rline, "%s%s", tline, conf_start); *alias_end = MODULE_CONFIG_DELIM; this->alias_len = alias_end - tline; @@ -152,9 +163,13 @@ static struct moduleInfoList *AddToModList(char *tline) exc = exc_create_null_context(); this->data = expand_vars(rline, NULL, False, True, NULL, exc); +#if 1 /*!!!*/ +fprintf(stderr, "%s: mldata '%s', mlaliaslen %d\n", __func__, this->data, this->alias_len); +#endif exc_destroy_context(exc); /* Free rline only if it is xasprintf'd memory (not pointing at tline - * anymore). If we free our tline argument it causes a crash in __execute_function. */ + * anymore). If we free our tline argument it causes a crash in + * __execute_function. */ if (rline != tline) free(rline); diff --git a/libs/defaults.h b/libs/defaults.h index 643b1f24..2dcb0fc6 100644 --- a/libs/defaults.h +++ b/libs/defaults.h @@ -362,7 +362,11 @@ #define DEF_FP_SORT_WINDOWLIST_BY 0 /* Function execution */ +#if 0 /*!!!*/ #define MAX_FUNCTION_DEPTH 512 +#else +#define MAX_FUNCTION_DEPTH 20 +#endif /* Tips */ #define FTIPS_DEFAULT_PLACEMENT FTIPS_PLACEMENT_AUTO_UPDOWN diff --git a/modules/FvwmButtons/dynamic.c b/modules/FvwmButtons/dynamic.c index 2739e291..e6d53c8b 100644 --- a/modules/FvwmButtons/dynamic.c +++ b/modules/FvwmButtons/dynamic.c @@ -242,6 +242,9 @@ void parse_message_line(char *line) return; } +#if 1 /*!!!*/ +fprintf(stderr, "action: '%d'\n", action); +#endif switch (action) { case 1: @@ -259,18 +262,32 @@ void parse_message_line(char *line) char *value0, *value; FvwmPicture *icon; +#if 1 /*!!!*/ +fprintf(stderr, "loop: rest: '%s'\n", rest); +#endif /* parse option and value and give diagnostics */ rest = GetQuotedString( rest, &option_pair, ",", NULL, NULL, NULL); +#if 1 /*!!!*/ +fprintf(stderr, "l2 : rest: '%s'\n", rest); +fprintf(stderr, "l2 : opt : '%s'\n", option_pair); +#endif while (isspace(*rest)) { rest++; } +#if 1 /*!!!*/ +fprintf(stderr, "l3 : rest: '%s'\n", rest); +#endif if (!option_pair) continue; option = GetTokenIndex( option_pair, button_options, -1, &value0); +#if 1 /*!!!*/ +fprintf(stderr, "4 : opt : '%d'\n", option); +fprintf(stderr, "4 : v0 : '%s'\n", value0); +#endif if (option < 0) { show_error( @@ -281,6 +298,9 @@ void parse_message_line(char *line) } GetNextToken(value0, &value); +#if 1 /*!!!*/ +fprintf(stderr, "5 : tok : '%s'\n", value); +#endif free(option_pair); if (value == NULL) @@ -306,6 +326,9 @@ void parse_message_line(char *line) b->flags.b_ActiveTitle = 1; b->title = value; value = NULL; +#if 1 /*!!!*/ +fprintf(stderr, "6 : copy: '%s'\n", b->title); +#endif break; case 4: /* PressTitle */ -- 2.30.2