支持宽字符的getopt
支持宽字符的getopt
雅各宾 发表于2年前
支持宽字符的getopt
  • 发表于 2年前
  • 阅读 158
  • 收藏 3
  • 点赞 0
  • 评论 1

新睿云服务器60天免费使用,快来体验!>>>   

头文件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
博文 92
码字总数 24099
评论 (1)
雅各宾
宽字符和“窄字符”泛化为类型TCHAR,这是很好的字符处理的思想。微软从VS2013开始边缘化/摒弃了MFC对窄字符的支持,我认为是个悲剧。
×
雅各宾
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: