文档章节

支持宽字符的getopt

雅各宾
 雅各宾
发布于 2015/10/09 23:50
字数 2407
阅读 168
收藏 3

头文件getopt.h:

////////////////////////////////////////////////////////////////////////////////
/* Getopt for Microsoft C
This code is a modification of the Free Software Foundation, Inc.
Getopt library for parsing command line argument the purpose was
to provide a Microsoft Visual C friendly derivative. This code
provides functionality for both Unicode and Multibyte builds.
Date:    02/03/2011 - Ludvik Jerabek - Initial Release
Version: 1.0
Comment: Supports getopt, getopt_long, and getopt_long_only and POSIXLY_CORRECT
         environment flag
License: LGPL
Revisions:
02/03/2011 - Ludvik Jerabek - Initial Release
02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4
07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument
                              , optional_argument defs
08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused
                              runtime exception
08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB
02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in
                              implementation file
**DISCLAIMER**
THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
////////////////////////////////////////////////////////////////////////////////
# ifndef __GETOPT_H_
# define __GETOPT_H_
////////////////////////////////////////////////////////////////////////////////
# ifdef _GETOPT_API
#     undef _GETOPT_API
# endif
//------------------------------------------------------------------------------
# if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
#     error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT \
can only be used individually"
# elif defined(STATIC_GETOPT)
#     pragma message("Warning static builds of getopt violate the Lesser GNU \
Public License")
#     define _GETOPT_API
# elif defined(EXPORTS_GETOPT)
#     pragma message("Exporting getopt library")
#     define _GETOPT_API __declspec(dllexport)
# else
#     pragma message("Importing getopt library")
#     define _GETOPT_API __declspec(dllimport)
# endif
////////////////////////////////////////////////////////////////////////////////
# include <tchar.h>
// Standard GNU options
# define null_argument           0 /*Argument Null*/
# define no_argument             0 /*Argument Switch Only*/
# define required_argument       1 /*Argument Required*/
# define optional_argument       2 /*Argument Optional*/
// Shorter Versions of options
# define ARG_NULL 0 /*Argument Null*/
# define ARG_NONE 0 /*Argument Switch Only*/
# define ARG_REQ  1 /*Argument Required*/
# define ARG_OPT  2 /*Argument Optional*/
// Change behavior for C\C++
# ifdef __cplusplus
#     define _BEGIN_EXTERN_C extern "C" {
#     define _END_EXTERN_C }
#     define _GETOPT_THROW throw()
# else
#     define _BEGIN_EXTERN_C
#     define _END_EXTERN_C
#     define _GETOPT_THROW
# endif
_BEGIN_EXTERN_C
extern _GETOPT_API TCHAR *optarg;
extern _GETOPT_API int    optind;
extern _GETOPT_API int    opterr;
extern _GETOPT_API int    optopt;
struct option
{
/* The predefined macro variable __STDC__ is defined for C++, and it has the in-
   teger value 0 when it is used in an #if statement, indicating that the C++ l-
   anguage is not a proper superset of C, and that the compiler does not confor-
   m to C. In C, __STDC__ has the integer value 1. */
# if defined (__STDC__) && __STDC__
    const TCHAR* name;
# else
    TCHAR* name;
# endif
    int has_arg;
    int *flag;
    TCHAR val;
};
extern _GETOPT_API int getopt( int argc, TCHAR *const *argv
                             , const TCHAR *optstring ) _GETOPT_THROW;
extern _GETOPT_API int getopt_long
                             ( int ___argc, TCHAR *const *___argv
                             , const TCHAR *__shortopts
                             , const struct option *__longopts
                             , int *__longind ) _GETOPT_THROW;
extern _GETOPT_API int getopt_long_only
                             ( int ___argc, TCHAR *const *___argv
                             , const TCHAR *__shortopts
                             , const struct option *__longopts
                             , int *__longind ) _GETOPT_THROW;
