aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-03-23 11:58:00 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-03-23 11:58:00 -0400
commit980a70b9763e330dab6d0eb994c96a007876e40e (patch)
tree0ac3c0b304aef20c27a28647d195e37db5368200
parentc81bd3b9a5e99315148f4f5714c32e633af30123 (diff)
downloadpostgresql-980a70b9763e330dab6d0eb994c96a007876e40e.tar.gz
postgresql-980a70b9763e330dab6d0eb994c96a007876e40e.zip
Fix our getopt_long's behavior for a command line argument of just "-".
src/port/getopt_long.c failed on such an argument, always seeing it as an unrecognized switch. This is unhelpful; better is to treat such an item as a non-switch argument. That behavior is what we find in GNU's getopt_long(); it's what src/port/getopt.c does; and it is required by POSIX for getopt(), which getopt_long() ought to be generally a superset of. Moreover, it's expected by ecpg, which intends an argument of "-" to mean "read from stdin". So fix it. Also add some documentation about ecpg's behavior in this area, since that was miserably underdocumented. I had to reverse-engineer it from the code. Per bug #16304 from James Gray. Back-patch to all supported branches, since this has been broken forever. Discussion: https://postgr.es/m/16304-c662b00a1322db7f@postgresql.org
-rw-r--r--doc/src/sgml/ref/ecpg-ref.sgml31
-rw-r--r--src/port/getopt_long.c14
2 files changed, 37 insertions, 8 deletions
diff --git a/doc/src/sgml/ref/ecpg-ref.sgml b/doc/src/sgml/ref/ecpg-ref.sgml
index df3c1054f0f..f3b6034f42a 100644
--- a/doc/src/sgml/ref/ecpg-ref.sgml
+++ b/doc/src/sgml/ref/ecpg-ref.sgml
@@ -41,15 +41,22 @@ PostgreSQL documentation
<para>
<command>ecpg</command> will convert each input file given on the
- command line to the corresponding C output file. Input files
- preferably have the extension <filename>.pgc</filename>.
- The extension will be replaced by <filename>.c</filename> to
- determine the output file name.
- The output file name can also be overridden using the
+ command line to the corresponding C output file. If an input file
+ name does not have any extension, <filename>.pgc</filename> is
+ assumed. The file's extension will be replaced
+ by <filename>.c</filename> to construct the output file name.
+ But the output file name can be overridden using the
<option>-o</option> option.
</para>
<para>
+ If an input file name is just <literal>-</literal>,
+ <command>ecpg</command> reads the program from standard input
+ (and writes to standard output, unless that is overridden
+ with <option>-o</option>).
+ </para>
+
+ <para>
This reference page does not describe the embedded SQL language.
See <xref linkend="ecpg"/> for more information on that topic.
</para>
@@ -95,6 +102,19 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
+ <term><option>-h</option></term>
+ <listitem>
+ <para>
+ Process header files. When this option is specified, the output file
+ extension becomes <literal>.h</literal> not <literal>.c</literal>,
+ and the default input file extension is <literal>.pgh</literal>
+ not <literal>.pgc</literal>. Also, the <option>-c</option> option is
+ forced on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-i</option></term>
<listitem>
<para>
@@ -125,6 +145,7 @@ PostgreSQL documentation
<para>
Specifies that <command>ecpg</command> should write all
its output to the given <replaceable>filename</replaceable>.
+ Write <literal>-o -</literal> to send all output to standard output.
</para>
</listitem>
</varlistentry>
diff --git a/src/port/getopt_long.c b/src/port/getopt_long.c
index ff379db29b0..c9892769883 100644
--- a/src/port/getopt_long.c
+++ b/src/port/getopt_long.c
@@ -79,14 +79,22 @@ getopt_long(int argc, char *const argv[],
place++;
- if (place[0] && place[0] == '-' && place[1] == '\0')
- { /* found "--" */
+ if (!*place)
+ {
+ /* treat "-" as not being an option */
+ place = EMSG;
+ return -1;
+ }
+
+ if (place[0] == '-' && place[1] == '\0')
+ {
+ /* found "--", treat it as end of options */
++optind;
place = EMSG;
return -1;
}
- if (place[0] && place[0] == '-' && place[1])
+ if (place[0] == '-' && place[1])
{
/* long option */
size_t namelen;