summaryrefslogtreecommitdiff
path: root/dos
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-07-19 17:23:16 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-07-19 17:23:16 -0700
commit61bfcb1fdf6f118e9347e668b9f9c4956b0b9999 (patch)
tree0af4b122dfa3736fb005ef2f16396ce9280ac5cb /dos
parentb5252103dfcf7eb843c888b9b66a90b2fbbe6e14 (diff)
downloadsyslinux-61bfcb1fdf6f118e9347e668b9f9c4956b0b9999.tar.gz
dos, win32: use our own getopt_long() for both
Use our own version of getopt_long() for both the DOS and Win32 installers. Currently, on MinGW, getopt_long() is a static library, but that could change in some installations. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'dos')
-rw-r--r--dos/Makefile5
-rw-r--r--dos/getopt.h25
-rw-r--r--dos/getopt_long.c152
3 files changed, 3 insertions, 179 deletions
diff --git a/dos/Makefile b/dos/Makefile
index 9f48962b..54bfb591 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -23,13 +23,14 @@ CFLAGS += -D__MSDOS__
LDFLAGS = -T dosexe.ld
OPTFLAGS = -g
INCLUDES = -include code16.h -nostdinc -iwithprefix include \
- -I. -I.. -I../libfat -I ../libinstaller
+ -I. -I.. -I../libfat -I ../libinstaller -I ../libinstaller/getopt
SRCS = syslinux.c \
../libinstaller/fat.c \
../libinstaller/syslxmod.c \
../libinstaller/syslxopt.c \
../libinstaller/setadv.c \
+ ../libinstaller/getopt/getopt_long.c \
../libinstaller/bootsect_bin.c \
../libinstaller/mbr_bin.c \
$(wildcard ../libfat/*.c)
@@ -39,7 +40,7 @@ LIBOBJS = int2526.o conio.o memcpy.o memset.o memmove.o skipatou.o atou.o \
malloc.o free.o getopt_long.o getsetsl.o strchr.o strtoul.o \
strntoumax.o argv.o printf.o __divdi3.o __udivmoddi4.o
-VPATH = .:../libfat:../libinstaller
+VPATH = .:../libfat:../libinstaller:../libinstaller/getopt
TARGETS = syslinux.com
diff --git a/dos/getopt.h b/dos/getopt.h
deleted file mode 100644
index a1b74b10..00000000
--- a/dos/getopt.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _GETOPT_H
-#define _GETOPT_H
-
-/* (Very slightly) adapted from klibc */
-
-struct option {
- const char *name;
- int has_arg;
- int *flag;
- int val;
-};
-
-enum {
- no_argument = 0,
- required_argument = 1,
- optional_argument = 2,
-};
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-
-extern int getopt_long(int, char *const *, const char *,
- const struct option *, int *);
-
-#endif /* _GETOPT_H */
diff --git a/dos/getopt_long.c b/dos/getopt_long.c
deleted file mode 100644
index 14587797..00000000
--- a/dos/getopt_long.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * getopt.c
- *
- * getopt_long(), or at least a common subset thereof:
- *
- * - Option reordering is not supported
- * - -W foo is not supported
- * - First optstring character "-" not supported.
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <getopt.h>
-#include "mystuff.h"
-
-char *optarg;
-int optind, opterr, optopt;
-static struct getopt_private_state {
- const char *optptr;
- const char *last_optstring;
- char *const *last_argv;
-} pvt;
-
-static inline const char *option_matches(const char *arg_str,
- const char *opt_name)
-{
- while (*arg_str != '\0' && *arg_str != '=') {
- if (*arg_str++ != *opt_name++)
- return NULL;
- }
-
- if (*opt_name)
- return NULL;
-
- return arg_str;
-}
-
-int getopt_long(int argc, char *const *argv, const char *optstring,
- const struct option *longopts, int *longindex)
-{
- const char *carg;
- const char *osptr;
- int opt;
-
- /* getopt() relies on a number of different global state
- variables, which can make this really confusing if there is
- more than one use of getopt() in the same program. This
- attempts to detect that situation by detecting if the
- "optstring" or "argv" argument have changed since last time
- we were called; if so, reinitialize the query state. */
-
- if (optstring != pvt.last_optstring || argv != pvt.last_argv ||
- optind < 1 || optind > argc) {
- /* optind doesn't match the current query */
- pvt.last_optstring = optstring;
- pvt.last_argv = argv;
- optind = 1;
- pvt.optptr = NULL;
- }
-
- carg = argv[optind];
-
- /* First, eliminate all non-option cases */
-
- if (!carg || carg[0] != '-' || !carg[1])
- return -1;
-
- if (carg[1] == '-') {
- const struct option *lo;
- const char *opt_end = NULL;
-
- optind++;
-
- /* Either it's a long option, or it's -- */
- if (!carg[2]) {
- /* It's -- */
- return -1;
- }
-
- for (lo = longopts; lo->name; lo++) {
- if ((opt_end = option_matches(carg+2, lo->name)))
- break;
- }
- if (!opt_end)
- return '?';
-
- if (longindex)
- *longindex = lo-longopts;
-
- if (*opt_end == '=') {
- if (lo->has_arg)
- optarg = (char *)opt_end+1;
- else
- return '?';
- } else if (lo->has_arg == 1) {
- if (!(optarg = argv[optind]))
- return '?';
- optind++;
- }
-
- if (lo->flag) {
- *lo->flag = lo->val;
- return 0;
- } else {
- return lo->val;
- }
- }
-
- if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) {
- /* Someone frobbed optind, change to new opt. */
- pvt.optptr = carg + 1;
- }
-
- opt = *pvt.optptr++;
-
- if (opt != ':' && (osptr = strchr(optstring, opt))) {
- if (osptr[1] == ':') {
- if (*pvt.optptr) {
- /* Argument-taking option with attached
- argument */
- optarg = (char *)pvt.optptr;
- optind++;
- } else {
- /* Argument-taking option with non-attached
- argument */
- if (argv[optind + 1]) {
- optarg = (char *)argv[optind+1];
- optind += 2;
- } else {
- /* Missing argument */
- optind++;
- return (optstring[0] == ':')
- ? ':' : '?';
- }
- }
- return opt;
- } else {
- /* Non-argument-taking option */
- /* pvt.optptr will remember the exact position to
- resume at */
- if (!*pvt.optptr)
- optind++;
- return opt;
- }
- } else {
- /* Unknown option */
- optopt = opt;
- if (!*pvt.optptr)
- optind++;
- return '?';
- }
-}