// harly.he add for reentrant 12.09/2013
extern _GETOPT_API void getopt_reset() _GETOPT_THROW;
_END_EXTERN_C
// Undefine so the macros are not included
# undef _BEGIN_EXTERN_C
# undef _END_EXTERN_C
# undef _GETOPT_THROW
# undef _GETOPT_API
# endif  // __GETOPT_H_
////////////////////////////////// FILE END ////////////////////////////////////

实现文件getopt.c:

////////////////////////////////////////////////////////////////////////////////
/* Getopt for Microsoft C
This code is a modification of the Free Software Foundation, Inc.
Getopt library for parsing command line argument the purpose was
to provide a Microsoft Visual C friendly derivative. This code
provides functionality for both Unicode and Multibyte builds.
Date:    02/03/2011 - Ludvik Jerabek - Initial Release
Version: 1.0
Comment: Supports getopt, getopt_long, and getopt_long_only and POSIXLY_CORRECT
         environment flag
License: LGPL
Revisions:
02/03/2011 - Ludvik Jerabek - Initial Release
02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4
07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument
                              , optional_argument defs
08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused
                              runtime exception
08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB
02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in
                              implementation file
**DISCLAIMER**
THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
////////////////////////////////////////////////////////////////////////////////
# ifndef _CRT_SECURE_NO_WARNINGS
#     define _CRT_SECURE_NO_WARNINGS
# endif
////////////////////////////////////////////////////////////////////////////////
# include <stdlib.h>
# include <stdio.h>
# include "getopt.h"
////////////////////////////////////////////////////////////////////////////////
# ifdef __cplusplus
#     define _GETOPT_THROW throw()
# else
#     define _GETOPT_THROW
# endif
////////////////////////////////////////////////////////////////////////////////
enum ENUM_ORDERING
{
    REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
};
////////////////////////////////////////////////////////////////////////////////
struct _getopt_data
{
    int     optind;
    int     opterr;
    int     optopt;
    TCHAR*  optarg;
    int     __initialized;
    TCHAR*  __nextchar;
    int     __ordering;
    int     __posixly_correct;
    int     __first_nonopt;
    int     __last_nonopt;
};
static struct _getopt_data  getopt_data = { 0, 0, 0, NULL, 0, NULL, 0, 0, 0, 0 };
////////////////////////////////////////////////////////////////////////////////
TCHAR*  optarg  = NULL;
int     optind  = 1;
int     opterr  = 1;
int     optopt  = _T( '?' );
////////////////////////////////////////////////////////////////////////////////
static void exchange( TCHAR** argv, struct _getopt_data* d )
{
    int     bottom  = d->__first_nonopt;
    int     middle  = d->__last_nonopt;
    int     top     = d->optind;
    TCHAR*  tem;
    while ( top > middle && middle > bottom )
    {
        if ( top - middle > middle - bottom )
        {
            int len = middle - bottom;
            register int i;
            for ( i = 0; i < len; i++ )
            {
                tem = argv[bottom + i];
                argv[bottom + i] = argv[top - ( middle - bottom ) + i];
                argv[top - ( middle - bottom ) + i] = tem;
            }
            top -= len;
        }
        else
        {
            int len = top - middle;
            register int i;
            for ( i = 0; i < len; i++ )
            {
                tem = argv[bottom + i];
                argv[bottom + i] = argv[middle + i];
                argv[middle + i] = tem;
            }
            bottom += len;
        }
    }
    d->__first_nonopt += ( d->optind - d->__last_nonopt );
    d->__last_nonopt = d->optind;
}
////////////////////////////////////////////////////////////////////////////////
static const TCHAR* _getopt_initialize( const TCHAR* optstring
                                      , struct _getopt_data* d
                                      , int posixly_correct )
{
    d->__first_nonopt = d->__last_nonopt = d->optind;
    d->__nextchar = NULL;
    d->__posixly_correct = posixly_correct
                         | !!_tgetenv( _T( "POSIXLY_CORRECT" ) );
    if ( optstring[0] == _T( '-' ) )
    {
        d->__ordering = RETURN_IN_ORDER;
        ++optstring;
    }
    else if ( optstring[0] == _T( '+' ) )
    {
        d->__ordering = REQUIRE_ORDER;
        ++optstring;
    }
    else if ( d->__posixly_correct )
    {
        d->__ordering = REQUIRE_ORDER;
    }
    else
    {
        d->__ordering = PERMUTE;
    }
    return optstring;
}
////////////////////////////////////////////////////////////////////////////////
int _getopt_internal_r( int argc
                      , TCHAR *const * argv
                      , const TCHAR* optstring
                      , const struct option* longopts
                      , int* longind
                      , int long_only
                      , struct _getopt_data* d
                      , int posixly_correct )
{
    int print_errors    = d->opterr;
    if ( argc < 1 )
    {
        return -1;
    }
    d->optarg = NULL;
    if ( d->optind == 0 || !d->__initialized )
    {
        if ( d->optind == 0 )
        {
            d->optind = 1;
        }
        optstring = _getopt_initialize( optstring, d, posixly_correct );
        d->__initialized = 1;
    }
    else if ( optstring[0] == _T( '-' ) || optstring[0] == _T( '+' ) )
    {
        optstring++;
    }
    if ( optstring[0] == _T( ':' ) )
    {
        print_errors = 0;
    }
    if ( d->__nextchar == NULL || *d->__nextchar == _T( '\0' ) )
    {
        if ( d->__last_nonopt > d->optind )
        {
            d->__last_nonopt = d->optind;
        }
        if ( d->__first_nonopt > d->optind )
        {
            d->__first_nonopt = d->optind;
        }
        if ( d->__ordering == PERMUTE )
        {
            if ( d->__first_nonopt != d->__last_nonopt
              && d->__last_nonopt != d->optind )
            {
                exchange( ( TCHAR * * ) argv, d );
            }
            else if ( d->__last_nonopt != d->optind )
            {
                d->__first_nonopt = d->optind;
            }
            while ( d->optind
                  < argc
                 && ( argv[d->optind][0] != _T( '-' )
                   || argv[d->optind][1] == _T( '\0' ) ) )
            {
                d->optind++;
            }
            d->__last_nonopt = d->optind;
        }
        if ( d->optind != argc && !_tcscmp( argv[d->optind], _T( "--" ) ) )
        {
            d->optind++;
            if ( d->__first_nonopt != d->__last_nonopt
              && d->__last_nonopt != d->optind )
            {
                exchange( ( TCHAR * * ) argv, d );
            }
            else if ( d->__first_nonopt == d->__last_nonopt )
            {
                d->__first_nonopt = d->optind;
            }
            d->__last_nonopt = argc;
            d->optind = argc;
        }
        if ( d->optind == argc )
        {
            if ( d->__first_nonopt != d->__last_nonopt )
            {
                d->optind = d->__first_nonopt;
            }
            return -1;
        }
        if ( ( argv[d->optind][0] != _T( '-' )
            || argv[d->optind][1] == _T( '\0' ) ) )
        {
            if ( d->__ordering == REQUIRE_ORDER )
            {
                return -1;
            }
            d->optarg = argv[d->optind++];
            return 1;
        }
        d->__nextchar = ( argv[d->optind]
                        + 1 + ( longopts != NULL
                             && argv[d->optind][1] == _T( '-' ) ) );
    }
    if ( longopts != NULL
        && ( argv[d->optind][1] == _T( '-' )
            || ( long_only && ( argv[d->optind][2]
                                || !_tcschr( optstring, argv[d->optind][1] ) )
               )
           )
        )
    {
        TCHAR*                  nameend;
        const struct option*    p;
        const struct option*    pfound      = NULL;
        int                     exact       = 0;
        int                     ambig       = 0;
        int                     indfound    = -1;
        int                     option_index;
        for ( nameend = d->__nextchar;
              *nameend && *nameend != _T( '=' );
              nameend++ )
            ;
        for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
        {
            if ( !_tcsncmp( p->name, d->__nextchar, nameend - d->__nextchar ) )
            {
                if ( ( unsigned int ) ( nameend - d->__nextchar )
                  == ( unsigned int ) _tcslen( p->name ) )
                {
                    pfound = p;
                    indfound = option_index;
                    exact = 1;
                    break;
                }
                else if ( pfound == NULL )
                {
                    pfound = p;
                    indfound = option_index;
                }
                else if ( long_only
                       || pfound->has_arg != p->has_arg
                       || pfound->flag != p->flag
                       || pfound->val != p->val )
                {
                         ambig = 1;
                }
            }
        }
        if ( ambig && !exact )
        {
            if ( print_errors )
            {
                _ftprintf( stderr
                         , _T( "%s: option '%s' is ambiguous\n" )
                         , argv[0]
                         , argv[d->optind] );
            }
            d->__nextchar += _tcslen( d->__nextchar );
            d->optind++;
            d->optopt = 0;
            return _T( '?' );
        }
        if ( pfound != NULL )
        {
            option_index = indfound;
            d->optind++;
            if ( *nameend )
            {
                if ( pfound->has_arg )
                {
                    d->optarg = nameend + 1;
                }
                else
                {
                    if ( print_errors )
                    {
                        if ( argv[d->optind - 1][1] == _T( '-' ) )
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '--%s' doesn't allow " )
                                       _T( "an argument\n" )
                                     , argv[0]
                                     , pfound->name );
                        }
                        else
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '%c%s' doesn't allow " )
                                       _T( "an argument\n" )
                                     , argv[0]
                                     , argv[d->optind - 1][0]
                                     , pfound->name );
                        }
                    }
                    d->__nextchar += _tcslen( d->__nextchar );
                    d->optopt = pfound->val;
                    return _T( '?' );
                }
            }
            else if ( pfound->has_arg == 1 )
            {
                if ( d->optind < argc )
                {
                    d->optarg = argv[d->optind++];
                }
                else
                {
                    if ( print_errors )
                    {
                        _ftprintf( stderr
                                 , _T( "%s: option '--%s' requires an " )
                                   _T( "argument\n" )
                                 , argv[0]
                                 , pfound->name );
                    }
                    d->__nextchar += _tcslen( d->__nextchar );
                    d->optopt = pfound->val;
                    return optstring[0] == _T( ':' ) ? _T( ':' ) : _T( '?' );
                }
            }
            d->__nextchar += _tcslen( d->__nextchar );
            if ( longind != NULL )
            {
                *longind = option_index;
            }
            if ( pfound->flag )
            {
                *( pfound->flag ) = pfound->val;
                return 0;
            }
            return pfound->val;
        }
        if ( !long_only
          || argv[d->optind][1]
          == _T( '-' )
          || _tcschr( optstring
                    , *d->__nextchar )
          == NULL )
        {
            if ( print_errors )
            {
                if ( argv[d->optind][1] == _T( '-' ) )
                {
                    /* --option */
                    _ftprintf( stderr
                             , _T( "%s: unrecognized option '--%s'\n" )
                             , argv[0]
                             , d->__nextchar );
                }
                else
                {
                    /* +option or -option */
                    _ftprintf( stderr
                             , _T( "%s: unrecognized option '%c%s'\n" )
                             , argv[0]
                             , argv[d->optind][0]
                             , d->__nextchar );
                }
            }
            d->__nextchar = ( TCHAR * ) _T( "" );
            d->optind++;
            d->optopt = 0;
            return _T( '?' );
        }
    }
    {
        TCHAR   c       = *d->__nextchar++;
        TCHAR*  temp    = ( TCHAR* ) _tcschr( optstring, c );
        if ( *d->__nextchar == _T( '\0' ) )
        {
            ++d->optind;
        }
        if ( temp == NULL || c == _T( ':' ) || c == _T( ';' ) )
        {
            if ( print_errors )
            {
                _ftprintf( stderr
                         , _T( "%s: invalid option -- '%c'\n" )
                         , argv[0]
                         , c );
            }
            d->optopt = c;
            return _T( '?' );
        }
        if ( temp[0] == _T( 'W' ) && temp[1] == _T( ';' ) )
        {
            TCHAR*                  nameend;
            const struct option*    p;
            const struct option*    pfound      = NULL;
            int                     exact       = 0;
            int                     ambig       = 0;
            int                     indfound    = 0;
            int                     option_index;
            if ( *d->__nextchar != _T( '\0' ) )
            {
                d->optarg = d->__nextchar;
                d->optind++;
            }
            else if ( d->optind == argc )
            {
                if ( print_errors )
                {
                    _ftprintf( stderr
                             , _T( "%s: option requires an argument -- '%c'\n" )
                             , argv[0]
                             , c );
                }
                d->optopt = c;
                if ( optstring[0] == _T( ':' ) )
                {
                    c = _T( ':' );
                }
                else
                {
                    c = _T( '?' );
                }
                return c;
            }
            else
            {
                d->optarg = argv[d->optind++];
            }
            for ( d->__nextchar = nameend = d->optarg;
                  *nameend && *nameend != _T( '=' );
                  nameend++ )
                ;
            for ( p = longopts, option_index = 0;
                  p->name;
                  p++, option_index++ )
            {
                if ( !_tcsncmp( p->name
                              , d->__nextchar
                              , nameend - d->__nextchar ) )
                {
                    if ( ( unsigned int ) ( nameend - d->__nextchar )
                      == _tcslen( p->name ) )
                    {
                        pfound = p;
                        indfound = option_index;
                        exact = 1;
                        break;
                    }
                    else if ( pfound == NULL )
                    {
                        pfound = p;
                        indfound = option_index;
                    }
                    else if ( long_only
                           || pfound->has_arg != p->has_arg
                           || pfound->flag != p->flag
                           || pfound->val != p->val )
                    {
                             ambig = 1;
                    }
                }
            }
            if ( ambig && !exact )
            {
                if ( print_errors )
                {
                    _ftprintf( stderr
                             , _T( "%s: option '-W %s' is ambiguous\n" )
                             , argv[0]
                             , d->optarg );
                }
                d->__nextchar += _tcslen( d->__nextchar );
                d->optind++;
                return _T( '?' );
            }
            if ( pfound != NULL )
            {
                option_index = indfound;
                if ( *nameend )
                {
                    if ( pfound->has_arg )
                    {
                        d->optarg = nameend + 1;
                    }
                    else
                    {
                        if ( print_errors )
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '-W %s' doesn't allow " )
                                       _T( "an argument\n" )
                                     , argv[0]
                                     , pfound->name );
                        }
                        d->__nextchar += _tcslen( d->__nextchar );
                        return _T( '?' );
                    }
                }
                else if ( pfound->has_arg == 1 )
                {
                    if ( d->optind < argc )
                    {
                        d->optarg = argv[d->optind++];
                    }
                    else
                    {
                        if ( print_errors )
                        {
                            _ftprintf( stderr
                                     , _T( "%s: option '-W %s' requires an " )
                                       _T( "argument\n" )
                                     , argv[0]
                                     , pfound->name );
                        }
                        d->__nextchar += _tcslen( d->__nextchar );
                        return optstring[0] == _T(':') ? _T(':') : _T('?');
                    }
                }
                else
                {
                    d->optarg = NULL;
                }
                d->__nextchar += _tcslen( d->__nextchar );
                if ( longind != NULL )
                {
                    *longind = option_index;
                }
                if ( pfound->flag )
                {
                    *( pfound->flag ) = pfound->val;
                    return 0;
                }
                return pfound->val;
            }
            d->__nextchar = NULL;
            return _T( 'W' );
        }
        if ( temp[1] == _T( ':' ) )
        {
            if ( temp[2] == _T( ':' ) )
            {
                if ( *d->__nextchar != _T( '\0' ) )
                {
                    d->optarg = d->__nextchar;
                    d->optind++;
                }
                else
                {
                    d->optarg = NULL;
                }
                d->__nextchar = NULL;
            }
            else
            {
                if ( *d->__nextchar != _T( '\0' ) )
                {
                    d->optarg = d->__nextchar;
                    d->optind++;
                }
                else if ( d->optind == argc )
                {
                    if ( print_errors )
                    {
                        _ftprintf( stderr
                                 , _T( "%s: option requires an " )
                                   _T( "argument -- '%c'\n" )
                                 , argv[0]
                                 , c );
                    }
                    d->optopt = c;
                    if ( optstring[0] == _T( ':' ) )
                    {
                        c = _T( ':' );
                    }
                    else
                    {
                        c = _T( '?' );
                    }
                }
                else
                {
                    d->optarg = argv[d->optind++];
                }
                d->__nextchar = NULL;
            }
        }
        return c;
    }
}
////////////////////////////////////////////////////////////////////////////////
int _getopt_internal( int argc
                    , TCHAR *const * argv
                    , const TCHAR* optstring
                    , const struct option* longopts
                    , int* longind
                    , int long_only
                    , int posixly_correct )
{
    int result;
    getopt_data.optind = optind;
    getopt_data.opterr = opterr;
    result = _getopt_internal_r( argc
                               , argv
                               , optstring
                               , longopts
                               , longind
                               , long_only
                               , &getopt_data
                               , posixly_correct );
    optind = getopt_data.optind;
    optarg = getopt_data.optarg;
    optopt = getopt_data.optopt;
    return result;
}
////////////////////////////////////////////////////////////////////////////////
int getopt( int argc, TCHAR *const * argv, const TCHAR* optstring) _GETOPT_THROW
{
    return _getopt_internal( argc
                           , argv
                           , optstring
                           , ( const struct option * ) 0
                           , ( int * ) 0
                           , 0
                           , 0 );
}
////////////////////////////////////////////////////////////////////////////////
int getopt_long( int argc
               , TCHAR *const * argv
               , const TCHAR* options
               , const struct option* long_options
               , int* opt_index ) _GETOPT_THROW
{
    return _getopt_internal( argc
                           , argv
                           , options
                           , long_options
                           , opt_index
                           , 0
                           , 0 );
}
////////////////////////////////////////////////////////////////////////////////
int _getopt_long_r( int argc
                  , TCHAR *const * argv
                  , const TCHAR* options
                  , const struct option* long_options
                  , int* opt_index
                  , struct _getopt_data* d )
{
    return _getopt_internal_r( argc
                             , argv
                             , options
                             , long_options
                             , opt_index
                             , 0
                             , d
                             , 0 );
}
////////////////////////////////////////////////////////////////////////////////
int getopt_long_only( int argc
                    , TCHAR *const * argv
                    , const TCHAR* options
                    , const struct option* long_options
                    , int* opt_index ) _GETOPT_THROW
{
    return _getopt_internal( argc
                           , argv
                           , options
                           , long_options
                           , opt_index
                           , 1
                           , 0 );
}
////////////////////////////////////////////////////////////////////////////////
int _getopt_long_only_r( int argc
                       , TCHAR *const * argv
                       , const TCHAR* options
                       , const struct option* long_options
                       , int* opt_index
                       , struct _getopt_data* d )
{
    return _getopt_internal_r( argc
                             , argv
                             , options
                             , long_options
                             , opt_index
                             , 1
                             , d
                             , 0 );
}
////////////////////////////////////////////////////////////////////////////////
void getopt_reset()
{
    optarg  = NULL;
    optind  = 1;
    opterr  = 1;
    optopt  = _T( '?' );
    //
    getopt_data.optind            = 0;
    getopt_data.opterr            = 0;
    getopt_data.optopt            = 0;
    getopt_data.optarg            = NULL;
    getopt_data.__initialized     = 0;
    getopt_data.__nextchar        = NULL;
    getopt_data.__ordering        = 0;
    getopt_data.__posixly_correct = 0;
    getopt_data.__first_nonopt    = 0;
    getopt_data.__last_nonopt     = 0;
}
////////////////////////////////// FILE END ////////////////////////////////////

