Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000191 [1003.1(2008)/Issue 7] System Interfaces Comment Enhancement Request 2009-12-03 03:38 2019-12-20 12:09
Reporter eblake View Status public  
Assigned To ajosey
Priority normal Resolution Accepted As Marked  
Status Applied  
Name Eric Blake
Organization NA
User Reference ebb.getopt2
Section getopt
Page Number 1040
Line Number 34822
Interp Status ---
Final Accepted Text See Note: 0000329
Summary 0000191: getopt and leading + in optstring
Description Multiple getopt implementations now support the extension of a leading '+' in the optstring enforcing POSIX semantics of stopping the parse at the first non-option, even if the application is otherwise in a non-conforming environment where getopt would permute the arguments and recognize options specified after non-options (such non-conforming behavior is often conditional on whether the environment variable POSIXLY_CORRECT is set, such that unsetting it causes a non-conforming environment where POSIX no longer applies).

Some application writers want to provide applications that can be used in both a confirming environment, and yet still provide predictable behavior in an otherwise non-conforming environment. For example, consider an implementation of env(1): it must not permute arguments, whether or not getopt() is conforming in the current environment. In a non-conforming environment where getopt understands leading '+', this is done easily with getopt(argc,argv,"+i"). The problem is that since leading '+' is not standardized by POSIX, it is not possible to portably write a POSIX-conforming implementation of env that will also work in a non-conforming environment, short of writing the argument parsing loop manually rather than relying on getopt.

The desired action attempts to standardize existing practice with leading '+' among the implementations that support it. However, incorporating it now would render any existing implementation that does not handle leading '+' non-compliant, so this is only an enhancement request. The proposed wording is careful to only specify behavior of a leading '+'; use of '+' anywhere else in the optstring is still implementation-defined.

Another commonly implemented application extension is the use of a leading '-' to force in-order parsing (for example, the standard requires that 'm4 -Da=1 f -Da=2 f' treat -Da=2 as a macro assignment effective after the first read of file f, rather than as a file name; this is most easily achieved with the leading '-' extension, and recognizing non-options by setting optarg to the argument and returning 1). For now, I am not including it in this enhancement request, but I can propose additional wording to standardize it if desired.
Desired Action At line 34820, before:

The implementation may accept other characters as an extension.

insert a sentence:

The optstring argument may optionally start with a <plus-sign> ('+'), which has no effect on behavior in a conforming environment. Use of a <plus-sign> anywhere besides the first byte of optstring has unspecified results.

At line 34828, change:

matches a character in optstring, if there is one that matches.

to:

matches a character in optstring (excluding any optional leading <plus-sign>), if there is one that matches.

At line 34843, replace:

If getopt( ) encounters an option character that is not contained in optstring, it shall return the <question-mark> ('?') character. If it detects a missing option-argument, it shall return the <colon> character (':') if the first character of optstring was a <colon>, or a <question-mark> character ('?') otherwise. In either case, getopt( ) shall set the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0 and the first character of optstring is not a <colon>, getopt( ) shall also print a diagnostic message to stderr in the format specified for the getopts utility.

with:

If getopt( ) encounters a <colon>, or encounters an option character that is not contained after any leading <plus-sign> in optstring, it shall return the <question-mark> ('?') character. If it detects a missing option-argument, it shall return the <colon> character (':') if the first character of optstring was a <colon> or the first character of optstring was a <plus-sign> and the second character a <colon>, or a <question-mark> character ('?') otherwise. In either case, getopt( ) shall set the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0, and either the first character of optstring is not a <colon>, or the first character of optstring is a <plus-sign> but the second character is not a <colon>, getopt( ) shall also print a diagnostic message to stderr in the format specified for the getopts utility.

Replace two paragraphs at line 34853:

A <colon> (':') shall be returned if getopt( ) detects a missing argument and the first character of optstring was a <colon> (':').

A <question-mark> ('?') shall be returned if getopt( ) encounters an option character not in optstring or detects a missing argument and the first character of optstring was not a <colon> (':').

with:

