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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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