Tom Lane wrote:
> It might work to measure time since the start of the whole process, or
> until the timeout target, rather than accumulating adjustments to the
> "remains" count each time through.  In other words something like
> 
>       at start: targettime = time() + specified-timeout
> 
>       each time we are about to wait: set select timeout to
>       targettime - time().
> 
> This bounds the error at 1 second which is probably good enough (you
> might want to add 1 to targettime to ensure the error is in the
> conservative direction of not timing out too soon).
> 

The attached patch fixes a number of issues related to compiling the client 
utilities (libpq.dll and psql.exe) for win32 (missing defines, adjustments to 
includes, pedantic casting, non-existent functions) per:
   http://developer.postgresql.org/docs/postgres/install-win32.html.

It compiles cleanly under Windows 2000 using Visual Studio .net. Also compiles 
clean and passes all regression tests (regular and contrib) under Linux.

In addition to a review by the usual suspects, it would be very desirable for 
someone well versed in the peculiarities of win32 to take a look.

If there are no objections, please commit.

Thanks,

Joe
Index: src/backend/libpq/md5.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/backend/libpq/md5.c,v
retrieving revision 1.18
diff -c -r1.18 md5.c
*** src/backend/libpq/md5.c     4 Sep 2002 20:31:19 -0000       1.18
--- src/backend/libpq/md5.c     26 Sep 2002 17:56:11 -0000
***************
*** 26,35 ****
   *    can be compiled stand-alone.
   */
  
! #ifndef MD5_ODBC
  #include "postgres.h"
  #include "libpq/crypt.h"
! #else
  #include "md5.h"
  #endif
  
--- 26,44 ----
   *    can be compiled stand-alone.
   */
  
! #if ! defined(MD5_ODBC) && ! defined(FRONTEND)
  #include "postgres.h"
  #include "libpq/crypt.h"
! #endif
! 
! #ifdef FRONTEND
! #include "postgres_fe.h"
! #ifndef WIN32
! #include "libpq/crypt.h"
! #endif /* WIN32 */
! #endif /* FRONTEND */
! 
! #ifdef MD5_ODBC
  #include "md5.h"
  #endif
  
Index: src/bin/psql/command.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/command.c,v
retrieving revision 1.81
diff -c -r1.81 command.c
*** src/bin/psql/command.c      22 Sep 2002 20:57:21 -0000      1.81
--- src/bin/psql/command.c      26 Sep 2002 18:18:17 -0000
***************
*** 23,28 ****
--- 23,29 ----
  #include <win32.h>
  #include <io.h>
  #include <fcntl.h>
+ #include <direct.h>
  #endif
  
  #include "libpq-fe.h"
***************
*** 1163,1169 ****
                                                return NULL;
                                        }
  
!                                       if (i < token_len - 1)
                                                return_val[i + 1] = '\0';
                                }
  
--- 1164,1170 ----
                                                return NULL;
                                        }
  
!                                       if (i < (int) token_len - 1)
                                                return_val[i + 1] = '\0';
                                }
  
***************
*** 1240,1246 ****
                exit(EXIT_FAILURE);
        }
  
