Skip to content

Commit 52494df

Browse files
8290845: Consider an alternative item separator for multi-item option values
Reviewed-by: prappo
1 parent c56c69e commit 52494df

File tree

6 files changed

+81
-52
lines changed

6 files changed

+81
-52
lines changed

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties

+9-6
Original file line numberDiff line numberDiff line change
@@ -531,14 +531,16 @@ doclet.usage.link-platform-properties.description=\
531531
Link to platform documentation URLs declared in properties file at <url>
532532

533533
doclet.usage.excludedocfilessubdir.parameters=\
534-
<name>:...
534+
<name>,<name>,...
535535
doclet.usage.excludedocfilessubdir.description=\
536-
Exclude any doc-files subdirectories with given name
536+
Exclude any doc-files subdirectories with given name.\n\
537+
':' can also be used anywhere in the argument as a separator.
537538

538539
doclet.usage.group.parameters=\
539-
<name> <g1>:<g2>...
540+
<name> <g1>,<g2>...
540541
doclet.usage.group.description=\
541-
Group specified elements together in overview page
542+
Group specified elements together in overview page.\n\
543+
':' can also be used anywhere in the argument as a separator.
542544

543545
doclet.usage.legal-notices.parameters=\
544546
'default' | 'none' | <directory>
@@ -552,9 +554,10 @@ doclet.usage.nodeprecated.description=\
552554
Do not include @deprecated information
553555

554556
doclet.usage.noqualifier.parameters=\
555-
<name1>:<name2>:...
557+
<name1>,<name2>,...
556558
doclet.usage.noqualifier.description=\
557-
Exclude the list of qualifiers from the output
559+
Exclude the list of qualifiers from the output.\n\
560+
':' can also be used anywhere in the argument as a separator.
558561

559562
doclet.usage.nosince.description=\
560563
Do not include @since information

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java

+17-16
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,13 @@ private void initTagletManager(Set<List<String>> customTagStrs) {
471471
tagletManager.addCustomTag(args.get(1), fileManager);
472472
continue;
473473
}
474-
List<String> tokens = tokenize(args.get(1), TagletManager.SIMPLE_TAGLET_OPT_SEPARATOR, 3);
474+
/* Since there are few constraints on the characters in a tag name,
475+
* and real world examples with ':' in the tag name, we cannot simply use
476+
* String.split(regex); instead, we tokenize the string, allowing
477+
* special characters to be escaped with '\'. */
478+
List<String> tokens = tokenize(args.get(1), 3);
475479
switch (tokens.size()) {
476-
case 1:
480+
case 1 -> {
477481
String tagName = args.get(1);
478482
if (tagletManager.isKnownCustomTag(tagName)) {
479483
//reorder a standard tag
@@ -484,18 +488,16 @@ private void initTagletManager(Set<List<String>> customTagStrs) {
484488
heading.setCharAt(0, Character.toUpperCase(tagName.charAt(0)));
485489
tagletManager.addNewSimpleCustomTag(tagName, heading.toString(), "a");
486490
}
487-
break;
491+
}
488492

489-
case 2:
493+
case 2 ->
490494
//Add simple taglet without heading, probably to excluding it in the output.
491495
tagletManager.addNewSimpleCustomTag(tokens.get(0), tokens.get(1), "");
492-
break;
493496

494-
case 3:
497+
case 3 ->
495498
tagletManager.addNewSimpleCustomTag(tokens.get(0), tokens.get(2), tokens.get(1));
496-
break;
497499

498-
default:
500+
default ->
499501
messages.error("doclet.Error_invalid_custom_tag_argument", args.get(1));
500502
}
501503
}
@@ -505,18 +507,17 @@ private void initTagletManager(Set<List<String>> customTagStrs) {
505507
}
506508

