Skip to content

Commit 2a63f72

Browse files
author
Vladimir Kotal
authored
enforce Universal ctags (#2294)
fixes #2261
1 parent a03217b commit 2a63f72

File tree

13 files changed

+60
-107
lines changed

13 files changed

+60
-107
lines changed

dev/before_install

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
44
sudo apt-get update -qq
5-
sudo apt-get install -qq exuberant-ctags cvs git mercurial cssc bzr subversion monotone rcs rcs-blame python3 python3-pip pep8;
5+
sudo apt-get install -qq cvs git mercurial cssc bzr subversion monotone rcs rcs-blame python3 python3-pip pep8;
66
sudo ./dev/install-bitkeeper.sh
77
sudo pip3 install --upgrade pip
88
sudo pip3 install flake8
@@ -12,3 +12,5 @@ elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
1212
brew upgrade python
1313
pip3 install pep8 flake8
1414
fi
15+
16+
sudo ./dev/install-universal_ctags.sh

dev/install-universal_ctags.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
3+
git clone https://github.com/universal-ctags/ctags.git
4+
cd ctags
5+
./autogen.sh
6+
./configure && make && make install

opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Ctags.java

Lines changed: 24 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ public class Ctags implements Resettable {
5656
private OutputStreamWriter ctagsIn;
5757
private BufferedReader ctagsOut;
5858
private static final String CTAGS_FILTER_TERMINATOR = "__ctags_done_with_file__";
59-
//default: setCtags(System.getProperty("org.opengrok.indexer.analysis.Ctags", "ctags"));
6059
private String binary;
6160
private String CTagsExtraOptionsFile = null;
6261
private int tabSize;
@@ -124,16 +123,15 @@ private void initialize() throws IOException {
124123
command.add(binary);
125124
command.add("--c-kinds=+l");
126125

127-
if (env.isUniversalCtags()) {
128-
command.add("--langmap=clojure:+.cljs");
129-
command.add("--langmap=clojure:+.cljx");
126+
command.add("--langmap=clojure:+.cljs");
127+
command.add("--langmap=clojure:+.cljx");
128+
129+
// Workaround for bug #14924: Don't get local variables in Java
130+
// code since that creates many false positives.
131+
// CtagsTest : bug14924 "too many methods" guards for this
132+
// universal ctags are however safe, so enabling for them
133+
command.add("--java-kinds=+l");
130134

131-
// Workaround for bug #14924: Don't get local variables in Java
132-
// code since that creates many false positives.
133-
// CtagsTest : bug14924 "too many methods" guards for this
134-
// universal ctags are however safe, so enabling for them
135-
command.add("--java-kinds=+l");
136-
}
137135
command.add("--sql-kinds=+l");
138136
command.add("--Fortran-kinds=+L");
139137
command.add("--C++-kinds=+l");
@@ -163,10 +161,6 @@ private void initialize() throws IOException {
163161

164162
addHaskellSupport(command);
165163

166-
if (!env.isUniversalCtags()) {
167-
addGoLangSupport(command);
168-
}
169-
170164
//temporarily use our defs until ctags will fix https://github.com/universal-ctags/ctags/issues/988
171165
addClojureSupport(command);
172166

@@ -198,19 +192,14 @@ private void initialize() throws IOException {
198192
processBuilder = new ProcessBuilder(command);
199193

200194
ctags = processBuilder.start();
201-
ctagsIn = env.isUniversalCtags() ? new OutputStreamWriter(
202-
ctags.getOutputStream(), StandardCharsets.UTF_8) :
203-
new OutputStreamWriter(ctags.getOutputStream());
204-
ctagsOut = new BufferedReader(env.isUniversalCtags() ?
205-
new InputStreamReader(ctags.getInputStream(),
206-
StandardCharsets.UTF_8) : new InputStreamReader(
207-
ctags.getInputStream()));
195+
ctagsIn = new OutputStreamWriter(
196+
ctags.getOutputStream(), StandardCharsets.UTF_8);
197+
ctagsOut = new BufferedReader(new InputStreamReader(ctags.getInputStream(),
198+
StandardCharsets.UTF_8));
208199

209200
errThread = new Thread(() -> {
210-
try (BufferedReader error = new BufferedReader(
211-
env.isUniversalCtags() ? new InputStreamReader(
212-
ctags.getErrorStream(), StandardCharsets.UTF_8) :
213-
new InputStreamReader(ctags.getErrorStream()))) {
201+
try (BufferedReader error = new BufferedReader(new InputStreamReader(ctags.getErrorStream(),
202+
StandardCharsets.UTF_8))) {
214203
String s;
215204
while ((s = error.readLine()) != null) {
216205
if (s.length() > 0) {
@@ -232,14 +221,7 @@ private void initialize() throws IOException {
232221
private void addRustSupport(List<String> command) {
233222
command.add("--langdef=rust");
234223
command.add("--langmap=rust:+.rs");
235-
if (!RuntimeEnvironment.getInstance().isUniversalCtags()) {
236-
command.add("--regex-rust=/^[[:space:]]*(#\\[[^]]+\\][[:space:]]*)*(pub[[:space:]]+)?(extern[[:space:]]+)?(\\\"[^\\\"]+\\\"[[:space:]]+)?(unsafe[[:space:]]+)?fn[[:space:]]+([[:alnum:]_]+)/\\6/h,functions,function definitions/");
237-
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?type[[:space:]]+([[:alnum:]_]+)/\\2/T,types,type definitions/");
238-
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?enum[[:space:]]+([[:alnum:]_]+)/\\2/g,enum,enumeration names/");
239-
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?struct[[:space:]]+([[:alnum:]_]+)/\\2/S,structure names/");
240-
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?mod[[:space:]]+([[:alnum:]_]+)/\\2/N,modules,module names/");
241-
command.add("--regex-rust=/^[[:space:]]*macro_rules![[:space:]]+([[:alnum:]_]+)/\\1/d,macros,macro definitions/");
242-
}
224+
243225
// The following are not supported yet in Universal Ctags b13cb551
244226
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?(static|const)[[:space:]]+(mut[[:space:]]+)?([[:alnum:]_]+)/\\4/C,consts,static constants/");
245227
command.add("--regex-rust=/^[[:space:]]*(pub[[:space:]]+)?(unsafe[[:space:]]+)?impl([[:space:]\n]*<[^>]*>)?[[:space:]]+(([[:alnum:]_:]+)[[:space:]]*(<[^>]*>)?[[:space:]]+(for)[[:space:]]+)?([[:alnum:]_]+)/\\5 \\7 \\8/I,impls,trait implementations/");
@@ -254,20 +236,14 @@ private void addPowerShellSupport(List<String> command) {
254236
command.add("--regex-Posh=/\\$([[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1/v,variable/");
255237
command.add("--regex-Posh=/^[[:space:]]*(:[^[:space:]]+)/\\1/l,label/");
256238

257-
if (!RuntimeEnvironment.getInstance().isUniversalCtags()) {
258-
command.add("--regex-Posh=/^[[:space:]]*([Ff]unction|[Ff]ilter)[[:space:]]+([^({[:space:]]+)[[:space:]]*(\\(([^)]+)\\))?/\\2/f,function,functions/");
259-
} else {
260-
command.add("--_fielddef-Posh=signature,signatures");
261-
command.add("--fields-Posh=+{signature}");
262-
263-
// escaped variable markers
264-
command.add("--regex-Posh=/`\\$([[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1//{exclusive}");
265-
command.add("--regex-Posh=/`\\$(\\{[^}]+\\})/\\1//{exclusive}");
266-
command.add("--regex-Posh=/#.*\\$([[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1//{exclusive}");
267-
command.add("--regex-Posh=/#.*\\$(\\{[^}]+\\})/\\1//{exclusive}");
268-
command.add("--regex-Posh=/^[[:space:]]*(function|filter)[[:space:]]+([^({[:space:]]+)[[:space:]]*(\\(([^)]+)\\))?/\\2/f,function,functions/{icase}{exclusive}{_field=signature:(\\4)}");
269-
270-
}
239+
command.add("--_fielddef-Posh=signature,signatures");
240+
command.add("--fields-Posh=+{signature}");
241+
// escaped variable markers
242+
command.add("--regex-Posh=/`\\$([[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1//{exclusive}");
243+
command.add("--regex-Posh=/`\\$(\\{[^}]+\\})/\\1//{exclusive}");
244+
command.add("--regex-Posh=/#.*\\$([[:alnum:]_]+([:.][[:alnum:]_]+)*)/\\1//{exclusive}");
245+
command.add("--regex-Posh=/#.*\\$(\\{[^}]+\\})/\\1//{exclusive}");
246+
command.add("--regex-Posh=/^[[:space:]]*(function|filter)[[:space:]]+([^({[:space:]]+)[[:space:]]*(\\(([^)]+)\\))?/\\2/f,function,functions/{icase}{exclusive}{_field=signature:(\\4)}");
271247
}
272248

273249
private void addPascalSupport(List<String> command) {
@@ -317,10 +293,7 @@ private void addKotlinSupport(List<String> command) {
317293
private void addClojureSupport(List<String> command) {
318294
command.add("--langdef=clojure"); // clojure support (patterns are from https://gist.github.com/kul/8704283)
319295
command.add("--langmap=clojure:+.clj");
320-
if (!RuntimeEnvironment.getInstance().isUniversalCtags()) {
321-
command.add("--regex-clojure=/\\([[:space:]]*defn[[:space:]]+([-[:alnum:]*+!_:\\/.?]+)/\\1/f,function/");
322-
command.add("--regex-clojure=/\\([[:space:]]*ns[[:space:]]+([-[:alnum:]*+!_:\\/.?]+)/\\1/n,namespace/");
323-
}
296+
324297
command.add("--regex-clojure=/\\([[:space:]]*create-ns[[:space:]]+([-[:alnum:]*+!_:\\/.?]+)/\\1/n,namespace/");
325298
command.add("--regex-clojure=/\\([[:space:]]*def[[:space:]]+([-[:alnum:]*+!_:\\/.?]+)/\\1/d,definition/");
326299
command.add("--regex-clojure=/\\([[:space:]]*defn-[[:space:]]+([-[:alnum:]*+!_:\\/.?]+)/\\1/p,private function/");
@@ -333,14 +306,6 @@ private void addClojureSupport(List<String> command) {
333306
command.add("--regex-clojure=/\\([[:space:]]*intern[[:space:]]+([-[:alnum:]*+!_:\\/.?]+)/\\1/v,intern/");
334307
}
335308

336-
private void addGoLangSupport(List<String> command) {
337-
command.add("--langdef=golang");
338-
command.add("--langmap=golang:+.go");
339-
command.add("--regex-golang=/func([[:space:]]+([^)]+))?[[:space:]]+([a-zA-Z0-9_]+)/\\2/f,func/");
340-
command.add("--regex-golang=/var[[:space:]]+([a-zA-Z_][a-zA-Z0-9_]+)/\\1/v,var/");
341-
command.add("--regex-golang=/type[[:space:]]+([a-zA-Z_][a-zA-Z0-9_]+)/\\1/t,type/");
342-
}
343-
344309
private void addHaskellSupport(List<String> command) {
345310
command.add("--langdef=haskell"); // below was added with #912
346311
command.add("--langmap=haskell:+.hs");

opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/RuntimeEnvironment.java

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ public final class RuntimeEnvironment {
142142
* value is not mediated to {@link Configuration}.
143143
*/
144144
private String ctags;
145+
private static final String SYSTEM_CTAGS_PROPERTY = "org.opengrok.indexer.analysis.Ctags";
145146
/**
146147
* Stores a transient value when
147148
* {@link #setMandoc(java.lang.String)} is called -- i.e. the
@@ -535,7 +536,7 @@ public String getCtags() {
535536
String value;
536537
return ctags != null ? ctags : (value =
537538
threadConfig.get().getCtags()) != null ? value :
538-
System.getProperty("org.opengrok.indexer.analysis.Ctags",
539+
System.getProperty(SYSTEM_CTAGS_PROPERTY,
539540
"ctags");
540541
}
541542

@@ -598,56 +599,32 @@ public void setHitsPerPage(int hitsPerPage) {
598599
threadConfig.get().setHitsPerPage(hitsPerPage);
599600
}
600601

601-
// cache these tests instead of rerunning them for every call
602-
private transient Boolean exCtagsFound;
603-
private transient Boolean isUniversalCtagsVal;
602+
private transient Boolean ctagsFound;
604603

605604
/**
606-
* Validate that I have a Exuberant ctags program I may use
605+
* Validate that there is a Universal ctags program.
607606
*
608607
* @return true if success, false otherwise
609608
*/
610-
public boolean validateExuberantCtags() {
611-
if (exCtagsFound == null) {
609+
public boolean validateUniversalCtags() {
610+
if (ctagsFound == null) {
612611
Executor executor = new Executor(new String[]{getCtags(), "--version"});
613612
executor.exec(false);
614613
String output = executor.getOutputString();
615614
boolean isUnivCtags = output != null && output.contains("Universal Ctags");
616-
if (output == null || (!output.contains("Exuberant Ctags") && !isUnivCtags)) {
617-
LOGGER.log(Level.SEVERE, "Error: No Exuberant Ctags found in PATH !\n"
615+
if (output == null && !isUnivCtags) {
616+
LOGGER.log(Level.SEVERE, "Error: No Universal Ctags found in PATH !\n"
618617
+ "(tried running " + "{0}" + ")\n"
619-
+ "Please use option -c to specify path to a good "
620-
+ "Exuberant Ctags program.\n"
621-
+ "Or set it in java property "
622-
+ "org.opengrok.indexer.analysis.Ctags", getCtags());
623-
exCtagsFound = false;
618+
+ "Please use the -c option to specify path to a "
619+
+ "Universal Ctags program.\n"
620+
+ "Or set it in Java system property "
621+
+ SYSTEM_CTAGS_PROPERTY, getCtags());
622+
ctagsFound = false;
624623
} else {
625-
if (isUnivCtags) {
626-
isUniversalCtagsVal = true;
627-
}
628-
exCtagsFound = true;
629-
}
630-
}
631-
return exCtagsFound;
632-
}
633-
634-
/**
635-
* Are we using Universal ctags?
636-
*
637-
* @return true if we are using Universal ctags
638-
*/
639-
public boolean isUniversalCtags() {
640-
if (isUniversalCtagsVal == null) {
641-
isUniversalCtagsVal = false;
642-
Executor executor = new Executor(new String[]{getCtags(), "--version"});
643-
644-
executor.exec(false);
645-
String output = executor.getOutputString();
646-
if (output.contains("Universal Ctags")) {
647-
isUniversalCtagsVal = true;
624+
ctagsFound = true;
648625
}
649626
}
650-
return isUniversalCtagsVal;
627+
return ctagsFound;
651628
}
652629

653630
/**

opengrok-indexer/src/main/java/org/opengrok/indexer/index/Indexer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,7 @@ public void prepareIndexer(RuntimeEnvironment env,
873873
throw new IndexerException("ERROR: please specify a SRC_ROOT with option -s !");
874874
}
875875

876-
if (zapCache.isEmpty() && !env.validateExuberantCtags()) {
876+
if (zapCache.isEmpty() && !env.validateUniversalCtags()) {
877877
throw new IndexerException("Didn't find Exuberant Ctags");
878878
}
879879
if (zapCache == null) {

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/c/CAnalyzerFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public static void setUpClass() throws Exception {
8989
CAnalyzerFactory analFact = new CAnalyzerFactory();
9090
analyzer = analFact.getAnalyzer();
9191
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
92-
if (env.validateExuberantCtags()) {
92+
if (env.validateUniversalCtags()) {
9393
analyzer.setCtags(new Ctags());
9494
}
9595
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/c/CxxAnalyzerFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public static void setUpClass() throws Exception {
8989
CxxAnalyzerFactory analFact = new CxxAnalyzerFactory();
9090
analyzer = analFact.getAnalyzer();
9191
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
92-
if (env.validateExuberantCtags()) {
92+
if (env.validateUniversalCtags()) {
9393
analyzer.setCtags(new Ctags());
9494
}
9595
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/clojure/ClojureAnalyzerFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public static void setUpClass() throws Exception {
8686
ClojureAnalyzerFactory analFact = new ClojureAnalyzerFactory();
8787
analyzer = analFact.getAnalyzer();
8888
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
89-
if (env.validateExuberantCtags()) {
89+
if (env.validateUniversalCtags()) {
9090
analyzer.setCtags(new Ctags());
9191
}
9292
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/csharp/CSharpAnalyzerFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public static void setUpClass() throws Exception {
8484
CSharpAnalyzerFactory analFact = new CSharpAnalyzerFactory();
8585
analyzer = analFact.getAnalyzer();
8686
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
87-
if (env.validateExuberantCtags()) {
87+
if (env.validateUniversalCtags()) {
8888
analyzer.setCtags(new Ctags());
8989
}
9090
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/java/JavaAnalyzerFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public static void setUpClass() throws Exception {
8989
JavaAnalyzerFactory analFact = new JavaAnalyzerFactory();
9090
analyzer = analFact.getAnalyzer();
9191
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
92-
if (env.validateExuberantCtags()) {
92+
if (env.validateUniversalCtags()) {
9393
analyzer.setCtags(new Ctags());
9494
}
9595
}

0 commit comments

Comments
 (0)