7
7
#include < matplot/util/common.h>
8
8
#include < matplot/util/popen.h>
9
9
#include < iostream>
10
- #include < regex >
10
+ #include < charconv >
11
11
#include < thread>
12
12
#include < cstring>
13
13
#include < cstdlib>
@@ -317,13 +317,28 @@ namespace matplot::backend {
317
317
}
318
318
}
319
319
320
+ // / returns the next word in text after prefix terminated with white space.
321
+ std::string_view word_after (std::string_view text, std::string_view prefix)
322
+ {
323
+ auto res = text.substr (0 ,0 );
324
+ if (auto b = text.find (prefix); b != std::string_view::npos) {
325
+ b += prefix.length ();
326
+ while (b < text.length () && std::isspace (text[b]))
327
+ ++b; // skip white space before word
328
+ auto e = b;
329
+ while (e < text.length () && !std::isspace (text[e]))
330
+ ++e; // scan until white space or end
331
+ res = text.substr (b, e-b);
332
+ }
333
+ return res;
334
+ }
335
+
320
336
std::string gnuplot::default_terminal_type () {
321
337
static std::string terminal_type;
322
338
const bool dont_know_term_type = terminal_type.empty ();
323
339
if (dont_know_term_type) {
324
340
terminal_type = run_and_get_output (" gnuplot -e \" show terminal\" 2>&1" );
325
- terminal_type = std::regex_replace (terminal_type,
326
- std::regex (" [^]*terminal type is ([^ ]+)[^]*" ), " $1" );
341
+ terminal_type = word_after (terminal_type, " terminal type is " );
327
342
const bool still_dont_know_term_type = terminal_type.empty ();
328
343
if (still_dont_know_term_type) {
329
344
terminal_type = " qt" ;
@@ -334,51 +349,25 @@ namespace matplot::backend {
334
349
335
350
bool gnuplot::terminal_is_available (std::string_view term) {
336
351
std::string msg = run_and_get_output (" gnuplot -e \" set terminal " +
337
- std::string ( term. data ()) + " \" 2>&1" );
352
+ std::string{ term} + " \" 2>&1" );
338
353
return msg.empty ();
339
354
}
340
355
341
- std::tuple<int , int , int > gnuplot::gnuplot_version () {
342
- static std::tuple<int , int , int > version{0 , 0 , 0 };
343
- const bool dont_know_gnuplot_version_yet =
344
- version == std::tuple<int , int , int >({0 , 0 , 0 });
345
- if (dont_know_gnuplot_version_yet) {
346
- std::string version_str =
347
- run_and_get_output (" gnuplot --version 2>&1" );
348
- std::string version_major = std::regex_replace (
349
- version_str,
350
- std::regex (" [^]*gnuplot (\\ d+)\\ .\\ d+ patchlevel \\ d+ *" ),
351
- " $1" );
352
- std::string version_minor = std::regex_replace (
353
- version_str,
354
- std::regex (" [^]*gnuplot \\ d+\\ .(\\ d+) patchlevel \\ d+ *" ),
355
- " $1" );
356
- std::string version_patch = std::regex_replace (
357
- version_str,
358
- std::regex (" [^]*gnuplot \\ d+\\ .\\ d+ patchlevel (\\ d+) *" ),
359
- " $1" );
360
- try {
361
- std::get<0 >(version) = std::stoi (version_major);
362
- } catch (...) {
363
- std::get<0 >(version) = 0 ;
364
- }
365
- try {
366
- std::get<1 >(version) = std::stoi (version_minor);
367
- } catch (...) {
368
- std::get<1 >(version) = 0 ;
369
- }
370
- try {
371
- std::get<2 >(version) = std::stoi (version_patch);
372
- } catch (...) {
373
- std::get<2 >(version) = 0 ;
374
- }
375
- const bool still_dont_know_gnuplot_version =
376
- version == std::tuple<int , int , int >({0 , 0 , 0 });
377
- if (still_dont_know_gnuplot_version) {
378
- // assume it's 5.2.6 by convention
379
- version = std::tuple<int , int , int >({5 , 2 , 6 });
356
+ Version gnuplot::gnuplot_version () {
357
+ static auto version = Version{0 , 0 , 0 };
358
+ if (!version) {
359
+ const auto version_str = run_and_get_output (" gnuplot --version 2>&1" );
360
+ const auto major = word_after (version_str, " gnuplot" );
361
+ const auto minor = word_after (major, " ." );
362
+ const auto patch = word_after (version_str, " patchlevel" );
363
+ if (!major.empty () && !minor.empty () && !patch.empty ()) {
364
+ std::from_chars (major.begin (), major.end (), version.major );
365
+ std::from_chars (minor.begin (), major.end (), version.minor );
366
+ std::from_chars (patch.begin (), major.end (), version.patch );
380
367
}
381
368
}
369
+ if (!version)
370
+ version = {5 , 2 , 6 }; // assume by convention
382
371
return version;
383
372
}
384
373
0 commit comments