507509
/**
508-
* Given a string, return an array of tokens. The separator can be escaped
509-
* with the '\' character. The '\' character may also be escaped by the
510-
* '\' character.
510+
* Given a string, return an array of tokens, separated by ':'.
511+
* The separator character can be escaped with the '\' character.
512+
* The '\' character may also be escaped with the '\' character.
511513
*
512-
* @param s the string to tokenize.
513-
* @param separator the separator char.
514+
* @param s the string to tokenize
514515
* @param maxTokens the maximum number of tokens returned. If the
515516
* max is reached, the remaining part of s is appended
516517
* to the end of the last token.
517-
* @return an array of tokens.
518+
* @return an array of tokens
518519
*/
519-
private List<String> tokenize(String s, char separator, int maxTokens) {
520+
private List<String> tokenize(String s, int maxTokens) {
520521
List<String> tokens = new ArrayList<>();
521522
StringBuilder token = new StringBuilder();
522523
boolean prevIsEscapeChar = false;
@@ -526,7 +527,7 @@ private List<String> tokenize(String s, char separator, int maxTokens) {
526527
// Case 1: escaped character
527528
token.appendCodePoint(currentChar);
528529
prevIsEscapeChar = false;
529-
} else if (currentChar == separator && tokens.size() < maxTokens - 1) {
530+
} else if (currentChar == ':' && tokens.size() < maxTokens - 1) {
530531
// Case 2: separator
531532
tokens.add(token.toString());
532533
token = new StringBuilder();

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java

+2-11
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ public boolean process(String opt, List<String> args) {
419419
new Option(resources, "-excludedocfilessubdir", 1) {
420420
@Override
421421
public boolean process(String opt, List<String> args) {
422-
addToSet(excludedDocFileDirs, args.get(0));
422+
excludedDocFileDirs.addAll(List.of(args.get(0).split("[,:]")));
423423
return true;
424424
}
425425
},
@@ -536,7 +536,7 @@ public boolean process(String opt, List<String> args) {
536536
new Option(resources, "-noqualifier", 1) {
537537
@Override
538538
public boolean process(String opt, List<String> args) {
539-
addToSet(excludedQualifiers, args.get(0));
539+
excludedQualifiers.addAll(List.of(args.get(0).split("[,:]")));
540540
return true;
541541
}
542542
},
@@ -764,15 +764,6 @@ private boolean checkOutputFileEncoding(String docencoding) {
764764
return true;
765765
}
766766

767-
private void addToSet(Set<String> s, String str) {
768-
StringTokenizer st = new StringTokenizer(str, ":");
769-
String current;
770-
while (st.hasMoreTokens()) {
771-
current = st.nextToken();
772-
s.add(current);
773-
}
774-
}
775-
776767
/**
777768
* Add a trailing file separator, if not found. Remove superfluous
778769
* file separators if any. Preserve the front double file separator for

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java

-5
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,6 @@
8585
*/
8686
public class TagletManager {
8787

88-
/**
89-
* The default separator for the simple tag option.
90-
*/
91-
public static final char SIMPLE_TAGLET_OPT_SEPARATOR = ':';
92-
9388
/**
9489
* All taglets, keyed either by their {@link Taglet#getName() name},
9590
* or by an alias.

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Group.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public Group(BaseConfiguration configuration) {
115115
* @param moduleNameFormList List of the module name formats.
116116
*/
117117
public boolean checkModuleGroups(String groupname, String moduleNameFormList) {
118-
String[] mdlPatterns = moduleNameFormList.split(":");
118+
String[] mdlPatterns = moduleNameFormList.split("[,:]");
119119
if (groupList.contains(groupname)) {
120120
initMessages();
121121
messages.warning("doclet.Groupname_already_used", groupname);
@@ -161,7 +161,7 @@ public boolean checkModuleGroups(String groupname, String moduleNameFormList) {
161161
* @param pkgNameFormList List of the package name formats.
162162
*/
163163
public boolean checkPackageGroups(String groupname, String pkgNameFormList) {
164-
String[] pkgPatterns = pkgNameFormList.split(":");
164+
String[] pkgPatterns = pkgNameFormList.split("[,:]");
165165
if (groupList.contains(groupname)) {
166166
initMessages();
167167
messages.warning("doclet.Groupname_already_used", groupname);

src/jdk.javadoc/share/man/javadoc.1

+51-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.\" Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved.
1+
.\" Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
22
.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
.\"
44
.\" This code is free software; you can redistribute it and/or modify it
@@ -609,6 +609,13 @@ javadoc\ \-docencoding\ "iso\-8859\-1"\ mypackage
609609
.TP
610610
.B \f[CB]\-docfilessubdirs\f[R]
611611
Recursively copies doc\-file subdirectories.
612+
Enables deep copying of doc\-files directories.
613+
Subdirectories and all contents are recursively copied to the
614+
destination.
615+
For example, the directory \f[CB]doc\-files/example/images\f[R] and all of
616+
its contents are copied.
617+
The \f[B]\f[BC]\-excludedocfilessubdir\f[B]\f[R] option can be used to
618+
exclude specific subdirectories.
612619
.RS
613620
.RE
614621
.TP
@@ -625,14 +632,12 @@ For example,
625632
.RS
626633
.RE
627634
.TP
628-
.B \f[CB]\-excludedocfilessubdir\f[R] \f[I]name\f[R]
629-
Excludes any doc files subdirectories with the given name.
630-
Enables deep copying of doc\-files directories.
631-
Subdirectories and all contents are recursively copied to the
632-
destination.
633-
For example, the directory \f[CB]doc\-files/example/images\f[R] and all of
634-
its contents are copied.
635-
There is also an option to exclude subdirectories.
635+
.B \f[CB]\-excludedocfilessubdir\f[R] \f[I]name1\f[R]\f[CB],\f[R]\f[I]name2...\f[R]
636+
Excludes any subdirectories with the given names when recursively
637+
copying doc\-file subdirectories.
638+
See \f[B]\f[BC]\-docfilessubdirs\f[B]\f[R].
639+
For historical reasons, \f[CB]:\f[R] can be used anywhere in the argument
640+
as a separator instead of \f[CB],\f[R].
636641
.RS
637642
.RE
638643
.TP
@@ -648,8 +653,10 @@ Use escape characters for any internal quotation marks within a footer.
648653
.RS
649654
.RE
650655
.TP
651-
.B \f[CB]\-group\f[R] \f[I]namep1\f[R]\f[CB]:\f[R]\f[I]p2\f[R]
656+
.B \f[CB]\-group\f[R] \f[I]name\f[R] \f[I]p1\f[R]\f[CB],\f[R]\f[I]p2...\f[R]
652657
Group the specified packages together in the Overview page.
658+
For historical reasons, \f[CB]:\f[R] can be used as a separator anywhere
659+
in the argument instead of \f[CB],\f[R].
653660
.RS
654661
.RE
655662
.TP
@@ -1004,10 +1011,12 @@ These links are generated by default.
10041011
.RS
10051012
.RE
10061013
.TP
1007-
.B \f[CB]\-noqualifier\f[R] \f[I]name1\f[R]\f[CB]:\f[R]\f[I]name2\f[R]...
1014+
.B \f[CB]\-noqualifier\f[R] \f[I]name1\f[R]\f[CB],\f[R]\f[I]name2...\f[R]
10081015
Excludes the list of qualifiers from the output.
10091016
The package name is removed from places where class or interface names
10101017
appear.
1018+
For historical reasons, \f[CB]:\f[R] can be used anywhere in the argument
1019+
as a separator instead of \f[CB],\f[R].
10111020
.RS
10121021
.PP
10131022
The following example omits all package qualifiers:
@@ -1134,7 +1143,7 @@ snippet, and then searches all the directories in the given list.
11341143
.RS
11351144
.RE
11361145
.TP
1137-
.B \f[CB]\-sourcetab\f[R] \f[I]tablength\f[R]
1146+
.B \f[CB]\-sourcetab\f[R] \f[I]tab\-length\f[R]
11381147
Specifies the number of spaces each tab uses in the source.
11391148
.RS
11401149
.RE
@@ -1162,6 +1171,8 @@ to include a \f[CB]\-tag\f[R] option for every custom tag that is present
11621171
in the source code, disabling (with \f[CB]X\f[R]) those that aren\[aq]t
11631172
being output in the current run.
11641173
The colon (\f[CB]:\f[R]) is always the separator.
1174+
To include a colon in the tag name, escape it with a backward slash
1175+
(\f[CB]\\\f[R]).
11651176
The \f[CB]\-tag\f[R] option outputs the tag heading, \f[I]header\f[R], in
11661177
bold, followed on the next line by the text from its single argument.
11671178
Similar to any block tag, the argument text can contain inline tags,
@@ -1170,7 +1181,35 @@ The output is similar to standard one\-argument tags, such as the
11701181
\f[CB]\@return\f[R] and \f[CB]\@author\f[R] tags.
11711182
Omitting a \f[I]header\f[R] value causes the \f[I]name\f[R] to be the
11721183
heading.
1184+
\f[I]locations\f[R] is a list of characters specifying the kinds of
1185+
declarations in which the tag may be used.
1186+
The following characters may be used, in either uppercase or lowercase:
11731187
.RS
1188+
.IP \[bu] 2
1189+
\f[CB]A\f[R]: all declarations
1190+
.IP \[bu] 2
1191+
\f[CB]C\f[R]: constructors
1192+
.IP \[bu] 2
1193+
\f[CB]F\f[R]: fields
1194+
.IP \[bu] 2
1195+
\f[CB]M\f[R]: methods
1196+
.IP \[bu] 2
1197+
\f[CB]O\f[R]: the overview page and other documentation files in
1198+
\f[CB]doc\-files\f[R] subdirectories
1199+
.IP \[bu] 2
1200+
\f[CB]P\f[R]: packages
1201+
.IP \[bu] 2
1202+
\f[CB]S\f[R]: modules
1203+
.IP \[bu] 2
1204+
\f[CB]T\f[R]: types (classes and interfaces)
1205+
.IP \[bu] 2
1206+
\f[CB]X\f[R]: nowhere: the tag is disabled, and will be ignored
1207+
.PP
1208+
The order in which tags are given on the command line will be used as
1209+
the order in which the tags appear in the generated output.
1210+
You can include standard tags in the order given on the command line by
1211+
using the \f[CB]\-tag\f[R] option with no \f[I]locations\f[R] or
1212+
\f[I]header\f[R].
11741213
.RE
11751214
.TP
11761215
.B \f[CB]\-taglet\f[R] \f[I]class\f[R]

0 commit comments

Comments
 (0)