//======================================== // Options.C // // Options Manager. Hum. Something to parse // command line and later to parse a config // file, if there ever is one. // // ZNibbles // Vincent Mallet 1999 - vmallet@enst.fr //======================================== // $Id: Options.C,v 1.6 1999/05/12 01:37:00 vmallet Exp $ /* ZNibbles - a small multiplayer game * Copyright (C) 1997, 1998, 1999 Vincent Mallet - vmallet@enst.fr * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "Options.H" #include "getopt.h" #define NB_SETS 2 // constructor Options::Options() : _help(false), _version(false), _debug(false), _twokey(false), _stdin_input(false), _port(5051), _hostname("localhost"), _playername(0), _message_file(0), _width(80), _height(40), _no_computer(false) { static struct option l1[] = { { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "no-computer", no_argument, NULL, 'c' }, { "port", required_argument, NULL, 'p' }, { "size", required_argument, NULL, 's' }, { "width", required_argument, NULL, 'w' }, { "height", required_argument, NULL, 'g' }, { 0, 0, 0, 0 } }; static char * o1 = "dhVcp:s:w:g:"; static struct option l2[] = { { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "twokeys", no_argument, NULL, 't' }, { "enable-stdin", no_argument, NULL, 'i' }, { "host-name", required_argument, NULL, 'n' }, { "message-file", required_argument, NULL, 'm' }, { "port", required_argument, NULL, 'p' }, { 0, 0, 0, 0 } }; static char * o2 = "dhVtin:p:m:"; _long_options_sets = (struct option **) malloc(NB_SETS * sizeof(struct option *)); _options_sets = (char **) malloc(NB_SETS * sizeof(char *)); _options_sets[0] = o1; _long_options_sets[0] = l1; _options_sets[1] = o2; _long_options_sets[1] = l2; _set = 0; } void Options::set_option_set(int set) { if (set >= 0 && set < NB_SETS) _set = set; // else, raise an exception ? } // parse command line parameters // return true if ok // return false if wrong parameters bool Options::parse(int argc, char **argv) { int c; int bad_params = false; while ((c = getopt_long (argc, argv, _options_sets[_set], _long_options_sets[_set], (int *) 0)) != EOF) { switch (c) { case 'V': // version _version = true; return true; case 'h': // help _help = true; return true; case 'd': set_debug(true); break; case 't': set_twoley(true); break; case 'm': set_message_file(optarg); break; case 'n': set_host_name(optarg); break; case 'c': set_no_computer(true); break; case 'i': set_stdin_input(true); break; case 'p': _port = atoi(optarg); if (_port == 0) { // cannot be 0 std::cerr << *argv << ": port: invalid argument: " << optarg << std::endl; bad_params = true; } break; case 's': // size (server only) int ooo ; if (2 != (ooo = sscanf(optarg, "%dx%d", &_width, &_height)) || _height == 0 || _width == 0) { std::cerr << *argv << ": size: invalid argument: " << optarg << std::endl; bad_params = true; } break; case 'g': // height (server only) _height = atoi(optarg); if (_height == 0) { // cannot be 0 std::cerr << *argv << ": height: invalid argument: " << optarg \ << std::endl; bad_params = true; } break; case 'w': // width (server only) _width = atoi(optarg); if (_width == 0) { // cannot be 0 std::cerr << *argv << ": width: invalid argument: " << optarg \ << std::endl; bad_params = true; } break; case '?': return false; default: printf("opt=%d (%c)\n", c, c); break; } } if (_set == OPTIONS_CLIENT_SET) { if (argv[optind] == NULL) { std::cerr << *argv << ": missing player name" << std::endl; bad_params = true; } else { set_player_name(argv[optind]); } } else if (_set == OPTIONS_SERVER_SET) { if (argv[optind] != NULL) { // user may be doing "nibbles portnum" int p = atoi(argv[optind]); if (p != 0) _port = p; else { std::cerr << *argv << ": too many parameters: " << argv[optind] << std::endl; bad_params = true; } } } return !bad_params; } #ifdef _TEST int main(int argc, char **argv) { Options& options = * new Options(); options.set_option_set(0); if (!options.parse(argc, argv)) { std::cout << "usage: .... " << std::endl; delete &options; return 1; } if (options.is_help()) { std::cout << "help: ..." << std::endl; delete &options; return 0; } if (options.is_version()) { std::cout << "... version ... " << std::endl; delete &options; return 0; } std::cout << "host: " << options.get_host_name() << ":" \ << options.get_port() << std::endl; std::cout << "message_file: " << options.get_message_file() << std::endl; std::cout << "twokey(" << options.is_twokey() << ") debug(" \ << options.is_debug() <<")" << std::endl; int i = options.get_nonoption_index(); std::cout << "argv left = " << std::endl; argv += i; while (*argv) { std::cout << " " << *argv++ << std::endl; } delete &options; } #endif //_TEST