@@ -369,12 +369,17 @@ void preloadScript(const std::string& filename) {
369369}
370370
371371bool matchesCompilerVersion (const std::string& minVersion, const std::string& maxVersion) {
372- if (minVersion.length ()) {
372+ // TODO: Short-circuited version matching for now, because the regex matcher
373+ // in `parseFile()` spirals into an infinite loop if the version is out of bounds.
374+ // Don't merge to master before fixing that!
375+ return true ;
376+
377+ if (!minVersion.empty ()) {
373378 const int version = std::stoi (minVersion);
374379 if (OSR_COMPILER_VERSION < version)
375380 return false ;
376381 }
377- if (maxVersion.length ()) {
382+ if (! maxVersion.empty ()) {
378383 const int version = std::stoi (maxVersion);
379384 if (OSR_COMPILER_VERSION > version)
380385 return false ;
@@ -393,6 +398,11 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
393398
394399 std::string& output = fl.contents ;
395400 output.reserve (size);
401+
402+ if (lines.empty ())
403+ return ;
404+ auto & start = lines.front ();
405+ const bool isOsrScript = trim (start) == " //#opensr" ;
396406
397407 ManagerType curType = getManagerType (man);
398408 ManagerType selType = curType;
@@ -404,16 +414,14 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
404414 reg_compile (pre_import_from, " ^[ \t ]*from[ \t ]+([A-Za-z0-9._-]+)[ \t ]+import[ \t ]+([^;]+);" );
405415 reg_compile (pre_import_all, " ^[ \t ]*import[ \t ]+(([A-Za-z0-9._-]|, )+);" );
406416 reg_compile (pre_export, " ^[ \t ]*export[ \t ]+(([A-Za-z0-9._-]|,* )+);" );
407- reg_compile (pre_osr_single_line, " (.*)//\$([0-9]*)-?([0-9]*)(.*)" );
408- reg_compile (pre_osr_multi_open, " (.*)/\*\$([0-9]*)-?([0-9]*)(.*)" );
409- reg_compile (pre_osr_multi_close, " (.*)[ \t ]([0-9]*)-?([0-9]*)\$\*/(.*)" );
417+ reg_compile (pre_osr_open, " (.*)/[/*]\\ %([0-9]*)-?([0-9]*)(.*)" );
418+ reg_compile (pre_osr_multi_close, " (.*)[ \t ]([0-9]*)-?([0-9]*)\\ %\\ */(.*)" );
410419 reg_compile_lock.release ();
411420 reg_result match;
412421
413422
414- for (auto iLine = lines.begin (), end = lines.end (); iLine != end; ++iLine) {
415- const std::string& line = *iLine;
416-
423+ for (const auto & line : lines)
424+ {
417425 auto lineStart = line.find_first_not_of (" \t " );
418426 if (lineStart == std::string::npos) {
419427 output.append (1 , ' \n ' );
@@ -449,7 +457,7 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
449457 else
450458 selType = MT_Client_Side;
451459
452- output += " \n " ;
460+ output += ' \n ' ;
453461 continue ;
454462 }
455463 else {
@@ -459,73 +467,71 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
459467 case MT_GUI:
460468 case MT_Menu:
461469 if (selType != curType) {
462- output += " \n " ;
470+ output += ' \n ' ;
463471 continue ;
464472 }
465473 break ;
466474 case MT_Game:
467475 if (curType != MT_GUI && curType != MT_Server && curType != MT_Shadow) {
468- output += " \n " ;
476+ output += ' \n ' ;
469477 continue ;
470478 }
471479 break ;
472480 case MT_Client_Side:
473481 if (curType != MT_Menu && curType != MT_GUI) {
474- output += " \n " ;
482+ output += ' \n ' ;
475483 continue ;
476484 }
477485 break ;
478486 case MT_Server_Side:
479487 if (curType != MT_Shadow && curType != MT_Server) {
480- output += " \n " ;
488+ output += ' \n ' ;
481489 continue ;
482490 }
483491 break ;
484492 }
485493 }
486494
487495 // TODO: Figure out something a little better-optimized than always running
488- // three regexes on every line of code?
496+ // two regexes on every line of code?
489497 // On the bright side, we're only running them if we're in the right section...
490- auto osrLine = new std::string (iLine);
491- while (reg_match (osrLine, match, pre_osr_single_line)) {
492- const std::string prefix = reg_str (osrLine, match, 1 );
493- const std::string postfix = reg_str (osrLine, match, 4 );
494- if (matchesCompilerVersion (reg_str (osrLine, match, 2 ), reg_str (osrLine, match, 3 ))) {
495- osrLine = prefix + postfix;
496- }
497- }
498- while (reg_match (osrLine, match, pre_osr_multi_open)) {
499- const std::string prefix = reg_str (osrLine, match, 1 );
500- const std::string postfix = reg_str (osrLine, match, 4 );
501- if (matchesCompilerVersion (reg_str (osrLine, match, 2 ), reg_str (osrLine, match, 3 ))) {
502- osrLine = prefix + postfix;
498+ // and an OSR-enabled script...
499+ std::string osrLine;
500+ if (isOsrScript)
501+ {
502+ osrLine = line;
503+ while (reg_match (osrLine, match, pre_osr_open)) {
504+ const std::string prefix = reg_str (osrLine, match, 1 );
505+ const std::string postfix = reg_str (osrLine, match, 4 );
506+ if (matchesCompilerVersion (reg_str (osrLine, match, 2 ), reg_str (osrLine, match, 3 ))) {
507+ osrLine = prefix + postfix;
508+ }
503509 }
504- }
505- while ( reg_match ( osrLine, match, pre_osr_multi_close)) {
506- const std::string prefix = reg_str (osrLine, match, 1 );
507- const std::string postfix = reg_str (osrLine, match, 4 );
508- if ( matchesCompilerVersion ( reg_str ( osrLine, match, 2 ), reg_str (osrLine, match, 3 ))) {
509- osrLine = prefix + postfix;
510+ while ( reg_match (osrLine, match, pre_osr_multi_close)) {
511+ const std::string prefix = reg_str ( osrLine, match, 1 );
512+ const std::string postfix = reg_str (osrLine, match, 4 );
513+ if ( matchesCompilerVersion ( reg_str (osrLine, match, 2 ), reg_str (osrLine, match, 3 ))) {
514+ osrLine = prefix + postfix;
515+ }
510516 }
511517 }
512518
513- if (osrLine[lineStart] == ' f' && reg_match (osrLine, match, pre_import_from)) {
514- std::string mod = reg_str (osrLine, match, 1 );
515- std::string def = reg_str (osrLine, match, 2 );
519+ const std::string& finalLine = isOsrScript ? osrLine : line;
520+ if (finalLine[lineStart] == ' f' && reg_match (finalLine, match, pre_import_from)) {
521+ std::string mod = reg_str (finalLine, match, 1 );
522+ std::string def = reg_str (finalLine, match, 2 );
516523
517524 fl.imports .insert (ImportSpec (mod, def));
518- output += " \n " ;
519- delete osrLine;
525+ output += ' \n ' ;
520526 continue ;
521527 }
522528
523- if (osrLine [lineStart] == ' i' && reg_match (osrLine , match, pre_import_all)) {
524- std::string mod = reg_str (osrLine , match, 1 );
529+ if (finalLine [lineStart] == ' i' && reg_match (finalLine , match, pre_import_all)) {
530+ std::string mod = reg_str (finalLine , match, 1 );
525531
526- if (mod.find (" , " ) != std::string::npos) {
532+ if (mod.find (' , ' ) != std::string::npos) {
527533 std::vector<std::string> modules;
528- split (mod, modules, " , " , true );
534+ split (mod, modules, ' , ' , true );
529535
530536 foreach (m, modules)
531537 fl.imports .insert (ImportSpec (*m, " *" ));
@@ -534,23 +540,22 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
534540 fl.imports .insert (ImportSpec (mod, " *" ));
535541 }
536542
537- output += " \n " ;
538- delete osrLine;
543+ output += ' \n ' ;
539544 continue ;
540545 }
541546
542- if (osrLine [lineStart] == ' e' && reg_match (osrLine , match, pre_export)) {
543- std::string sym = reg_str (osrLine , match, 1 );
547+ if (finalLine [lineStart] == ' e' && reg_match (finalLine , match, pre_export)) {
548+ std::string sym = reg_str (finalLine , match, 1 );
544549 auto * lst = &fl.exports ;
545550
546551 if (sym.compare (0 , 5 , " from " ) == 0 ) {
547552 sym = sym.substr (5 );
548553 lst = &fl.exportsFrom ;
549554 }
550555
551- if (sym.find (" , " ) != std::string::npos) {
556+ if (sym.find (' , ' ) != std::string::npos) {
552557 std::vector<std::string> symbols;
553- split (sym, symbols, " , " , true );
558+ split (sym, symbols, ' , ' , true );
554559
555560 foreach (s, symbols)
556561 lst->insert (*s);
@@ -559,14 +564,13 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
559564 lst->insert (sym);
560565 }
561566
562- output += " \n " ;
563- delete osrLine;
567+ output += ' \n ' ;
564568 continue ;
565569 }
566570
567- if (mayBeDirective && reg_match (osrLine , match, pre_priority)) {
568- std::string type = reg_str (osrLine , match, 1 );
569- std::string prior = reg_str (osrLine , match, 2 );
571+ if (mayBeDirective && reg_match (finalLine , match, pre_priority)) {
572+ std::string type = reg_str (finalLine , match, 1 );
573+ std::string prior = reg_str (finalLine , match, 2 );
570574 int priority = toNumber<int >(prior);
571575
572576 if (type == " init" ) {
@@ -586,10 +590,10 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
586590 filename.c_str (), type.c_str ());
587591 }
588592
589- output += " \n " ;
593+ output += ' \n ' ;
590594 }
591- else if (mayBeDirective && reg_match (osrLine , match, pre_include)) {
592- std::string filePart = reg_str (osrLine , match, 1 );
595+ else if (mayBeDirective && reg_match (finalLine , match, pre_include)) {
596+ std::string filePart = reg_str (finalLine , match, 1 );
593597
594598 // Check include relative to current file first
595599 std::string includeFile = getAbsolutePath (devices.mods .resolve (
@@ -618,25 +622,23 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
618622 filePart, *it));
619623 error (" Tried %s" , includeFile.c_str ());
620624 }
621- output += " \n " ;
622- delete osrLine;
625+ output += ' \n ' ;
623626 continue ;
624627 }
625628 }
626629
627630 // Don't include the same file multiple times
628631 if (fl.includes .find (includeFile) != fl.includes .end ()) {
629- output += " \n " ;
630- delete osrLine;
632+ output += ' \n ' ;
631633 continue ;
632634 }
633635
634636 if (!cacheFiles) {
635- std::string path = getAbsolutePath (includeFile);
637+ std::string includePath = getAbsolutePath (includeFile);
636638 File& incl = *new File ();
637639 parseFile (man, incl, includeFile, false );
638640
639- fl.includes [path ] = &incl;
641+ fl.includes [includePath ] = &incl;
640642 }
641643 else {
642644 man->load (" " , includeFile);
@@ -652,12 +654,10 @@ void parseFile(Manager* man, File& fl, const std::string& filename, bool cacheFi
652654 }
653655
654656 output.append (1 ,' \n ' );
655- delete osrLine;
656657 }
657658 else {
658- output += osrLine ;
659+ output += finalLine ;
659660 output.append (1 ,' \n ' );
660- delete osrLine;
661661 }
662662 }
663663}
0 commit comments