fix for client utils compilation under win32 - Mailing list pgsql-hackers

From Joe Conway
Subject fix for client utils compilation under win32
Date
Msg-id 3D937E07.9020605@joeconway.com
Whole thread Raw
In response to compiling client utils under win32 - current 7.3devel is broken  (Joe Conway <mail@joeconway.com>)
Responses Re: fix for client utils compilation under win32  (Bruce Momjian <pgman@candle.pha.pa.us>)
Re: fix for client utils compilation under win32  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-hackers
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(¤t_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 */
+ }

pgsql-hackers by date:

Previous
From: Doug McNaught
Date:
Subject: Re: [GENERAL] Performance while loading data and indexing
Next
From: Bruce Momjian
Date:
Subject: Re: [GENERAL] Performance while loading data and indexing