Samples: Add fxload sample for Cypress EZ-USB chips
authorPete Batard <pete@akeo.ie>
Tue, 11 Sep 2012 00:01:07 +0000 (01:01 +0100)
committerPete Batard <pete@akeo.ie>
Thu, 13 Sep 2012 22:58:09 +0000 (23:58 +0100)
* This program was modified from the original fxload at:
  http://linux-hotplug.sourceforge.net to add libusbx
  as well as non HEX images support.
* Only supports RAM upload for now, with EEPROM and FX3
  support to be added at a later stage.

17 files changed:
examples/Makefile.am
examples/ezusb.c [new file with mode: 0644]
examples/ezusb.h [new file with mode: 0644]
examples/fxload.c [new file with mode: 0644]
examples/getopt/getopt.c [new file with mode: 0644]
examples/getopt/getopt.h [new file with mode: 0644]
examples/getopt/getopt1.c [new file with mode: 0644]
libusb/version_nano.h
msvc/ddk_build.cmd
msvc/fxload.vcxproj [new file with mode: 0644]
msvc/fxload.vcxproj.filters [new file with mode: 0644]
msvc/fxload_sources [new file with mode: 0644]
msvc/getopt.vcproj [new file with mode: 0644]
msvc/getopt.vcxproj [new file with mode: 0644]
msvc/getopt.vcxproj.filters [new file with mode: 0644]
msvc/getopt_sources [new file with mode: 0644]
msvc/libusb_2010.sln

index 6921484..6884aeb 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = -I$(top_srcdir)/libusb
 LDADD = ../libusb/libusb-1.0.la
 
-noinst_PROGRAMS = listdevs xusb
+noinst_PROGRAMS = listdevs xusb fxload
 
 if HAVE_SIGACTION
 noinst_PROGRAMS += dpfp
@@ -13,3 +13,6 @@ dpfp_threaded_CFLAGS = $(THREAD_CFLAGS) $(AM_CFLAGS)
 noinst_PROGRAMS += dpfp_threaded
 endif
 endif
+
+fxload_SOURCES = ezusb.c fxload.c
+fxload_CFLAGS = $(THREAD_CFLAGS) $(AM_CFLAGS)
diff --git a/examples/ezusb.c b/examples/ezusb.c
new file mode 100644 (file)
index 0000000..330a4f8
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+ * Copyright © 2001 Stephen Williams (steve@icarus.com)
+ * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
+ * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
+ * Copyright © 2012 Pete Batard (pete@akeo.ie)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form under the terms of the GNU
+ *    General Public License as published by the Free Software
+ *    Foundation; either version 2 of the License, or (at your option)
+ *    any later version.
+ *
+ *    This program 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 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <libusb.h>
+#include "ezusb.h"
+
+extern void logerror(const char *format, ...)
+       __attribute__ ((format(printf, 1, 2)));
+
+/*
+ * This file contains functions for uploading firmware into Cypress
+ * EZ-USB microcontrollers. These chips use control endpoint 0 and vendor
+ * specific commands to support writing into the on-chip SRAM. They also
+ * support writing into the CPUCS register, which is how we reset the
+ * processor after loading firmware (including the reset vector).
+ *
+ * These Cypress devices are 8-bit 8051 based microcontrollers with
+ * special support for USB I/O.  They come in several packages, and
+ * some can be set up with external memory when device costs allow.
+ * Note that the design was originally by AnchorChips, so you may find
+ * references to that vendor (which was later merged into Cypress).
+ * The Cypress FX parts are largely compatible with the Anchorhip ones.
+ */
+
+int verbose;
+
+/*
+ * return true if [addr,addr+len] includes external RAM
+ * for Anchorchips EZ-USB or Cypress EZ-USB FX
+ */
+static bool fx_is_external(uint32_t addr, size_t len)
+{
+       /* with 8KB RAM, 0x0000-0x1b3f can be written
+        * we can't tell if it's a 4KB device here
+        */
+       if (addr <= 0x1b3f)
+               return ((addr + len) > 0x1b40);
+
+       /* there may be more RAM; unclear if we can write it.
+        * some bulk buffers may be unused, 0x1b3f-0x1f3f
+        * firmware can set ISODISAB for 2KB at 0x2000-0x27ff
+        */
+       return true;
+}
+
+/*
+ * return true if [addr,addr+len] includes external RAM
+ * for Cypress EZ-USB FX2
+ */
+static bool fx2_is_external(uint32_t addr, size_t len)
+{
+       /* 1st 8KB for data/code, 0x0000-0x1fff */
+       if (addr <= 0x1fff)
+               return ((addr + len) > 0x2000);
+
+       /* and 512 for data, 0xe000-0xe1ff */
+       else if (addr >= 0xe000 && addr <= 0xe1ff)
+               return ((addr + len) > 0xe200);
+
+       /* otherwise, it's certainly external */
+       else
+               return true;
+}
+
+/*
+ * return true if [addr,addr+len] includes external RAM
+ * for Cypress EZ-USB FX2LP
+ */
+static bool fx2lp_is_external(uint32_t addr, size_t len)
+{
+       /* 1st 16KB for data/code, 0x0000-0x3fff */
+       if (addr <= 0x3fff)
+               return ((addr + len) > 0x4000);
+
+       /* and 512 for data, 0xe000-0xe1ff */
+       else if (addr >= 0xe000 && addr <= 0xe1ff)
+               return ((addr + len) > 0xe200);
+
+       /* otherwise, it's certainly external */
+       else
+               return true;
+}
+
+
+/*****************************************************************************/
+
+/*
+ * These are the requests (bRequest) that the bootstrap loader is expected
+ * to recognize.  The codes are reserved by Cypress, and these values match
+ * what EZ-USB hardware, or "Vend_Ax" firmware (2nd stage loader) uses.
+ * Cypress' "a3load" is nice because it supports both FX and FX2, although
+ * it doesn't have the EEPROM support (subset of "Vend_Ax").
+ */
+#define RW_INTERNAL     0xA0   /* hardware implements this one */
+#define RW_MEMORY       0xA3
+
+/*
+ * Issues the specified vendor-specific write request.
+ */
+static int ezusb_write(libusb_device_handle *device, char *label,
+       uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
+{
+       int status;
+
+       if (verbose)
+               logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
+       status = libusb_control_transfer(device,
+               LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
+               opcode, addr & 0xFFFF, addr >> 16,
+               (unsigned char*)data, (uint16_t)len, 1000);
+       if (status != len) {
+               if (status < 0)
+                       logerror("%s: %s\n", label, libusb_error_name(status));
+               else
+                       logerror("%s ==> %d\n", label, status);
+       }
+       return (status < 0) ? -EIO : 0;
+}
+
+/*
+ * Modifies the CPUCS register to stop or reset the CPU.
+ * Returns false on error.
+ */
+static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun)
+{
+       int status;
+       uint8_t data = doRun ? 0x00 : 0x01;
+
+       if (verbose)
+               logerror("%s\n", data ? "stop CPU" : "reset CPU");
+       status = libusb_control_transfer(device,
+               LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
+               RW_INTERNAL, addr & 0xFFFF, addr >> 16,
+               &data, 1, 1000);
+       if ((status != 1) &&
+               /* We may get an I/O error from libusbx as the device disappears */
+               ((!doRun) || (status != LIBUSB_ERROR_IO)))
+       {
+               char *mesg = "can't modify CPUCS";
+               if (status < 0)
+                       logerror("%s: %s\n", mesg, libusb_error_name(status));
+               else
+                       logerror("%s\n", mesg);
+               return false;
+       } else
+               return true;
+}
+
+/*****************************************************************************/
+
+/*
+ * Parse an Intel HEX image file and invoke the poke() function on the
+ * various segments to implement policies such as writing to RAM (with
+ * a one or two stage loader setup, depending on the firmware) or to
+ * EEPROM (two stages required).
+ *
+ * image       - the hex image file
+ * context     - for use by poke()
+ * is_external - if non-null, used to check which segments go into
+ *               external memory (writable only by software loader)
+ * poke        - called with each memory segment; errors indicated
+ *               by returning negative values.
+ *
+ * Caller is responsible for halting CPU as needed, such as when
+ * overwriting a second stage loader.
+ */
+int parse_ihex(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
+       int (*poke) (void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
+{
+       unsigned char data[1023];
+       uint32_t data_addr = 0;
+       size_t data_len = 0;
+       int rc;
+       int first_line = 1;
+       bool external = false;
+
+       /* Read the input file as an IHEX file, and report the memory segments
+        * as we go.  Each line holds a max of 16 bytes, but uploading is
+        * faster (and EEPROM space smaller) if we merge those lines into larger
+        * chunks.  Most hex files keep memory segments together, which makes
+        * such merging all but free.  (But it may still be worth sorting the
+        * hex files to make up for undesirable behavior from tools.)
+        *
+        * Note that EEPROM segments max out at 1023 bytes; the upload protocol
+        * allows segments of up to 64 KBytes (more than a loader could handle).
+        */
+       for (;;) {
+               char buf[512], *cp;
+               char tmp, type;
+               size_t len;
+               unsigned idx, off;
+
+               cp = fgets(buf, sizeof(buf), image);
+               if (cp == NULL) {
+                       logerror("EOF without EOF record!\n");
+                       break;
+               }
+
+               /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
+               if (buf[0] == '#')
+                       continue;
+
+               if (buf[0] != ':') {
+                       logerror("not an ihex record: %s", buf);
+                       return -2;
+               }
+
+               /* ignore any newline */
+               cp = strchr(buf, '\n');
+               if (cp)
+                       *cp = 0;
+
+               if (verbose >= 3)
+                       logerror("** LINE: %s\n", buf);
+
+               /* Read the length field (up to 16 bytes) */
+               tmp = buf[3];
+               buf[3] = 0;
+               len = strtoul(buf+1, NULL, 16);
+               buf[3] = tmp;
+
+               /* Read the target offset (address up to 64KB) */
+               tmp = buf[7];
+               buf[7] = 0;
+               off = strtoul(buf+3, NULL, 16);
+               buf[7] = tmp;
+
+               /* Initialize data_addr */
+               if (first_line) {
+                       data_addr = off;
+                       first_line = 0;
+               }
+
+               /* Read the record type */
+               tmp = buf[9];
+               buf[9] = 0;
+               type = (char)strtoul(buf+7, NULL, 16);
+               buf[9] = tmp;
+
+               /* If this is an EOF record, then make it so. */
+               if (type == 1) {
+                       if (verbose >= 2)
+                               logerror("EOF on hexfile\n");
+                       break;
+               }
+
+               if (type != 0) {
+                       logerror("unsupported record type: %u\n", type);
+                       return -3;
+               }
+
+               if ((len * 2) + 11 > strlen(buf)) {
+                       logerror("record too short?\n");
+                       return -4;
+               }
+
+               /* FIXME check for _physically_ contiguous not just virtually
+                * e.g. on FX2 0x1f00-0x2100 includes both on-chip and external
+                * memory so it's not really contiguous */
+
+               /* flush the saved data if it's not contiguous,
+               * or when we've buffered as much as we can.
+               */
+               if (data_len != 0
+                       && (off != (data_addr + data_len)
+                       /* || !merge */
+                       || (data_len + len) > sizeof(data))) {
+                               if (is_external)
+                                       external = is_external(data_addr, data_len);
+                               rc = poke(context, data_addr, external, data, data_len);
+                               if (rc < 0)
+                                       return -1;
+                               data_addr = off;
+                               data_len = 0;
+               }
+
+               /* append to saved data, flush later */
+               for (idx = 0, cp = buf+9 ;  idx < len ;  idx += 1, cp += 2) {
+                       tmp = cp[2];
+                       cp[2] = 0;
+                       data[data_len + idx] = (uint8_t)strtoul(cp, NULL, 16);
+                       cp[2] = tmp;
+               }
+               data_len += len;
+       }
+
+
+       /* flush any data remaining */
+       if (data_len != 0) {
+               if (is_external)
+                       external = is_external(data_addr, data_len);
+               rc = poke(context, data_addr, external, data, data_len);
+               if (rc < 0)
+                       return -1;
+       }
+       return 0;
+}
+
+/*
+ * Parse a binary image file and write it as is to the target.
+ * Applies to Cypress BIX images for RAM or Cypress IIC images
+ * for EEPROM.
+ *
+ * image       - the BIX image file
+ * context     - for use by poke()
+ * is_external - if non-null, used to check which segments go into
+ *               external memory (writable only by software loader)
+ * poke        - called with each memory segment; errors indicated
+ *               by returning negative values.
+ *
+ * Caller is responsible for halting CPU as needed, such as when
+ * overwriting a second stage loader.
+ */
+int parse_bin(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
+       int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
+{
+       unsigned char data[4096];
+       uint32_t data_addr = 0;
+       size_t data_len = 0;
+       int rc;
+       bool external = false;
+
+       for (;;) {
+               data_len = fread(data, 1, 4096, image);
+               if (data_len == 0)
+                       break;
+               if (is_external)
+                       external = is_external(data_addr, data_len);
+               rc = poke(context, data_addr, external, data, data_len);
+               if (rc < 0)
+                       return -1;
+               data_addr += (uint32_t)data_len;
+       }
+       return feof(image)?0:-1;
+}
+
+/*
+ * Parse a Cypress IIC image file and invoke the poke() function on the
+ * various segments for writing to RAM
+ *
+ * image       - the IIC image file
+ * context     - for use by poke()
+ * is_external - if non-null, used to check which segments go into
+ *               external memory (writable only by software loader)
+ * poke        - called with each memory segment; errors indicated
+ *               by returning negative values.
+ *
+ * Caller is responsible for halting CPU as needed, such as when
+ * overwriting a second stage loader.
+ */
+int parse_iic(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
+       int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
+{
+       unsigned char data[4096];
+       uint32_t data_addr = 0;
+       size_t data_len = 0, read_len;
+       uint8_t block_header[4];
+       int rc;
+       bool external = false;
+       long file_size, initial_pos = ftell(image);
+
+       fseek(image, 0L, SEEK_END);
+       file_size = ftell(image);
+       fseek(image, initial_pos, SEEK_SET);
+       for (;;) {
+               /* Ignore the trailing reset IIC data (5 bytes) */
+               if (ftell(image) >= (file_size - 5))
+                       break;
+               if (fread(&block_header, 1, sizeof(block_header), image) != 4) {
+                       logerror("unable to read IIC block header\n");
+                       return -1;
+               }
+               data_len = (block_header[0] << 8) + block_header[1];
+               data_addr = (block_header[2] << 8) + block_header[3];
+               if (data_len > sizeof(data)) {
+                       /* If this is ever reported as an error, switch to using malloc/realloc */
+                       logerror("IIC data block too small - please report this error to libusbx.org\n");
+                       return -1;
+               }
+               read_len = fread(data, 1, data_len, image);
+               if (read_len != data_len) {
+                       logerror("read error\n");
+                       return -1;
+               }
+               if (is_external)
+                       external = is_external(data_addr, data_len);
+               rc = poke(context, data_addr, external, data, data_len);
+               if (rc < 0)
+                       return -1;
+       }
+       return 0;
+}
+
+/* the parse call will be selected according to the image type */
+int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
+       int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
+       = { parse_ihex, parse_iic, parse_bin };
+
+/*****************************************************************************/
+
+/*
+ * For writing to RAM using a first (hardware) or second (software)
+ * stage loader and 0xA0 or 0xA3 vendor requests
+ */
+typedef enum {
+       _undef = 0,
+       internal_only,          /* hardware first-stage loader */
+       skip_internal,          /* first phase, second-stage loader */
+       skip_external           /* second phase, second-stage loader */
+} ram_mode;
+
+struct ram_poke_context {
+       libusb_device_handle *device;
+       ram_mode mode;
+       size_t total, count;
+};
+
+#define RETRY_LIMIT 5
+
+static int ram_poke(void *context, uint32_t addr, bool external,
+       const unsigned char *data, size_t len)
+{
+       struct ram_poke_context *ctx = (struct ram_poke_context*)context;
+       int rc;
+       unsigned retry = 0;
+
+       switch (ctx->mode) {
+       case internal_only:             /* CPU should be stopped */
+               if (external) {
+                       logerror("can't write %u bytes external memory at 0x%08x\n",
+                               (unsigned)len, addr);
+                       return -EINVAL;
+               }
+               break;
+       case skip_internal:             /* CPU must be running */
+               if (!external) {
+                       if (verbose >= 2) {
+                               logerror("SKIP on-chip RAM, %u bytes at 0x%08x\n",
+                                       (unsigned)len, addr);
+                       }
+                       return 0;
+               }
+               break;
+       case skip_external:             /* CPU should be stopped */
+               if (external) {
+                       if (verbose >= 2) {
+                               logerror("SKIP external RAM, %u bytes at 0x%08x\n",
+                                       (unsigned)len, addr);
+                       }
+                       return 0;
+               }
+               break;
+       default:
+               logerror("bug\n");
+               return -EDOM;
+       }
+
+       ctx->total += len;
+       ctx->count++;
+
+       /* Retry this till we get a real error. Control messages are not
+        * NAKed (just dropped) so time out means is a real problem.
+        */
+       while ((rc = ezusb_write(ctx->device,
+               external ? "write external" : "write on-chip",
+               external ? RW_MEMORY : RW_INTERNAL,
+               addr, data, len)) < 0
+               && retry < RETRY_LIMIT) {
+               if (rc != LIBUSB_ERROR_TIMEOUT)
+                       break;
+               retry += 1;
+       }
+       return rc;
+}
+
+/*
+ * Load a firmware file into target RAM. device is the open libusbx
+ * device, and the path is the name of the source file. Open the file,
+ * parse the bytes, and write them in one or two phases.
+ *
+ * If stage == 0, this uses the first stage loader, built into EZ-USB
+ * hardware but limited to writing on-chip memory or CPUCS.  Everything
+ * is written during one stage, unless there's an error such as the image
+ * holding data that needs to be written to external memory.
+ *
+ * Otherwise, things are written in two stages.  First the external
+ * memory is written, expecting a second stage loader to have already
+ * been loaded.  Then file is re-parsed and on-chip memory is written.
+ */
+int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type, int img_type, int stage)
+{
+       FILE *image;
+       uint32_t cpucs_addr;
+       bool (*is_external)(uint32_t off, size_t len);
+       struct ram_poke_context ctx;
+       int status;
+       uint8_t iic_header[8] = { 0 };
+
+       image = fopen(path, "rb");
+       if (image == NULL) {
+               logerror("%s: unable to open for input.\n", path);
+               return -2;
+       } else if (verbose)
+               logerror("open firmware image %s for RAM upload\n", path);
+
+       if (img_type == IMG_TYPE_IIC) {
+               if ( (fread(iic_header, 1, sizeof(iic_header), image) != sizeof(iic_header))
+                 || (((fx_type == FX_TYPE_FX2LP) || (fx_type == FX_TYPE_FX2)) && (iic_header[0] != 0xC2))
+                 || ((fx_type == FX_TYPE_AN21) && (iic_header[0] != 0xB2))
+                 || ((fx_type == FX_TYPE_FX1) && (iic_header[0] != 0xB6)) ) {
+                       logerror("IIC image does not contain executable code - cannot load to RAM.\n");
+                       return -1;
+               }
+       }
+
+       /* EZ-USB original/FX and FX2 devices differ, apart from the 8051 core */
+       switch(fx_type) {
+       case FX_TYPE_FX2LP:
+               cpucs_addr = 0xe600;
+               is_external = fx2lp_is_external;
+               break;
+       case FX_TYPE_FX2:
+               cpucs_addr = 0xe600;
+               is_external = fx2_is_external;
+               break;
+       default:
+               cpucs_addr = 0x7f92;
+               is_external = fx_is_external;
+               break;
+       }
+
+       /* use only first stage loader? */
+       if (stage == 0) {
+               ctx.mode = internal_only;
+
+               /* if required, halt the CPU while we overwrite its code/data */
+               if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
+                       return -1;
+
+               /* 2nd stage, first part? loader was already uploaded */
+       } else {
+               ctx.mode = skip_internal;
+
+               /* let CPU run; overwrite the 2nd stage loader later */
+               if (verbose)
+                       logerror("2nd stage: write external memory\n");
+       }
+
+       /* scan the image, first (maybe only) time */
+       ctx.device = device;
+       ctx.total = ctx.count = 0;
+       status = parse[img_type](image, &ctx, is_external, ram_poke);
+       if (status < 0) {
+               logerror("unable to upload %s\n", path);
+               return status;
+       }
+
+       /* second part of 2nd stage: rescan */
+       // TODO: what should we do for non HEX images there?
+       if (stage) {
+               ctx.mode = skip_external;
+
+               /* if needed, halt the CPU while we overwrite the 1st stage loader */
+               if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
+                       return -1;
+
+               /* at least write the interrupt vectors (at 0x0000) for reset! */
+               rewind(image);
+               if (verbose)
+                       logerror("2nd stage: write on-chip memory\n");
+               status = parse_ihex(image, &ctx, is_external, ram_poke);
+               if (status < 0) {
+                       logerror("unable to completely upload %s\n", path);
+                       return status;
+               }
+       }
+
+       if (verbose)
+               logerror("... WROTE: %d bytes, %d segments, avg %d\n",
+               (int)ctx.total, (int)ctx.count, (int)(ctx.total/ctx.count));
+
+       /* if required, reset the CPU so it runs what we just uploaded */
+       if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, true))
+               return -1;
+
+       return 0;
+}
diff --git a/examples/ezusb.h b/examples/ezusb.h
new file mode 100644 (file)
index 0000000..5ea4237
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef __ezusb_H
+#define __ezusb_H
+/*
+ * Copyright © 2001 Stephen Williams (steve@icarus.com)
+ * Copyright © 2002 David Brownell (dbrownell@users.sourceforge.net)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form under the terms of the GNU
+ *    General Public License as published by the Free Software
+ *    Foundation; either version 2 of the License, or (at your option)
+ *    any later version.
+ *
+ *    This program 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 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#if !defined(_MSC_VER)
+#include <stdbool.h>
+#else
+#define __attribute__(x)
+#if !defined(bool)
+#define bool int
+#endif
+#if !defined(true)
+#define true (1 == 1)
+#endif
+#if !defined(false)
+#define false (!true)
+#endif
+#if defined(_PREFAST_)
+#pragma warning(disable:28193)
+#endif
+#endif
+
+#define FX_TYPE_UNDEFINED  -1
+#define FX_TYPE_AN21       0   /* Original AnchorChips parts */
+#define FX_TYPE_FX1        1   /* Updated Cypress versions */
+#define FX_TYPE_FX2        2   /* USB 2.0 versions */
+#define FX_TYPE_FX2LP      3   /* Updated FX2 */
+#define FX_TYPE_MAX        4
+#define FX_TYPE_NAMES      { "an21", "fx", "fx2", "fx2lp" }
+
+#define IMG_TYPE_UNDEFINED -1
+#define IMG_TYPE_HEX       0   /* Intel HEX */
+#define IMG_TYPE_IIC       1   /* Cypress 8051 IIC */
+#define IMG_TYPE_BIX       2   /* Cypress 8051 BIX */
+#define IMG_TYPE_MAX       3
+#define IMG_TYPE_NAMES     { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX" }
+
+/* 
+ * Automatically identified devices (VID, PID, type, designation).
+ * TODO: Could use some validation. Also where's the FX2?
+ */
+typedef struct {
+       uint16_t vid;
+       uint16_t pid;
+       int type;
+       const char* designation;
+} fx_known_device;
+
+#define FX_KNOWN_DEVICES { \
+       { 0x0547, 0x2122, FX_TYPE_AN21, "Cypress EZ-USB (2122S)" },\
+       { 0x0547, 0x2125, FX_TYPE_AN21, "Cypress EZ-USB (2121S/2125S)" },\
+       { 0x0547, 0x2126, FX_TYPE_AN21, "Cypress EZ-USB (2126S)" },\
+       { 0x0547, 0x2131, FX_TYPE_AN21, "Cypress EZ-USB (2131Q/2131S/2135S)" },\
+       { 0x0547, 0x2136, FX_TYPE_AN21, "Cypress EZ-USB (2136S)" },\
+       { 0x0547, 0x2225, FX_TYPE_AN21, "Cypress EZ-USB (2225)" },\
+       { 0x0547, 0x2226, FX_TYPE_AN21, "Cypress EZ-USB (2226)" },\
+       { 0x0547, 0x2235, FX_TYPE_AN21, "Cypress EZ-USB (2235)" },\
+       { 0x0547, 0x2236, FX_TYPE_AN21, "Cypress EZ-USB (2236)" },\
+       { 0x04b4, 0x6473, FX_TYPE_FX1, "Cypress EZ-USB FX1" },\
+       { 0x04b4, 0x8613, FX_TYPE_FX2LP, "Cypress EZ-USB FX2LP (68013A/68014A/68015A/68016A)" }, \
+}
+
+/*
+ * This function uploads the firmware from the given file into RAM.
+ * Stage == 0 means this is a single stage load (or the first of
+ * two stages).  Otherwise it's the second of two stages; the 
+ * caller having preloaded the second stage loader.
+ *
+ * The target processor is reset at the end of this upload.
+ */
+extern int ezusb_load_ram(libusb_device_handle *device,
+       const char *path, int fx_type, int img_type, int stage);
+
+/*
+ * This function uploads the firmware from the given file into EEPROM.
+ * This uses the right CPUCS address to terminate the EEPROM load with
+ * a reset command where FX parts behave differently than FX2 ones.
+ * The configuration byte is as provided here (zero for an21xx parts)
+ * and the EEPROM type is set so that the microcontroller will boot
+ * from it.
+ *
+ * The caller must have preloaded a second stage loader that knows
+ * how to respond to the EEPROM write request.
+ */
+extern int ezusb_load_eeprom(libusb_device_handle *device,
+       const char *path, int fx_type, int img_type, int config);
+
+/* boolean flag, says whether to write extra messages to stderr */
+extern int verbose;
+#endif
diff --git a/examples/fxload.c b/examples/fxload.c
new file mode 100644 (file)
index 0000000..31c090b
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2001 Stephen Williams (steve@icarus.com)
+ * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
+ * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
+ * Copyright © 2012 Pete Batard (pete@akeo.ie)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form under the terms of the GNU
+ *    General Public License as published by the Free Software
+ *    Foundation; either version 2 of the License, or (at your option)
+ *    any later version.
+ *
+ *    This program 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 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * This program supports uploading firmware into a target USB device.
+ *
+ *     -I <path>       -- Upload this firmware
+ *     -t <type>       -- uController type: an21, fx, fx2, fx2lp
+ *
+ *     -D <vid:pid>    -- Use this device, instead of $DEVICE
+ *
+ *     -V              -- Print version ID for program
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <getopt.h>
+
+#include <libusb.h>
+#include "ezusb.h"
+
+#if !defined(_WIN32) || defined(__CYGWIN__ )
+#include <syslog.h>
+static bool dosyslog = false;
+#include <strings.h>
+#define _stricmp strcasecmp
+#endif
+
+#ifndef FXLOAD_VERSION
+#define FXLOAD_VERSION (__DATE__ " (development)")
+#endif
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+#endif
+
+void logerror(const char *format, ...)
+       __attribute__ ((format (__printf__, 1, 2)));
+
+void logerror(const char *format, ...)
+{
+       va_list ap;
+       va_start(ap, format);
+
+#if !defined(_WIN32) || defined(__CYGWIN__ )
+       if (dosyslog)
+               vsyslog(LOG_ERR, format, ap);
+       else
+#endif
+               vfprintf(stderr, format, ap);
+       va_end(ap);
+}
+
+#define FIRMWARE 0
+#define LOADER 1
+int main(int argc, char*argv[])
+{
+       fx_known_device known_device[] = FX_KNOWN_DEVICES;
+       const char *path[] = { NULL, NULL };
+       const char *device_id = getenv("DEVICE");
+       const char *type = NULL;
+       const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
+       const char *ext, *img_name[] = IMG_TYPE_NAMES;
+       int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
+       int i, j, opt, status;
+       unsigned vid = 0, pid = 0;
+       libusb_device *dev, **devs;
+       libusb_device_handle *device = NULL;
+       struct libusb_device_descriptor desc;
+
+       while ((opt = getopt(argc, argv, "vV?D:I:c:s:t:")) != EOF)
+               switch (opt) {
+
+               case 'D':
+                       device_id = optarg;
+                       break;
+
+               case 'I':
+                       path[FIRMWARE] = optarg;
+                       break;
+
+               case 'V':
+                       puts(FXLOAD_VERSION);
+                       return 0;
+
+               case 't':
+                       type = optarg;
+                       break;
+
+               case 'v':
+                       verbose++;
+                       break;
+
+               case '?':
+               default:
+                       goto usage;
+
+       }
+
+       if (path[FIRMWARE] == NULL) {
+               logerror("no firmware specified!\n");
+usage:
+               fprintf(stderr, "\nusage: %s [-vV] [-t type] [-D vid:pid] -I firmware\n", argv[0]);
+               fprintf(stderr, "      type: one of an21, fx, fx2, fx2lp\n");
+               return -1;
+       }
+
+       if ((device_id != NULL) && (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 )) {
+               fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr);
+               return -1;
+       }
+
+       /* determine the target type */
+       if (type != NULL) {
+               for (i=0; i<FX_TYPE_MAX; i++) {
+                       if (strcmp(type, fx_name[i]) == 0) {
+                               fx_type = i;
+                               break;
+                       }
+               }
+               if (i >= FX_TYPE_MAX) {
+                       logerror("illegal microcontroller type: %s\n", type);
+                       goto usage;
+               }
+       }
+
+       /* open the device using libusbx */
+       status = libusb_init(NULL);
+       if (status < 0) {
+               logerror("libusb_init() failed: %s\n", libusb_error_name(status));
+               return -1;
+       }
+       libusb_set_debug(NULL, verbose);
+
+       /* try to pick up missing parameters from known devices */
+       if ((type == NULL) || (device_id == NULL)) {
+               if (libusb_get_device_list(NULL, &devs) < 0) {
+                       logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status));
+                       goto err;
+               }
+               for (i=0; (dev=devs[i]) != NULL; i++) {
+                       status = libusb_get_device_descriptor(dev, &desc);
+                       if (status >= 0) {
+                               if (verbose >= 2)
+                                       logerror("trying to match against %04x:%04x\n", desc.idVendor, desc.idProduct);
+                               for (j=0; j<ARRAYSIZE(known_device); j++) {
+                                       if ((desc.idVendor == known_device[j].vid)
+                                               && (desc.idProduct == known_device[j].pid)) {
+                                               if ((type == NULL) && (device_id == NULL)) {
+                                                       fx_type = known_device[j].type;
+                                                       vid = desc.idVendor;
+                                                       pid = desc.idProduct;
+                                                       break;
+                                               } else if ((type == NULL) && (vid == desc.idVendor)
+                                                       && (pid == desc.idProduct)) {
+                                                       fx_type = known_device[j].type;
+                                                       break;
+                                               } else if ((device_id == NULL)
+                                                       && (fx_type == known_device[j].type)) {
+                                                       vid = desc.idVendor;
+                                                       pid = desc.idProduct;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               if (j < ARRAYSIZE(known_device)) {
+                                       if (verbose)
+                                               logerror("found device '%s' [%04x:%04x]\n",
+                                                       known_device[j].designation, vid, pid);
+                                       break;
+                               }
+                       }
+               }
+               if (dev == NULL) {
+                       libusb_free_device_list(devs, 1);
+                       logerror("could not find a known device - please specify type and/or vid:pid\n");
+                       goto usage;
+               }
+               status = libusb_open(dev, &device);
+               if (status < 0) {
+                       logerror("libusb_open() failed: %s\n", libusb_error_name(status));
+                       goto err;
+               }
+               libusb_free_device_list(devs, 1);
+       } else {
+               device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid);
+               if (device == NULL) {
+                       logerror("libusb_open() failed\n");
+                       goto err;
+               }
+       }
+       /* We need to claim the first interface */
+       status = libusb_claim_interface(device, 0);
+#if defined(__linux__)
+       if (status != LIBUSB_SUCCESS) {
+               /* Maybe we need to detach the driver */
+               libusb_detach_kernel_driver(device, 0);
+               status = libusb_claim_interface(device, 0);
+       }
+#endif
+       if (status != LIBUSB_SUCCESS) {
+               logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status));
+               goto err;
+       }
+
+       if (verbose)
+               logerror("microcontroller type: %s\n", fx_name[fx_type]);
+
+       for (i=0; i<ARRAYSIZE(path); i++) {
+               if (path[i] != NULL) {
+                       ext = path[i] + strlen(path[i]) - 4;
+                       if ((_stricmp(ext, ".hex") == 0) || (strcmp(ext, ".ihx") == 0))
+                               img_type[i] = IMG_TYPE_HEX;
+                       else if (_stricmp(ext, ".iic") == 0)
+                               img_type[i] = IMG_TYPE_IIC;
+                       else if (_stricmp(ext, ".bix") == 0)
+                               img_type[i] = IMG_TYPE_BIX;
+                       else {
+                               logerror("%s is not a recognized image type\n", path[i]);
+                               goto err;
+                       }
+               }
+               if (verbose && path[i] != NULL)
+                       logerror("%s: type %s\n", path[i], img_name[img_type[i]]);
+       }
+
+       /* single stage, put into internal memory */
+       if (verbose)
+               logerror("single stage: load on-chip memory\n");
+       status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);
+
+       libusb_release_interface(device, 0);
+       libusb_close(device);
+       libusb_exit(NULL);
+       return status;
+err:
+       libusb_exit(NULL);
+       return -1;
+}
diff --git a/examples/getopt/getopt.c b/examples/getopt/getopt.c
new file mode 100644 (file)
index 0000000..b7f26eb
--- /dev/null
@@ -0,0 +1,1060 @@
+/* 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 drepper@gnu.org
+   before changing it!
+   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#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>
+
+/* 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
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   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.  */
+
+#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__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+# 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
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.  */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || 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
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   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.  */
+
+/* 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.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   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 -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\f
+#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
+#else
+
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#ifndef getenv
+#ifdef _MSC_VER
+// DDK will complain if you don't use the stdlib defined getenv
+#include <stdlib.h>
+#else
+extern char *getenv ();
+#endif
+#endif
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* 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__ */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+   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).  */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+#  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
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
+#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.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `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 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.  */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  /* 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
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* 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;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  if (posixly_correct == NULL
+      && argc == __libc_argc && argv == __libc_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;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   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 -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.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int print_errors = opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      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.  */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# 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,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc && NONOPTION_P)
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* The special 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], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         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 (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        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][1] == '-'
+         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *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)
+               == (unsigned int) 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 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 (print_errors)
+           fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         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)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                _("%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"),
+                                argv[0], argv[optind - 1][0], pfound->name);
+                   }
+
+                 nextchar += strlen (nextchar);
+
+                 optopt = pfound->val;
+                 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);
+                 optopt = pfound->val;
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         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.  */
+      if (!long_only || argv[optind][1] == '-'
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (print_errors)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               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 short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (print_errors)
+         {
+           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: 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 != NULL && 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] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = NULL;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* 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 = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/examples/getopt/getopt.h b/examples/getopt/getopt.h
new file mode 100644 (file)
index 0000000..a1b8dd6
--- /dev/null
@@ -0,0 +1,180 @@
+/* Declarations for getopt.
+   Copyright (C) 1989-1994, 1996-1999, 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+   standalone, or this is the first header included in the source file.
+   If we are being used with glibc, we need to include <features.h>, but
+   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
+   not defined, include <ctype.h>, which will pull in <features.h> for us
+   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
+   doesn't flood the namespace with stuff the way some other headers do.)  */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   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;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+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.
+
+   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
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+  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
+#endif /* need getopt */
+
+
+/* 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__) || defined __cplusplus
+# 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 /* __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);
+# 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
+
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/examples/getopt/getopt1.c b/examples/getopt/getopt1.c
new file mode 100644 (file)
index 0000000..22a7efb
--- /dev/null
@@ -0,0 +1,188 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+     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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#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>
+
+/* 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
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   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.  */
+
+#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>
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
index e645bd3..56536af 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10561
+#define LIBUSB_NANO 10562
index 714945a..a68b5e2 100644 (file)
@@ -108,6 +108,38 @@ copy %srcPath%\xusb.pdb %dstPath%\examples
 
 @echo off
 
+if exist examples\getopt\getopt_ddkbuild goto md9
+md examples\getopt\getopt_ddkbuild
+:md9
+
+cd examples\getopt\getopt_ddkbuild
+copy ..\..\..\msvc\getopt_sources sources >NUL 2>&1
+@echo on
+%BUILD_CMD%
+@echo off
+if errorlevel 1 goto builderror
+cd ..\..\..
+
+if exist examples\fxload_ddkbuild goto md8
+md examples\fxload_ddkbuild
+:md8
+
+cd examples\fxload_ddkbuild
+copy ..\..\msvc\fxload_sources sources >NUL 2>&1
+@echo on
+%BUILD_CMD%
+@echo off
+if errorlevel 1 goto builderror
+cd ..\..
+
+set srcPath=examples\fxload_ddkbuild\obj%BUILD_ALT_DIR%\%cpudir%
+@echo on
+
+copy %srcPath%\fxload.exe %dstPath%\examples
+copy %srcPath%\fxload.pdb %dstPath%\examples
+
+@echo off
+
 cd msvc
 goto done
 
diff --git a/msvc/fxload.vcxproj b/msvc/fxload.vcxproj
new file mode 100644 (file)
index 0000000..8c27259
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>fxload</ProjectName>
+    <ProjectGuid>{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}</ProjectGuid>
+    <RootNamespace>examples</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\examples\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <BuildLog>
+      <Path>$(IntDir)$(ProjectName).htm</Path>
+    </BuildLog>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <BuildLog>
+      <Path>$(IntDir)$(ProjectName).htm</Path>
+    </BuildLog>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <BuildLog>
+      <Path>$(IntDir)$(ProjectName).htm</Path>
+    </BuildLog>
+    <ClCompile>
+      <AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <BuildLog>
+      <Path>$(IntDir)$(ProjectName).htm</Path>
+    </BuildLog>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <AdditionalIncludeDirectories>.;..\examples\getopt;..\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;__GNU_LIBRARY__;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\examples\ezusb.c" />
+    <ClCompile Include="..\examples\fxload.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include=".\libusb_static.vcxproj">
+      <Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="getopt.vcxproj">
+      <Project>{ae83e1b4-ce06-47ee-b7a3-c3a1d7c2d71e}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\examples\ezusb.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/msvc/fxload.vcxproj.filters b/msvc/fxload.vcxproj.filters
new file mode 100644 (file)
index 0000000..c274b23
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{651ff73d-037b-4903-8dd3-56e9950be25c}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\examples\fxload.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\examples\ezusb.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\examples\ezusb.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/msvc/fxload_sources b/msvc/fxload_sources
new file mode 100644 (file)
index 0000000..d6e31d6
--- /dev/null
@@ -0,0 +1,23 @@
+TARGETNAME=fxload
+TARGETTYPE=PROGRAM
+386_STDCALL=0
+
+_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
+
+!IFNDEF MSC_WARNING_LEVEL
+MSC_WARNING_LEVEL=/W3
+!ENDIF
+
+!IFDEF STATIC_LIBC
+USE_LIBCMT=1
+!ELSE
+USE_MSVCRT=1
+!ENDIF
+
+UMTYPE=console
+INCLUDES=..\..\msvc;..\..\libusb;..\getopt;$(DDK_INC_PATH)
+C_DEFINES=$(C_DEFINES) /D__GNU_LIBRARY__
+UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib \
+       ..\getopt\getopt_ddkbuild\obj$(BUILD_ALT_DIR)\*\getopt.lib
+SOURCES=..\ezusb.c \
+        ..\fxload.c
diff --git a/msvc/getopt.vcproj b/msvc/getopt.vcproj
new file mode 100644 (file)
index 0000000..0efcb0b
--- /dev/null
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9.00"
+       Name="getopt"
+       ProjectGUID="{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}"
+       RootNamespace="getopt"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+               <Platform
+                       Name="x64"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\getopt"
+                       ConfigurationType="4"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               PreprocessorDefinitions="HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS"
+                               MinimalRebuild="true"
+                               RuntimeLibrary="1"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               IgnoreAllDefaultLibraries="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|x64"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\getopt"
+                       ConfigurationType="4"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               PreprocessorDefinitions="HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS"
+                               RuntimeLibrary="1"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               IgnoreAllDefaultLibraries="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\getopt"
+                       ConfigurationType="4"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               PreprocessorDefinitions="HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS"
+                               RuntimeLibrary="0"
+                               WarningLevel="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               IgnoreAllDefaultLibraries="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|x64"
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib"
+                       IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\lib\getopt"
+                       ConfigurationType="4"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               PreprocessorDefinitions="HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS"
+                               RuntimeLibrary="0"
+                               WarningLevel="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               IgnoreAllDefaultLibraries="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath="..\examples\getopt\getopt.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\examples\getopt\getopt1.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath="..\examples\getopt\getopt.h"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/msvc/getopt.vcxproj b/msvc/getopt.vcxproj
new file mode 100644 (file)
index 0000000..3f413c7
--- /dev/null
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}</ProjectGuid>
+    <RootNamespace>getopt</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\$(Platform)\$(Configuration)\lib\getopt\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Lib>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Lib>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <PreprocessorDefinitions>HAVE_STRING_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <Lib>
+      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\examples\getopt\getopt.c" />
+    <ClCompile Include="..\examples\getopt\getopt1.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\examples\getopt\getopt.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/msvc/getopt.vcxproj.filters b/msvc/getopt.vcxproj.filters
new file mode 100644 (file)
index 0000000..d5f4518
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\examples\getopt\getopt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\examples\getopt\getopt1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\examples\getopt\getopt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/msvc/getopt_sources b/msvc/getopt_sources
new file mode 100644 (file)
index 0000000..b9adc1b
--- /dev/null
@@ -0,0 +1,20 @@
+TARGETTYPE=LIBRARY
+TARGETNAME=getopt
+386_STDCALL=0
+
+_NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP)
+
+!IFNDEF MSC_WARNING_LEVEL
+MSC_WARNING_LEVEL=/W3
+!ENDIF
+
+USE_MSVCRT=1
+
+INCLUDES=$(DDK_INC_PATH)
+C_DEFINES = $(C_DEFINES) /DDDKBUILD /DHAVE_STRING_H
+
+TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
+           $(SDK_LIB_PATH)\user32.lib
+
+SOURCES=..\getopt1.c \
+        ..\getopt.c
index 20bfd32..8bd7e4d 100644 (file)
@@ -8,6 +8,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "listdevs", "listdevs.vcxpro
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xusb", "xusb.vcxproj", "{3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fxload", "fxload.vcxproj", "{9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}"
+       ProjectSection(ProjectDependencies) = postProject
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E} = {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt", "getopt.vcxproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -44,6 +51,22 @@ Global
                {3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|Win32.Build.0 = Release|Win32
                {3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|x64.ActiveCfg = Release|x64
                {3F3138D0-7AB7-4268-9BF3-1A3EA5503A11}.Release|x64.Build.0 = Release|x64
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|Win32.ActiveCfg = Debug|Win32
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|Win32.Build.0 = Debug|Win32
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|x64.ActiveCfg = Debug|x64
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Debug|x64.Build.0 = Debug|x64
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|Win32.ActiveCfg = Release|Win32
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|Win32.Build.0 = Release|Win32
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|x64.ActiveCfg = Release|x64
+               {9E166F7A-A793-9FB6-0A67-F0AED8AE8C88}.Release|x64.Build.0 = Release|x64
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.Build.0 = Debug|x64
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.ActiveCfg = Release|Win32
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.Build.0 = Release|Win32
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.ActiveCfg = Release|x64
+               {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE