>From 86a868045b8f4b132222e11fe87f5296a63eb544 Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Fri, 8 Oct 2010 23:22:25 +0200
Subject: [PATCH] wmmenugen: Finish Wmconfig parser, touch up PropList writer

As far as i can tell this finishes the Wmconfig parser (all bits we are
interested in/can use are parsed and converted).

The PropList writer gained ability to properly react to and handle various
flags passed by parsers.

Signed-off-by: Tamas TEVESZ <[email protected]>
---
 util/wmmenugen.c                |   46 ++++++++++++++++++----
 util/wmmenugen.h                |    6 ++-
 util/wmmenugen_parse_wmconfig.c |   80 ++++++++++++++++++++++++++++++++------
 util/wmmenugen_parse_xdg.c      |    1 +
 4 files changed, 111 insertions(+), 22 deletions(-)

diff --git a/util/wmmenugen.c b/util/wmmenugen.c
index 030e7ba..cbb55d8 100644
--- a/util/wmmenugen.c
+++ b/util/wmmenugen.c
@@ -46,12 +46,12 @@ static WMTreeNode *findPositionInMenu(char *submenu);
 static void (*parse)(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
 
 static WMArray *plMenuNodes;
+char *terminal;
 
 extern char *__progname;
 
 int main(int argc, char **argv)
 {
-       char *terminal;
        struct stat st;
        int i;
        int *previousDepth;
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
 #endif
                                parse = &parse_wmconfig;
                        } else {
-                               fprintf(stderr, "%s: Unknown parser \"%s\"\n", 
__progname, argv[i] + 1);
+                               fprintf(stderr, "%s: Unknown parser \"%s\"\n", 
__progname, argv[i] + 8);
                        }
                        continue;
                }
@@ -210,12 +210,42 @@ static void assemblePLMenuFunc(WMTreeNode *aNode, void 
*data)
                WMAddToArray(plMenuNodes, 
WMCreatePLArray(WMCreatePLString(wm->Name), NULL));
        } else {                                        /* new menu item */
                pl = WMPopFromArray(plMenuNodes);
-               WMAddToPLArray(pl, WMCreatePLArray(
-                       WMCreatePLString(wm->Name),
-                       WMCreatePLString(wm->Flags & F_RESTART ? "RESTART" : 
"SHEXEC"),
-                       WMCreatePLString(wm->CmdLine),
-                       NULL)
-               );
+               if (wm->Flags & F_RESTART_OTHER) {      /* RESTART, somewm */
+                       char buf[1024];
+                       memset(buf, 0, sizeof(buf));
+                       snprintf(buf, sizeof(buf), "%s %s", _("Restart"), 
wm->Name);
+                       WMAddToPLArray(pl, WMCreatePLArray(
+                               WMCreatePLString(buf),
+                               WMCreatePLString("RESTART"),
+                               WMCreatePLString(wm->CmdLine),
+                               NULL)
+                       );
+               } else if (wm->Flags & F_RESTART_SELF) {/* RESTART */
+                       WMAddToPLArray(pl, WMCreatePLArray(
+                               WMCreatePLString(_("Restart Window Maker")),
+                               WMCreatePLString("RESTART"),
+                               NULL)
+                       );
+               } else if (wm->Flags & F_QUIT) {        /* EXIT */
+                       WMAddToPLArray(pl, WMCreatePLArray(
+                               WMCreatePLString(_("Exit Window Maker")),
+                               WMCreatePLString("EXIT"),
+                               NULL)
+                       );
+               } else {                                /* plain simple command 
*/
+                       char buf[1024];
+                       memset(buf, 0, sizeof(buf));
+                       if (wm->Flags & F_TERMINAL)     /* XXX: quoting! */
+                               snprintf(buf, sizeof(buf), "%s -e \"%s\"", 
terminal, wm->CmdLine);
+                       else
+                               snprintf(buf, sizeof(buf), "%s", wm->CmdLine);
+                       WMAddToPLArray(pl, WMCreatePLArray(
+                               WMCreatePLString(wm->Name),
+                               WMCreatePLString("SHEXEC"),
+                               WMCreatePLString(buf),
+                               NULL)
+                       );
+               }
                WMAddToArray(plMenuNodes, pl);
        }
 
diff --git a/util/wmmenugen.h b/util/wmmenugen.h
index 8b75ebc..a1d7ea5 100644
--- a/util/wmmenugen.h
+++ b/util/wmmenugen.h
@@ -20,9 +20,13 @@
 
 #include <WINGs/WUtil.h>
 
+#include "../src/wconfig.h"
+
 /* flags attached to a particular WMMenuEntry */
 #define F_TERMINAL             (1 << 0)
-#define F_RESTART              (1 << 1)
+#define F_RESTART_SELF         (1 << 1)
+#define F_RESTART_OTHER                (1 << 2)
+#define F_QUIT                 (1 << 3)
 
 
 /* a representation of a Window Maker menu entry. all menus are
diff --git a/util/wmmenugen_parse_wmconfig.c b/util/wmmenugen_parse_wmconfig.c
index 6c53c9f..a03e62e 100644
--- a/util/wmmenugen_parse_wmconfig.c
+++ b/util/wmmenugen_parse_wmconfig.c
@@ -35,11 +35,13 @@ typedef struct {
        char    *Name;
        char    *Exec;
        char    *Category;
+       char    *Restart;
        int      Flags;
 } WMConfigMenuEntry;
 
 static Bool wmc_to_wm(WMConfigMenuEntry **wmc, WMMenuEntry **wm);
 static void parse_wmconfig_line(char **label, char **key, char **value, char 
*line);
+static void init_wmconfig_storage(WMConfigMenuEntry **wmc);
 
 void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry *aEntry))
 {
@@ -63,6 +65,7 @@ void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry
        wmc->Name = NULL;
        wmc->Exec = NULL;
        wmc->Category = NULL;
+       wmc->Restart = NULL;
        wmc->Flags = 0;
 
        wm = (WMMenuEntry *)wmalloc(sizeof(WMMenuEntry));
@@ -94,17 +97,11 @@ void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry
                        lastlabel = wstrdup(label);
 
                if (strcmp(lastlabel, label) != 0) {
-                       if (wmc->Name && wmc->Exec && wmc->Category &&
-                           wmc_to_wm(&wmc, &wm))
+                       if (wmc_to_wm(&wmc, &wm)) {
                                (*addWMMenuEntryCallback)(wm);
+                               init_wmconfig_storage(&wmc);
+                       }
 
-                       wfree(wmc->Name);
-                       wmc->Name = NULL;
-                       wfree(wmc->Exec);
-                       wmc->Exec = NULL;
-                       wfree(wmc->Category);
-                       wmc->Category = NULL;
-                       wmc->Flags = 0;
                        wfree(lastlabel);
                        lastlabel = wstrdup(label);
                }
@@ -117,7 +114,7 @@ void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry
                        else if (strcmp(key, "group") == 0)
                                wmc->Category = value;
                        else if (strcmp(key, "restart") == 0)
-                               wmc->Flags |= F_RESTART;
+                               wmc->Restart = value;
                        else if (strcmp(key, "terminal") == 0)
                                wmc->Flags |= F_TERMINAL;
                }
@@ -126,9 +123,10 @@ void parse_wmconfig(const char *file, void 
(*addWMMenuEntryCallback)(WMMenuEntry
 
        fclose(fp);
 
-       if (wmc_to_wm(&wmc, &wm))
+       if (wmc_to_wm(&wmc, &wm)) {
                (*addWMMenuEntryCallback)(wm);
-
+               init_wmconfig_storage(&wmc);
+       }
 }
 
 /* get a line allocating label, key and value as necessary */
@@ -181,11 +179,52 @@ static void parse_wmconfig_line(char **label, char **key, 
char **value, char *li
        *value = wstrndup(p + kstart, kend - kstart);
 }
 
+/* normalize and convert one wmconfig-format entry to wm format */
 static Bool wmc_to_wm(WMConfigMenuEntry **wmc, WMMenuEntry **wm)
 {
-       if (!*wmc || !(*wmc)->Name)
+       char *p;
+       size_t slen;
+
+       /* only Exec is mandatory */
+       if (!*wmc || !(*wmc)->Exec || !*(*wmc)->Exec)
                return False;
 
+       /* normalize Exec: wmconfig tends to stuck an ampersand
+        * at the end of everything, which we don't need */
+       slen = strlen((*wmc)->Exec) - 1;
+       p = (*wmc)->Exec;
+       while (slen > 0 && (isspace(*(p + slen)) || *(p + slen) == '&'))
+               *(p + slen--) = '\0';
+
+       /* if there's no Name, use the first word of Exec; still better
+        * than nothing. i realize it's highly arguable whether `xterm' from
+        * `xterm -e "ssh dev push-to-prod"' is helpful or not, but since
+        * the alternative is to completely lose the entry, i opt for this.
+        * you could just fix the descriptor file to have a label <G> */
+       if (!(*wmc)->Name) {
+               (*wmc)->Name = wstrdup((*wmc)->Exec);
+               p = strchr((*wmc)->Name, ' ');
+               if (p)
+                       *p = '\0';
+       }
+
+       /* if there's no Category, use "Applications"; apparently "no category"
+        * can manifest both as no `group' descriptor at all, or a group
+        * descriptor of "" */
+       if (!(*wmc)->Category || !*(*wmc)->Category)
+               (*wmc)->Category = wstrdup("Applications");
+
+       /* the `restart' type is used for restart, restart other
+        * wm and quit current wm too. separate these cases. */
+       if ((*wmc)->Restart) {
+               if (strcmp((*wmc)->Restart, "restart") == 0)
+                       (*wmc)->Flags |= F_RESTART_SELF;
+               else if (strcmp((*wmc)->Restart, "quit") == 0)
+                       (*wmc)->Flags |= F_QUIT;
+               else
+                       (*wmc)->Flags |= F_RESTART_OTHER;
+       }
+
        (*wm)->Name = (*wmc)->Name;
        (*wm)->CmdLine = (*wmc)->Exec;
        (*wm)->SubMenu = (*wmc)->Category;
@@ -193,3 +232,18 @@ static Bool wmc_to_wm(WMConfigMenuEntry **wmc, WMMenuEntry 
**wm)
 
        return True;
 }
+
+static void init_wmconfig_storage(WMConfigMenuEntry **wmc)
+{
+       if ((*wmc)->Category)
+               wfree((*wmc)->Category);
+       (*wmc)->Category = NULL;
+       if ((*wmc)->Name)
+               wfree((*wmc)->Name);
+       (*wmc)->Name = NULL;
+       if ((*wmc)->Restart)
+               wfree((*wmc)->Restart);
+       (*wmc)->Restart = NULL;
+       (*wmc)->Flags = 0;
+}
+
diff --git a/util/wmmenugen_parse_xdg.c b/util/wmmenugen_parse_xdg.c
index 0ee23f8..e19c0a2 100644
--- a/util/wmmenugen_parse_xdg.c
+++ b/util/wmmenugen_parse_xdg.c
@@ -467,3 +467,4 @@ static Bool compare_matchlevel(int *current_level, const 
char *found_locale)
 
        return False;
 }
+
-- 
1.7.0.4


-- 
[-]

mkdir /nonexistent
From 86a868045b8f4b132222e11fe87f5296a63eb544 Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Fri, 8 Oct 2010 23:22:25 +0200
Subject: [PATCH] wmmenugen: Finish Wmconfig parser, touch up PropList writer

As far as i can tell this finishes the Wmconfig parser (all bits we are
interested in/can use are parsed and converted).

The PropList writer gained ability to properly react to and handle various
flags passed by parsers.

Signed-off-by: Tamas TEVESZ <[email protected]>
---
 util/wmmenugen.c                |   46 ++++++++++++++++++----
 util/wmmenugen.h                |    6 ++-
 util/wmmenugen_parse_wmconfig.c |   80 ++++++++++++++++++++++++++++++++------
 util/wmmenugen_parse_xdg.c      |    1 +
 4 files changed, 111 insertions(+), 22 deletions(-)

diff --git a/util/wmmenugen.c b/util/wmmenugen.c
index 030e7ba..cbb55d8 100644
--- a/util/wmmenugen.c
+++ b/util/wmmenugen.c
@@ -46,12 +46,12 @@ static WMTreeNode *findPositionInMenu(char *submenu);
 static void (*parse)(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry *aEntry));
 
 static WMArray *plMenuNodes;
+char *terminal;
 
 extern char *__progname;
 
 int main(int argc, char **argv)
 {
-	char *terminal;
 	struct stat st;
 	int i;
 	int *previousDepth;
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
 #endif
 				parse = &parse_wmconfig;
 			} else {
-				fprintf(stderr, "%s: Unknown parser \"%s\"\n", __progname, argv[i] + 1);
+				fprintf(stderr, "%s: Unknown parser \"%s\"\n", __progname, argv[i] + 8);
 			}
 			continue;
 		}
@@ -210,12 +210,42 @@ static void assemblePLMenuFunc(WMTreeNode *aNode, void *data)
 		WMAddToArray(plMenuNodes, WMCreatePLArray(WMCreatePLString(wm->Name), NULL));
 	} else {					/* new menu item */
 		pl = WMPopFromArray(plMenuNodes);
-		WMAddToPLArray(pl, WMCreatePLArray(
-			WMCreatePLString(wm->Name),
-			WMCreatePLString(wm->Flags & F_RESTART ? "RESTART" : "SHEXEC"),
-			WMCreatePLString(wm->CmdLine),
-			NULL)
-		);
+		if (wm->Flags & F_RESTART_OTHER) {	/* RESTART, somewm */
+			char buf[1024];
+			memset(buf, 0, sizeof(buf));
+			snprintf(buf, sizeof(buf), "%s %s", _("Restart"), wm->Name);
+			WMAddToPLArray(pl, WMCreatePLArray(
+				WMCreatePLString(buf),
+				WMCreatePLString("RESTART"),
+				WMCreatePLString(wm->CmdLine),
+				NULL)
+			);
+		} else if (wm->Flags & F_RESTART_SELF) {/* RESTART */
+			WMAddToPLArray(pl, WMCreatePLArray(
+				WMCreatePLString(_("Restart Window Maker")),
+				WMCreatePLString("RESTART"),
+				NULL)
+			);
+		} else if (wm->Flags & F_QUIT) {	/* EXIT */
+			WMAddToPLArray(pl, WMCreatePLArray(
+				WMCreatePLString(_("Exit Window Maker")),
+				WMCreatePLString("EXIT"),
+				NULL)
+			);
+		} else {				/* plain simple command */
+			char buf[1024];
+			memset(buf, 0, sizeof(buf));
+			if (wm->Flags & F_TERMINAL)	/* XXX: quoting! */
+				snprintf(buf, sizeof(buf), "%s -e \"%s\"", terminal, wm->CmdLine);
+			else
+				snprintf(buf, sizeof(buf), "%s", wm->CmdLine);
+			WMAddToPLArray(pl, WMCreatePLArray(
+				WMCreatePLString(wm->Name),
+				WMCreatePLString("SHEXEC"),
+				WMCreatePLString(buf),
+				NULL)
+			);
+		}
 		WMAddToArray(plMenuNodes, pl);
 	}
 
diff --git a/util/wmmenugen.h b/util/wmmenugen.h
index 8b75ebc..a1d7ea5 100644
--- a/util/wmmenugen.h
+++ b/util/wmmenugen.h
@@ -20,9 +20,13 @@
 
 #include <WINGs/WUtil.h>
 
+#include "../src/wconfig.h"
+
 /* flags attached to a particular WMMenuEntry */
 #define F_TERMINAL		(1 << 0)
-#define F_RESTART		(1 << 1)
+#define F_RESTART_SELF		(1 << 1)
+#define F_RESTART_OTHER		(1 << 2)
+#define F_QUIT			(1 << 3)
 
 
 /* a representation of a Window Maker menu entry. all menus are
diff --git a/util/wmmenugen_parse_wmconfig.c b/util/wmmenugen_parse_wmconfig.c
index 6c53c9f..a03e62e 100644
--- a/util/wmmenugen_parse_wmconfig.c
+++ b/util/wmmenugen_parse_wmconfig.c
@@ -35,11 +35,13 @@ typedef struct {
 	char	*Name;
 	char	*Exec;
 	char	*Category;
+	char	*Restart;
 	int	 Flags;
 } WMConfigMenuEntry;
 
 static Bool wmc_to_wm(WMConfigMenuEntry **wmc, WMMenuEntry **wm);
 static void parse_wmconfig_line(char **label, char **key, char **value, char *line);
+static void init_wmconfig_storage(WMConfigMenuEntry **wmc);
 
 void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry *aEntry))
 {
@@ -63,6 +65,7 @@ void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry
 	wmc->Name = NULL;
 	wmc->Exec = NULL;
 	wmc->Category = NULL;
+	wmc->Restart = NULL;
 	wmc->Flags = 0;
 
 	wm = (WMMenuEntry *)wmalloc(sizeof(WMMenuEntry));
@@ -94,17 +97,11 @@ void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry
 			lastlabel = wstrdup(label);
 
 		if (strcmp(lastlabel, label) != 0) {
-			if (wmc->Name && wmc->Exec && wmc->Category &&
-			    wmc_to_wm(&wmc, &wm))
+			if (wmc_to_wm(&wmc, &wm)) {
 				(*addWMMenuEntryCallback)(wm);
+				init_wmconfig_storage(&wmc);
+			}
 
-			wfree(wmc->Name);
-			wmc->Name = NULL;
-			wfree(wmc->Exec);
-			wmc->Exec = NULL;
-			wfree(wmc->Category);
-			wmc->Category = NULL;
-			wmc->Flags = 0;
 			wfree(lastlabel);
 			lastlabel = wstrdup(label);
 		}
@@ -117,7 +114,7 @@ void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry
 			else if (strcmp(key, "group") == 0)
 				wmc->Category = value;
 			else if (strcmp(key, "restart") == 0)
-				wmc->Flags |= F_RESTART;
+				wmc->Restart = value;
 			else if (strcmp(key, "terminal") == 0)
 				wmc->Flags |= F_TERMINAL;
 		}
@@ -126,9 +123,10 @@ void parse_wmconfig(const char *file, void (*addWMMenuEntryCallback)(WMMenuEntry
 
 	fclose(fp);
 
-	if (wmc_to_wm(&wmc, &wm))
+	if (wmc_to_wm(&wmc, &wm)) {
 		(*addWMMenuEntryCallback)(wm);
-
+		init_wmconfig_storage(&wmc);
+	}
 }
 
 /* get a line allocating label, key and value as necessary */