A <colon> (':') shall be returned if getopt( ) detects a missing argument and the first character of optstring was a <colon> (':') or the first character of optstring was a <plus-sign> ('+') and the second character a <colon>.

A <question-mark> ('?') shall be returned if getopt( ) encounters an option character not in optstring or detects a missing argument and the first character of optstring was not a <colon> (':') or the first character was a <plus-sign> and the second character not a <colon>.

At line 34988, replace:

The special significance of a <colon> as the first character of optstring makes getopt( ) consistent with the getopts utility.

with:

The special significance of a <colon> at the beginning of optstring makes getopt( ) consistent with the getopts utility.

Add a new paragraph to the RATIONALE, after line 34992:

In some non-conforming environments, the use of a leading <plus-sign> in optstring forces getopt( ) to stop parsing at the first non-option, when it would otherwise permute the arguments and recognize options after arguments. Stopping at the first non-option is required by default of a conforming getopt( ) without the need for a leading <plus-sign>; however, the practice has been standardized to allow applications to be written that can guarantee behavior consistent with this specification even in an otherwise non-conforming environment. If both <plus-sign> and <colon> are used at the beginning of optstring, the <plus-sign> must be first.
Tags issue8
Attached Files

- Relationships
related to 0001784Applied Issue 8 drafts getopts specification needs fixing (multiple issues) 

-  Notes
(0000315)
eblake (manager)
2009-12-03 14:03

Here's an alternate proposed resolution that also permits leading '-' for in-order processing, and incorporates word-smithing improvements from the list.

At line 34820, before:

The implementation may accept other characters as an extension.

insert two sentences:

The optstring argument can optionally start with a <plus-sign> ('+'), which shall have no effect on behavior in a conforming environment, or a <hyphen-minus> ('-'), which shall have the effects documented below. If a <plus-sign> or <hyphen-minus> occurs anywhere besides the first character of optstring, the behavior is unspecified.

At line 34828, change:

matches a character in optstring, if there is one that matches.

to:

matches a character in optstring (excluding an optional leading <plus-sign> or <hyphen-minus>), if there is one that matches.

At line 34836, change the paragraph:

If, when getopt( ) is called:

to:

If, when getopt( ) is called, the first character of optstring is <hyphen-minus> ('-'), and argv[optind] is either the string "-" or does not start with '-', then getopt( ) shall set the variable optarg to the operand at argv[optind], then increment the variable optind by 1, and return 1. Otherwise, if:

At line 34843, replace:

If getopt( ) encounters an option character that is not contained in optstring, it shall return the <question-mark> ('?') character. If it detects a missing option-argument, it shall return the <colon> character (':') if the first character of optstring was a <colon>, or a <question-mark> character ('?') otherwise. In either case, getopt( ) shall set the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0 and the first character of optstring is not a <colon>, getopt( ) shall also print a diagnostic message to stderr in the format specified for the getopts utility.

with:

If getopt( ) encounters a <colon> as an option character, or encounters an option character that is not contained in optstring after an optional leading <plus-sign> or <hyphen-minus>, it shall return the <question-mark> ('?') character. If it detects a missing option-argument, it shall return the <colon> character (':') if the first character of optstring after an optional <plus-sign> or <hyphen-minus> was a <colon>, or a <question-mark> character ('?') otherwise. In either case, getopt( ) shall set the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0, and either the first character of optstring after an optional <plus-sign> or <hyphen-minus> is not a <colon>, getopt( ) shall also print a diagnostic message to stderr in the format specified for the getopts utility.

Replace two paragraphs at line 34853:

A <colon> (':') shall be returned if getopt( ) detects a missing argument and the first character of optstring was a <colon> (':').

A <question-mark> ('?') shall be returned if getopt( ) encounters an option character not in optstring or detects a missing argument and the first character of optstring was not a <colon> (':').

with three:

A <colon> (':') shall be returned if getopt( ) detects a missing argument and the first character of optstring after an optional <plus-sign> or <hyphen-minus> was a <colon> (':').

