1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-01-09 15:24:12 +01:00

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 <ice@extreme.hu>
This commit is contained in:
Tamas TEVESZ
2010-10-08 23:22:25 +02:00
committed by Carlos R. Mafra
parent a396f3bd66
commit 0451160f7d
3 changed files with 109 additions and 22 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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,17 @@ 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;
}