Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[filesystems] Fix "Filesystem library edits/issues" #3874

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

cpplearner
Copy link
Contributor

@cpplearner cpplearner commented Mar 16, 2020

Addresses #1246

I copied the list of issues from #1246, and added my response to each item.

Of all 40 issues,

  • 11 are addressed in this PR (marked as "Will be addressed by" + corresponding commit message)
  • 13 need no action in my opinion (marked as "Suggest NAD") There might be room for wording improvement, but I think it's fine to leave them as is.
  • 9 have already been fixed (marked as "Suggest Resolved")
  • 7 might need further action (marked as "Needs guidance") Note that two of them seem to be the manifest of the same underlying problem.

To maintainers: Since there are a lot of issues to review, I've added a checkbox before my response to each item. If you are OK with my response, please check the box to indicate that it has been reviewed.


e* In 27.10.2.1 of WD [fs.conform.9945],
Inconsistent naming for section. What is 9945?
Section name should be [fs.conform.posix]?

  • Will be addressed by 977b2df "Rename stable label from [fs.conform.9945] to [fs.conform.posix]".

e* In 27.10.4 of WD [fs.definitions],
Should definitions begin with lower case and not end with period as
in [intro.defs]? If so, how to handle defs with multiple sentences?

  • Suggest Resolved: [fs.definitions] has been replaced by inline definitions.

e* In 27.10.4.18 of WD [fs.def.pathres],
Include version in reference "section 4.11, Pathname resolution".?

  • Needs guidance: The version is stated in [intro.refs], but maybe the reference should be tracked somehow, so it will get updated when the spec is changed to refer to a newer version of POSIX standard in the future?

e* In 27.10.4.18 of WD [fs.def.pathres],
Example should be a note.

  • Needs guidance: The spec is inconsistent in the use of Example and Note for describing POSIX behavior.

e* In 27.10.4.19 of WD [fs.def.relative-path],
Note should be an example because '.' and '..' are
only otherwise meaningful as filenames in the generic path grammar.
=> \enterexample Pathnames .'' and ..'' are relative paths
on POSIX and Windows systems.
\examplenote

  • Will be addressed by 07006c1 "[fs.class.path] Meaning of '.' and '..' in native format is OS-dependent".

e* In 27.10.4.20 of WD [fs.def.symlink],
Wording in definition is unclear.

  • Needs guidance: The wording ("the string stored by the file is used to modify the pathname resolution") is very ambiguous. It might be read as allowing symlinks to arbitrarily modify the resolution, which I think is not desirable (nor intended, according to the note immediately following it). Might need normative change.

i* In 27.10.6 of WD [fs.filesystem.syn],
No details for "size_t hash_value(const path& p) noexcept;"

  • Suggest NAD: The description in [fs.path.nonmember], while short, seems to provide enough information.

e* In 27.10.8p2 of WD [class.path],
In "value_type is a typedef for the operating system dependent
encoded character type used to represent pathnames",
is the "character type" the "native encoding" in ([fs.def.native.encode])?
Or is it the character type used to form a NTCTS ([fs.def.ntcts])?
Add reference to clarify the "encoded character type":
=> "character type used to represent pathnames,
where the encoding is the native encoding ([fs.def.native.encode])."
or => "character type used to form a NTCTS ([fs.def.ntcts])"
Same for "encoding"s throughout - which ones are we talking about?

  • Suggest NAD: It feels redundant to mention "native encoding" when the definition already says "operating system dependent encoded [...] used to represent pathnames".

i* In 27.10.8.1p1 of WD [path.generic],
Statement doesn't make sense when talking about a grammar term.
Should a new term "directory separator" be defined for this?
References to grammar term directory-separator throughout should be checked
to see if they should be replaced with this new term.

  • Will be addressed by c0cdfd8 "[filesystems] Un-grammarterm 'directory-separator character'".

