// File: fullSample.cpp // Library: SimpleOpt // Author: Brodie Thiesfield <code@jellycan.com> // Source: http://code.jellycan.com/simpleopt/ // // MIT LICENCE // =========== // The licence text below is the boilerplate "MIT Licence" used from: // http://www.opensource.org/licenses/mit-license.php // // Copyright (c) 2006, Brodie Thiesfield // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is furnished // to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(_MSC_VER) # include <windows.h> # include <tchar.h> #else # define TCHAR char # define _T(x) x # define _tprintf printf # define _tmain main # define _ttoi atoi #endif #include <stdio.h> #include <locale.h> #include "SimpleOpt.h" #include "SimpleGlob.h" static void ShowUsage() { _tprintf( _T("Usage: fullSample [OPTIONS] [FILES]\n") _T("\n") _T("--exact Disallow partial matching of option names\n") _T("--noslash Disallow use of slash as an option marker on Windows\n") _T("--shortarg Permit arguments on single letter options with no equals sign\n") _T("--clump Permit single char options to be clumped as long string\n") _T("--noerr Do not generate any errors for invalid options\n") _T("--pedantic Generate an error for petty things\n") _T("\n") _T("-d -e -f -g -flag --flag Flag (no arg)\n") _T("-s ARG -sep ARG --sep ARG Separate required arg\n") _T("-cARG -c=ARG -com=ARG --com=ARG Combined required arg\n") _T("-o[ARG] -o[=ARG] -opt[=ARG] --opt[=ARG] Combined optional arg\n") _T("-man -mandy -mandate Shortcut matching tests\n") _T("--man --mandy --mandate Shortcut matching tests\n") _T("--multi0 --multi1 ARG --multi2 ARG1 ARG2 Multiple argument tests\n") _T("--multi N ARG-1 ARG-2 ... ARG-N Multiple argument tests\n") _T("open read write close zip unzip Special words\n") _T("\n") _T("-? -h -help --help Output this help.\n") _T("\n") _T("If a FILE is `-', read standard input.\n") ); } CSimpleOpt::SOption g_rgFlags[] = { { SO_O_EXACT, _T("--exact"), SO_NONE }, { SO_O_NOSLASH, _T("--noslash"), SO_NONE }, { SO_O_SHORTARG, _T("--shortarg"), SO_NONE }, { SO_O_CLUMP, _T("--clump"), SO_NONE }, { SO_O_NOERR, _T("--noerr"), SO_NONE }, { SO_O_PEDANTIC, _T("--pedantic"), SO_NONE }, SO_END_OF_OPTIONS }; enum { OPT_HELP = 0, OPT_MULTI = 100, OPT_MULTI0, OPT_MULTI1, OPT_MULTI2 }; CSimpleOpt::SOption g_rgOptions[] = { { OPT_HELP, _T("-?"), SO_NONE }, { OPT_HELP, _T("-h"), SO_NONE }, { OPT_HELP, _T("-help"), SO_NONE }, { OPT_HELP, _T("--help"), SO_NONE }, { 1, _T("-"), SO_NONE }, { 2, _T("-d"), SO_NONE }, { 3, _T("-e"), SO_NONE }, { 4, _T("-f"), SO_NONE }, { 5, _T("-g"), SO_NONE }, { 6, _T("-flag"), SO_NONE }, { 7, _T("--flag"), SO_NONE }, { 8, _T("-s"), SO_REQ_SEP }, { 9, _T("-sep"), SO_REQ_SEP }, { 10, _T("--sep"), SO_REQ_SEP }, { 11, _T("-c"), SO_REQ_CMB }, { 12, _T("-com"), SO_REQ_CMB }, { 13, _T("--com"), SO_REQ_CMB }, { 14, _T("-o"), SO_OPT }, { 15, _T("-opt"), SO_OPT }, { 16, _T("--opt"), SO_OPT }, { 17, _T("-man"), SO_NONE }, { 18, _T("-mandy"), SO_NONE }, { 19, _T("-mandate"), SO_NONE }, { 20, _T("--man"), SO_NONE }, { 21, _T("--mandy"), SO_NONE }, { 22, _T("--mandate"), SO_NONE }, { 23, _T("open"), SO_NONE }, { 24, _T("read"), SO_NONE }, { 25, _T("write"), SO_NONE }, { 26, _T("close"), SO_NONE }, { 27, _T("zip"), SO_NONE }, { 28, _T("unzip"), SO_NONE }, { OPT_MULTI, _T("--multi"), SO_MULTI }, { OPT_MULTI0, _T("--multi0"), SO_MULTI }, { OPT_MULTI1, _T("--multi1"), SO_MULTI }, { OPT_MULTI2, _T("--multi2"), SO_MULTI }, SO_END_OF_OPTIONS }; void ShowFiles(int argc, TCHAR ** argv) { // glob files to catch expand wildcards CSimpleGlob glob(SG_GLOB_NODOT|SG_GLOB_NOCHECK); if (SG_SUCCESS != glob.Add(argc, argv)) { _tprintf(_T("Error while globbing files\n")); return; } for (int n = 0; n < glob.FileCount(); ++n) { _tprintf(_T("file %2d: '%s'\n"), n, glob.File(n)); } } static const TCHAR * GetLastErrorText( int a_nError ) { switch (a_nError) { case SO_SUCCESS: return _T("Success"); case SO_OPT_INVALID: return _T("Unrecognized option"); case SO_OPT_MULTIPLE: return _T("Option matched multiple strings"); case SO_ARG_INVALID: return _T("Option does not accept argument"); case SO_ARG_INVALID_TYPE: return _T("Invalid argument format"); case SO_ARG_MISSING: return _T("Required argument is missing"); case SO_ARG_INVALID_DATA: return _T("Invalid argument data"); default: return _T("Unknown error"); } } static void DoMultiArgs( CSimpleOpt & args, int nMultiArgs ) { TCHAR ** rgpszArg = NULL; // get the number of arguments if necessary if (nMultiArgs == -1) { // first arg is a count of how many we have rgpszArg = args.MultiArg(1); if (!rgpszArg) { _tprintf( _T("%s: '%s' (use --help to get command line help)\n"), GetLastErrorText(args.LastError()), args.OptionText()); return; } nMultiArgs = _ttoi(rgpszArg[0]); } _tprintf(_T("%s: expecting %d args\n"), args.OptionText(), nMultiArgs); // get the arguments to follow rgpszArg = args.MultiArg(nMultiArgs); if (!rgpszArg) { _tprintf( _T("%s: '%s' (use --help to get command line help)\n"), GetLastErrorText(args.LastError()), args.OptionText()); return; } for (int n = 0; n < nMultiArgs; ++n) { _tprintf(_T("MultiArg %d: %s\n"), n, rgpszArg[n]); } } int _tmain(int argc, TCHAR * argv[]) { setlocale( LC_ALL, "Japanese" ); // get the flags to use for SimpleOpt from the command line int nFlags = SO_O_USEALL; CSimpleOpt flags(argc, argv, g_rgFlags, SO_O_NOERR|SO_O_EXACT); while (flags.Next()) { nFlags |= flags.OptionId(); } // now process the remainder of the command line with these flags CSimpleOpt args(flags.FileCount(), flags.Files(), g_rgOptions, nFlags); while (args.Next()) { if (args.LastError() != SO_SUCCESS) { _tprintf( _T("%s: '%s' (use --help to get command line help)\n"), GetLastErrorText(args.LastError()), args.OptionText()); continue; } switch (args.OptionId()) { case OPT_HELP: ShowUsage(); return 0; case OPT_MULTI: DoMultiArgs(args, -1); break; case OPT_MULTI0: DoMultiArgs(args, 0); break; case OPT_MULTI1: DoMultiArgs(args, 1); break; case OPT_MULTI2: DoMultiArgs(args, 2); break; default: if (args.OptionArg()) { _tprintf(_T("option: %2d, text: '%s', arg: '%s'\n"), args.OptionId(), args.OptionText(), args.OptionArg()); } else { _tprintf(_T("option: %2d, text: '%s'\n"), args.OptionId(), args.OptionText()); } } } /* process files from command line */ ShowFiles(args.FileCount(), args.Files()); return 0; }