示例test_getopt.c:

////////////////////////////////////////////////////////////////////////////////
# include <tchar.h>
# include <ctype.h>
# include <stdio.h>
# include <stdlib.h>
# include "getopt.h"
////////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, TCHAR **argv)
{
    int aflag = 0;
    int bflag = 0;
    TCHAR *cvalue = NULL;
    int index;
    int c;
    opterr = 0;
    while((c = getopt(argc,argv, _T("abc:"))) != -1)
    switch(c)
    {
    case 'a':
        aflag = 1;
        break;
    case 'b':
        bflag = 1;
        break;
    case 'c':
        cvalue = optarg;
        break;
    case '?':
        if(optopt == 'c')
            _ftprintf(stderr,_T("Option -%c requires an argument.\n"),optopt);
        else if(isprint(optopt))
            _ftprintf(stderr,_T("Unknown option `-%c'.\n"),optopt);
        else
            _ftprintf(stderr,_T("Unknown option character `\\x%x'.\n"),optopt);
        return 1;
    default:
        abort();
    }
    _tprintf(_T("aflag = %d, bflag = %d, cvalue = %s\n"), aflag,bflag,cvalue);
    for(index = optind; index < argc; index++)
        _tprintf(_T("Non-option argument %s\n"),argv[index]);
    return 0;
}
/////////////////////////////////// END ////////////////////////////////////////


