mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
Use the NetBSD getopt_long implementation on Windows.
This makes the espeak-ng.c and speak-ng.c source code easier to read and maintain. It also addresses bugs in command-line argument parsing with the espeak implementation, for example it treats `--compile-phonemes` as `--compile` due to an argument matching bug.
This commit is contained in:
+12
-22
@@ -29,29 +29,19 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: getopt_long.c,v 1.27 2015/09/01 19:39:57 kamil Exp $");
|
||||
|
||||
#include "namespace.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "compat_getopt.h"
|
||||
#else
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND
|
||||
#define REPLACE_GETOPT
|
||||
#endif
|
||||
|
||||
#define _DIAGASSERT(x) assert(x)
|
||||
#define __UNCONST(x) (char *)(x)
|
||||
|
||||
#ifdef REPLACE_GETOPT
|
||||
#ifdef __weak_alias
|
||||
@@ -251,7 +241,7 @@ start:
|
||||
if (!*place)
|
||||
++optind;
|
||||
if (PRINT_ERROR)
|
||||
warnx(illoptchar, optchar);
|
||||
fprintf(stderr, illoptchar, optchar);
|
||||
optopt = optchar;
|
||||
return BADCH;
|
||||
}
|
||||
@@ -263,7 +253,7 @@ start:
|
||||
if (++optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
warnx(recargchar, optchar);
|
||||
fprintf(stderr, recargchar, optchar);
|
||||
optopt = optchar;
|
||||
return BADARG;
|
||||
} else /* white space */
|
||||
@@ -286,7 +276,7 @@ start:
|
||||
if (++optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
warnx(recargchar, optchar);
|
||||
fprintf(stderr, recargchar, optchar);
|
||||
optopt = optchar;
|
||||
return BADARG;
|
||||
} else
|
||||
@@ -407,7 +397,7 @@ getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
if (ambiguous) {
|
||||
/* ambiguous abbreviation */
|
||||
if (PRINT_ERROR)
|
||||
warnx(ambig, (int)current_argv_len,
|
||||
fprintf(stderr, ambig, (int)current_argv_len,
|
||||
current_argv);
|
||||
optopt = 0;
|
||||
return BADCH;
|
||||
@@ -416,7 +406,7 @@ getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
if (long_options[match].has_arg == no_argument
|
||||
&& has_equal) {
|
||||
if (PRINT_ERROR)
|
||||
warnx(noarg, (int)current_argv_len,
|
||||
fprintf(stderr, noarg, (int)current_argv_len,
|
||||
current_argv);
|
||||
/*
|
||||
* XXX: GNU sets optopt to val regardless of
|
||||
@@ -448,7 +438,7 @@ getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
* indicates no error should be generated
|
||||
*/
|
||||
if (PRINT_ERROR)
|
||||
warnx(recargstring, current_argv);
|
||||
fprintf(stderr, recargstring, current_argv);
|
||||
/*
|
||||
* XXX: GNU sets optopt to val regardless
|
||||
* of flag
|
||||
@@ -462,7 +452,7 @@ getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
}
|
||||
} else { /* unknown option */
|
||||
if (PRINT_ERROR)
|
||||
warnx(illoptstring, current_argv);
|
||||
fprintf(stderr, illoptstring, current_argv);
|
||||
optopt = 0;
|
||||
return BADCH;
|
||||
}
|
||||
|
||||
@@ -25,9 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -296,22 +294,6 @@ static void PrintVersion()
|
||||
printf("eSpeak text-to-speech: %s Data at: %s\n", version, path_data);
|
||||
}
|
||||
|
||||
#ifndef HAVE_GETOPT_H
|
||||
struct option {
|
||||
char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
int optind;
|
||||
static int optional_argument;
|
||||
static const char *arg_opts = "abdfgklpsvw"; // which options have arguments
|
||||
static char *opt_string = "";
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
@@ -375,51 +357,6 @@ int main(int argc, char **argv)
|
||||
devicename[0] = 0;
|
||||
option_punctlist[0] = 0;
|
||||
|
||||
#ifndef HAVE_GETOPT_H
|
||||
optind = 1;
|
||||
opt_string = "";
|
||||
while (optind < argc) {
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
if ((c = *opt_string) == 0) {
|
||||
opt_string = argv[optind];
|
||||
if (opt_string[0] != '-')
|
||||
break;
|
||||
|
||||
optind++;
|
||||
opt_string++;
|
||||
c = *opt_string;
|
||||
}
|
||||
opt_string++;
|
||||
p = optarg2 = opt_string;
|
||||
|
||||
if (c == '-') {
|
||||
if (p[0] == 0)
|
||||
break; // -- means don't interpret further - as commands
|
||||
|
||||
opt_string = "";
|
||||
for (ix = 0;; ix++) {
|
||||
if (long_options[ix].name == 0)
|
||||
break;
|
||||
len = strlen(long_options[ix].name);
|
||||
if (memcmp(long_options[ix].name, p, len) == 0) {
|
||||
c = long_options[ix].val;
|
||||
optarg2 = NULL;
|
||||
|
||||
if ((long_options[ix].has_arg != 0) && (p[len] == '='))
|
||||
optarg2 = &p[len+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (strchr(arg_opts, c) != NULL) {
|
||||
opt_string = "";
|
||||
if (optarg2[0] == 0) {
|
||||
// the option's value is in the next argument
|
||||
optarg2 = argv[optind++];
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (true) {
|
||||
c = getopt_long(argc, argv, "a:b:d:f:g:hk:l:mp:qs:v:w:xXz",
|
||||
long_options, &option_index);
|
||||
@@ -428,7 +365,6 @@ int main(int argc, char **argv)
|
||||
if (c == -1)
|
||||
break;
|
||||
optarg2 = optarg;
|
||||
#endif
|
||||
|
||||
switch (c)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Compatibility shim for <getopt.h>
|
||||
*
|
||||
* Copyright (C) 2006 to 2013 by Jonathan Duddington
|
||||
* email: jonsd@users.sourceforge.net
|
||||
* Copyright (C) 2016 Reece H. Dunn
|
||||
*
|
||||
* 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 3 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/>.
|
||||
*/
|
||||
|
||||
#ifndef GETOPT_H_COMPAT_SHIM
|
||||
#define GETOPT_H_COMPAT_SHIM
|
||||
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
#pragma GCC system_header // Silence "warning: #include_next is a GCC extension"
|
||||
#include_next <getopt.h>
|
||||
#else
|
||||
|
||||
struct option {
|
||||
char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
int
|
||||
getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -40,9 +40,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <locale.h>
|
||||
@@ -286,22 +284,6 @@ static int WavegenFile(void)
|
||||
return finished;
|
||||
}
|
||||
|
||||
#ifndef HAVE_GETOPT_H
|
||||
struct option {
|
||||
char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
int optind;
|
||||
static int optional_argument;
|
||||
static const char *arg_opts = "abfgklpsvw"; // which options have arguments
|
||||
static char *opt_string = "";
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
@@ -361,51 +343,6 @@ int main(int argc, char **argv)
|
||||
option_multibyte = espeakCHARS_AUTO;
|
||||
f_trans = stdout;
|
||||
|
||||
#ifndef HAVE_GETOPT_H
|
||||
optind = 1;
|
||||
opt_string = "";
|
||||
while (optind < argc) {
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
if ((c = *opt_string) == 0) {
|
||||
opt_string = argv[optind];
|
||||
if (opt_string[0] != '-')
|
||||
break;
|
||||
|
||||
optind++;
|
||||
opt_string++;
|
||||
c = *opt_string;
|
||||
}
|
||||
opt_string++;
|
||||
p = optarg2 = opt_string;
|
||||
|
||||
if (c == '-') {
|
||||
if (p[0] == 0)
|
||||
break; // -- means don't interpret further - as commands
|
||||
|
||||
opt_string = "";
|
||||
for (ix = 0;; ix++) {
|
||||
if (long_options[ix].name == 0)
|
||||
break;
|
||||
len = strlen(long_options[ix].name);
|
||||
if (memcmp(long_options[ix].name, p, len) == 0) {
|
||||
c = long_options[ix].val;
|
||||
optarg2 = NULL;
|
||||
|
||||
if ((long_options[ix].has_arg != 0) && (p[len] == '='))
|
||||
optarg2 = &p[len+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (strchr(arg_opts, c) != NULL) {
|
||||
opt_string = "";
|
||||
if (optarg2[0] == 0) {
|
||||
// the option's value is in the next argument
|
||||
optarg2 = argv[optind++];
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (true) {
|
||||
c = getopt_long(argc, argv, "a:b:f:g:hk:l:p:qs:v:w:xXmz", // NOTE: also change arg_opts to indicate which commands have a numeric value
|
||||
long_options, &option_index);
|
||||
@@ -414,7 +351,6 @@ int main(int argc, char **argv)
|
||||
if (c == -1)
|
||||
break;
|
||||
optarg2 = optarg;
|
||||
#endif
|
||||
|
||||
switch (c)
|
||||
{
|
||||
|
||||
@@ -150,9 +150,11 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\compat\getopt.c" />
|
||||
<ClCompile Include="..\espeak-ng.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\compat\getopt.h" />
|
||||
<ClInclude Include="config.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -13,15 +13,27 @@
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\compat">
|
||||
<UniqueIdentifier>{c530f203-dd49-4aa0-a7a3-5116f781f03c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\compat">
|
||||
<UniqueIdentifier>{2ab8716c-709b-4284-9dc7-ec9610d37eab}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\espeak-ng.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\compat\getopt.c">
|
||||
<Filter>Source Files\compat</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\compat\getopt.h">
|
||||
<Filter>Header Files\compat</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user