mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 20:38:08 +01:00
util: improve the command line argument parsing in wmmenugen
The code ignored the last argument provided on the command line; It did not support the recommended '--version' and '--help' from GNU which are often handy; It used an unusual syntax to specify the parser, now it can also use more usual "-parser=name" and "-parser name", the old syntax is still supported to avoid breaking compatibility; When a problem is found with an argument, the program stops instead of printing an error message and continuing; There's been updates on the exit codes in case of problem because it is an information that could be useful for people calling the program from a script; Took the opportunity to provide more information in the man page and to get it cross-checked against the program's option list during "make check". Signed-off-by: Christophe CURIS <christophe.curis@free.fr>
This commit is contained in:
committed by
Carlos R. Mafra
parent
8088dc1eab
commit
0a009143c3
@@ -49,7 +49,7 @@ am__v_CHKOPTS_0 = @echo " CHK $@" ;
|
|||||||
am__v_CHKOPTS_1 =
|
am__v_CHKOPTS_1 =
|
||||||
|
|
||||||
check-local: wmaker-args WPrefs-args wmagnify-args geticonset-args getstyle-args seticons-args setstyle-args \
|
check-local: wmaker-args WPrefs-args wmagnify-args geticonset-args getstyle-args seticons-args setstyle-args \
|
||||||
wdread-args wdwrite-args wmgenmenu-args wmsetbg-args wxcopy-args wxpaste-args
|
wdread-args wdwrite-args wmgenmenu-args wmmenugen-args wmsetbg-args wxcopy-args wxpaste-args
|
||||||
|
|
||||||
wmaker-args:
|
wmaker-args:
|
||||||
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
||||||
@@ -91,6 +91,10 @@ wmgenmenu-args:
|
|||||||
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
||||||
--program "$(top_builddir)/util/wmgenmenu" --man-page "$(top_srcdir)/doc/wmgenmenu.1"
|
--program "$(top_builddir)/util/wmgenmenu" --man-page "$(top_srcdir)/doc/wmgenmenu.1"
|
||||||
|
|
||||||
|
wmmenugen-args:
|
||||||
|
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
||||||
|
--program "$(top_builddir)/util/wmmenugen" --man-page "$(top_srcdir)/doc/wmmenugen.1"
|
||||||
|
|
||||||
wmsetbg-args:
|
wmsetbg-args:
|
||||||
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
$(AM_V_CHKOPTS)$(top_srcdir)/script/check-cmdline-options-doc.sh \
|
||||||
--program "$(top_builddir)/util/wmsetbg" --man-page "wmsetbg.1"
|
--program "$(top_builddir)/util/wmsetbg" --man-page "wmsetbg.1"
|
||||||
@@ -104,4 +108,4 @@ wxpaste-args:
|
|||||||
--program "$(top_builddir)/util/wxpaste" --man-page "$(top_srcdir)/doc/wxpaste.1"
|
--program "$(top_builddir)/util/wxpaste" --man-page "$(top_srcdir)/doc/wxpaste.1"
|
||||||
|
|
||||||
.PHONY: wmaker-args WPrefs-args wmagnify-args geticonset-args getstyle-args seticons-args setstyle-args \
|
.PHONY: wmaker-args WPrefs-args wmagnify-args geticonset-args getstyle-args seticons-args setstyle-args \
|
||||||
wdread-args wdwrite-args wmgenmenu-args wmsetbg-args wxcopy-args wxpaste-args
|
wdread-args wdwrite-args wmgenmenu-args wmmenugen-args wmsetbg-args wxcopy-args wxpaste-args
|
||||||
|
|||||||
@@ -1,22 +1,93 @@
|
|||||||
.TH "wmmenugen" "1" "15 August 2011"
|
.TH "wmmenugen" "1" "16 May 2015"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBwmmenugen\fR \- Window Maker PropList menu generator
|
\fBwmmenugen\fR \- Window Maker PropList menu generator
|
||||||
.PP
|
.PP
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.B wmmenugen \fI\-parser:<parser> fspec \fR[ fpsec ... \fR]
|
.B wmmenugen
|
||||||
\fR[\fI\-parser:<parser> fspec \fR[ fpsec ... \fR] ... \fR]
|
.RI [ options ...]
|
||||||
.PP
|
.BI \-parser= <name>
|
||||||
|
.IR fspec " [" fspec "...]"
|
||||||
|
.BI \fR[\fP\-parser= <name>
|
||||||
|
.IR fspec " [" fspec "...]...]"
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
\fBwmmenugen \fR\- Window Maker PropList menu generator
|
.B wmmenugen
|
||||||
.PP
|
generates a menu in the
|
||||||
|
.I PropList
|
||||||
|
format for Window Maker from the input file
|
||||||
|
.IR fspec .
|
||||||
|
In the case where
|
||||||
|
.I fspec
|
||||||
|
is a directory instead of a file, then
|
||||||
|
.B wmmenugen
|
||||||
|
will read all the files present in the hierarchy of this directory.
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
.TP
|
.TP
|
||||||
.B \-parser
|
.BR \-\-help ", " \-h
|
||||||
\fRspecify the parser. Known parsers are xdg and wmconfig.
|
print a help message with the list of options
|
||||||
.TP
|
.TP
|
||||||
.B \-fspec
|
.B \-parser
|
||||||
\fRspecify the file.
|
specify the format of the file to be parsed
|
||||||
|
.TP
|
||||||
|
.B \-\-version
|
||||||
|
print the version of Window Maker from which the program comes
|
||||||
|
.SH "PARSERS"
|
||||||
|
.B wmmenugen
|
||||||
|
supports these file formats for input files:
|
||||||
|
.TP
|
||||||
|
.I wmconfig
|
||||||
|
the format of the menu generation tool for X of the same name
|
||||||
|
.TP
|
||||||
|
.I xdg
|
||||||
|
the format of the menu specification as defined by the
|
||||||
|
.I FreeDesktop
|
||||||
|
standard, currently at version 1.1
|
||||||
|
.SH "RETURN VALUE"
|
||||||
|
The exit status from the
|
||||||
|
.B wmmenugen
|
||||||
|
command provides information for the caller:
|
||||||
|
.TP
|
||||||
|
.B 0
|
||||||
|
when the
|
||||||
|
.I PropList
|
||||||
|
menu was successfully generated on
|
||||||
|
.IR stdout .
|
||||||
|
.TP
|
||||||
|
.B 1
|
||||||
|
when a
|
||||||
|
.I fspec
|
||||||
|
caused a problem (non readable file, ...)
|
||||||
|
.TP
|
||||||
|
.B 2
|
||||||
|
the arguments of the command line where not recognised
|
||||||
|
.TP
|
||||||
|
.B 3
|
||||||
|
the program met an unexpected menu structure;
|
||||||
|
you probably want to look at the section
|
||||||
|
.B BUGS
|
||||||
|
below.
|
||||||
|
.SH "BUGS"
|
||||||
|
If you get the exit status
|
||||||
|
.B 3
|
||||||
|
with the unclear error message about
|
||||||
|
.IR "unprocessed levels on the stack" ,
|
||||||
|
you encountered a limitation of
|
||||||
|
.BR wmmenugen .
|
||||||
|
It would be a good idea to prepare an archive with the files incriminated and submit them to the
|
||||||
|
mailing list (wmaker-dev@lists.windowmaker.org) with you command line, so the team can work on
|
||||||
|
improving the behaviour of the program on this case.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR wmgenmenu (1),
|
||||||
|
the tool to generate a default menu
|
||||||
.PP
|
.PP
|
||||||
|
the
|
||||||
|
.I Wmconfig
|
||||||
|
program can be found at:
|
||||||
|
<http://www.arrishq.net/index.html>
|
||||||
|
.PP
|
||||||
|
the
|
||||||
|
.I xdg
|
||||||
|
specification can be found at:
|
||||||
|
<http://standards.freedesktop.org/menu-spec/menu-spec-1.1.html>
|
||||||
.SH "AUTHOR"
|
.SH "AUTHOR"
|
||||||
wmmenugen is a part of Window Maker. It was written by Tamas TEVESZ.
|
wmmenugen is a part of Window Maker. It was written by Tamas TEVESZ.
|
||||||
.PP
|
.PP
|
||||||
|
|||||||
117
util/wmmenugen.c
117
util/wmmenugen.c
@@ -28,6 +28,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "wmmenugen.h"
|
#include "wmmenugen.h"
|
||||||
|
|
||||||
@@ -54,6 +55,35 @@ static const char *prog_name;
|
|||||||
WMTreeNode *menu;
|
WMTreeNode *menu;
|
||||||
char *env_lang, *env_ctry, *env_enc, *env_mod;
|
char *env_lang, *env_ctry, *env_enc, *env_mod;
|
||||||
|
|
||||||
|
static void print_help(void)
|
||||||
|
{
|
||||||
|
printf("Usage: %s -parser:<parser> fspec [fspec...]\n", prog_name);
|
||||||
|
puts("Dynamically generate a menu in Property List format for Window Maker");
|
||||||
|
puts("");
|
||||||
|
puts(" -h, --help\t\tdisplay this help and exit");
|
||||||
|
puts(" -parser=<name>\tspecify the format of the input, see below");
|
||||||
|
puts(" --version\t\toutput version information and exit");
|
||||||
|
puts("");
|
||||||
|
puts("fspec: the file to be converted or the directory containing all the menu files");
|
||||||
|
puts("");
|
||||||
|
puts("Known parsers:");
|
||||||
|
puts(" xdg\t\tDesktop Entry from FreeDesktop standard");
|
||||||
|
puts(" wmconfig\tfrom the menu generation tool by the same name");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static const char *get_parser_name(void)
|
||||||
|
{
|
||||||
|
if (parse == &parse_xdg)
|
||||||
|
return "xdg";
|
||||||
|
if (parse == &parse_wmconfig)
|
||||||
|
return "wmconfig";
|
||||||
|
|
||||||
|
/* This case is not supposed to happen, but if it does it means that someone to update this list */
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -76,45 +106,69 @@ int main(int argc, char **argv)
|
|||||||
parse_locale(NULL, &env_lang, &env_ctry, &env_enc, &env_mod);
|
parse_locale(NULL, &env_lang, &env_ctry, &env_enc, &env_mod);
|
||||||
terminal = find_terminal_emulator();
|
terminal = find_terminal_emulator();
|
||||||
|
|
||||||
if (argc < 3) {
|
for (i = 1; i <= argc; i++)
|
||||||
fprintf(stderr, "Usage: %s -parser:<parser> fspec [fpsec...] "
|
|
||||||
"[-parser:<parser> fspec [fpsec...]...]\n", prog_name);
|
|
||||||
fputs( "Known parsers: xdg wmconfig\n", stderr);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
|
||||||
{
|
{
|
||||||
if (strncmp(argv[i], "-parser:", 8) == 0) {
|
if (strncmp(argv[i], "-parser", 7) == 0 &&
|
||||||
if (strcmp(argv[i] + 8, "xdg") == 0) {
|
(argv[i][7] == '=' ||
|
||||||
#if DEBUG
|
argv[i][7] == ':' || /* for legacy compatibility */
|
||||||
fputs("Using parser \"xdg\"\n", stderr);
|
argv[i][7] == '\0')) {
|
||||||
#endif
|
const char *name;
|
||||||
|
|
||||||
|
if (argv[i][7] == '\0') {
|
||||||
|
if (++i > argc) {
|
||||||
|
fprintf(stderr, "%s: Missing parser name after \"-parser\"\n", prog_name);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
name = argv[i];
|
||||||
|
} else {
|
||||||
|
name = argv[i] + 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(name, "xdg") == 0) {
|
||||||
parse = &parse_xdg;
|
parse = &parse_xdg;
|
||||||
} else if (strcmp(argv[i] + 8, "wmconfig") == 0) {
|
} else if (strcmp(name, "wmconfig") == 0) {
|
||||||
#if DEBUG
|
|
||||||
fputs("Using parser \"wmconfig\"\n", stderr);
|
|
||||||
#endif
|
|
||||||
parse = &parse_wmconfig;
|
parse = &parse_wmconfig;
|
||||||
validateFilename = &wmconfig_validate_file;
|
validateFilename = &wmconfig_validate_file;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: Unknown parser \"%s\"\n", prog_name, argv[i] + 8);
|
fprintf(stderr, "%s: Unknown parser \"%s\"\n", prog_name, name);
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse) {
|
if (strcmp(argv[i], "--version") == 0) {
|
||||||
if (stat(argv[i], &st) == -1) {
|
printf("%s (Window Maker %s)\n", prog_name, VERSION);
|
||||||
fprintf(stderr, "%s: unable to stat \"%s\"\n", prog_name, argv[i]);
|
return 0;
|
||||||
} else if (S_ISREG(st.st_mode)) {
|
}
|
||||||
parse(argv[i], addWMMenuEntryCallback);
|
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
if (strcmp(argv[i], "-h") == 0 ||
|
||||||
nftw(argv[i], dirParseFunc, 16, FTW_PHYS);
|
strcmp(argv[i], "-help") == 0 ||
|
||||||
} else {
|
strcmp(argv[i], "--help") == 0) {
|
||||||
fprintf(stderr, "%s: \"%s\" is not a file or directory\n", prog_name, argv[i]);
|
print_help();
|
||||||
}
|
return 0;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (parse == NULL) {
|
||||||
fprintf(stderr, "%s: argument \"%s\" with no valid parser\n", prog_name, argv[i]);
|
fprintf(stderr, "%s: argument \"%s\" with no valid parser\n", prog_name, argv[i]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
fprintf(stderr, "%s: Using parser \"%s\" to process \"%s\"\n",
|
||||||
|
prog_name, get_parser_name(), argv[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (stat(argv[i], &st) == -1) {
|
||||||
|
fprintf(stderr, "%s: unable to stat \"%s\", %s\n",
|
||||||
|
prog_name, argv[i], strerror(errno));
|
||||||
|
return 1;
|
||||||
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
|
parse(argv[i], addWMMenuEntryCallback);
|
||||||
|
} else if (S_ISDIR(st.st_mode)) {
|
||||||
|
nftw(argv[i], dirParseFunc, 16, FTW_PHYS);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: \"%s\" is not a file or directory\n", prog_name, argv[i]);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,16 +183,17 @@ int main(int argc, char **argv)
|
|||||||
i = WMGetArrayItemCount(plMenuNodes);
|
i = WMGetArrayItemCount(plMenuNodes);
|
||||||
if (i > 2) { /* more than one submenu unprocessed is almost certainly an error */
|
if (i > 2) { /* more than one submenu unprocessed is almost certainly an error */
|
||||||
fprintf(stderr, "%s: unprocessed levels on the stack. fishy.\n", prog_name);
|
fprintf(stderr, "%s: unprocessed levels on the stack. fishy.\n", prog_name);
|
||||||
return 1;
|
return 3;
|
||||||
} else if (i > 1 ) { /* possibly the top-level attachment is not yet done */
|
} else if (i > 1 ) { /* possibly the top-level attachment is not yet done */
|
||||||
WMPropList *first, *next;
|
WMPropList *first, *next;
|
||||||
|
|
||||||
next = WMPopFromArray(plMenuNodes);
|
next = WMPopFromArray(plMenuNodes);
|
||||||
first = WMPopFromArray(plMenuNodes);
|
first = WMPopFromArray(plMenuNodes);
|
||||||
WMAddToPLArray(first, next);
|
WMAddToPLArray(first, next);
|
||||||
WMAddToArray(plMenuNodes, first);
|
WMAddToArray(plMenuNodes, first);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s\n", WMGetPropListDescription((WMPropList *)WMGetFromArray(plMenuNodes, 0), True));
|
puts(WMGetPropListDescription((WMPropList *)WMGetFromArray(plMenuNodes, 0), True));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user