© 著作权归作者所有

共有 人打赏支持
雅各宾
粉丝 9
博文 123
码字总数 52806
作品 0
深圳
技术主管
加载中

评论(1)

雅各宾
雅各宾
宽字符和“窄字符”泛化为类型TCHAR,这是很好的字符处理的思想。微软从VS2013开始边缘化/摒弃了MFC对窄字符的支持,我认为是个悲剧。
Linux程序设计——用getopt处理命令行参数

原来命令行参数处理可以这么写-getopt? 经常要写点Linux下命令行的测试程序,都需要对命令行参数做一些处理,以前都是自己来写参数的处理,不只每次写的都不一样,而且每次还浪费时间去做参...

雅各宾
2013/09/03
0
0
getopt,getoptlong学习

getopt和getoptlong被用来解析命令行参数。 一、getopt #include extern char *optarg; extern int optind, extern int opterr, extern int optopt; int getopt(int argc, char const argv[......

沈小错
2016/08/20
0
0
getopt 与 getoptlong

getopt 简介 getopt被用来解析命令行选项参数。 #include <unistd.h>extern char *optarg; //选项的参数指针extern int optind, //下一次调用getopt的时,从optind存储的位置处重新开始检查选...

面码
2014/04/29
0
0
Linux命令行参数处理——getopt系列函数

1 函数原型   成员name是长选项的名称。   成员hasarg是:noargument(或0)如果该选项没有参数; requiredargument(或1)如果该选项需要参数;或optionalargument(或2)如果该选项具有可...

liao20081228
2017/08/01
0
0
getopt函数—分析命令行参数

getopt(分析命令行参数) 相关函数 表头文件 #include<unistd.h> 定义函数 int getopt(int argc,char const argv[ ],const char optstring); extern char *optarg; extern int optind, opte......

无若
2014/04/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

咕泡-Factory设计模式笔记

个人感悟: 设计模式都是处理复杂问题的,如果问题本身很简单,使用设计模式反而累赘,增加了开发的复杂性 遇到最简单的情况,直接 new 如果创建对象的过程简单,但是需要匹配不同情况,返回...

职业搬砖20年
15分钟前
0
0
Java中的锁分类

在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类。介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏...

Funcy1122
23分钟前
0
0
Ansible随机数

想为你的Ansible剧本取一个随机数?还想在接下来的运行中保持系统的等幂性?这里有一个答案。 假如,你要为一大批服务器设置cron任务,却不想让它们同时启动,你可以这样设置分钟数: minute...

大别阿郎
33分钟前
0
0
SpringCloud之服务注册中心Eureka

本系列介绍的配置均基于 Spring Boot 2.0.1.RELEASE 版本和 Spring Cloud Finchley.SR1 服务注册中心 Spring Cloud 已经帮我们实现了服务注册中心,我们只需要很简单的几个步骤就可以完成。 ...

熊小飞呀
今天
7
1
“Comparison method violates ...”异常的再现方法

前提条件:JDK8 代码: import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;public class Test { public stat......

hunterli
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部