From f62f20a22613c5d0a32e0b308f6b3092a40392ca Mon Sep 17 00:00:00 2001 From: dhilvert Date: Sat, 15 Jul 2006 03:07:00 +0000 Subject: [PATCH] Add declarations for new static variables in input::environment; move utility functions in ui/input.h to the class definition of input in order to avoid link errors; add restrictions on setting of variables from outside of the environment class, making ---this and ---chain protected; set a ---this variable; add a C string token reader to ui::input; add a function to evaluate streams; and add code to call environment and token stream handlers to the input handling method. darcs-hash:20060715030753-789c2-45163155bad3c98969377d0b558eefc639e3df1a.gz --- Makefile | 8 +-- ui/input.h | 208 +++++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 151 insertions(+), 65 deletions(-) diff --git a/Makefile b/Makefile index 2650aa4..38f52ce 100644 --- a/Makefile +++ b/Makefile @@ -82,15 +82,15 @@ clean: find testsuite -name "*temp.*" | xargs rm -rf find testsuite -name "*.output.*" | xargs rm -rf -ale-phony: ale.cc ui/ui.cc d2.cc *.h d2/*.h d2/render/*.h d2/render/psf/*.h d3.cc d3/*.h - $(CXX) -o ale $(CFLAGS) ale.cc ui/ui.cc d3.cc d2.cc $(LDFLAGS) +ale-phony: ale.cc ui/ui.cc ui/input.cc d2.cc *.h d2/*.h d2/render/*.h d2/render/psf/*.h d3.cc d3/*.h + $(CXX) -o ale $(CFLAGS) ale.cc ui/ui.cc ui/input.cc d3.cc d2.cc $(LDFLAGS) # The following approach to building a Windows binary is probably very # dependent on the host platform configuration. The above target may be a # better place to start for Windows users. -ale.exe: ale.cc ui/ui.cc d2.cc *.h d2/*.h d2/render/*.h d2/render/psf/*.h d3.cc d3/*.h - i586-mingw32msvc-g++ -Wall $(OPTIMIZATION_CFLAGS) $(PRECISION_CFLAGS) $(DEBUG_CFLAGS) -o ale.exe -O2 ale.cc ui/ui.cc d3.cc d2.cc -lm +ale.exe: ale.cc ui/ui.cc ui/input.cc d2.cc *.h d2/*.h d2/render/*.h d2/render/psf/*.h d3.cc d3/*.h + i586-mingw32msvc-g++ -Wall $(OPTIMIZATION_CFLAGS) $(PRECISION_CFLAGS) $(DEBUG_CFLAGS) -o ale.exe -O2 ale.cc ui/ui.cc ui/input.cc d3.cc d2.cc -lm # # The following rules may require additional software to be installed. diff --git a/ui/input.h b/ui/input.h index 037e33c..9c4f9dc 100644 --- a/ui/input.h +++ b/ui/input.h @@ -18,6 +18,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __input_h__ +#define __input_h__ + /* * ANSI C and POSIX include files. */ @@ -77,65 +80,69 @@ #include "help.h" -/* - * Argument counter. - * - * Counts instances of a given option. - */ -unsigned int arg_count(int argc, const char *argv[], const char *arg) { - unsigned int count = 0; - for (int i = 0; i < argc; i++) { - if (!strcmp(argv[i], arg)) - count++; - else if (!strcmp(argv[i], "--")) - return count; +class input { + /* + * Helper functions. + */ + + /* + * Argument counter. + * + * Counts instances of a given option. + */ + static unsigned int arg_count(int argc, const char *argv[], const char *arg) { + unsigned int count = 0; + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], arg)) + count++; + else if (!strcmp(argv[i], "--")) + return count; + } + return count; } - return count; -} -/* - * Argument prefix counter. - * - * Counts instances of a given option prefix. - */ -unsigned int arg_prefix_count(int argc, const char *argv[], const char *pfix) { - unsigned int count = 0; - for (int i = 0; i < argc; i++) { - if (!strncmp(argv[i], pfix, strlen(pfix))) - count++; - else if (!strcmp(argv[i], "--")) - return count; + /* + * Argument prefix counter. + * + * Counts instances of a given option prefix. + */ + static unsigned int arg_prefix_count(int argc, const char *argv[], const char *pfix) { + unsigned int count = 0; + for (int i = 0; i < argc; i++) { + if (!strncmp(argv[i], pfix, strlen(pfix))) + count++; + else if (!strcmp(argv[i], "--")) + return count; + } + return count; } - return count; -} -/* - * Reallocation function - */ -void *local_realloc(void *ptr, size_t size) { - void *new_ptr = realloc(ptr, size); + /* + * Reallocation function + */ + static void *local_realloc(void *ptr, size_t size) { + void *new_ptr = realloc(ptr, size); - if (new_ptr == NULL) - ui::get()->memory_error_location("main()"); + if (new_ptr == NULL) + ui::get()->memory_error_location("main()"); - return new_ptr; -} + return new_ptr; + } -/* - * Not enough arguments function. - */ -void not_enough(const char *opt_name) { - ui::get()->cli_not_enough(opt_name); -} + /* + * Not enough arguments function. + */ + static void not_enough(const char *opt_name) { + ui::get()->cli_not_enough(opt_name); + } -/* - * Bad argument function - */ -void bad_arg(const char *opt_name) { - ui::get()->cli_bad_arg(opt_name); -} + /* + * Bad argument function + */ + static void bad_arg(const char *opt_name) { + ui::get()->cli_bad_arg(opt_name); + } -class input { /* * Environment structures. * @@ -152,19 +159,15 @@ class input { std::map environment_map; - public: - const char *get(const char *name) { - if (environment_map.count(name) == 0) - return NULL; - - return environment_map[name]; - } + /* + * Internal set operations do not protect any data. + */ - void set(const char *name, const char *value) { + void internal_set(const char *name, const char *value) { environment_map[name] = value; } - void set_ptr(const char *name, const void *pointer) { + void internal_set_ptr(const char *name, const void *pointer) { int chars = sizeof(void *) * 2 + 3; char *c = (char *) malloc(sizeof(char) * chars); @@ -181,6 +184,40 @@ class input { } /* + * Check for restricted names. + */ + + void name_check(const char *name) { + if (!strcmp(name, "---chain") || !strcmp(name, "---this")) { + fprintf(stderr, "Bad set operation."); + exit(1); + } + } + + public: + + /* + * Public set operations restrict valid names. + */ + + void set(const char *name, const char *value) { + name_check(name); + internal_set(name, value); + } + + void set_ptr(const char *name, const void *pointer) { + name_check(name); + internal_set_ptr(name, pointer); + } + + const char *get(const char *name) { + if (environment_map.count(name) == 0) + return NULL; + + return environment_map[name]; + } + + /* * Make an environment substructure. Note that since deep * structures are currently referenced rather than copied when * the stack is pushed, there is no current need for any @@ -224,6 +261,7 @@ class input { e->environment_map = environment_stack.top()->environment_map; e->set_ptr("---chain", environment_stack.top()); + e->set_ptr("---this", e); environment_stack.push(e); environment_set.insert(e); @@ -253,21 +291,47 @@ class input { * Read tokens from a stream. */ class token_reader { + public: /* * Get the next token */ - virtual char *get() = 0; + virtual const char *get() = 0; virtual ~token_reader() { } }; - class cli_token_reader { + class cstring_token_reader : public token_reader { + const char *string; + char *cur_token; + + public: + cstring_token_reader(const char *s) { + string = s; + cur_token = 0; + } + + const char *get() { + const char *separators = "\n \t"; + string += strcspn(string, separators); + + int length = strcspn(string, separators); + + free(cur_token); + + cur_token = strndup(string, length); + + return cur_token; + } + }; + + class cli_token_reader : public token_reader { int arg_index; int argc; const char **argv; + public: cli_token_reader(int c, const char *v[]) { argc = c; argv = v; @@ -279,6 +343,9 @@ class input { } }; + static void evaluate_stream(token_reader *tr) { + } + public: /* * Input handler. @@ -295,6 +362,23 @@ public: static void handle(int argc, const char *argv[], const char *package, const char *short_version, const char *version) { /* + * Set basic program information in the environment. + */ + + environment::top()->set("---package", package); + environment::top()->set("---short-version", short_version); + environment::top()->set("---version", version); + environment::top()->set("---invocation", argv[0]); + + /* + * Evaluate the command-line arguments to generate environment + * structures. + */ + + token_reader *tr = new cli_token_reader(argc, argv); + evaluate_stream(tr); + + /* * Initialize help object */ @@ -2162,3 +2246,5 @@ public: } }; + +#endif -- 2.11.4.GIT