Patch applied. Thanks.
--------------------------------------------------------------------------- Joe Conway wrote: > 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 */ > + } > > ---------------------------(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 -- Bruce Momjian | http://candle.pha.pa.us [EMAIL PROTECTED] | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 ---------------------------(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