A <question-mark> ('?') shall be returned if getopt( ) encounters a <colon> as an option character, encounters an option character not in optstring, or detects a missing argument and the first character of optstring after an optional <plus-sign> or <hyphen-minus> was not a <colon> (':').

The value 1 shall be returned if getopt( ) encounters an operand that is not an option and the first character of optstring was <hyphen-minus> ('-').

At line 34988, replace:

The special significance of a <colon> as the first character of optstring makes getopt( ) consistent with the getopts utility.

with:

The special significance of a <colon> as the first character of optstring after an optional <plus-sign> or <hyphen-minus> makes getopt( ) consistent with the getopts utility.

Add two new paragraphs to the RATIONALE, after line 34992:

In some non-conforming environments, the use of a leading <plus-sign> in optstring forces getopt( ) to behave in a conforming way, when it would otherwise have non-conforming behavior. Its use has been standardized to allow applications to be written that can guarantee behavior consistent with this specification even in an otherwise non-conforming environment. If both <plus-sign> and <colon> are used at the beginning of optstring, the <plus-sign> must be first.

The use of a leading <hyphen-minus> in optstring allows getopt( ) to be used for applications that parse options interspersed with operands. Although this use is counter to Guidelines 9 and 11 of XBD Utility Syntax Guidelines, it allows getopt( ) to be used in the implementation of standard utilities (such as m4) that are exempt from these two guidelines. Application writers are discouraged from using a leading <hyphen-minus> in new applications. If both <hyphen-minus> and <colon> are used at the beginning of optstring, the <hyphen-minus> must be first.
(0000316)
eblake (manager)
2009-12-03 16:02

The following additional changes are needed to comment 315 if we would rather invent a new constant for returning operands via a leading '-', rather than codifying existing practice of returning 1, since that risks collision with a weirdnix character encoding that uses the value of 1 for an alphanumeric character.

In XCU:
At line 15033, add a new paragraph (unistd Constants for Functions):

The <unistd.h> header shall define the following symbolic constant for use with getopt( ):
GETOPT_OPERAND Value returned when getopt( ) detects a non-option but has not finished parsing for options. This symbol shall be defined to a positive value of a non-whitespace control character.

In XSH:
At line 34836, change the proposed wording within the new paragraph:

...then increment the variable optind by 1, and return 1.

to:

...then increment the variable optind by 1, and return GETOPT_OPERAND.

At line 34853, change the proposed wording of the new paragraph:

The value 1 shall be returned if getopt( ) encounters an operand that is not an option and the first character of optstring was <hyphen-minus> ('-').

to:

The value GETOPT_OPERAND shall be returned if getopt( ) encounters an operand that is not an option and the first character of optstring was <hyphen-minus> ('-').

At line 34992, add the following sentence at the end of the proposed new paragraph about <hyphen-minus>:

Traditional implementations used the value of 1 for GETOPT_OPERAND when returning a value that indicates that optarg was set to a non-option argument; however, the standard only guarantees that GETOPT_OPERAND will be a positive value distinct from any valid option character.
(0000326)
nick (manager)
2009-12-10 16:58

At the Dec 10 teleconference, the general concensus was to go for the original "Desired Action" (just add the leading +), but there is also the need for an additional note to explain the asymmetry with the getopt command/utility.

ACTION: New words for Application Usage describing the asymmetry with the getopt utility needs to be added.
(0000329)
eblake (manager)
2009-12-11 13:31
edited on: 2010-01-07 16:23

Another attempt, incorporating the action from the Dec 10 teleconference:


At line 34820, before:

The implementation may accept other characters as an extension.

insert one sentence:

The optstring argument can optionally start with a <plus-sign> ('+'), which shall have no effect on behavior in a conforming environment. If a <plus-sign> occurs anywhere besides the first character of optstring, the behavior is unspecified.

At line 34828, change:

matches a character in optstring, if there is one that matches.

to:

matches a character in optstring (excluding an optional leading <plus-sign>), if there is one that matches.

At line 34843, replace:

