Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
1c1e1ee6
...
1c1e1ee61e6eea30f5647f596ee705997bfab1ff
authored
2001-04-16 00:06:55 +0000
by
Alain Magloire
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Update some functions from GLIBC.
1 parent
8f4858ac
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
707 additions
and
250 deletions
lib/Makefile.am
lib/getopt.c
lib/getopt.h
lib/getopt1.c
lib/strndup.c
lib/strnlen.c
lib/Makefile.am
View file @
1c1e1ee
AUTOMAKE_OPTIONS
=
ansi2knr
noinst_LIBRARIES
=
libmailutils.a
libmailutils_a_SOURCES
=
basename.c getopt.c getopt1.c md5.c getline.c
\
xstrdup.c xmalloc.c argcv.c
EXTRA_DIST
=
alloca.c snprintf.c strtok_r.c xstrtol.c
EXTRA_DIST
=
alloca.c snprintf.c strchrnul.c strndup.c strnlen.c strtok_r.c
\
xstrtol.c vasprintf.c
noinst_HEADERS
=
getopt.h md5.h getline.h snprintf.h xstrtol.h xalloc.h
\
argcv.h error.h
...
...
lib/getopt.c
View file @
1c1e1ee
/* Getopt for GNU.
NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
NOTE: The canonical source of this file is maintained with the GNU
C Library. Bugs can be reported to bug-glibc@gnu.org.
Copyright (C) 1987, 88, 89, 90, 91, 92,
1993
Free Software Foundation, Inc.
Copyright (C) 1987, 88, 89, 90, 91, 92,
93, 94, 95, 96, 97, 98, 99, 2000
Free Software Foundation, Inc.
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
...
...
@@ -17,38 +16,25 @@
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, 675 Mass Ave, Cambridge, MA 02139
, USA. */
along with this program; if not, write to the Free Software
Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307
, USA. */
/*
NOTE!!! AIX requires this to be the first thing in the file
.
D
o not put ANYTHING before it!
*/
#if
!defined (__GNUC__) && defined (_AIX)
#
pragma alloca
/*
This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>
.
D
itto for AIX 3.2 and <stdlib.h>.
*/
#if
ndef _NO_PROTO
#
define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
/* not __GNUC__ */
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
#include <alloca.h>
#else
#ifndef _AIX
char
*
alloca
();
# include <config.h>
#endif
#endif
/* alloca.h */
#endif
/* not __GNUC__ */
#if !__STDC__ && !defined(const) && IN_GCC
#define const
#endif
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
# ifndef const
# define const
# endif
#endif
#include <stdio.h>
...
...
@@ -61,24 +47,44 @@ char *alloca ();
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
# include <gnu-versions.h>
# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
# define ELIDE_CODE
# endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#undef alloca
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
#include <stdlib.h>
#else
/* Not GNU C library. */
#define __alloca alloca
#endif
/* GNU C library. */
# include <stdlib.h>
# include <unistd.h>
#endif
/* GNU C library. */
#ifdef VMS
# include <unixlib.h>
# if HAVE_STRING_H - 0
# include <string.h>
# endif
#endif
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
long-named option. Because this is not POSIX.2 compliant, it is
being phased out. */
/* #define GETOPT_COMPAT */
#ifndef _
/* This is for other GNU distributions with internationalized messages. */
# if defined HAVE_LIBINTL_H || defined _LIBC
# include <libintl.h>
# ifndef _
# define _(msgid) gettext (msgid)
# endif
# else
# define _(msgid) (msgid)
# endif
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
...
...
@@ -102,7 +108,7 @@ char *alloca ();
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char
*
optarg
=
0
;
char
*
optarg
;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
...
...
@@ -110,14 +116,20 @@ char *optarg = 0;
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns
EOF
, this is the index of the first of the
When `getopt' returns
-1
, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* XXX 1003.2 says this must be 1 before any call. */
int
optind
=
0
;
/* 1003.2 says this must be 1 before any call. */
int
optind
=
1
;
/* Formerly, initialization of getopt depended on optind==0, which
causes problems with re-calling getopt as programs generally don't
know that. */
int
__getopt_initialized
;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
...
...
@@ -166,28 +178,37 @@ int optopt = '?';
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return
EOF
with `optind' != ARGC. */
`--' can cause `getopt' to return
-1
with `optind' != ARGC. */
static
enum
{
REQUIRE_ORDER
,
PERMUTE
,
RETURN_IN_ORDER
}
ordering
;
{
REQUIRE_ORDER
,
PERMUTE
,
RETURN_IN_ORDER
}
ordering
;
/* Value of POSIXLY_CORRECT environment variable. */
static
char
*
posixly_correct
;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
#include <string.h>
#define my_index strchr
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
# include <string.h>
# define my_index strchr
#else
# if HAVE_STRING_H
# include <string.h>
# else
# include <strings.h>
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
char
*
getenv
();
#ifndef getenv
extern
char
*
getenv
();
#endif
static
char
*
my_index
(
str
,
chr
)
...
...
@@ -203,17 +224,19 @@ my_index (str, chr)
return
0
;
}
static
void
my_bcopy
(
from
,
to
,
size
)
const
char
*
from
;
char
*
to
;
int
size
;
{
int
i
;
for
(
i
=
0
;
i
<
size
;
i
++
)
to
[
i
]
=
from
[
i
];
}
#endif
/* GNU C library. */
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
# if (!defined __STDC__ || !__STDC__) && !defined strlen
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern
int
strlen
(
const
char
*
);
# endif
/* not __STDC__ */
#endif
/* __GNUC__ */
#endif
/* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
...
...
@@ -224,6 +247,46 @@ my_bcopy (from, to, size)
static
int
first_nonopt
;
static
int
last_nonopt
;
#ifdef _LIBC
/* Bash 2.0 gives us an environment variable containing flags
indicating ARGV elements that should not be considered arguments. */
/* Defined in getopt_init.c */
extern
char
*
__getopt_nonoption_flags
;
static
int
nonoption_flags_max_len
;
static
int
nonoption_flags_len
;
static
int
original_argc
;
static
char
*
const
*
original_argv
;
/* Make sure the environment variable bash 2.0 puts in the environment
is valid for the getopt call we must make sure that the ARGV passed
to getopt is that one passed to the process. */
static
void
__attribute__
((
unused
))
store_args_and_env
(
int
argc
,
char
*
const
*
argv
)
{
/* XXX This is no good solution. We should rather copy the args so
that we can compare them later. But we must not use malloc(3). */
original_argc
=
argc
;
original_argv
=
argv
;
}
# ifdef text_set_element
text_set_element
(
__libc_subinit
,
store_args_and_env
);
# endif
/* text_set_element */
# define SWAP_FLAGS(ch1, ch2) \
if (nonoption_flags_len > 0) \
{ \
char __tmp = __getopt_nonoption_flags[ch1]; \
__getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
__getopt_nonoption_flags[ch2] = __tmp; \
}
#else
/* !_LIBC */
# define SWAP_FLAGS(ch1, ch2)
#endif
/* _LIBC */
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
...
...
@@ -233,27 +296,160 @@ static int last_nonopt;
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
#if defined __STDC__ && __STDC__
static
void
exchange
(
char
**
);
#endif
static
void
exchange
(
argv
)
char
**
argv
;
{
int
nonopts_size
=
(
last_nonopt
-
first_nonopt
)
*
sizeof
(
char
*
);
char
**
temp
=
(
char
**
)
__alloca
(
nonopts_size
);
int
bottom
=
first_nonopt
;
int
middle
=
last_nonopt
;
int
top
=
optind
;
char
*
tem
;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
#ifdef _LIBC
/* First make sure the handling of the `__getopt_nonoption_flags'
string can work normally. Our top argument must be in the range
of the string. */
if
(
nonoption_flags_len
>
0
&&
top
>=
nonoption_flags_max_len
)
{
/* We must extend the array. The user plays games with us and
presents new arguments. */
char
*
new_str
=
malloc
(
top
+
1
);
if
(
new_str
==
NULL
)
nonoption_flags_len
=
nonoption_flags_max_len
=
0
;
else
{
memset
(
__mempcpy
(
new_str
,
__getopt_nonoption_flags
,
nonoption_flags_max_len
),
'\0'
,
top
+
1
-
nonoption_flags_max_len
);
nonoption_flags_max_len
=
top
+
1
;
__getopt_nonoption_flags
=
new_str
;
}
}
#endif
/* Interchange the two blocks of data in ARGV. */
while
(
top
>
middle
&&
middle
>
bottom
)
{
if
(
top
-
middle
>
middle
-
bottom
)
{
/* Bottom segment is the short one. */
int
len
=
middle
-
bottom
;
register
int
i
;
my_bcopy
((
char
*
)
&
argv
[
first_nonopt
],
(
char
*
)
temp
,
nonopts_size
);
my_bcopy
((
char
*
)
&
argv
[
last_nonopt
],
(
char
*
)
&
argv
[
first_nonopt
],
(
optind
-
last_nonopt
)
*
sizeof
(
char
*
));
my_bcopy
((
char
*
)
temp
,
(
char
*
)
&
argv
[
first_nonopt
+
optind
-
last_nonopt
],
nonopts_size
);
/* Swap it with the top part of the top segment. */
for
(
i
=
0
;
i
<
len
;
i
++
)
{
tem
=
argv
[
bottom
+
i
];
argv
[
bottom
+
i
]
=
argv
[
top
-
(
middle
-
bottom
)
+
i
];
argv
[
top
-
(
middle
-
bottom
)
+
i
]
=
tem
;
SWAP_FLAGS
(
bottom
+
i
,
top
-
(
middle
-
bottom
)
+
i
);
}
/* Exclude the moved bottom segment from further swapping. */
top
-=
len
;
}
else
{
/* Top segment is the short one. */
int
len
=
top
-
middle
;
register
int
i
;
/* Swap it with the bottom part of the bottom segment. */
for
(
i
=
0
;
i
<
len
;
i
++
)
{
tem
=
argv
[
bottom
+
i
];
argv
[
bottom
+
i
]
=
argv
[
middle
+
i
];
argv
[
middle
+
i
]
=
tem
;
SWAP_FLAGS
(
bottom
+
i
,
middle
+
i
);
}
/* Exclude the moved top segment from further swapping. */
bottom
+=
len
;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt
+=
(
optind
-
last_nonopt
);
last_nonopt
=
optind
;
}
/* Initialize the internal data when the first call is made. */
#if defined __STDC__ && __STDC__
static
const
char
*
_getopt_initialize
(
int
,
char
*
const
*
,
const
char
*
);
#endif
static
const
char
*
_getopt_initialize
(
argc
,
argv
,
optstring
)
int
argc
;
char
*
const
*
argv
;
const
char
*
optstring
;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt
=
last_nonopt
=
optind
;
nextchar
=
NULL
;
posixly_correct
=
getenv
(
"POSIXLY_CORRECT"
);
/* Determine how to handle the ordering of options and nonoptions. */
if
(
optstring
[
0
]
==
'-'
)
{
ordering
=
RETURN_IN_ORDER
;
++
optstring
;
}
else
if
(
optstring
[
0
]
==
'+'
)
{
ordering
=
REQUIRE_ORDER
;
++
optstring
;
}
else
if
(
posixly_correct
!=
NULL
)
ordering
=
REQUIRE_ORDER
;
else
ordering
=
PERMUTE
;
#ifdef _LIBC
if
(
posixly_correct
==
NULL
&&
argc
==
original_argc
&&
argv
==
original_argv
)
{
if
(
nonoption_flags_max_len
==
0
)
{
if
(
__getopt_nonoption_flags
==
NULL
||
__getopt_nonoption_flags
[
0
]
==
'\0'
)
nonoption_flags_max_len
=
-
1
;
else
{
const
char
*
orig_str
=
__getopt_nonoption_flags
;
int
len
=
nonoption_flags_max_len
=
strlen
(
orig_str
);
if
(
nonoption_flags_max_len
<
argc
)
nonoption_flags_max_len
=
argc
;
__getopt_nonoption_flags
=
(
char
*
)
malloc
(
nonoption_flags_max_len
);
if
(
__getopt_nonoption_flags
==
NULL
)
nonoption_flags_max_len
=
-
1
;
else
memset
(
__mempcpy
(
__getopt_nonoption_flags
,
orig_str
,
len
),
'\0'
,
nonoption_flags_max_len
-
len
);
}
}
nonoption_flags_len
=
nonoption_flags_max_len
;
}
else
nonoption_flags_len
=
0
;
#endif
return
optstring
;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
...
...
@@ -268,7 +464,7 @@ exchange (argv)
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns
`EOF'
.
If there are no more option characters, `getopt' returns
-1
.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
...
...
@@ -320,41 +516,46 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int
*
longind
;
int
long_only
;
{
int
option_index
;
int
print_errors
=
opterr
;
if
(
optstring
[
0
]
==
':'
)
print_errors
=
0
;
optarg
=
0
;
if
(
argc
<
1
)
return
-
1
;
/* Initialize the internal data when the first call is made.
Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
optarg
=
NULL
;
if
(
optind
==
0
)
if
(
optind
==
0
||
!
__getopt_initialized
)
{
first_nonopt
=
last_nonopt
=
optind
=
1
;
nextchar
=
NULL
;
/* Determine how to handle the ordering of options and nonoptions. */
if
(
optstring
[
0
]
==
'-'
)
{
ordering
=
RETURN_IN_ORDER
;
++
optstring
;
}
else
if
(
optstring
[
0
]
==
'+'
)
{
ordering
=
REQUIRE_ORDER
;
++
optstring
;
}
else
if
(
getenv
(
"POSIXLY_CORRECT"
)
!=
NULL
)
ordering
=
REQUIRE_ORDER
;
else
ordering
=
PERMUTE
;
if
(
optind
==
0
)
optind
=
1
;
/* Don't scan ARGV[0], the program name. */
optstring
=
_getopt_initialize
(
argc
,
argv
,
optstring
);
__getopt_initialized
=
1
;
}
/* Test whether ARGV[optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#ifdef _LIBC
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|| (optind < nonoption_flags_len \
&& __getopt_nonoption_flags[optind] == '1'))
#else
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#endif
if
(
nextchar
==
NULL
||
*
nextchar
==
'\0'
)
{
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if
(
last_nonopt
>
optind
)
last_nonopt
=
optind
;
if
(
first_nonopt
>
optind
)
first_nonopt
=
optind
;
if
(
ordering
==
PERMUTE
)
{
/* If we have just processed some options following some non-options,
...
...
@@ -365,24 +566,18 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
else
if
(
last_nonopt
!=
optind
)
first_nonopt
=
optind
;
/*
Now s
kip any additional non-options
/*
S
kip any additional non-options
and extend the range of non-options previously skipped. */
while
(
optind
<
argc
&&
(
argv
[
optind
][
0
]
!=
'-'
||
argv
[
optind
][
1
]
==
'\0'
)
#ifdef GETOPT_COMPAT
&&
(
longopts
==
NULL
||
argv
[
optind
][
0
]
!=
'+'
||
argv
[
optind
][
1
]
==
'\0'
)
#endif
/* GETOPT_COMPAT */
)
while
(
optind
<
argc
&&
NONOPTION_P
)
optind
++
;
last_nonopt
=
optind
;
}
/*
S
pecial ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
/*
The s
pecial ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if
(
optind
!=
argc
&&
!
strcmp
(
argv
[
optind
],
"--"
))
{
...
...
@@ -398,7 +593,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
and back over any non-options that we skipped and permuted. */
if
(
optind
==
argc
)
{
...
...
@@ -406,56 +601,64 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
that we previously skipped, so the caller will digest them. */
if
(
first_nonopt
!=
last_nonopt
)
optind
=
first_nonopt
;
return
EOF
;
return
-
1
;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if
((
argv
[
optind
][
0
]
!=
'-'
||
argv
[
optind
][
1
]
==
'\0'
)
#ifdef GETOPT_COMPAT
&&
(
longopts
==
NULL
||
argv
[
optind
][
0
]
!=
'+'
||
argv
[
optind
][
1
]
==
'\0'
)
#endif
/* GETOPT_COMPAT */
)
either stop the scan or describe it to the caller and pass it by. */
if
(
NONOPTION_P
)
{
if
(
ordering
==
REQUIRE_ORDER
)
return
EOF
;
return
-
1
;
optarg
=
argv
[
optind
++
];
return
1
;
}
/* We have found another option-ARGV-element.
Start decoding its characters
. */
Skip the initial punctuation
. */
nextchar
=
(
argv
[
optind
]
+
1
+
(
longopts
!=
NULL
&&
argv
[
optind
][
1
]
==
'-'
));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if
(
longopts
!=
NULL
&&
((
argv
[
optind
][
0
]
==
'-'
&&
(
argv
[
optind
][
1
]
==
'-'
||
long_only
))
#ifdef GETOPT_COMPAT
||
argv
[
optind
][
0
]
==
'+'
#endif
/* GETOPT_COMPAT */
))
&&
(
argv
[
optind
][
1
]
==
'-'
||
(
long_only
&&
(
argv
[
optind
][
2
]
||
!
my_index
(
optstring
,
argv
[
optind
][
1
])))))
{
char
*
nameend
;
const
struct
option
*
p
;
c
har
*
s
=
nextchar
;
c
onst
struct
option
*
pfound
=
NULL
;
int
exact
=
0
;
int
ambig
=
0
;
const
struct
option
*
pfound
=
NULL
;
int
indfound
;
int
indfound
=
-
1
;
int
option_index
;
while
(
*
s
&&
*
s
!=
'='
)
s
++
;
for
(
nameend
=
nextchar
;
*
nameend
&&
*
nameend
!=
'='
;
nameend
++
)
/* Do nothing. */
;
/* Test all
options for either exact match or abbreviated matches. */
for
(
p
=
longopts
,
option_index
=
0
;
p
->
name
;
p
++
,
option_index
++
)
if
(
!
strncmp
(
p
->
name
,
nextchar
,
s
-
nextchar
))
/* Test all
long options for either exact match
or abbreviated matches. */
for
(
p
=
longopts
,
option_index
=
0
;
p
->
name
;
p
++
,
option_index
++
)
if
(
!
strncmp
(
p
->
name
,
nextchar
,
nameend
-
nextchar
))
{
if
(
s
-
nextchar
==
strlen
(
p
->
name
))
if
((
unsigned
int
)
(
nameend
-
nextchar
)
==
(
unsigned
int
)
strlen
(
p
->
name
))
{
/* Exact match found. */
pfound
=
p
;
...
...
@@ -469,18 +672,22 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
pfound
=
p
;
indfound
=
option_index
;
}
else
/* Second nonexact match found. */
else
if
(
long_only
||
pfound
->
has_arg
!=
p
->
has_arg
||
pfound
->
flag
!=
p
->
flag
||
pfound
->
val
!=
p
->
val
)
/* Second or later nonexact match found. */
ambig
=
1
;
}
if
(
ambig
&&
!
exact
)
{
if
(
opterr
)
fprintf
(
stderr
,
"%s: option `%s' is ambiguous
\n
"
,
if
(
print_errors
)
fprintf
(
stderr
,
_
(
"%s: option `%s' is ambiguous
\n
"
)
,
argv
[
0
],
argv
[
optind
]);
nextchar
+=
strlen
(
nextchar
);
optind
++
;
optopt
=
0
;
return
'?'
;
}
...
...
@@ -488,28 +695,31 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
{
option_index
=
indfound
;
optind
++
;
if
(
*
s
)
if
(
*
nameend
)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
allow it to be used on enums. */
if
(
pfound
->
has_arg
)
optarg
=
s
+
1
;
optarg
=
nameend
+
1
;
else
{
if
(
opterr
)
if
(
print_errors
)
{
if
(
argv
[
optind
-
1
][
1
]
==
'-'
)
/* --option */
fprintf
(
stderr
,
"%s: option `--%s' doesn't allow an argument
\n
"
,
_
(
"%s: option `--%s' doesn't allow an argument
\n
"
)
,
argv
[
0
],
pfound
->
name
);
else
/* +option or -option */
fprintf
(
stderr
,
"%s: option `%c%s' doesn't allow an argument
\n
"
,
_
(
"%s: option `%c%s' doesn't allow an argument
\n
"
)
,
argv
[
0
],
argv
[
optind
-
1
][
0
],
pfound
->
name
);
}
nextchar
+=
strlen
(
nextchar
);
optopt
=
pfound
->
val
;
return
'?'
;
}
}
...
...
@@ -519,10 +729,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optarg
=
argv
[
optind
++
];
else
{
if
(
opterr
)
fprintf
(
stderr
,
"%s: option `%s' requires an argument
\n
"
,
argv
[
0
],
argv
[
optind
-
1
]);
if
(
print_errors
)
fprintf
(
stderr
,
_
(
"%s: option `%s' requires an argument
\n
"
),
argv
[
0
],
argv
[
optind
-
1
]);
nextchar
+=
strlen
(
nextchar
);
optopt
=
pfound
->
val
;
return
optstring
[
0
]
==
':'
?
':'
:
'?'
;
}
}
...
...
@@ -536,34 +748,33 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
return
pfound
->
val
;
}
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if
(
!
long_only
||
argv
[
optind
][
1
]
==
'-'
#ifdef GETOPT_COMPAT
||
argv
[
optind
][
0
]
==
'+'
#endif
/* GETOPT_COMPAT */
||
my_index
(
optstring
,
*
nextchar
)
==
NULL
)
{
if
(
opterr
)
if
(
print_errors
)
{
if
(
argv
[
optind
][
1
]
==
'-'
)
/* --option */
fprintf
(
stderr
,
"%s: unrecognized option `--%s'
\n
"
,
fprintf
(
stderr
,
_
(
"%s: unrecognized option `--%s'
\n
"
)
,
argv
[
0
],
nextchar
);
else
/* +option or -option */
fprintf
(
stderr
,
"%s: unrecognized option `%c%s'
\n
"
,
fprintf
(
stderr
,
_
(
"%s: unrecognized option `%c%s'
\n
"
)
,
argv
[
0
],
argv
[
optind
][
0
],
nextchar
);
}
nextchar
=
(
char
*
)
""
;
optind
++
;
optopt
=
0
;
return
'?'
;
}
}
/* Look at and handle the next option-character. */
/* Look at and handle the next
short
option-character. */
{
char
c
=
*
nextchar
++
;
...
...
@@ -575,22 +786,143 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
if
(
temp
==
NULL
||
c
==
':'
)
{
if
(
opterr
)
if
(
print_errors
)
{
#if 0
if (c < 040 || c >= 0177)
fprintf (stderr,
"%s: unrecognized option, character code 0%o\n"
,
if
(
posixly_correct
)
/* 1003.2 specifies the format of this message. */
fprintf
(
stderr
,
_
(
"%s: illegal option -- %c
\n
"
)
,
argv
[
0
],
c
);
else
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
#else
/* 1003.2 specifies the format of this message. */
fprintf
(
stderr
,
"%s: illegal option -- %c
\n
"
,
argv
[
0
],
c
);
#endif
fprintf
(
stderr
,
_
(
"%s: invalid option -- %c
\n
"
),
argv
[
0
],
c
);
}
optopt
=
c
;
return
'?'
;
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if
(
temp
[
0
]
==
'W'
&&
temp
[
1
]
==
';'
)
{
char
*
nameend
;
const
struct
option
*
p
;
const
struct
option
*
pfound
=
NULL
;
int
exact
=
0
;
int
ambig
=
0
;
int
indfound
=
0
;
int
option_index
;
/* This is an option that requires an argument. */
if
(
*
nextchar
!=
'\0'
)
{
optarg
=
nextchar
;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind
++
;
}
else
if
(
optind
==
argc
)
{
if
(
print_errors
)
{
/* 1003.2 specifies the format of this message. */
fprintf
(
stderr
,
_
(
"%s: option requires an argument -- %c
\n
"
),
argv
[
0
],
c
);
}
optopt
=
c
;
if
(
optstring
[
0
]
==
':'
)
c
=
':'
;
else
c
=
'?'
;
return
c
;
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg
=
argv
[
optind
++
];
/* optarg is now the argument, see if it's in the
table of longopts. */
for
(
nextchar
=
nameend
=
optarg
;
*
nameend
&&
*
nameend
!=
'='
;
nameend
++
)
/* Do nothing. */
;
/* Test all long options for either exact match
or abbreviated matches. */
for
(
p
=
longopts
,
option_index
=
0
;
p
->
name
;
p
++
,
option_index
++
)
if
(
!
strncmp
(
p
->
name
,
nextchar
,
nameend
-
nextchar
))
{
if
((
unsigned
int
)
(
nameend
-
nextchar
)
==
strlen
(
p
->
name
))
{
/* Exact match found. */
pfound
=
p
;
indfound
=
option_index
;
exact
=
1
;
break
;
}
else
if
(
pfound
==
NULL
)
{
/* First nonexact match found. */
pfound
=
p
;
indfound
=
option_index
;
}
else
/* Second or later nonexact match found. */
ambig
=
1
;
}
if
(
ambig
&&
!
exact
)
{
if
(
print_errors
)
fprintf
(
stderr
,
_
(
"%s: option `-W %s' is ambiguous
\n
"
),
argv
[
0
],
argv
[
optind
]);
nextchar
+=
strlen
(
nextchar
);
optind
++
;
return
'?'
;
}
if
(
pfound
!=
NULL
)
{
option_index
=
indfound
;
if
(
*
nameend
)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if
(
pfound
->
has_arg
)
optarg
=
nameend
+
1
;
else
{
if
(
print_errors
)
fprintf
(
stderr
,
_
(
"\
%s: option `-W %s' doesn't allow an argument
\n
"
),
argv
[
0
],
pfound
->
name
);
nextchar
+=
strlen
(
nextchar
);
return
'?'
;
}
}
else
if
(
pfound
->
has_arg
==
1
)
{
if
(
optind
<
argc
)
optarg
=
argv
[
optind
++
];
else
{
if
(
print_errors
)
fprintf
(
stderr
,
_
(
"%s: option `%s' requires an argument
\n
"
),
argv
[
0
],
argv
[
optind
-
1
]);
nextchar
+=
strlen
(
nextchar
);
return
optstring
[
0
]
==
':'
?
':'
:
'?'
;
}
}
nextchar
+=
strlen
(
nextchar
);
if
(
longind
!=
NULL
)
*
longind
=
option_index
;
if
(
pfound
->
flag
)
{
*
(
pfound
->
flag
)
=
pfound
->
val
;
return
0
;
}
return
pfound
->
val
;
}
nextchar
=
NULL
;
return
'W'
;
/* Let the application handle it. */
}
if
(
temp
[
1
]
==
':'
)
{
if
(
temp
[
2
]
==
':'
)
...
...
@@ -602,7 +934,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
optind
++
;
}
else
optarg
=
0
;
optarg
=
NULL
;
nextchar
=
NULL
;
}
else
...
...
@@ -617,16 +949,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
else
if
(
optind
==
argc
)
{
if
(
opterr
)
if
(
print_errors
)
{
#if 0
fprintf (stderr, "%s: option `-%c' requires an argument\n",
argv[0], c);
#else
/* 1003.2 specifies the format of this message. */
fprintf
(
stderr
,
"%s: option requires an argument -- %c
\n
"
,
fprintf
(
stderr
,
_
(
"%s: option requires an argument -- %c
\n
"
),
argv
[
0
],
c
);
#endif
}
optopt
=
c
;
if
(
optstring
[
0
]
==
':'
)
...
...
@@ -636,7 +964,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
increment it again when taking next ARGV-elt as argument. */
optarg
=
argv
[
optind
++
];
nextchar
=
NULL
;
}
...
...
@@ -657,7 +985,7 @@ getopt (argc, argv, optstring)
0
);
}
#endif
/* _LIBC or not __GNU_LIBRARY__
. */
#endif
/* Not ELIDE_CODE
. */
#ifdef TEST
...
...
@@ -677,7 +1005,7 @@ main (argc, argv)
int
this_option_optind
=
optind
?
optind
:
1
;
c
=
getopt
(
argc
,
argv
,
"abc:d:0123456789"
);
if
(
c
==
EOF
)
if
(
c
==
-
1
)
break
;
switch
(
c
)
...
...
lib/getopt.h
View file @
1c1e1ee
/* Declarations for getopt.
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
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, or (at your option) any
...
...
@@ -13,14 +14,17 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifndef __need_getopt
# define _GETOPT_H 1
#endif
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
#endif
/* For communication from `getopt' to the caller.
...
...
@@ -29,7 +33,7 @@ extern "C"
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern
char
*
optarg
;
extern
char
*
optarg
;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
...
...
@@ -37,32 +41,33 @@ extern "C"
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns
EOF
, this is the index of the first of the
When `getopt' returns
-1
, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern
int
optind
;
extern
int
optind
;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern
int
opterr
;
extern
int
opterr
;
/* Set to an option character which was unrecognized. */
extern
int
optopt
;
extern
int
optopt
;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument
(or 0) if the option does not take an argument,
required_argument
(or 1) if the option requires an argument,
optional_argument
(or 2) if the option takes an optional argument.
no_argument
(or 0) if the option does not take an argument,
required_argument
(or 1) if the option requires an argument,
optional_argument
(or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
...
...
@@ -75,56 +80,90 @@ extern "C"
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct
option
{
#
if
__STDC__
const
char
*
name
;
#else
char
*
name
;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int
has_arg
;
int
*
flag
;
int
val
;
};
struct
option
{
#
if defined __STDC__ &&
__STDC__
const
char
*
name
;
#
else
char
*
name
;
#
endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int
has_arg
;
int
*
flag
;
int
val
;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif
/* need getopt */
#if __STDC__
#if defined(__GNU_LIBRARY__)
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
If OPTS begins with `--', then non-option arguments are treated as
arguments to the option '\0'. This behavior is specific to the GNU
`getopt'. */
#if defined __STDC__ && __STDC__
# ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern
int
getopt
(
int
argc
,
char
*
const
*
argv
,
const
char
*
shortopts
);
#else
/* not __GNU_LIBRARY__ */
extern
int
getopt
();
#endif
/* not __GNU_LIBRARY__ */
extern
int
getopt_long
(
int
argc
,
char
*
const
*
argv
,
const
char
*
shortopts
,
const
struct
option
*
longopts
,
int
*
longind
);
extern
int
getopt_long_only
(
int
argc
,
char
*
const
*
argv
,
const
char
*
shortopts
,
const
struct
option
*
longopts
,
int
*
longind
);
extern
int
getopt
(
int
__argc
,
char
*
const
*
__argv
,
const
char
*
__shortopts
);
# else
/* not __GNU_LIBRARY__ */
extern
int
getopt
();
# endif
/* __GNU_LIBRARY__ */
# ifndef __need_getopt
extern
int
getopt_long
(
int
__argc
,
char
*
const
*
__argv
,
const
char
*
__shortopts
,
const
struct
option
*
__longopts
,
int
*
__longind
);
extern
int
getopt_long_only
(
int
__argc
,
char
*
const
*
__argv
,
const
char
*
__shortopts
,
const
struct
option
*
__longopts
,
int
*
__longind
);
/* Internal only. Users should not call this directly. */
extern
int
_getopt_internal
(
int
argc
,
char
*
const
*
argv
,
const
char
*
shortopts
,
const
struct
option
*
longopts
,
int
*
longind
,
int
long_only
);
#else
/* not __STDC__ */
extern
int
getopt
();
extern
int
getopt_long
();
extern
int
getopt_long_only
();
extern
int
_getopt_internal
();
#endif
/* not __STDC__ */
extern
int
_getopt_internal
(
int
__argc
,
char
*
const
*
__argv
,
const
char
*
__shortopts
,
const
struct
option
*
__longopts
,
int
*
__longind
,
int
__long_only
);
# endif
#else
/* not __STDC__ */
extern
int
getopt
();
# ifndef __need_getopt
extern
int
getopt_long
();
extern
int
getopt_long_only
();
extern
int
_getopt_internal
();
# endif
#endif
/* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif
/* _GETOPT_H */
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif
/* getopt.h */
...
...
lib/getopt1.c
View file @
1c1e1ee
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
Free Software Foundation, Inc.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
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
...
...
@@ -13,18 +15,22 @@
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, 675 Mass Ave, Cambridge, MA 02139
, USA. */
along with this program; if not, write to the Free Software
Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307
, USA. */
#ifdef HAVE_CONFIG_H
#include
"config.h"
#include
<config.h>
#endif
#include "getopt.h"
#if !__STDC__ && !defined(const) && IN_GCC
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
...
...
@@ -36,15 +42,21 @@
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#else
char
*
getenv
();
#endif
#ifndef NULL
...
...
@@ -79,7 +91,7 @@ getopt_long_only (argc, argv, options, long_options, opt_index)
}
#endif
/* _LIBC or not __GNU_LIBRARY__
. */
#endif
/* Not ELIDE_CODE
. */
#ifdef TEST
...
...
@@ -110,7 +122,7 @@ main (argc, argv)
c
=
getopt_long
(
argc
,
argv
,
"abc:d:0123456789"
,
long_options
,
&
option_index
);
if
(
c
==
EOF
)
if
(
c
==
-
1
)
break
;
switch
(
c
)
...
...
lib/strndup.c
0 → 100644
View file @
1c1e1ee
/* Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#if defined _LIBC || defined STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
char
*
malloc
();
#endif
char
*
strndup
(
s
,
n
)
const
char
*
s
;
size_t
n
;
{
size_t
len
=
strnlen
(
s
,
n
);
char
*
nouveau
=
malloc
(
len
+
1
);
if
(
nouveau
==
NULL
)
return
NULL
;
nouveau
[
len
]
=
'\0'
;
return
(
char
*
)
memcpy
(
nouveau
,
s
,
len
);
}
lib/strnlen.c
0 → 100644
View file @
1c1e1ee
/* Find the length of STRING, but scan at most MAXLEN characters.
Copyright (C) 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <string.h>
/* Find the length of STRING, but scan at most MAXLEN characters.
If no '\0' terminator is found in that many characters, return MAXLEN. */
size_t
strnlen
(
const
char
*
string
,
size_t
maxlen
)
{
const
char
*
end
=
memchr
(
string
,
'\0'
,
maxlen
);
return
end
?
(
size_t
)
(
end
-
string
)
:
maxlen
;
}
Please
register
or
sign in
to post a comment