@@ -181,11 +179,52 @@ static void parse_wmconfig_line(char **label, char **key, char **value, char *li
 	*value = wstrndup(p + kstart, kend - kstart);
 }
 
+/* normalize and convert one wmconfig-format entry to wm format */
 static Bool wmc_to_wm(WMConfigMenuEntry **wmc, WMMenuEntry **wm)
 {
-	if (!*wmc || !(*wmc)->Name)
+	char *p;
+	size_t slen;
+
+	/* only Exec is mandatory */
+	if (!*wmc || !(*wmc)->Exec || !*(*wmc)->Exec)
 		return False;
 
+	/* normalize Exec: wmconfig tends to stuck an ampersand
+	 * at the end of everything, which we don't need */
+	slen = strlen((*wmc)->Exec) - 1;
+	p = (*wmc)->Exec;
+	while (slen > 0 && (isspace(*(p + slen)) || *(p + slen) == '&'))
+		*(p + slen--) = '\0';
+
+	/* if there's no Name, use the first word of Exec; still better
+	 * than nothing. i realize it's highly arguable whether `xterm' from
+	 * `xterm -e "ssh dev push-to-prod"' is helpful or not, but since
+	 * the alternative is to completely lose the entry, i opt for this.
+	 * you could just fix the descriptor file to have a label <G> */
+	if (!(*wmc)->Name) {
+		(*wmc)->Name = wstrdup((*wmc)->Exec);
+		p = strchr((*wmc)->Name, ' ');
+		if (p)
+			*p = '\0';
+	}
+
+	/* if there's no Category, use "Applications"; apparently "no category"
+	 * can manifest both as no `group' descriptor at all, or a group
+	 * descriptor of "" */
+	if (!(*wmc)->Category || !*(*wmc)->Category)
+		(*wmc)->Category = wstrdup("Applications");
+
+	/* the `restart' type is used for restart, restart other
+	 * wm and quit current wm too. separate these cases. */
+	if ((*wmc)->Restart) {
+		if (strcmp((*wmc)->Restart, "restart") == 0)
+			(*wmc)->Flags |= F_RESTART_SELF;
+		else if (strcmp((*wmc)->Restart, "quit") == 0)
+			(*wmc)->Flags |= F_QUIT;
+		else
+			(*wmc)->Flags |= F_RESTART_OTHER;
+	}
+
 	(*wm)->Name = (*wmc)->Name;
 	(*wm)->CmdLine = (*wmc)->Exec;
 	(*wm)->SubMenu = (*wmc)->Category;
@@ -193,3 +232,18 @@ static Bool wmc_to_wm(WMConfigMenuEntry **wmc, WMMenuEntry **wm)
 
 	return True;
 }
+
+static void init_wmconfig_storage(WMConfigMenuEntry **wmc)
+{
+	if ((*wmc)->Category)
+		wfree((*wmc)->Category);
+	(*wmc)->Category = NULL;
+	if ((*wmc)->Name)
+		wfree((*wmc)->Name);
+	(*wmc)->Name = NULL;
+	if ((*wmc)->Restart)
+		wfree((*wmc)->Restart);
+	(*wmc)->Restart = NULL;
+	(*wmc)->Flags = 0;
+}
+
diff --git a/util/wmmenugen_parse_xdg.c b/util/wmmenugen_parse_xdg.c
index 0ee23f8..e19c0a2 100644
--- a/util/wmmenugen_parse_xdg.c
+++ b/util/wmmenugen_parse_xdg.c
@@ -467,3 +467,4 @@ static Bool compare_matchlevel(int *current_level, const char *found_locale)
 
 	return False;
 }
+
-- 
1.7.0.4

Reply via email to