i* In 27.10.8.2.1p1 of WD [path.fmt.cvt],
bullet 1.1:
Note says "The generic format is acceptable as a native path"
but this is not true on Windows because the grammar includes
'/' as a possible directory-separator
('d1/d2' is not a valid path on Windows).
=> "A native path can be parsed by the generic grammar"

  • Suggest Resolved: The note now says "on POSIX-based operating systems".

e* In 27.10.8.2.1p4 of WD [path.fmt.cvt],
Wording is inconsistent in use of "regular file" vs. "non-directory file" throughout spec, and "regular file" is never defined.
Should it be defined to be a file that is not a directory, or POSIX S_ISREG?
Inconsistent use of "directory path" .vs "directory" throughout.

  • Will be addressed by bda5e32 "[fs.path.fmt.cvt] Make a sentence consistent with the rest of spec" (and fixed up in 41c63b8). Other places either do not care the difference between "regular file" and "non-directory file", or rely on [fs.op.status], which says "as if by POSIX S_ISREG". Outside [fs.path.fmt.cvt], "directory path" is only used in the description of temp_directory_path.

i* In 27.10.8.2.2p1 of WD [path.type.cvt],
In "For member function arguments that take character sequences",
these are the functions that take Source arguments, right?
Where is that stated?
What about the non-member functions?

  • Suggest NAD: Each function that needs this conversion links back to this section. I think it is clear enough. See Richard's comment. Will be addressed by 1eb2393 "[fs.path.type.cvt] Change 'arguments' to 'parameters'".

e* In 27.10.8.2.2p2 of WD [path.type.cvt],
what are "source characters"?
=> "any of the characters in the argument or return value"?

  • Will be addressed by 0730d2c "[fs.path.type.cvt] Rephrase 'source characters'".

e* In 27.10.8.3p1 of WD [path.req],
What's an "effective range"? (used throughout)

  • Will be addressed by 9b9da1c "[fs.path.req] Remove 'shall' in local definition of 'effective range'". (It's a local definition used to describe path's constructors.)

e* In 27.10.8.3p2 of WD [path.req],
In "the value types above and their encodings", what encodings?
(was "these value types and ...")

  • Will be addressed by 88f2e8f "[fs.path.req] Remove 'and their encodings'".

e* In 27.10.8.4.1p6 of WD [path.construct],
Bullet 6.2:
What "current narrow encoding"?
=> "current native narrow encoding~(\ref{fs.def.native.encode})"?
Check uses elsewhere.
Be consistent throughout in uses of
"[current] [native] [narrow/wide] encoding"

  • Will be addressed by 4ff0566 "[fs.path.construct] Consistently use 'native ordinary encoding'".

e* In 27.10.8.4.5p11 of WD [path.modifiers],
Bullet 11.1: what's "a dot character"?
Be consistent in use of "dot" vs. "period" vs. "'.'",
and use /dot/ when referring to /filename/ in generic grammar.

  • Will be addressed by 9f118f8 "[fs.path.modifiers] Change 'dot character' to 'period character'".

e* In 27.10.8.4.6 of WD [path.native.obs],
Section is WD [path.native.objs] in paper but [path.native.obs] in WD. Ok?

  • Suggest NAD: 'objs' is apparently a typo. I think there's nothing to change.

e* In 27.10.8.4.7p2 of WD [path.generic.obs],
The reference to 27.10.8.1 is to the generic pathname format, but it doesn't say how to "return strings formatted according to" this generic pathname format".
Where is this (re)formatting described? [path.fmt.cvt] doesn't appear to to it.
Same with "reformatted according to" in 27.10.8.4.7p6 of WD [path.generic.obs].

  • Suggest NAD: I think it's mentioned in [fs.path.fmt.cvt]: "Pathnames are converted as needed between the generic and native formats in an operating-system-dependent manner."

e* In 27.10.8.4.8p2 of WD [path.compare],
What "elements"?

  • Suggest NAD: I'm not sure how to rephrase "the elements of this->relative_path()" to make it clearer. But I'm personally fine with the current form.

