From e5d4cbddf745b28733c0d53ecd133ecf848c4b2b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Aug 2011 10:11:25 -0700 Subject: [PATCH] emscripten modifications --- src/Makefile | 10 +- src/emscripten.sh | 10 + src/getopt.cpp | 480 +++++++++++++++++++++++++++++++++++++++++++++ src/getopt.h | 190 ++++++++++++++++++ src/readclause.cpp | 27 +-- src/strtok.cpp | 202 +++++++++++++++++++ 6 files changed, 903 insertions(+), 16 deletions(-) create mode 100644 src/emscripten.sh create mode 100644 src/getopt.cpp create mode 100644 src/getopt.h create mode 100644 src/strtok.cpp diff --git a/src/Makefile b/src/Makefile index a884f6f..d602879 100755 --- a/src/Makefile +++ b/src/Makefile @@ -25,8 +25,8 @@ INSTALL = install LN_SF = /bin/ln -sf MKDIR = mkdir -p -AUDIO = portaudio -#AUDIO = pulseaudio +#AUDIO = portaudio +AUDIO = pulseaudio #AUDIO = sada ifeq ($(AUDIO),pulseaudio) @@ -51,13 +51,13 @@ endif speak_SOURCES = speak.cpp compiledict.cpp dictionary.cpp intonation.cpp \ readclause.cpp setlengths.cpp numbers.cpp synth_mbrola.cpp \ synthdata.cpp synthesize.cpp translate.cpp mbrowrap.cpp \ - tr_languages.cpp voices.cpp wavegen.cpp phonemelist.cpp klatt.cpp sonic.cpp + tr_languages.cpp voices.cpp wavegen.cpp phonemelist.cpp klatt.cpp sonic.cpp getopt.cpp strtok.cpp libespeak_SOURCES = speak_lib.cpp compiledict.cpp dictionary.cpp intonation.cpp \ readclause.cpp setlengths.cpp numbers.cpp synth_mbrola.cpp \ synthdata.cpp synthesize.cpp translate.cpp mbrowrap.cpp \ tr_languages.cpp voices.cpp wavegen.cpp phonemelist.cpp \ - espeak_command.cpp event.cpp fifo.cpp $(WAVE) debug.cpp klatt.cpp sonic.cpp + espeak_command.cpp event.cpp fifo.cpp $(WAVE) debug.cpp klatt.cpp sonic.cpp getopt.cpp strtok.cpp SRCS1=$(speak_SOURCES) OBJS1=$(patsubst %.cpp,%.o,$(SRCS1)) @@ -71,7 +71,7 @@ SRCS3 = espeak.cpp OBJS3=$(patsubst %.cpp,%.o,$(SRCS3)) LIBS3=-lstdc++ -L . -lespeak -CXXFLAGS=-O2 +CXXFLAGS=-g -DNEED_WCHAR_FUNCTIONS all: $(BIN_NAME) $(LIB_NAME) $(STATIC_LIB_NAME) $(BIN2_NAME) diff --git a/src/emscripten.sh b/src/emscripten.sh new file mode 100644 index 0000000..ef389a0 --- /dev/null +++ b/src/emscripten.sh @@ -0,0 +1,10 @@ +echo "make" +RANLIB=/home/alon/Dev/git-emscripten/tools/emmaken.py AR=/home/alon/Dev/git-emscripten/tools/emmaken.py CXX=/home/alon/Dev/git-emscripten/tools/emmaken.py CC=/home/alon/Dev/git-emscripten/tools/emmaken.py make +echo "dis" +~/Dev/llvm-2.9/cbuild/bin/llvm-dis -show-annotations speak -o=speak.ll +echo "emscripten" +python /home/alon/Dev/git-emscripten/emscripten.py -O -s USE_TYPED_ARRAYS=2 -s ASSERTIONS=0 -s OPTIMIZE=1 -s RELOOP=1 speak.ll > speak.js +#~/Dev/mozilla-central/js/src/js -m speak.js -w wav.wav --path="/home/alon/Dev/espeak-1.45.04-source" "hello world" +#~/Dev/v8/d8 header.js speak.js footer.js +#gnome-sound-recorder wav.wav + diff --git a/src/getopt.cpp b/src/getopt.cpp new file mode 100644 index 0000000..4bba64a --- /dev/null +++ b/src/getopt.cpp @@ -0,0 +1,480 @@ +/**************************************************************************** + +getopt.c - Read command line options + +AUTHOR: Gregory Pietsch +CREATED Fri Jan 10 21:13:05 1997 + +DESCRIPTION: + +The getopt() function parses the command line arguments. Its arguments argc +and argv are the argument count and array as passed to the main() function +on program invocation. The argument optstring is a list of available option +characters. If such a character is followed by a colon (`:'), the option +takes an argument, which is placed in optarg. If such a character is +followed by two colons, the option takes an optional argument, which is +placed in optarg. If the option does not take an argument, optarg is NULL. + +The external variable optind is the index of the next array element of argv +to be processed; it communicates from one call to the next which element to +process. + +The getopt_long() function works like getopt() except that it also accepts +long options started by two dashes `--'. If these take values, it is either +in the form + +--arg=value + + or + +--arg value + +It takes the additional arguments longopts which is a pointer to the first +element of an array of type struct option. The last element of the array +has to be filled with NULL for the name field. + +The longind pointer points to the index of the current long option relative +to longopts if it is non-NULL. + +The getopt() function returns the option character if the option was found +successfully, `:' if there was a missing parameter for one of the options, +`?' for an unknown option character, and EOF for the end of the option list. + +The getopt_long() function's return value is described in the header file. + +The function getopt_long_only() is identical to getopt_long(), except that a +plus sign `+' can introduce long options as well as `--'. + +The following describes how to deal with options that follow non-option +argv-elements. + +If the caller did not specify anything, the default is REQUIRE_ORDER if the +environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. + +REQUIRE_ORDER means don't recognize them as options; stop option processing +when the first non-option is seen. This is what Unix does. This mode of +operation is selected by either setting the environment variable +POSIXLY_CORRECT, or using `+' as the first character of the optstring +parameter. + +PERMUTE is the default. We permute the contents of ARGV as we scan, so that +eventually all the non-options are at the end. This allows options to be +given in any order, even with programs that were not written to expect this. + +RETURN_IN_ORDER is an option available to programs that were written to +expect options and other argv-elements in any order and that care about the +ordering of the two. We describe each non-option argv-element as if it were +the argument of an option with character code 1. Using `-' as the first +character of the optstring parameter selects this mode of operation. + +The special argument `--' forces an end of option-scanning regardless of the +value of ordering. In the case of RETURN_IN_ORDER, only `--' can cause +getopt() and friends to return EOF with optind != argc. + +COPYRIGHT NOTICE AND DISCLAIMER: + +Copyright (C) 1997 Gregory Pietsch + +This file and the accompanying getopt.h header file are hereby placed in the +public domain without restrictions. Just give the author credit, don't +claim you wrote it or prevent anyone else from using it. + +Gregory Pietsch's current e-mail address: +gpietsch@comcast.net +****************************************************************************/ + +#ifndef HAVE_GETOPT + +/* include files */ +#include +#include +#include +#define __need_getopt_newlib +#define _EXFUN(x, y) x(y) +#include "getopt.h" + +/* macros */ + +/* types */ +typedef enum GETOPT_ORDERING_T +{ + PERMUTE, + RETURN_IN_ORDER, + REQUIRE_ORDER +} GETOPT_ORDERING_T; + +/* globally-defined variables */ +char *optarg = 0; +int optind = 0; +int opterr = 1; +int optopt = '?'; + +/* static variables */ +static int optwhere = 0; + +/* functions */ + +/* reverse_argv_elements: reverses num elements starting at argv */ +static void +reverse_argv_elements (char **argv, int num) +{ + int i; + char *tmp; + + for (i = 0; i < (num >> 1); i++) + { + tmp = argv[i]; + argv[i] = argv[num - i - 1]; + argv[num - i - 1] = tmp; + } +} + +/* permute: swap two blocks of argv-elements given their lengths */ +static void +permute (char *const argv[], int len1, int len2) +{ + reverse_argv_elements ((char **) argv, len1); + reverse_argv_elements ((char **) argv, len1 + len2); + reverse_argv_elements ((char **) argv, len2); +} + +/* is_option: is this argv-element an option or the end of the option list? */ +static int +is_option (char *argv_element, int only) +{ + return ((argv_element == 0) + || (argv_element[0] == '-') || (only && argv_element[0] == '+')); +} + +/* read_globals: read the values from the globals into a getopt_data + structure */ +static void +read_globals (struct getopt_data *data) +{ + data->optarg = optarg; + data->optind = optind; + data->opterr = opterr; + data->optopt = optopt; + data->optwhere = optwhere; +} + +/* write_globals: write the values into the globals from a getopt_data + structure */ +static void +write_globals (struct getopt_data *data) +{ + optarg = data->optarg; + optind = data->optind; + opterr = data->opterr; + optopt = data->optopt; + optwhere = data->optwhere; +} + +/* getopt_internal: the function that does all the dirty work */ +static int +getopt_internal (int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind, int only, + struct getopt_data *data) +{ + GETOPT_ORDERING_T ordering = PERMUTE; + size_t permute_from = 0; + int num_nonopts = 0; + int optindex = 0; + size_t match_chars = 0; + char *possible_arg = 0; + int longopt_match = -1; + int has_arg = -1; + char *cp = 0; + int arg_next = 0; + + /* first, deal with silly parameters and easy stuff */ + if (argc == 0 || argv == 0 || (shortopts == 0 && longopts == 0) + || data->optind >= argc || argv[data->optind] == 0) + return EOF; + if (strcmp (argv[data->optind], "--") == 0) + { + data->optind++; + return EOF; + } + + /* if this is our first time through */ + if (data->optind == 0) + data->optind = data->optwhere = 1; + + /* define ordering */ + if (shortopts != 0 && (*shortopts == '-' || *shortopts == '+')) + { + ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER; + shortopts++; + } + else + ordering = (getenv ("POSIXLY_CORRECT") != 0) ? REQUIRE_ORDER : PERMUTE; + + /* + * based on ordering, find our next option, if we're at the beginning of + * one + */ + if (data->optwhere == 1) + { + switch (ordering) + { + default: /* shouldn't happen */ + case PERMUTE: + permute_from = data->optind; + num_nonopts = 0; + while (!is_option (argv[data->optind], only)) + { + data->optind++; + num_nonopts++; + } + if (argv[data->optind] == 0) + { + /* no more options */ + data->optind = permute_from; + return EOF; + } + else if (strcmp (argv[data->optind], "--") == 0) + { + /* no more options, but have to get `--' out of the way */ + permute (argv + permute_from, num_nonopts, 1); + data->optind = permute_from + 1; + return EOF; + } + break; + case RETURN_IN_ORDER: + if (!is_option (argv[data->optind], only)) + { + data->optarg = argv[data->optind++]; + return (data->optopt = 1); + } + break; + case REQUIRE_ORDER: + if (!is_option (argv[data->optind], only)) + return EOF; + break; + } + } + /* we've got an option, so parse it */ + + /* first, is it a long option? */ + if (longopts != 0 + && (memcmp (argv[data->optind], "--", 2) == 0 + || (only && argv[data->optind][0] == '+')) && data->optwhere == 1) + { + /* handle long options */ + if (memcmp (argv[data->optind], "--", 2) == 0) + data->optwhere = 2; + longopt_match = -1; + possible_arg = strchr (argv[data->optind] + data->optwhere, '='); + if (possible_arg == 0) + { + /* no =, so next argv might be arg */ + match_chars = strlen (argv[data->optind]); + possible_arg = argv[data->optind] + match_chars; + match_chars = match_chars - data->optwhere; + } + else + match_chars = (possible_arg - argv[data->optind]) - data->optwhere; + for (optindex = 0; longopts[optindex].name != 0; ++optindex) + { + if (memcmp + (argv[data->optind] + data->optwhere, longopts[optindex].name, + match_chars) == 0) + { + /* do we have an exact match? */ + if (match_chars == (int) (strlen (longopts[optindex].name))) + { + longopt_match = optindex; + break; + } + /* do any characters match? */ + else + { + if (longopt_match < 0) + longopt_match = optindex; + else + { + /* we have ambiguous options */ + if (data->opterr) + fprintf (stderr, "%s: option `%s' is ambiguous " + "(could be `--%s' or `--%s')\n", + argv[0], + argv[data->optind], + longopts[longopt_match].name, + longopts[optindex].name); + return (data->optopt = '?'); + } + } + } + } + if (longopt_match >= 0) + has_arg = longopts[longopt_match].has_arg; + } + + /* if we didn't find a long option, is it a short option? */ + if (longopt_match < 0 && shortopts != 0) + { + cp = strchr ((char*)shortopts, argv[data->optind][data->optwhere]); + if (cp == 0) + { + /* couldn't find option in shortopts */ + if (data->opterr) + fprintf (stderr, + "%s: invalid option -- `-%c'\n", + argv[0], argv[data->optind][data->optwhere]); + data->optwhere++; + if (argv[data->optind][data->optwhere] == '\0') + { + data->optind++; + data->optwhere = 1; + } + return (data->optopt = '?'); + } + has_arg = ((cp[1] == ':') + ? ((cp[2] == ':') ? OPTIONAL_ARG : REQUIRED_ARG) : NO_ARG); + possible_arg = argv[data->optind] + data->optwhere + 1; + data->optopt = *cp; + } + + /* get argument and reset data->optwhere */ + arg_next = 0; + switch (has_arg) + { + case OPTIONAL_ARG: + if (*possible_arg == '=') + possible_arg++; + data->optarg = (*possible_arg != '\0') ? possible_arg : 0; + data->optwhere = 1; + break; + case REQUIRED_ARG: + if (*possible_arg == '=') + possible_arg++; + if (*possible_arg != '\0') + { + data->optarg = possible_arg; + data->optwhere = 1; + } + else if (data->optind + 1 >= argc) + { + if (data->opterr) + { + fprintf (stderr, "%s: argument required for option `", argv[0]); + if (longopt_match >= 0) + fprintf (stderr, "--%s'\n", longopts[longopt_match].name); + else + fprintf (stderr, "-%c'\n", *cp); + } + data->optind++; + return (data->optopt = ':'); + } + else + { + data->optarg = argv[data->optind + 1]; + arg_next = 1; + data->optwhere = 1; + } + break; + default: /* shouldn't happen */ + case NO_ARG: + if (longopt_match < 0) + { + data->optwhere++; + if (argv[data->optind][data->optwhere] == '\0') + data->optwhere = 1; + } + else + data->optwhere = 1; + data->optarg = 0; + break; + } + + /* do we have to permute or otherwise modify data->optind? */ + if (ordering == PERMUTE && data->optwhere == 1 && num_nonopts != 0) + { + permute (argv + permute_from, num_nonopts, 1 + arg_next); + data->optind = permute_from + 1 + arg_next; + } + else if (data->optwhere == 1) + data->optind = data->optind + 1 + arg_next; + + /* finally return */ + if (longopt_match >= 0) + { + if (longind != 0) + *longind = longopt_match; + if (longopts[longopt_match].flag != 0) + { + *(longopts[longopt_match].flag) = longopts[longopt_match].val; + return 0; + } + else + return longopts[longopt_match].val; + } + else + return data->optopt; +} + +int +getopt (int argc, char *const argv[], const char *optstring) +{ + struct getopt_data data; + int r; + + read_globals (&data); + r = getopt_internal (argc, argv, optstring, 0, 0, 0, &data); + write_globals (&data); + return r; +} + +int +getopt_long (int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind) +{ + struct getopt_data data; + int r; + + read_globals (&data); + r = getopt_internal (argc, argv, shortopts, longopts, longind, 0, &data); + write_globals (&data); + return r; +} + +int +getopt_long_only (int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind) +{ + struct getopt_data data; + int r; + + read_globals (&data); + r = getopt_internal (argc, argv, shortopts, longopts, longind, 1, &data); + write_globals (&data); + return r; +} + +int +__getopt_r (int argc, char *const argv[], const char *optstring, + struct getopt_data *data) +{ + return getopt_internal (argc, argv, optstring, 0, 0, 0, data); +} + +int +__getopt_long_r (int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind, + struct getopt_data *data) +{ + return getopt_internal (argc, argv, shortopts, longopts, longind, 0, data); +} + +int +__getopt_long_only_r (int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind, + struct getopt_data *data) +{ + return getopt_internal (argc, argv, shortopts, longopts, longind, 1, data); +} + +#endif /* !HAVE_GETOPT */ + +/* end of file GETOPT.C */ diff --git a/src/getopt.h b/src/getopt.h new file mode 100644 index 0000000..e6c09c5 --- /dev/null +++ b/src/getopt.h @@ -0,0 +1,190 @@ +/**************************************************************************** + +getopt.h - Read command line options + +AUTHOR: Gregory Pietsch +CREATED Thu Jan 09 22:37:00 1997 + +DESCRIPTION: + +The getopt() function parses the command line arguments. Its arguments argc +and argv are the argument count and array as passed to the main() function +on program invocation. The argument optstring is a list of available option +characters. If such a character is followed by a colon (`:'), the option +takes an argument, which is placed in optarg. If such a character is +followed by two colons, the option takes an optional argument, which is +placed in optarg. If the option does not take an argument, optarg is NULL. + +The external variable optind is the index of the next array element of argv +to be processed; it communicates from one call to the next which element to +process. + +The getopt_long() function works like getopt() except that it also accepts +long options started by two dashes `--'. If these take values, it is either +in the form + +--arg=value + + or + +--arg value + +It takes the additional arguments longopts which is a pointer to the first +element of an array of type GETOPT_LONG_OPTION_T, defined below. The last +element of the array has to be filled with NULL for the name field. + +The longind pointer points to the index of the current long option relative +to longopts if it is non-NULL. + +The getopt() function returns the option character if the option was found +successfully, `:' if there was a missing parameter for one of the options, +`?' for an unknown option character, and EOF for the end of the option list. + +The getopt_long() function's return value is described below. + +The function getopt_long_only() is identical to getopt_long(), except that a +plus sign `+' can introduce long options as well as `--'. + +Describe how to deal with options that follow non-option ARGV-elements. + +If the caller did not specify anything, the default is REQUIRE_ORDER if the +environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. + +REQUIRE_ORDER means don't recognize them as options; stop option processing +when the first non-option is seen. This is what Unix does. This mode of +operation is selected by either setting the environment variable +POSIXLY_CORRECT, or using `+' as the first character of the optstring +parameter. + +PERMUTE is the default. We permute the contents of ARGV as we scan, so that +eventually all the non-options are at the end. This allows options to be +given in any order, even with programs that were not written to expect this. + +RETURN_IN_ORDER is an option available to programs that were written to +expect options and other ARGV-elements in any order and that care about the +ordering of the two. We describe each non-option ARGV-element as if it were +the argument of an option with character code 1. Using `-' as the first +character of the optstring parameter selects this mode of operation. + +The special argument `--' forces an end of option-scanning regardless of the +value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause +getopt() and friends to return EOF with optind != argc. + +COPYRIGHT NOTICE AND DISCLAIMER: + +Copyright (C) 1997 Gregory Pietsch + +This file and the accompanying getopt.c implementation file are hereby +placed in the public domain without restrictions. Just give the author +credit, don't claim you wrote it or prevent anyone else from using it. + +Gregory Pietsch's current e-mail address: +gpietsch@comcast.net +****************************************************************************/ + +/* This is a glibc-extension header file. */ + +#ifndef GETOPT_H +#define GETOPT_H + +/* #include <_ansi.h> */ + +/* include files needed by this include file */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#ifdef __cplusplus +extern "C" +{ + +#endif /* __cplusplus */ + +/* types defined by this include file */ + struct option + { + char *name; /* the name of the long option */ + int has_arg; /* one of the above macros */ + int *flag; /* determines if getopt_long() returns a + * value for a long option; if it is + * non-NULL, 0 is returned as a function + * value and the value of val is stored in + * the area pointed to by flag. Otherwise, + * val is returned. */ + int val; /* determines the value to return if flag is + * NULL. */ + + }; + +/* While getopt.h is a glibc extension, the following are newlib extensions. + * They are optionally included via the __need_getopt_newlib flag. */ + +#ifdef __need_getopt_newlib + + /* macros defined by this include file */ + #define NO_ARG no_argument + #define REQUIRED_ARG required_argument + #define OPTIONAL_ARG optional_argument + + /* The GETOPT_DATA_INITIALIZER macro is used to initialize a statically- + allocated variable of type struct getopt_data. */ + #define GETOPT_DATA_INITIALIZER {0,0,0,0,0} + + /* These #defines are to make accessing the reentrant functions easier. */ + #define getopt_r __getopt_r + #define getopt_long_r __getopt_long_r + #define getopt_long_only_r __getopt_long_only_r + + /* The getopt_data structure is for reentrancy. Its members are similar to + the externally-defined variables. */ + typedef struct getopt_data + { + char *optarg; + int optind, opterr, optopt, optwhere; + } getopt_data; + +#endif /* __need_getopt_newlib */ + + /* externally-defined variables */ + extern char *optarg; + extern int optind; + extern int opterr; + extern int optopt; + + /* function prototypes */ + int getopt + (int __argc, char *const __argv[], const char *__optstring); + + int getopt_long + (int __argc, char *const __argv[], const char *__shortopts, + const struct option * __longopts, int *__longind); + + int getopt_long_only + (int __argc, char *const __argv[], const char *__shortopts, + const struct option * __longopts, int *__longind); + +#ifdef __need_getopt_newlib + int __getopt_r + (int __argc, char *const __argv[], const char *__optstring, + struct getopt_data * __data); + + int __getopt_long_r + (int __argc, char *const __argv[], const char *__shortopts, + const struct option * __longopts, int *__longind, + struct getopt_data * __data); + + int __getopt_long_only_r + (int __argc, char *const __argv[], const char *__shortopts, + const struct option * __longopts, int *__longind, + struct getopt_data * __data); +#endif /* __need_getopt_newlib */ + +#ifdef __cplusplus +} + +#endif /* __cplusplus */ + +#endif /* GETOPT_H */ + +/* END OF FILE getopt.h */ diff --git a/src/readclause.cpp b/src/readclause.cpp index f1dd053..ac76dab 100755 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +//#include #include #include "speak_lib.h" @@ -204,6 +204,8 @@ const int param_defaults[N_SPEECH_PARAM] = { #ifdef NEED_WCHAR_FUNCTIONS +extern "C" { + // additional Latin characters beyond the Latin1 character set #define MAX_WALPHA 0x233 // indexed by character - 0x100 @@ -232,7 +234,7 @@ static unsigned char walpha_tab[MAX_WALPHA-0xff] = { 1,0xff, 1,0xff }; // 230 // use ctype.h functions for Latin1 (character < 0x100) -int iswalpha(int c) +int iswalpha(wint_t c) { if(c < 0x100) return(isalpha(c)); @@ -243,21 +245,21 @@ int iswalpha(int c) return(walpha_tab[c-0x100]); } -int iswdigit(int c) +int iswdigit(wint_t c) { if(c < 0x100) return(isdigit(c)); return(0); } -int iswalnum(int c) +int iswalnum(wint_t c) { if(iswdigit(c)) return(1); return(iswalpha(c)); } -int towlower(int c) +wint_t towlower(wint_t c) { int x; if(c < 0x100) @@ -273,7 +275,7 @@ int towlower(int c) return(c + x); // convert to lower case } -int towupper(int c) +wint_t towupper(wint_t c) { // check whether the previous character code is the upper-case equivalent of this character if(tolower(c-1) == c) @@ -281,7 +283,7 @@ int towupper(int c) return(c); // no } -int iswupper(int c) +int iswupper(wint_t c) { int x; if(c < 0x100) @@ -291,7 +293,7 @@ int iswupper(int c) return(1); } -int iswlower(int c) +int iswlower(wint_t c) { if(c < 0x100) return(islower(c)); @@ -300,14 +302,14 @@ int iswlower(int c) return(1); } -int iswspace(int c) +int iswspace(wint_t c) { if(c < 0x100) return(isspace(c)); return(0); } -int iswpunct(int c) +int iswpunct(wint_t c) { if(c < 0x100) return(ispunct(c)); @@ -353,7 +355,10 @@ float wcstod(const wchar_t *str, wchar_t **tailptr) *tailptr = (wchar_t *)&str[ix]; return(atof(buf)); } -#endif + +} + +#endif // NEED_WCHAR_FUNCTIONS int towlower2(unsigned int c) { diff --git a/src/strtok.cpp b/src/strtok.cpp new file mode 100644 index 0000000..d7db22f --- /dev/null +++ b/src/strtok.cpp @@ -0,0 +1,202 @@ +extern "C" { + +/* + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +//#include + +#define _AND , +#define NULL 0 + +char *__strtok_r ( + register char *s _AND + register const char *delim _AND + char **lasts _AND + int skip_leading_delim) +{ + register char *spanp; + register int c, sc; + char *tok; + + + if (s == NULL && (s = *lasts) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) { + if (skip_leading_delim) { + goto cont; + } + else { + *lasts = s; + s[-1] = 0; + return (s - 1); + } + } + } + + if (c == 0) { /* no non-delimiter characters */ + *lasts = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *lasts = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +char * strtok_r( + register char *s _AND + register const char *delim _AND + char **lasts) +{ + return __strtok_r (s, delim, lasts, 1); +} + +/* +FUNCTION + <>, <>, <>---get next token from a string + +INDEX + strtok + +INDEX + strtok_r + +INDEX + strsep + +ANSI_SYNOPSIS + #include + char *strtok(char *<[source]>, const char *<[delimiters]>) + char *strtok_r(char *<[source]>, const char *<[delimiters]>, + char **<[lasts]>) + char *strsep(char **<[source_ptr]>, const char *<[delimiters]>) + +TRAD_SYNOPSIS + #include + char *strtok(<[source]>, <[delimiters]>) + char *<[source]>; + char *<[delimiters]>; + + char *strtok_r(<[source]>, <[delimiters]>, <[lasts]>) + char *<[source]>; + char *<[delimiters]>; + char **<[lasts]>; + + char *strsep(<[source_ptr]>, <[delimiters]>) + char **<[source_ptr]>; + char *<[delimiters]>; + +DESCRIPTION + The <> function is used to isolate sequential tokens in a + null-terminated string, <<*<[source]>>>. These tokens are delimited + in the string by at least one of the characters in <<*<[delimiters]>>>. + The first time that <> is called, <<*<[source]>>> should be + specified; subsequent calls, wishing to obtain further tokens from + the same string, should pass a null pointer instead. The separator + string, <<*<[delimiters]>>>, must be supplied each time and may + change between calls. + + The <> function returns a pointer to the beginning of each + subsequent token in the string, after replacing the separator + character itself with a null character. When no more tokens remain, + a null pointer is returned. + + The <> function has the same behavior as <>, except + a pointer to placeholder <<*<[lasts]>>> must be supplied by the caller. + + The <> function is similar in behavior to <>, except + a pointer to the string pointer must be supplied <<<[source_ptr]>>> and + the function does not skip leading delimiters. When the string starts + with a delimiter, the delimiter is changed to the null character and + the empty string is returned. Like <> and <>, the + <<*<[source_ptr]>>> is updated to the next character following the + last delimiter found or NULL if the end of string is reached with + no more delimiters. + +RETURNS + <>, <>, and <> all return a pointer to the + next token, or <> if no more tokens can be found. For + <>, a token may be the empty string. + +NOTES + <> is unsafe for multi-threaded applications. <> + and <> are thread-safe and should be used instead. + +PORTABILITY +<> is ANSI C. +<> is POSIX. +<> is a BSD extension. + +<>, <>, and <> require no supporting OS subroutines. + +QUICKREF + strtok ansi impure +*/ + +/* undef STRICT_ANSI so that strtok_r prototype will be defined */ +#undef __STRICT_ANSI__ +//#include + +#ifndef _REENT_ONLY + +char *strtok( + register char *s _AND + register const char *delim) +{ + char *chr; + return __strtok_r (s, delim, &chr, 1); +} +#endif + +} /* extern "C" */ +