mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 20:38:08 +01:00
renamed ParseCommand() to TokenizeString()
added rootmenu reader rewrite start
This commit is contained in:
@@ -2940,7 +2940,7 @@ execCommand(WAppIcon *btn, char *command, WSavedState *state)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseCommand(cmdline, &argv, &argc);
|
TokenizeString(cmdline, &argv, &argc);
|
||||||
|
|
||||||
if (argv==NULL) {
|
if (argv==NULL) {
|
||||||
if (cmdline)
|
if (cmdline)
|
||||||
|
|||||||
@@ -151,8 +151,7 @@ void wHackedGrabButton(unsigned int button, unsigned int modifiers,
|
|||||||
int keyboard_mode, Window confine_to, Cursor cursor);
|
int keyboard_mode, Window confine_to, Cursor cursor);
|
||||||
|
|
||||||
|
|
||||||
/* this function is in dock.c */
|
void TokenizeString(char *command, char ***argv, int *argc);
|
||||||
void ParseCommand(char *command, char ***argv, int *argc);
|
|
||||||
|
|
||||||
void ExecExitScript();
|
void ExecExitScript();
|
||||||
|
|
||||||
|
|||||||
464
src/menureader.c
Normal file
464
src/menureader.c
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
/* menureader.c- root menu definition readers
|
||||||
|
*
|
||||||
|
* Window Maker window manager
|
||||||
|
*
|
||||||
|
* Copyright (c) 2000 Alfredo K. Kojima
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "WindowMaker.h"
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
#include "rootmenu.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PLMenuReaderData {
|
||||||
|
WRootMenuReader *reader;
|
||||||
|
|
||||||
|
proplist_t pl;
|
||||||
|
int curIndex;
|
||||||
|
|
||||||
|
proplist_t *submenu;
|
||||||
|
int *curSubIndex;
|
||||||
|
int submenuDepth;
|
||||||
|
|
||||||
|
} PLMenuReaderData;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct TextMenuReaderData {
|
||||||
|
WRootMenuReader *reader;
|
||||||
|
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
} TextMenuReaderData;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PipeMenuReaderData {
|
||||||
|
WRootMenuReader *reader;
|
||||||
|
|
||||||
|
} PipeMenuReaderData;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct DirMenuReaderData {
|
||||||
|
WRootMenuReader *reader;
|
||||||
|
|
||||||
|
char **dirList;
|
||||||
|
int dirCount;
|
||||||
|
|
||||||
|
} DirMenuReaderData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef struct GNOMEMenuReaderData {
|
||||||
|
} GNOMEMenuReaderData;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuData *pl_openMenu(proplist_t pl);
|
||||||
|
static Bool pl_hasMoreData(WRootMenuData *data);
|
||||||
|
static Bool pl_nextCommand(WRootMenuData *data,
|
||||||
|
char **title,
|
||||||
|
char **command,
|
||||||
|
char **parameter,
|
||||||
|
char **shortcut);
|
||||||
|
static void pl_closeMenuFile(WRootMenuData *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuData *text_openMenuFile(char *path);
|
||||||
|
static Bool text_hasMoreData(WRootMenuData *data);
|
||||||
|
static Bool text_nextCommand(WRootMenuData *data,
|
||||||
|
char **title,
|
||||||
|
char **command,
|
||||||
|
char **parameter,
|
||||||
|
char **shortcut);
|
||||||
|
static void text_closeMenuFile(WRootMenuData *data);
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuData *dir_openMenuFile(char *path);
|
||||||
|
static Bool dir_hasMoreData(WRootMenuData *data);
|
||||||
|
static Bool dir_nextCommand(WRootMenuData *data,
|
||||||
|
char **title,
|
||||||
|
char **command,
|
||||||
|
char **parameter,
|
||||||
|
char **shortcut);
|
||||||
|
static void dir_closeMenuFile(WRootMenuData *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuReader PLMenuReader = {
|
||||||
|
pl_hasMoreData,
|
||||||
|
pl_nextCommand,
|
||||||
|
pl_closeMenuFile
|
||||||
|
};
|
||||||
|
|
||||||
|
static WRootMenuReader TextMenuReader = {
|
||||||
|
text_hasMoreData,
|
||||||
|
text_nextCommand,
|
||||||
|
text_closeMenuFile
|
||||||
|
};
|
||||||
|
|
||||||
|
static WRootMenuReader DirMenuReaderData = {
|
||||||
|
dir_hasMoreData,
|
||||||
|
dir_nextCommand,
|
||||||
|
dir_closeMenuFile
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
WRootMenuReader GNOMEMenuReaderData = {
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define LINESIZE 1024
|
||||||
|
|
||||||
|
static char linebuf[LINESIZE];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- proplist ---------- */
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuData *pl_openMenuFile(proplist_t pl)
|
||||||
|
{
|
||||||
|
PLRootMenuData *data = wmalloc(sizeof(PLRootMenuData));
|
||||||
|
|
||||||
|
data->reader = PLMenuReader;
|
||||||
|
|
||||||
|
data->pl = pl;
|
||||||
|
data->curIndex = 0;
|
||||||
|
|
||||||
|
data->submenu = NULL;
|
||||||
|
data->curSubIndex = NULL;
|
||||||
|
data->submenuDepth = 0;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool pl_hasMoreData(WRootMenuData *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool pl_nextCommand(WRootMenuData *data,
|
||||||
|
char **title,
|
||||||
|
char **command,
|
||||||
|
char **parameter,
|
||||||
|
char **shortcut)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void pl_closeMenuFile(WRootMenuData *data)
|
||||||
|
{
|
||||||
|
if (data->submenu)
|
||||||
|
free(data->submenu);
|
||||||
|
if (data->curSubIndex)
|
||||||
|
free(data->curSubIndex);
|
||||||
|
|
||||||
|
PLRelease(data->pl);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- text ---------- */
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuData *text_openMenuFile(char *path)
|
||||||
|
{
|
||||||
|
TextMenuReaderData *data;
|
||||||
|
|
||||||
|
data = wmalloc(sizeof(TextMenuReaderData));
|
||||||
|
data->reader = TextMenuReader;
|
||||||
|
|
||||||
|
data->file = fopen(path, "r");
|
||||||
|
if (!data->file) {
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool text_hasMoreData(WRootMenuData *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool text_nextCommand(WRootMenuData *data,
|
||||||
|
char **title,
|
||||||
|
char **command,
|
||||||
|
char **parameter,
|
||||||
|
char **shortcut)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void text_closeMenuFile(WRootMenuData *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- directory ---------- */
|
||||||
|
|
||||||
|
|
||||||
|
static WRootMenuData *dir_openMenuFile(char *paths, time_t *timestamp)
|
||||||
|
{
|
||||||
|
DirMenuReaderData *data;
|
||||||
|
char **dirs;
|
||||||
|
int dirN;
|
||||||
|
time_t checksum = 0;
|
||||||
|
int i, c;
|
||||||
|
|
||||||
|
/* timestamp for directory is a "checksum" of the directory times */
|
||||||
|
|
||||||
|
TokenizeString(paths, &dirs, &dirN);
|
||||||
|
|
||||||
|
if (dirN == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (c = 0, i = 0; i < dirN; i++) {
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
if (strcmp(dirs[i], "-noext")==0) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = wexpandpath(dirs[i]);
|
||||||
|
free(dirs[i]);
|
||||||
|
dirs[i] = tmp;
|
||||||
|
|
||||||
|
if (stat(dirs[i], &stat_buf)<0) {
|
||||||
|
wsyserror(_("%s:could not stat menu"), dirs[i]);
|
||||||
|
free(dirs[i]);
|
||||||
|
dirs[i] = NULL;
|
||||||
|
} else {
|
||||||
|
c++;
|
||||||
|
checksum += stat_buf.st_mtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*timestamp == checksum && *timestamp != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 0) {
|
||||||
|
for (i = 0; i < dirN; i++) {
|
||||||
|
if (dirs[i])
|
||||||
|
free(dirs[i]);
|
||||||
|
}
|
||||||
|
free(dirs);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = wmalloc(sizeof(DirMenuReaderData));
|
||||||
|
data->reader = DirMenuReader;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Bool dir_hasMoreData(WRootMenuData *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool dir_nextCommand(WRootMenuData *data,
|
||||||
|
char **title,
|
||||||
|
char **command,
|
||||||
|
char **parameter,
|
||||||
|
char **shortcut)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dir_closeMenuFile(WRootMenuData *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WRootMenuData *OpenMenu(char *path, time_t *menuTime)
|
||||||
|
{
|
||||||
|
proplist pl;
|
||||||
|
struct stat stat_buf;
|
||||||
|
WRootMenuData *data;
|
||||||
|
|
||||||
|
/* check whether it's a piped menu */
|
||||||
|
if (*path == '|') {
|
||||||
|
/* piped menus have the following semantics for menuTime:
|
||||||
|
* if it's 0, then it wasnt loaded yet
|
||||||
|
* if it's 1, it was already loaded, so do not reload
|
||||||
|
* (would be too slow)
|
||||||
|
* now, menuTime will only be set to 1 if the pipe command is
|
||||||
|
* specified as ||command instead of |command
|
||||||
|
* in other words ||command means force the submenu to always refresh
|
||||||
|
*/
|
||||||
|
if (*menuTime == 0) {
|
||||||
|
data = pipe_openMenu(path);
|
||||||
|
}
|
||||||
|
if (path[1] != '|') {
|
||||||
|
*menuTime = 1;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(path, &stat_buf) < 0) {
|
||||||
|
wsyserror(_("could not stat() menu file '%s'"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check whether it's a directory */
|
||||||
|
if (S_ISDIR(stat_buf.st_mode)) {
|
||||||
|
return dir_openMenuFile(path, menuTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (*menuTime >= stat_buf.st_mtime && *menuTime != 0) {
|
||||||
|
/* no changes in the menu file */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then check whether it's a proplist menu */
|
||||||
|
pl = ReadProplistFromFile(path);
|
||||||
|
if (pl && PLIsArray(pl)) {
|
||||||
|
*menuTime = stat_buf.st_mtime;
|
||||||
|
return pl_openMenu(pl);
|
||||||
|
}
|
||||||
|
|
||||||
|
*menuTime = stat_buf.st_mtime;
|
||||||
|
/* assume its a plain text menu */
|
||||||
|
return text_openMenuFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WRootMenuData *ReopenRootMenu(time_t *checkTime,
|
||||||
|
char **menuPath,
|
||||||
|
time_t *menuTimestamp)
|
||||||
|
{
|
||||||
|
proplist pl;
|
||||||
|
struct stat stat_buf;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
|
||||||
|
if (stat(path, &stat_buf) < 0) {
|
||||||
|
wsyserror(_("could not stat() menu file '%s'"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*menuTime >= stat_buf.st_mtime && *checkTime != 0) {
|
||||||
|
/* no changes in WMRootMenu, see if the contents changed */
|
||||||
|
if (*menuPath != NULL) {
|
||||||
|
return OpenMenu(*menuPath, menuTimestamp);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*checkTime = stat_buf.st_mtime;
|
||||||
|
|
||||||
|
pl = ReadProplistFromFile(path);
|
||||||
|
if (!pl) {
|
||||||
|
wwarning(_("could not load domain %s from user defaults database"),
|
||||||
|
"WMRootMenu");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PLIsString(pl)) {
|
||||||
|
char *tmp;
|
||||||
|
char *path;
|
||||||
|
Bool menu_is_default = False;
|
||||||
|
|
||||||
|
tmp = wexpandpath(PLGetString(pl));
|
||||||
|
|
||||||
|
path = getLocalizedMenuFile(tmp);
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
path = wfindfile(DEF_CONFIG_PATHS, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
wwarning(_("could not find menu file '%s' referenced in WMRootMenu"),
|
||||||
|
tmp);
|
||||||
|
path = wfindfile(DEF_CONFIG_PATHS, DEF_MENU_FILE);
|
||||||
|
menu_is_default = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
wwarning(_("could not find any usable menu files. Please check '%s'"),
|
||||||
|
tmp);
|
||||||
|
free(tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
if (*menuPath) {
|
||||||
|
if (strcmp(*menuPath, path) != 0) {
|
||||||
|
*menuTimestamp = 0;
|
||||||
|
free(*menuPath);
|
||||||
|
*menuPath = path;
|
||||||
|
|
||||||
|
if (menu_is_default) {
|
||||||
|
wwarning(_("using default menu file \"%s\" as the menu referenced in WMRootMenu could not be found "),
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* the menu path didn't change, but the
|
||||||
|
* pointed file might have changed, so we don't return
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*menuPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OpenMenu(*menuPath, menuTimestamp);
|
||||||
|
} else if (PLIsArray(pl)) {
|
||||||
|
|
||||||
|
*menuTimestamp = stat_buf.st_mtime;
|
||||||
|
|
||||||
|
return pl_openMenu(pl);
|
||||||
|
} else {
|
||||||
|
wwarning(_("invalid content in menu file '%s'.\nIt should either be a property list menu or the path to the file, enclosed in \"."),
|
||||||
|
path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
20
src/misc.c
20
src/misc.c
@@ -625,29 +625,27 @@ next_token(char *word, char **next)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* separate a string in tokens, taking " and ' into account */
|
||||||
void
|
void
|
||||||
ParseCommand(char *command, char ***argv, int *argc)
|
TokenizeString(char *command, char ***argv, int *argc)
|
||||||
{
|
{
|
||||||
WMBag *bag = WMCreateBag(4);
|
|
||||||
char *token, *line;
|
char *token, *line;
|
||||||
int count, j;
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
line = command;
|
line = command;
|
||||||
do {
|
do {
|
||||||
token = next_token(line, &line);
|
token = next_token(line, &line);
|
||||||
if (token) {
|
if (token) {
|
||||||
WMPutInBag(bag, token);
|
if (count == 0)
|
||||||
|
*argv = wmalloc(sizeof(char**));
|
||||||
|
else
|
||||||
|
*argv = wrealloc(*argv, (count+1)*sizeof(char**));
|
||||||
|
(*argv)[count++] = token;
|
||||||
}
|
}
|
||||||
} while (token!=NULL && line!=NULL);
|
} while (token!=NULL && line!=NULL);
|
||||||
|
|
||||||
count = WMGetBagItemCount(bag);
|
|
||||||
*argv = wmalloc(sizeof(char*)*count);
|
|
||||||
for (j = 0; j < count; j++) {
|
|
||||||
(*argv)[j] = WMGetFromBag(bag, j);
|
|
||||||
}
|
|
||||||
*argc = count;
|
*argc = count;
|
||||||
|
|
||||||
WMFreeBag(bag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ execCommand(WScreen *scr, char *command, char *host)
|
|||||||
char **argv;
|
char **argv;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
ParseCommand(command, &argv, &argc);
|
TokenizeString(command, &argv, &argc);
|
||||||
|
|
||||||
if (argv==NULL) {
|
if (argv==NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user