e* In 27.10.8.4.9p5 of WD [path.decompose],
How does one "compose" a path from pathname?
What if /root-path/ is empty?
I think we need to say something like:
=> "A path P, where P is composed from the |pathname| as follows:
If !empty(), let R be the /pathname/ of |pathname|. Then

  • if R contains a /root-path/, P is the substring of |pathname|
    starting with the first /filename/ in R after the /root-path/,

  • otherwise, P is the substring of |pathname|
    starting with the first /filename/ in R.
    Otherwise, P = path()."

  • Needs guidance: The behavior of relative_path when this has no root-path seems underspecified. Is this editorial? If so, the wording here needs to be rebased.

e* In 27.10.8.4.9p9 of WD [path.decompose],
Use grammar term for /dot/ and /dot-dot/:
"if filename() contains a period but does not
consist solely of one or two periods"
=> "if filename() contains a period but is not /dot/ or /dot-dot/"
Same for other Returns throughout paper.
Fix consistency in use of 'period' vs. 'dot' vs. '.' throughout.

  • Suggest NAD: dot and dot-dot are no longer grammar terms.

e* In 27.10.8.4.9p11 of WD [path.decompose],
What's an "empty path"? Is it the path "" or an empty path object?
Check 3 uses throughout spec.
Also fix inconsistencies with "\tcode{path} object" vs. "path object"

  • Suggest Resolved: [fs.path.decompose] no longer has any mention of "empty path", and the spec seems to consistently use "\tcode{path} object".

e* In 27.10.8.5p4 of WD [path.itr],
Bullet 4.4: clarify "trailing non-root /slash/ characters".
What about the /preferred-separator/?
Check uses of /slash/ for cases where /directory-separator/ should be used.

  • Suggest Resolved: slash is no longer a grammar term.

i* In 27.10.13p7 of WD [class.directory_iterator],
What are "the current (dot) and parent (dot-dot) directories"?

  • Will be addressed by be3f357 "[fs.class.directory.iterator] Turn imprecise and redundant statement into a note". (I think the statement is redundant because dot and dot-dot are not files in the directory.)

e* In 27.10.13.1p21 of WD [directory_iterator.members],
"the current depth" is described in a note which is non-normative.
=> "The current depth of the directory tree being traversed, where
the initial directory passed to the constructor is at depth 0,
it's immediate subdirectories are at depth 1, and so forth."

  • Suggest NAD: The iteration done by recursive_directory_iterator can be described more precisely, with more defined terms. But the current form seems good enough. Update: see Richard's comment

e* In 27.10.15.2p1 of WD [fs.op.canonical],
"an absolute path that has no symbolic link, ".", or ".." elements."
=> "a canonical path (27.10.4.2 [fs.def.canonical.path])"

  • Suggest Resolved: The definition of canonical path does not exist any more.

e* In 27.10.15.3p3 of WD [fs.op.copy],
What is meant by "Before the first use of f and t"?
=> "Let f and t be as follows"?
Bullet 3.1: "if needed"? How to know when auto t is needed?

  • Needs guidance: This is a mess. Someone more knowledgeable than me needs to take a look at it. Update: I think the intent is to avoid initializing t if e.g. is_regular_file(f) is true, but implementations (libc++/libstdc++/MSVC STL) all initialize t before testing is_regular_file(t). See also LWG 3057.

e* In 27.10.15.3p4 of WD [fs.op.copy],
"error is reported" => "error is handled"?
Errors are handled, not reported.
Same throughout FS.

  • Suggest NAD: Is this a problem?

e* In in 27.10.15.19 of WD [fs.op.is_empty],
|s| is determined by status(p, ec),
but in 27.10.15.13 of WD [fs.op.equivalent],
|s1| and |s2| are determined by status(p1) and status(p2).
Should both be calling the ec variant or not?
Note that both is_empty and equivalent have both the ec and non-ec variants.
(FYI: the details of these funcs have since been rewritten to introduce
s1, s2 and s so they apply to the whole function
since otherwise they have no meaning outside the Effects pnum).

  • Suggest Resolved: [fs.op.is.empty] now says "as if by status(p) or status(p, ec), respectively".