!       for (p = source; p - source < len && *p; p += PQmblen(p, pset.encoding))
        {
                if (esc)
                {
--- 1241,1247 ----
                exit(EXIT_FAILURE);
        }
  
!       for (p = source; p - source < (int) len && *p; p += PQmblen(p, pset.encoding))
        {
                if (esc)
                {
***************
*** 1278,1284 ****
                                                char       *end;
  
                                                l = strtol(p, &end, 0);
!                                               c = l;
                                                p = end - 1;
                                                break;
                                        }
--- 1279,1285 ----
                                                char       *end;
  
                                                l = strtol(p, &end, 0);
!                                               c = (char) l;
                                                p = end - 1;
                                                break;
                                        }
Index: src/bin/psql/common.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/common.c,v
retrieving revision 1.45
diff -c -r1.45 common.c
*** src/bin/psql/common.c       14 Sep 2002 19:46:01 -0000      1.45
--- src/bin/psql/common.c       26 Sep 2002 18:43:31 -0000
***************
*** 11,27 ****
  
  #include <errno.h>
  #include <stdarg.h>
- #include <sys/time.h>
  #ifndef HAVE_STRDUP
  #include <strdup.h>
  #endif
  #include <signal.h>
  #ifndef WIN32
  #include <unistd.h>                           /* for write() */
  #include <setjmp.h>
  #else
  #include <io.h>                                       /* for _write() */
  #include <win32.h>
  #endif
  
  #include "libpq-fe.h"
--- 11,28 ----
  
  #include <errno.h>
  #include <stdarg.h>
  #ifndef HAVE_STRDUP
  #include <strdup.h>
  #endif
  #include <signal.h>
  #ifndef WIN32
+ #include <sys/time.h>
  #include <unistd.h>                           /* for write() */
  #include <setjmp.h>
  #else
  #include <io.h>                                       /* for _write() */
  #include <win32.h>
+ #include <sys/timeb.h>                        /* for _ftime() */
  #endif
  
  #include "libpq-fe.h"
***************
*** 295,303 ****
        bool            success = false;
        PGresult   *results;
        PGnotify   *notify;
        struct timeval before,
                                after;
!       struct timezone tz;
  
        if (!pset.db)
        {
--- 296,308 ----
        bool            success = false;
        PGresult   *results;
        PGnotify   *notify;
+ #ifndef WIN32
        struct timeval before,
                                after;
! #else
!       struct _timeb before,
!                               after;
! #endif
  
        if (!pset.db)
        {
***************
*** 327,337 ****
        }
  
        cancelConn = pset.db;
        if (pset.timing)
!               gettimeofday(&before, &tz);
        results = PQexec(pset.db, query);
        if (pset.timing)
!               gettimeofday(&after, &tz);
        if (PQresultStatus(results) == PGRES_COPY_IN)
                copy_in_state = true;
        /* keep cancel connection for copy out state */
--- 332,352 ----
        }
  
        cancelConn = pset.db;
+ 
+ #ifndef WIN32
+       if (pset.timing)
+               gettimeofday(&before, NULL);
+       results = PQexec(pset.db, query);
+       if (pset.timing)
+               gettimeofday(&after, NULL);
+ #else
        if (pset.timing)
!               _ftime(&before);
        results = PQexec(pset.db, query);
        if (pset.timing)
!               _ftime(&after);
! #endif
! 
        if (PQresultStatus(results) == PGRES_COPY_IN)
                copy_in_state = true;
        /* keep cancel connection for copy out state */
***************
*** 463,470 ****
--- 478,490 ----
  
        /* Possible microtiming output */
        if (pset.timing && success)
+ #ifndef WIN32
                printf(gettext("Time: %.2f ms\n"),
                           ((after.tv_sec - before.tv_sec) * 1000000.0 + after.tv_usec 
- before.tv_usec) / 1000.0);
+ #else
+               printf(gettext("Time: %.2f ms\n"),
+                          ((after.time - before.time) * 1000.0 + after.millitm - 
+before.millitm));
+ #endif
  
        return success;
  }
Index: src/bin/psql/copy.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/copy.c,v
retrieving revision 1.25
diff -c -r1.25 copy.c
*** src/bin/psql/copy.c 22 Sep 2002 20:57:21 -0000      1.25
--- src/bin/psql/copy.c 26 Sep 2002 18:59:11 -0000
***************
*** 28,33 ****
--- 28,35 ----
  
  #ifdef WIN32
  #define strcasecmp(x,y) stricmp(x,y)
+ #define       __S_ISTYPE(mode, mask)  (((mode) & S_IFMT) == (mask))
+ #define       S_ISDIR(mode)    __S_ISTYPE((mode), S_IFDIR)
  #endif
  
  bool          copy_in_state;
Index: src/bin/psql/large_obj.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/large_obj.c,v
retrieving revision 1.21
diff -c -r1.21 large_obj.c
*** src/bin/psql/large_obj.c    4 Sep 2002 20:31:36 -0000       1.21
--- src/bin/psql/large_obj.c    26 Sep 2002 19:04:07 -0000
***************
*** 196,202 ****
        {
                char       *cmdbuf;
                char       *bufptr;
!               int                     slen = strlen(comment_arg);
  
                cmdbuf = malloc(slen * 2 + 256);
                if (!cmdbuf)
--- 196,202 ----
        {
                char       *cmdbuf;
                char       *bufptr;
!               size_t          slen = strlen(comment_arg);
  
                cmdbuf = malloc(slen * 2 + 256);
                if (!cmdbuf)
Index: src/bin/psql/mbprint.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/mbprint.c,v
retrieving revision 1.4
diff -c -r1.4 mbprint.c
*** src/bin/psql/mbprint.c      27 Aug 2002 20:16:48 -0000      1.4
--- src/bin/psql/mbprint.c      26 Sep 2002 20:11:44 -0000
***************
*** 202,208 ****
        for (; *pwcs && len > 0; pwcs += l)
        {
                l = pg_utf_mblen(pwcs);
!               if ((len < l) || ((w = ucs_wcwidth(utf2ucs(pwcs))) < 0))
                        return width;
                len -= l;
                width += w;
--- 202,208 ----
        for (; *pwcs && len > 0; pwcs += l)
        {
                l = pg_utf_mblen(pwcs);
!               if ((len < (size_t) l) || ((w = ucs_wcwidth(utf2ucs(pwcs))) < 0))
                        return width;
                len -= l;
                width += w;
Index: src/bin/psql/print.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/bin/psql/print.c,v
retrieving revision 1.31
diff -c -r1.31 print.c
*** src/bin/psql/print.c        1 Sep 2002 23:30:46 -0000       1.31
--- src/bin/psql/print.c        26 Sep 2002 21:10:59 -0000
***************
*** 282,288 ****
        {
                int                     tlen;
  
!               if ((tlen = pg_wcswidth((unsigned char *) title, strlen(title))) >= 
total_w)
                        fprintf(fout, "%s\n", title);
                else
                        fprintf(fout, "%-*s%s\n", (int) (total_w - tlen) / 2, "", 
title);
--- 282,288 ----
        {
                int                     tlen;
  
!               if ((unsigned int) (tlen = pg_wcswidth((unsigned char *) title, 
strlen(title))) >= total_w)
                        fprintf(fout, "%s\n", title);
                else
                        fprintf(fout, "%-*s%s\n", (int) (total_w - tlen) / 2, "", 
title);
***************
*** 1184,1191 ****
                           footers ? (const char *const *) footers : (const char 
*const *) (opt->footers),
                           align, &opt->topt, fout);
  
!       free(headers);
!       free(cells);
        if (footers)
        {
                free(footers[0]);
--- 1184,1191 ----
                           footers ? (const char *const *) footers : (const char 
*const *) (opt->footers),
                           align, &opt->topt, fout);
  
!       free((void *) headers);
!       free((void *) cells);
        if (footers)
        {
                free(footers[0]);
Index: src/include/pg_config.h.win32
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/include/pg_config.h.win32,v
retrieving revision 1.7
diff -c -r1.7 pg_config.h.win32
*** src/include/pg_config.h.win32       4 Sep 2002 22:54:18 -0000       1.7
--- src/include/pg_config.h.win32       26 Sep 2002 17:32:07 -0000
***************
*** 16,21 ****
--- 16,23 ----
  
  #define MAXPGPATH 1024
  
+ #define INDEX_MAX_KEYS 32
+ 
  #define HAVE_ATEXIT
  #define HAVE_MEMMOVE
  
***************
*** 48,53 ****
--- 50,59 ----
  
  #define DLLIMPORT
  
+ #endif
+ 
+ #ifndef __CYGWIN__
+ #include <windows.h>
  #endif
  
  #endif /* pg_config_h_win32__ */
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.205
diff -c -r1.205 fe-connect.c
*** src/interfaces/libpq/fe-connect.c   22 Sep 2002 20:57:21 -0000      1.205
--- src/interfaces/libpq/fe-connect.c   26 Sep 2002 00:32:48 -0000
***************
*** 21,27 ****
  #include <errno.h>
  #include <ctype.h>
  #include <time.h>
- #include <unistd.h>
  
  #include "libpq-fe.h"
  #include "libpq-int.h"
--- 21,26 ----
***************
*** 1053,1062 ****
  {
        PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
  
!       struct timeval remains,
!                          *rp = NULL,
!                               finish_time,
!                               start_time;
  
        if (conn == NULL || conn->status == CONNECTION_BAD)
                return 0;
--- 1052,1061 ----
  {
        PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
  
!       time_t                  finish_time = 0,
!                                       current_time;
!       struct timeval  remains,
!                                  *rp = NULL;
  
        if (conn == NULL || conn->status == CONNECTION_BAD)
                return 0;
***************
*** 1074,1093 ****
                }
                remains.tv_usec = 0;
                rp = &remains;
        }
  
        while (rp == NULL || remains.tv_sec > 0 || remains.tv_usec > 0)
        {
                /*
-                * If connecting timeout is set, get current time.
-                */
-               if (rp != NULL && gettimeofday(&start_time, NULL) == -1)
-               {
-                       conn->status = CONNECTION_BAD;
-                       return 0;
-               }
- 
-               /*
                 * Wait, if necessary.  Note that the initial state (just after
                 * PQconnectStart) is to wait for the socket to select for
                 * writing.
--- 1073,1086 ----
                }
                remains.tv_usec = 0;
                rp = &remains;
+ 
+               /* calculate the finish time based on start + timeout */
+               finish_time = time((time_t *) NULL) + remains.tv_sec;
        }
  
        while (rp == NULL || remains.tv_sec > 0 || remains.tv_usec > 0)
        {
                /*
                 * Wait, if necessary.  Note that the initial state (just after
                 * PQconnectStart) is to wait for the socket to select for
                 * writing.
***************
*** 1128,1153 ****
                flag = PQconnectPoll(conn);
  
                /*
!                * If connecting timeout is set, calculate remain time.
                 */
                if (rp != NULL)
                {
!                       if (gettimeofday(&finish_time, NULL) == -1)
                        {
                                conn->status = CONNECTION_BAD;
                                return 0;
                        }
!                       if ((finish_time.tv_usec -= start_time.tv_usec) < 0)
!                       {
!                               remains.tv_sec++;
!                               finish_time.tv_usec += 1000000;
!                       }
!                       if ((remains.tv_usec -= finish_time.tv_usec) < 0)
!                       {
!                               remains.tv_sec--;
!                               remains.tv_usec += 1000000;
!                       }
!                       remains.tv_sec -= finish_time.tv_sec - start_time.tv_sec;
                }
        }
        conn->status = CONNECTION_BAD;
--- 1121,1138 ----
                flag = PQconnectPoll(conn);
  
                /*
!                * If connecting timeout is set, calculate remaining time.
                 */
                if (rp != NULL)
                {
!                       if (time(&current_time) == -1)
                        {
                                conn->status = CONNECTION_BAD;
                                return 0;
                        }
! 
!                       remains.tv_sec = finish_time - current_time;
!                       remains.tv_usec = 0;
                }
        }
        conn->status = CONNECTION_BAD;
***************
*** 2946,2951 ****
--- 2931,2937 ----
                return NULL;
        }
  
+ #ifndef WIN32
        /* If password file is insecure, alert the user and ignore it. */
        if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
        {
***************
*** 2955,2960 ****
--- 2941,2947 ----
                free(pgpassfile);
                return NULL;
        }
+ #endif
  
        fp = fopen(pgpassfile, "r");
        free(pgpassfile);
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.79
diff -c -r1.79 fe-misc.c
*** src/interfaces/libpq/fe-misc.c      4 Sep 2002 20:31:47 -0000       1.79
--- src/interfaces/libpq/fe-misc.c      26 Sep 2002 05:16:52 -0000
***************
*** 150,158 ****
                                 * try to grow the buffer. FIXME: The new size could be
                                 * chosen more intelligently.
                                 */
!                               size_t          buflen = conn->outCount + nbytes;
  
!                               if (buflen > conn->outBufSize)
                                {
                                        char       *newbuf = realloc(conn->outBuffer, 
buflen);
  
--- 150,158 ----
                                 * try to grow the buffer. FIXME: The new size could be
                                 * chosen more intelligently.
                                 */
!                               size_t          buflen = (size_t) conn->outCount + 
nbytes;
  
!                               if (buflen > (size_t) conn->outBufSize)
                                {
                                        char       *newbuf = realloc(conn->outBuffer, 
buflen);
  
***************
*** 240,246 ****
  int
  pqGetnchar(char *s, size_t len, PGconn *conn)
  {
!       if (len < 0 || len > conn->inEnd - conn->inCursor)
                return EOF;
  
        memcpy(s, conn->inBuffer + conn->inCursor, len);
--- 240,246 ----
  int
  pqGetnchar(char *s, size_t len, PGconn *conn)
  {
!       if (len < 0 || len > (size_t) (conn->inEnd - conn->inCursor))
                return EOF;
  
        memcpy(s, conn->inBuffer + conn->inCursor, len);
Index: src/interfaces/libpq/fe-print.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/fe-print.c,v
retrieving revision 1.46
diff -c -r1.46 fe-print.c
*** src/interfaces/libpq/fe-print.c     29 Aug 2002 07:22:30 -0000      1.46
--- src/interfaces/libpq/fe-print.c     26 Sep 2002 05:08:47 -0000
***************
*** 299,305 ****
                                        (PQntuples(res) == 1) ? "" : "s");
                free(fieldMax);
                free(fieldNotNum);
!               free(fieldNames);
                if (usePipe)
                {
  #ifdef WIN32
--- 299,305 ----
                                        (PQntuples(res) == 1) ? "" : "s");
                free(fieldMax);
                free(fieldNotNum);
!               free((void *) fieldNames);
                if (usePipe)
                {
  #ifdef WIN32
Index: src/interfaces/libpq/libpq-int.h
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.57
diff -c -r1.57 libpq-int.h
*** src/interfaces/libpq/libpq-int.h    4 Sep 2002 20:31:47 -0000       1.57
--- src/interfaces/libpq/libpq-int.h    25 Sep 2002 21:08:03 -0000
***************
*** 21,28 ****
  #define LIBPQ_INT_H
  
  #include <time.h>
- #include <sys/time.h>
  #include <sys/types.h>
  
  #if defined(WIN32) && (!defined(ssize_t))
  typedef int ssize_t;                  /* ssize_t doesn't exist in VC (atleast
--- 21,30 ----
  #define LIBPQ_INT_H
  
  #include <time.h>
  #include <sys/types.h>
+ #ifndef WIN32
+ #include <sys/time.h>
+ #endif
  
  #if defined(WIN32) && (!defined(ssize_t))
  typedef int ssize_t;                  /* ssize_t doesn't exist in VC (atleast
Index: src/interfaces/libpq/libpqdll.def
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/libpqdll.def,v
retrieving revision 1.15
diff -c -r1.15 libpqdll.def
*** src/interfaces/libpq/libpqdll.def   2 Jun 2002 22:36:30 -0000       1.15
--- src/interfaces/libpq/libpqdll.def   26 Sep 2002 20:18:48 -0000
***************
*** 1,5 ****
  LIBRARY LIBPQ
- DESCRIPTION "Postgres Client Access Library"
  EXPORTS
        PQconnectdb             @ 1
        PQsetdbLogin            @ 2
--- 1,4 ----
***************
*** 90,92 ****
--- 89,95 ----
        PQfreeNotify            @ 87
        PQescapeString          @ 88
        PQescapeBytea           @ 89
+       printfPQExpBuffer       @ 90
+       appendPQExpBuffer       @ 91
+       pg_encoding_to_char     @ 92
+       pg_utf_mblen            @ 93
Index: src/interfaces/libpq/pqexpbuffer.c
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/pqexpbuffer.c,v
retrieving revision 1.13
diff -c -r1.13 pqexpbuffer.c
*** src/interfaces/libpq/pqexpbuffer.c  20 Jun 2002 20:29:54 -0000      1.13
--- src/interfaces/libpq/pqexpbuffer.c  26 Sep 2002 05:12:17 -0000
***************
*** 192,198 ****
                         * actually stored, but at least one returns -1 on failure. Be
                         * conservative about believing whether the print worked.
                         */
!                       if (nprinted >= 0 && nprinted < avail - 1)
                        {
                                /* Success.  Note nprinted does not include trailing 
null. */
                                str->len += nprinted;
--- 192,198 ----
                         * actually stored, but at least one returns -1 on failure. Be
                         * conservative about believing whether the print worked.
                         */
!                       if (nprinted >= 0 && nprinted < (int) avail - 1)
                        {
                                /* Success.  Note nprinted does not include trailing 
null. */
                                str->len += nprinted;
***************
*** 240,246 ****
                         * actually stored, but at least one returns -1 on failure. Be
                         * conservative about believing whether the print worked.
                         */
!                       if (nprinted >= 0 && nprinted < avail - 1)
                        {
                                /* Success.  Note nprinted does not include trailing 
null. */
                                str->len += nprinted;
--- 240,246 ----
                         * actually stored, but at least one returns -1 on failure. Be
                         * conservative about believing whether the print worked.
                         */
!                       if (nprinted >= 0 && nprinted < (int) avail - 1)
                        {
                                /* Success.  Note nprinted does not include trailing 
null. */
                                str->len += nprinted;
Index: src/interfaces/libpq/win32.h
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/interfaces/libpq/win32.h,v
retrieving revision 1.19
diff -c -r1.19 win32.h
*** src/interfaces/libpq/win32.h        20 Jul 2002 05:43:31 -0000      1.19
--- src/interfaces/libpq/win32.h        26 Sep 2002 17:32:19 -0000
***************
*** 22,28 ****
  /*
   * crypt not available (yet)
   */
! #define crypt(a,b) (a)
  
  #undef EAGAIN                                 /* doesn't apply on sockets */
  #undef EINTR
--- 22,28 ----
  /*
   * crypt not available (yet)
   */
! #define crypt(a,b) ((char *) a)
  
  #undef EAGAIN                                 /* doesn't apply on sockets */
  #undef EINTR
Index: src/utils/Makefile
===================================================================
RCS file: /opt/src/cvs/pgsql-server/src/utils/Makefile,v
retrieving revision 1.14
diff -c -r1.14 Makefile
*** src/utils/Makefile  27 Jul 2002 20:10:05 -0000      1.14
--- src/utils/Makefile  26 Sep 2002 05:34:49 -0000
***************
*** 15,18 ****
  all:
  
  clean distclean maintainer-clean:
!       rm -f dllinit.o
--- 15,18 ----
  all:
  
  clean distclean maintainer-clean:
!       rm -f dllinit.o getopt.o
Index: src/utils/getopt.c
===================================================================
RCS file: src/utils/getopt.c
diff -N src/utils/getopt.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- src/utils/getopt.c  26 Nov 2001 19:30:58 -0000
***************
*** 0 ****
--- 1,125 ----
+ /*
+  * Copyright (c) 1987, 1993, 1994
+  *    The Regents of the University of California.  All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *      notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *      notice, this list of conditions and the following disclaimer in the
+  *      documentation and/or other materials provided with the distribution.
+  * 3. All advertising materials mentioning features or use of this software
+  *      must display the following acknowledgement:
+  *    This product includes software developed by the University of
+  *    California, Berkeley and its contributors.
+  * 4. Neither the name of the University nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.    IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ #if defined(LIBC_SCCS) && !defined(lint)
+ static char sccsid[] = "@(#)getopt.c  8.3 (Berkeley) 4/27/95";
+ #endif   /* LIBC_SCCS and not lint */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ int                   opterr = 1,                     /* if error message should be 
+printed */
+                       optind = 1,                     /* index into parent argv 
+vector */
+                       optopt,                         /* character checked for 
+validity */
+                       optreset;                       /* reset getopt */
+ char     *optarg;                             /* argument associated with option */
+ 
+ #define BADCH (int)'?'
+ #define BADARG        (int)':'
+ #define EMSG  ""
+ 
+ /*
+  * getopt
+  *    Parse argc/argv argument vector.
+  */
+ int
+ getopt(nargc, nargv, ostr)
+ int                   nargc;
+ char     *const * nargv;
+ const char *ostr;
+ {
+       extern char *__progname;
+       static char *place = EMSG;      /* option letter processing */
+       char       *oli;                        /* option letter list index */
+ 
+       if (optreset || !*place)
+       {                                                       /* update scanning 
+pointer */
+               optreset = 0;
+               if (optind >= nargc || *(place = nargv[optind]) != '-')
+               {
+                       place = EMSG;
+                       return -1;
+               }
+               if (place[1] && *++place == '-' && place[1] == '\0')
+               {                                               /* found "--" */
+                       ++optind;
+                       place = EMSG;
+                       return -1;
+               }
+       }                                                       /* option letter okay? 
+*/
+       if ((optopt = (int) *place++) == (int) ':' ||
+               !(oli = strchr(ostr, optopt)))
+       {
+               /*
+                * if the user didn't specify '-' as an option, assume it means
+                * -1.
+                */
+               if (optopt == (int) '-')
+                       return -1;
+               if (!*place)
+                       ++optind;
+               if (opterr && *ostr != ':')
+                       (void) fprintf(stderr,
+                                          "%s: illegal option -- %c\n", __progname, 
+optopt);
+               return BADCH;
+       }
+       if (*++oli != ':')
+       {                                                       /* don't need argument 
+*/
+               optarg = NULL;
+               if (!*place)
+                       ++optind;
+       }
+       else
+       {                                                       /* need an argument */
+               if (*place)                             /* no white space */
+                       optarg = place;
+               else if (nargc <= ++optind)
+               {                                               /* no arg */
+                       place = EMSG;
+                       if (*ostr == ':')
+                               return BADARG;
+                       if (opterr)
+                               (void) fprintf(stderr,
+                                                          "%s: option requires an 
+argument -- %c\n",
+                                                          __progname, optopt);
+                       return BADCH;
+               }
+               else
+ /* white space */
+                       optarg = nargv[optind];
+               place = EMSG;
+               ++optind;
+       }
+       return optopt;                          /* dump back option letter */
+ }

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly

Reply via email to