]> mj.ucw.cz Git - pciutils.git/commitdiff
compat/getopt: Fix compatibility with non-GNU C library
authorPali Rohár <pali@kernel.org>
Sun, 26 Dec 2021 17:19:25 +0000 (18:19 +0100)
committerMartin Mares <mj@ucw.cz>
Tue, 28 Dec 2021 15:26:39 +0000 (16:26 +0100)
Remove "#if defined(__GNU_LIBRARY__)" guard for getopt() function
prototype in compat/getopt.h header file. The only purpose of
compat/getopt.h header is to provide getopt() function prototype for
compatibility purpose on every platform, specially those which do not use
GNU C library (e.g. Windows).

Without this change i586-mingw32msvc-gcc compiler complains that function
getopt() is used without defined prototype.

Also remove inclusion of #include <string.h> header file in compat/getopt.c
source file. Probably due to compatibility purposes compat/getopt.c file
has defined custom prototype for function strncmp() incompatible with C99
(length argument in C99 should be of type size_t). Including C99 prototype
of strncmp() function from MinGW32 <string.h> header file cause compile
errors for i586-mingw32msvc-gcc compiler. Instead of including <stringh>
provides custom and simple my_strncmp() implementation.

Thsi change fixes compilation of compat/getopt.c with i586-mingw32msvc-gcc,
i686-w64-mingw32-gcc, x86_64-w64-mingw32-gcc and also MSVC cl compilers.

compat/getopt.c
compat/getopt.h

index 1d0beb76953e787571a3e3faa276279d82a2305c..f3ccb4b49781c59b886f922ce65b1ec2dc0d3b20 100644 (file)
@@ -36,7 +36,6 @@
 #endif
 
 #include <stdio.h>
-#include <string.h>
 
 /* Comment out all this code if we are using the GNU C Library, and are not
    actually compiling the library itself.  This code is part of the GNU C
@@ -163,6 +162,8 @@ static enum {
 #include <string.h>
 #define        my_index        strchr
 #define        my_strlen       strlen
+#define        my_strcmp       strcmp
+#define        my_strncmp      strncmp
 #else
 
 /* Avoid depending on library functions or files
@@ -170,11 +171,11 @@ static enum {
 
 #if __STDC__ || defined(PROTO)
 extern char *getenv(const char *name);
-extern int strcmp(const char *s1, const char *s2);
-extern int strncmp(const char *s1, const char *s2, int n);
 
 static int my_strlen(const char *s);
 static char *my_index(const char *str, int chr);
+static int my_strncmp(const char *s1, const char *s2, int n);
+static int my_strcmp(const char *s1, const char *s2);
 #else
 extern char *getenv();
 #endif
@@ -197,6 +198,23 @@ static char *my_index(const char *str, int chr)
        return 0;
 }
 
+static int my_strncmp(const char *s1, const char *s2, int n)
+{
+       while (n && *s1 && (*s1 == *s2)) {
+               ++s1;
+               ++s2;
+               --n;
+       }
+       if (n == 0)
+               return 0;
+       return *(const unsigned char *)s1 - *(const unsigned char *)s2;
+}
+
+static int my_strcmp(const char *s1, const char *s2)
+{
+       return my_strncmp(s1, s2, -1);
+}
+
 #endif                         /* GNU C library.  */
 \f
 /* Handle permutation of arguments.  */
@@ -385,7 +403,7 @@ int _getopt_internal(int argc, char *const *argv, const char *optstring,
                   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], "--")) {
+               if (optind != argc && !my_strcmp(argv[optind], "--")) {
                        optind++;
 
                        if (first_nonopt != last_nonopt && last_nonopt != optind)
@@ -445,7 +463,7 @@ int _getopt_internal(int argc, char *const *argv, const char *optstring,
 
                /* 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)) {
+                       if (!my_strncmp(p->name, nextchar, s - nextchar)) {
                                if (s - nextchar == my_strlen(p->name)) {
                                        /* Exact match found.  */
                                        pfound = p;
index 0abce6e921dd83c812a4da6cc9af14fa717160c7..e7b4bfe8f5affb89b926478cfbbf9d91c61c6b26 100644 (file)
@@ -95,12 +95,7 @@ struct option
 #define optional_argument      2
 
 #if __STDC__ || defined(PROTO)
-#if defined(__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);
-#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,