e* In 27.10.15.26p2 of WD [fs.op.permissions],
What are "effective permissions bits"?

  • Suggest Resolved: [fs.op.permissions] has been completely redone.

i* In 27.10.15.28 of WD [fs.op.remove],
Do Postconditions only apply if the function succeeded?
If not, what if p is a directory? Then p could not
be removed and the Postcondition would not hold.
Also, the Returns would return true if p is a directory (because p exists),
even though p was not removed.

  • Needs guidance: Note that the function might return normally even if an error is reported. Update: see Richard's comment

e* In 27.10.15.29p1 of WD [fs.op.remove_all],
Effects assumes p is a directory - must it be?
If not:
=> "Same as remove() ([fs.op.remove]), except that if p is a directory,
also recursively deletes the contents of p."
If so: add \requires.

  • Will be addressed by 32c8862 "[fs.op.remove.all] Clarify the effect when p is not a directory".

e* In 27.10.15.33p9 of WD [fs.op.status],
Unclear. How to reword?

  • Suggest NAD: There's room for improvement, but I'm personally fine with the current form. Update: see Richard's comment. Cleanup done in "[fs.op.status] Cleanup"

e* In 27.10.15.36p6 of WD [fs.op.system_complete],
Why is this an example? Should be a Note?

  • Needs guidance: The spec is inconsistent in the use of Example and Note when describing POSIX behavior.

i* In 27.10.8.4.9p2 of WD [path.decompose],
What was intended in root_directory()?
As worded, root_directory() will only ever return "" or path().
Note that /root-directory/ is /directory-separator/ in the grammar.
So the /root-directory/ of "/bla/f.cpp" is "/", and the /root-directory/ of "bla/f.cpp" is "", and any leading "/" is removed in p3.
p3 also makes no sense since /name/ can't be part of the /root-directory/.

  • Suggest Resolved: LWG 2667 removed p3.

i* In 27.10.8.6.1p1 of WD [path.io],
Should "Equivelent to" be added after "Effects:"?
If "Equivelent to" isn't correct, is there something else that can be added?
It is odd to have "Effects:" with only code - what is the relationship between calling the function call and the code?
See similar "Effects:" throughout the feature.

  • Suggest Resolved: LWG 2680 added "Equivalent to".

i* In 27.10.15.9 of WD [fs.op.create_hard_lk],
What should happen if a hardlink is not supported on the OS?
Same for symlinks in 27.10.15.8 of WD [fs.op.create_dir_symlk]
and in 27.10.15.10 of WD [fs.op.create_symlink],
and other unsupported functions.

  • Suggest NAD: This seems to be described in [fs.conform.9945] (being renamed to [fs.conform.posix]): "If an implementation cannot provide any reasonable behavior, the implementation shall report an error as specified in [fs.err.report]." Update: see Richard's comment. Notes are improved in 75d8cc8 "[fs.op.funcs] Clarify the behavior of unsupported functions".

i* In 27.10.4.2 of WD [fs.def.canonical.path],
Is canonical path supposed to be unique?
If so:
What about c:\path\ vs. \path\ from drive c: on Windows, or UCN paths?
What about substituted drives on Windows?
Suppose we do this on Windows:
subst g: c:\mydir
g:\foo.cpp and c:\mydir\foo.cpp are not canonical.
I believe the wording would treat them as different files, correct?
Please give examples of canonical paths.

  • Suggest NAD: [fs.def.canonical.path] has been removed.

i* "resolves" and "resolves to" are never defined
What's it mean to "resolve" a directory, or what a directory "resolves to"?
Suppose we do this on Windows:
subst g: c:\mydir
g:\foo.cpp and c:\mydir\foo.cpp are not canonical.
Do they "resolve" to the same file?
Please define "resolves" and "resolves to", and give examples.

  • Suggest NAD: Per [fs.op.equivalent]: "Two paths are considered to resolve to the same file system entity if two candidate entities reside on the same device at the same location." The definition of "pathname resolution" says that it's an operating system dependent mechanism. I personally think it's good enough.

@zygoloid
Copy link
Member

i* In 27.10.8.2.2p1 of WD [path.type.cvt],
In "For member function arguments that take character sequences",

This should at least be changed to say "parameters" instead of "arguments". If we really mean "for member function parameters whose type is a template parameter Source", we should explicitly say that like we do in [algorithms.requirements]/4.

@zygoloid
Copy link
Member

e* In 27.10.13.1p21 of WD [directory_iterator.members],
"the current depth" is described in a note which is non-normative.

I think we need a fix here. There is no adequate normative specification for depth().

@zygoloid
Copy link
Member

i* In 27.10.15.28 of WD [fs.op.remove],
Do Postconditions only apply if the function succeeded?

Beyond that, these postconditions are impossible for an implementation to guarantee due to the possibility of FS races. LWG considered a similar issue (http://cplusplus.github.io/LWG/lwg-closed.html#2630) and marked it NAD; we should report it again and ask them to actually fix it this time. In any case, not editorial.

@zygoloid
Copy link
Member

e* In 27.10.15.33p9 of WD [fs.op.status],
Unclear. How to reword?

Some simple cleanups would help a bit:

  • Reorder ec overload before non-ec overload
  • Non-ec overload: replace "As if" with "Equivalent to" and delete the "Returns:" and "Throws:". (Keep the note.)

Otherwise it seems fine to me.

@zygoloid
Copy link
Member

i* In 27.10.15.9 of WD [fs.op.create_hard_lk],
What should happen if a hardlink is not supported on the OS?
Same for symlinks in 27.10.15.8 of WD [fs.op.create_dir_symlk]
and in 27.10.15.10 of WD [fs.op.create_symlink],
and other unsupported functions.

We have a note saying "Some operating systems do not support hard links", which seems like an incomplete thought and leaves the reader hanging -- what happens in that case? Finishing the note by saying "In such cases, an error is reported as specified in [fs.conform.posix]." would help.

@cpplearner
Copy link
Contributor Author

I think we need a fix here. There is no adequate normative specification for depth().

I think the problem is, the iteration is not precisely described. E.g. [fs.rec.dir.itr.members] says "iteration over the parent directory resumes", "recursively iterated into", "cease iteration of the directory currently being iterated over, and continue iteration over the parent directory". These need to be defined more precisely for depth() to get an accurate definition.

(Lifting the note to normative text doesn't work in my opinion, because it just adds more undefined terms, e.g. what does "immediate subdirectories" mean in the presence of symlinks?)

@zygoloid zygoloid requested a review from jwakely October 17, 2020 23:32
@zygoloid zygoloid added the needs rebase The pull request needs a git rebase to resolve merge conflicts. label Oct 17, 2020
If the native format requires paths for directories to be formatted
differently from paths for other types of files,
the path shall be treated as a path to a directory if and only if
its last element is a \grammarterm{directory-separator}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear whether the subject of "its last element" is the native format or the path. I assume it's the former because except for a root-directory, an element of a path is never a directory-separator. I think this should say "the native format's last element" or "the last character of the native format" instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pre-existing.

I think "its" refers to the textual representation of the path before it's converted to the native format.

For example, for a hypothetical implementation on OpenVMS, it might be the case that

path("FOO/BAR/", path::format::generic_format).native() // returns "[FOO.BAR]"
path("FOO/BAR",  path::format::generic_format).native() // returns "[FOO]BAR"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, old Boost.Filesystem documentation says:

If the native format requires regular file paths and directory paths to be formatted differently, the implementation shall determine which format to use according to whether or not the last element of the generic format string is a separator. [Example: On OpenVMS, a path constructed from "/cats/jane" would considered a regular file path, and have a native format of "[CATS]JANE", while a path constructed from "/cats/jane/" would be considered a directory path, and have a native format of "[CATS.JANE]". --end example] [Note: POSIX and Windows use the same native format for both regular file and directory pathnames, so this paragraph does not apply to them. --end note]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "last character of the generic format string" would be correct and unambiguous.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

If the encoding being converted to has no representation for source
characters, the resulting converted characters, if any, are unspecified.
If the encoding being converted to has no representation for
any of the characters in the argument or return value,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems ambiguous. No representation "for any of the characters" could mean that every character has no representation, or at least one of the characters has no representation. The latter is intended.

Maybe something like "if any of the characters in the argument or return value has no representation in the destination encoding", or just replace "any" with "one or more".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -11440,7 +11440,7 @@
Conformance is specified in terms of behavior. Ideal behavior is not always
implementable, so the conformance subclauses take that into account.

\rSec3[fs.conform.9945]{POSIX conformance}
\rSec3[fs.conform.posix]{POSIX conformance}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to change this now that we've published two standards with that stable name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. Leaving it up to the maintainers.

Pathnames ``.''\ and ``..''\ are relative paths.
\end{note}
\begin{example}
Pathnames ``.''\ and ``..''\ are relative paths on POSIX and Windows systems.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the grammar they are always relative paths.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this sentence applies to the native format, whose grammar is OS-dependent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it? We haven't introduced any concept of generic or native formats at this point.

[fs.path.generic] defines the dot and dot-dot filenames, although it doesn't say what it means for them to occur as a complete path (not just a filename). I suppose some OS could require a prefix like [rel].. to make a path relative.

Copy link
Contributor Author

@cpplearner cpplearner Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preceding sentence ([fs.class.path.general]/4) says

The elements of a path that determine if it is relative are operating system dependent.

So it does look like the standard allows an OS to treat . or .. as a non-relative path.

otherwise it shall be treated as a path to a regular file.
If the native format requires paths for directories to be formatted
differently from paths for other types of files,
the path shall be treated as a path to a directory if and only if
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"to a directory" or "for a directory"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving it up to the maintainers.

@jensmaurer jensmaurer removed the needs rebase The pull request needs a git rebase to resolve merge conflicts. label Jun 20, 2021
@wg21bot wg21bot added the needs rebase The pull request needs a git rebase to resolve merge conflicts. label Oct 24, 2021
Pathnames ``.''\ and ``..''\ are relative paths.
\end{note}
\begin{example}
Pathnames ``.''\ and ``..''\ are relative paths on POSIX and Windows systems.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it? We haven't introduced any concept of generic or native formats at this point.

[fs.path.generic] defines the dot and dot-dot filenames, although it doesn't say what it means for them to occur as a complete path (not just a filename). I suppose some OS could require a prefix like [rel].. to make a path relative.

@@ -13011,7 +13011,7 @@

\begin{ncbnf}
\nontermdef{filename}\br
\textnormal{non-empty sequence of characters other than \grammarterm{directory-separator} characters}
\textnormal{non-empty sequence of characters other than directory separator characters}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a "directory separator character" if not a directory-separator ? I think if you want to make this change (here and elsewhere) we need a definition of "directory separator character", don't we?

That's what the original comment suggested:

Should a new term "directory separator" be defined for this?

Without actually defining it, this makes the spec worse, by replacing the inappropriate use of a grammar term in the wrong context with a completely undefined term.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A directory-separator is a sequence of preferred-separators and fallback-separators. A "directory separator character" should probably be an element of a directory-separator, i. e. a preferred-separator or a fallback-separator.

Would adding a definition of "directory separator character" be editorial? If "directory separator character" is defined, should the definition of preferred-separator be changed to not mention "directory separator character", in order to avoid seemingly circular definition?

draft/source/iostreams.tex

Lines 13421 to 13424 in 88e574e

\begin{ncbnf}
\nontermdef{preferred-separator}\br
\textnormal{operating system dependent directory separator character}
\end{ncbnf}

source/iostreams.tex Outdated Show resolved Hide resolved
Co-authored-by: Jonathan Wakely <github@kayari.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs rebase The pull request needs a git rebase to resolve merge conflicts.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants