Skip to content

Commit 99d004f

Browse files
committed
[rootbrowse] better option parsing, exit if in batch mode
1 parent 1a0fefe commit 99d004f

File tree

2 files changed

+60
-23
lines changed

2 files changed

+60
-23
lines changed

main/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ if(WIN32)
111111
set_property(TARGET rootcling APPEND_STRING PROPERTY LINK_FLAGS " -STACK:4000000")
112112
endif()
113113

114-
if(gui)
115-
ROOT_EXECUTABLE(rootbrowse src/rootbrowse.cxx LIBRARIES RIO Core Rint Gui)
116-
endif()
114+
ROOT_EXECUTABLE(rootbrowse src/rootbrowse.cxx LIBRARIES RIO Core Rint Gui)
117115
ROOT_EXECUTABLE(rootls src/rootls.cxx LIBRARIES RIO Tree Core Rint ROOTNTuple)
118116

119117
# Create aliases: rootcint, genreflex.

main/src/rootbrowse.cxx

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <TBrowser.h>
1111
#include <TError.h>
1212
#include <TFile.h>
13+
#include <TGFrame.h>
1314
#include <TROOT.h>
1415
#include <TSystem.h>
1516

@@ -18,6 +19,7 @@
1819
#include <iostream>
1920
#include <memory>
2021
#include <thread>
22+
#include <string_view>
2123

2224
static const char *const kShortHelp = "usage: rootbrowse [-w WEB|-wf] <file.root>\n";
2325
static const char *const kLongHelp = R"(
@@ -53,8 +55,8 @@ struct RootBrowseArgs {
5355
kLong
5456
};
5557
EPrintUsage fPrintHelp = EPrintUsage::kNo;
56-
const char *fWeb = "on";
57-
const char *fFileName = nullptr;
58+
std::string_view fWeb;
59+
std::string_view fFileName;
5860
};
5961

6062
static RootBrowseArgs ParseArgs(const char **args, int nArgs)
@@ -64,25 +66,50 @@ static RootBrowseArgs ParseArgs(const char **args, int nArgs)
6466

6567
for (int i = 0; i < nArgs; ++i) {
6668
const char *arg = args[i];
69+
70+
if (strcmp(arg, "--") == 0) {
71+
forcePositional = true;
72+
continue;
73+
}
74+
6775
bool isFlag = !forcePositional && arg[0] == '-';
6876
if (isFlag) {
69-
if (strcmp(arg, "-w") == 0 || strcmp(arg, "--web") == 0) {
77+
++arg;
78+
// Parse long or short flag and its argument into `argStr` / `nxtArgStr`.
79+
std::string_view argStr, nxtArgStr;
80+
if (arg[0] == '-') {
81+
++arg;
82+
// long flag: may be either of the form `--web off` or `--web=off`
83+
const char *eq = strchr(arg, '=');
84+
if (eq) {
85+
argStr = std::string_view(arg, eq - arg);
86+
nxtArgStr = std::string_view(eq + 1);
87+
} else {
88+
argStr = std::string_view(arg);
89+
if (i < nArgs - 1 && args[i + 1][0] != '-') {
90+
nxtArgStr = args[i + 1];
91+
++i;
92+
}
93+
}
94+
} else {
95+
// short flag (note that it might be more than 1 character long, like `-wf`)
96+
argStr = std::string_view(arg);
7097
if (i < nArgs - 1 && args[i + 1][0] != '-') {
98+
nxtArgStr = args[i + 1];
7199
++i;
72-
outArgs.fWeb = args[i];
73100
}
74-
} else if (strcmp(arg, "-wf") == 0 || strcmp(arg, "--webOff") == 0) {
75-
outArgs.fWeb = "off";
76-
} else if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
101+
}
102+
103+
if (argStr == "w" || argStr == "web") {
104+
outArgs.fWeb = nxtArgStr.empty() ? "on" : nxtArgStr;
105+
} else if (argStr == "h" || argStr == "help") {
77106
outArgs.fPrintHelp = RootBrowseArgs::EPrintUsage::kLong;
78107
break;
79-
} else if (strcmp(arg, "--") == 0) {
80-
forcePositional = true;
81-
} else {
82-
outArgs.fPrintHelp = RootBrowseArgs::EPrintUsage::kShort;
83-
break;
108+
} else if (argStr == "wf" || argStr == "--webOff") {
109+
outArgs.fWeb = "off";
84110
}
85-
} else if (outArgs.fFileName) {
111+
112+
} else if (!outArgs.fFileName.empty()) {
86113
outArgs.fPrintHelp = RootBrowseArgs::EPrintUsage::kShort;
87114
break;
88115
} else {
@@ -105,23 +132,35 @@ int main(int argc, char **argv)
105132
return 1;
106133
}
107134

108-
gROOT->SetWebDisplay(args.fWeb);
135+
// NOTE: we need to instantiate TApplication ourselves, otherwise TBrowser
136+
// will create a batch application that cannot show graphics.
137+
TApplication app("rootbrowse", nullptr, nullptr);
138+
139+
if (!args.fWeb.empty())
140+
gROOT->SetWebDisplay(std::string(args.fWeb).c_str());
109141

110142
std::unique_ptr<TFile> file;
111-
if (args.fFileName) {
143+
if (!args.fFileName.empty()) {
112144
gErrorIgnoreLevel = kError;
113-
file = std::unique_ptr<TFile>(TFile::Open(args.fFileName, "READ"));
145+
file = std::unique_ptr<TFile>(TFile::Open(std::string(args.fFileName).c_str(), "READ"));
114146
if (!file || file->IsZombie()) {
115147
R__LOG_WARNING(RootBrowseLog()) << "File " << args.fFileName << " does not exist or is unreadable.";
116148
}
117149
gErrorIgnoreLevel = kUnset;
118150
}
119151

120-
// NOTE: we need to instantiate TApplication ourselves, otherwise TBrowser
121-
// will create a batch application that cannot show graphics.
122-
TApplication app("rootbrowse", nullptr, nullptr);
123-
124152
auto browser = std::make_unique<TBrowser>();
153+
154+
if (gROOT->IsBatch())
155+
return 1;
156+
157+
// For classic graphics: ensure rootbrowse quits when the window is closed
158+
if (auto imp = browser->GetBrowserImp()) {
159+
if (auto mainframe = imp->GetMainFrame()) {
160+
mainframe->Connect("CloseWindow()", "TApplication", &app, "Terminate()");
161+
}
162+
}
163+
125164
std::cout << "Press ctrl+c to exit.\n";
126165
while (!gROOT->IsInterrupted() && !gSystem->ProcessEvents()) {
127166
std::this_thread::sleep_for(std::chrono::milliseconds(10));

0 commit comments

Comments
 (0)