If getopt( ) encounters an option character that is not contained in optstring, it shall return the <question-mark> ('?') character. If it detects a missing option-argument, it shall return the <colon> character (':') if the first character of optstring was a <colon>, or a <question-mark> character ('?') otherwise. In either case, getopt( ) shall set the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0 and the first character of optstring is not a <colon>, getopt( ) shall also print a diagnostic message to stderr in the format specified for the getopts utility.

with:

If getopt( ) encounters a <colon> as an option character, or encounters an option character that is not contained in optstring after an optional leading <plus-sign>, it shall return the <question-mark> ('?') character. If it detects a missing option-argument, it shall return the <colon> character (':') if the first character of optstring after an optional <plus-sign> was a <colon>, or a <question-mark> character ('?') otherwise. In either case, getopt( ) shall set the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0, and the first character of optstring after an optional <plus-sign> is not a <colon>, getopt( ) shall also print a diagnostic message to stderr in the format specified for the getopts utility.

Replace two paragraphs at line 34853:

A <colon> (':') shall be returned if getopt( ) detects a missing argument and the first character of optstring was a <colon> (':').

A <question-mark> ('?') shall be returned if getopt( ) encounters an option character not in optstring or detects a missing argument and the first character of optstring was not a <colon> (':').

with:

A <colon> (':') shall be returned if getopt( ) detects a missing argument and the first character of optstring after an optional <plus-sign> was a <colon> (':').

A <question-mark> ('?') shall be returned if getopt( ) encounters a <colon> as an option character, encounters an option character not in optstring, or detects a missing argument and the first character of optstring after an optional <plus-sign> was not a <colon> (':').

Add two new paragraphs to the RATIONALE, after line 34992:

In some non-conforming environments, the use of a leading <plus-sign> in optstring forces getopt( ) to behave in a conforming way, when it would otherwise have non-conforming behavior. Its use has been standardized to allow applications to be written that can guarantee behavior consistent with this specification even in an otherwise non-conforming environment. If both <plus-sign> and <colon> are used at the beginning of optstring, the <plus-sign> must be first.

Note that the use of a leading <plus-sign> in optstring is only standardized for getopt( ). Use of a <plus-sign> is intentionally left unspecified for the getopts utility, where historical implementations did not require a leading <plus-sign> for conforming behavior, and because some historical getopts implementations used a leading <plus-sign> for a different extension.

At line 90718, insert a new paragraph to the getopts RATIONALE:

Although a leading <plus-sign> in optstring is required to have no effect on the behavior of getopt( ), this specification intentionally allows implementations of the getopts utility to use a leading <plus-sign> as an extension that alters behavior.


- Issue History
Date Modified Username Field Change
2009-12-03 03:38 eblake New Issue
2009-12-03 03:38 eblake Status New => Under Review
2009-12-03 03:38 eblake Assigned To => ajosey
2009-12-03 03:38 eblake Name => Eric Blake
2009-12-03 03:38 eblake Organization => NA
2009-12-03 03:38 eblake User Reference => ebb.getopt2
2009-12-03 03:38 eblake Section => getopt
2009-12-03 03:38 eblake Page Number => 1040
2009-12-03 03:38 eblake Line Number => 34822
2009-12-03 14:03 eblake Note Added: 0000315
2009-12-03 16:02 eblake Note Added: 0000316
2009-12-10 16:58 nick Note Added: 0000326
2009-12-11 13:31 eblake Note Added: 0000329
2010-01-07 16:23 Don Cragun Note Edited: 0000329
2010-01-07 16:24 Don Cragun Interp Status => ---
2010-01-07 16:24 Don Cragun Final Accepted Text => See Note: 0000329
2010-01-07 16:24 Don Cragun Status Under Review => Resolved
2010-01-07 16:24 Don Cragun Resolution Open => Accepted As Marked
2010-09-09 15:41 Don Cragun Tag Attached: issue8
2010-09-09 15:42 Don Cragun Resolution Accepted As Marked => Future Enhancement
2011-07-08 16:01 Don Cragun Resolution Future Enhancement => Accepted As Marked
2019-12-20 12:09 geoffclare Status Resolved => Applied
2023-12-14 09:47 geoffclare Relationship added related to 0001784


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker