⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmdlineopt.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
字号:
// Copyright (C) 2001 Gianni Mariani//// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// As a special exception to the GNU General Public License, permission is// granted for additional uses of the text contained in its release// of Common C++.//// The exception is that, if you link the Common C++ library with other// files to produce an executable, this does not by itself cause the// resulting executable to be covered by the GNU General Public License.// Your use of that executable is in no way restricted on account of// linking the Common C++ library code into it.//// This exception does not however invalidate any other reasons why// the executable file might be covered by the GNU General Public License.//// This exception applies only to the code released under the// name Common C++.  If you copy code from other releases into a copy of// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.////// Example for Common C++ the command line parser interface.//// // This exmaple code shows how to use the command line parser provided by// CommonC++.  The command line parser provides an interface which is// "object oriented" such that command line parameters are true "objects".//// Each command line option needs to be created.  By defining "CommandOption"s// statically, the C++ constructor is called when the objects are loaded and// before the "main" function is called.  The constructor links itself to// a list of other CommandOptionXXX in the list provided.  If no// list is specified in the constructor, a default one is used. Because of// the undefined nature as to the order in which constructors are called,// no assumption as to the order in which the CommandOptionXXX constructors// are called should be made.//// CommandOptionXXX classes can be used to derive specialized parameter// classes that are specific to applications.  The second example shows// just how this can be done.////// Include the CommandOption definitions//#include <cc++/common.h>#include <iostream>#ifdef	CCXX_NAMESPACESusing namespace std;using namespace ost;#endif	//// The following definition of options all use the list header// defaultCommandOptionList (which is specified as the value of the// default parameter in the constructor.  This convention would// allow other object files to link into the same list and add parameters// to the command line of this executable.CommandOptionArg	test_option1(	"test_option1", "p", "This option takes an argument", true);CommandOptionNoArg	test_noarg(	"test_noarg", "b", "This option does not take an argument");CommandOptionNoArg	helparg(	"help", "?", "Print help usage");CommandOptionCollect	restoargs(	0, 0, "Collect all the parameters", true);//// Normally this would me the regular main().  In this example// this processes the first command option list.//int Example_main( int argc, char ** argv ){	// Create a CommandOptionParse object.  This takes the	// defaultCommandOptionList and parses the command line arguments.	// 	CommandOptionParse * args = makeCommandOptionParse(		argc, argv,		"CommonC++ command like option interface.  This is example\n"		"	code only."	);	// If the user requested help then suppress all the usage error	// messages.	if ( helparg.numSet ) {		cerr << args->printUsage();		::exit(0);	}	// Print usage your way.	if ( args->argsHaveError() ) {		cerr << args->printErrors();		cerr << args->printUsage();		::exit(1);	}	// Go off and run any option specific task	args->performTask();	// print all the -p options	for ( int i = 0; i < test_option1.numValue; i ++ ) {		cerr << "test_option1 = " << test_option1.values[ i ] << endl;	}	// print all the other options.	for ( int i = 0; i < restoargs.numValue; i ++ ) {		cerr << "restoargs " << i << " : " << restoargs.values[ i ] << endl;	}	delete args;	return 0;}// // This shows how to build a second option list.  The example is similar to// the first as well as it shows how to derive a new command object.//CommandOption * TestList = 0;extern CommandOptionRest	test_restoargs;#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <strstream>#include <errno.h>#include <string.h>#include <stdlib.h>#include <sys/wait.h>//// This is a parameter class derived from CommandOptionArg that takes// a file name parameter and detects wether the file is accessible// flagging an error if the file is inaccessible to read.//class file_option : public CommandOptionArg {public:	// the constructor calls the regular CommandOptionArg constructor	// and all should be well.	file_option(		const char      * in_option_name,		const char      * in_option_letter,		const char      * in_description,		bool              in_required = false,		CommandOption  ** pp_next = & defaultCommandOptionList	)		: CommandOptionArg(			in_option_name,			in_option_letter,			in_description,			in_required,			pp_next		)	{	}	//	// When parsing is done check if the file is accessible and register	// an error with the CommandOptionParse object to let it know so.	virtual void parseDone( CommandOptionParse * cop )	{		if ( numValue ) {			if ( ::access( values[ numValue - 1 ], R_OK ) ) {				int	errno_s = errno;				strstream msg;				msg << "Error: " << optionName << " '" << values[ numValue - 1 ];				msg << "' : " << ::strerror( errno_s );								cop->registerError( msg.str() );			}		}	}	//	// Open said file.  Do some operations on things - like open the file.	int OpenFile()	{		// Should put in way more error handling here ...		return ::open( values[ numValue - 1 ], O_RDONLY );	}	//	// The most elaborate way to spit the contents of a file	// to standard output.	pid_t   pid;	virtual void performTask( CommandOptionParse * cop )	{		pid = ::fork();		if ( pid ) {			return;		}				int fd = OpenFile();		if ( fd < 0 ) {			int errno_s = errno;			cerr				<< "Error:  '"				<< values[ numValue - 1 ]				<< "' : "				<< ::strerror( errno_s )			;			::exit( 1 );		}		dup2(fd, 0);		::execvp( test_restoargs.values[0], (char**) test_restoargs.values );		::exit(1);	}	~file_option()	{		if ( pid <= 0 ) return;		int status;		::wait(&status);	}};//// This is the linked list head for the options in the second example.// Note that the first example used the default value defined in the// method.  Here it is explicitly specified as TestList in all the following// CommandOption constructors.file_option	test_file(	"test_file", "f", "Filename to read from", true, &TestList);CommandOptionNoArg	test_xnoarg(	"test_xnoarg", "b", "This option does not take an argument", false, &TestList);CommandOptionNoArg	test_helparg(	"help", "?", "Print help usage", false, &TestList);CommandOptionRest	test_restoargs(	0, 0, "Command to be executed", true, &TestList);//// in most apps this would be the regular "main" function.int Test_main( int argc, char ** argv ){	CommandOptionParse * args = makeCommandOptionParse(		argc, argv,		"Command line parser X test.\n"		"	This example is executed when the command ends in 'x'\n"		"	It shows how the -f parameter can be specialized.\n",		TestList	);	// If the user requested help then suppress all the usage error	// messages.	if ( test_helparg.numSet ) {		cerr << args->printUsage();		::exit(0);	}	// Print usage your way.	if ( args->argsHaveError() ) {		cerr << args->printErrors();		cerr << "Get help by --help\n";		::exit(1);	}	// Go off and run any option specific task	args->performTask();	for ( int i = 0; i < test_file.numValue; i ++ ) {		cerr << "test_file = " << test_file.values[ i ] << endl;	}		for ( int i = 0; i < test_restoargs.numValue; i ++ ) {		cerr << "test_restoargs " << i << " : " << test_restoargs.values[ i ] << endl;	}	delete args;	return 0;}//// This switches behaviour of this executable depending of wether it is// invoked with a command ending in "x".  This is mimicking for example// the behaviour of bunzip2 and bzip2.  These executables are THE SAME// file i.e.//   0 lrwxrwxrwx    1 root     root    5 Oct 11 14:04 /usr/bin/bunzip2 -> bzip2*// and the behaviour is determined by the executable name.//// This example is way more complex than the way most people will end up// using feature.int main( int argc, char ** argv ){	int i = ::strlen( argv[ 0 ] );	// determine which real "main" function do I call	if ( argv[ 0 ][ i - 1 ] == 'x' ) {		return Test_main( argc, argv );	} else {		return Example_main( argc, argv );	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -