[megoldva] perl - "Can't "next" outside a loop block"

Sziasztok,

A subcheck nevű perl szkriptet használom arra, hogy DVD lejátszók által is emészthetővé tegyem a feliratokat, tökéletesen is működik, egészen addig, amíg a legutolsó feliratot hibásnak nem érzékeli az 543. sorban található rutin alapján, ugyanis ekkor az alábbi hibaüzenetet kapom:
"Can't "next" outside a loop block at /usr/bin/subcheck.pl line 552, line 3913."
Erre a részre hivatkozik:

sub isRealSub {
    my $subtitle = shift;
    my $returnCode = 0;
    if ($subtitle =~ /^[0-9]+\r\n[0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3} --> [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}\r\n.*/) {
        $returnCode = 1;
    }
    return $returnCode;
}

# Check if the subtitle-unit is valid
sub checkToKeepSub {
    my $lastTime = "00:00:00,000";
    if (!isRealSub($total)) {   # Total empty string no subtitle unit
        if (!$quietMode) {
            print "Removing bogus subtitle unit after subtitle unit " . 
                getSubNumber($sublist[$counter-1]) . " \n" .
                "Containing the following:\n[$total]\n" ;
        }
        $total = '';
        next;
    }

Ilyenkor semmilyen változást nem eszközöl a fájlon egészen addig amíg manuálisan ki nem törlöm a hibás sort a végéről.
Gugliban volt pár találat, de nem tudtam kihámozni, hogy mégis mit kellene csinálnom ahhoz, hogy megoldódjon.
A srác aki írta szkriptet 2005 óta nem eszközölt rajta változást és egy 2007-ben jelentett bugra sem reagált, így nem sok értelmét látom, hogy írjak neki.

Hozzászólások

a masodik fuggvenyed vegen van egy "next", ami nem kell oda. a checkToKeepSub metodus hol es hogyan hivodik meg?

> mégis mit kellene csinálnom ahhoz, hogy megoldódjon.

Pld be lehetne építeni a kódba, hogy hagyja ki "a hibás sort a végéről".

> Ha annyira tudnék programozni akkor nem kértem volna segítséget.

Ha tudnám hogy néz ki _pontosan_ az az input amit szeretnél feldolgoztatni a programmal, akkor segítenék.

> Egy 50-100 soros szkripttel még valahogy elboldogulok,

A 672-ik sornál kezdődik egy 8 soros ciklus, ami a szöveget dolgozza fel. Oda lehetne beírni, hogy hagyja ki a "hibás" sorokat.

Az input egy sima srt fájl.

Közben én is nézegettem azt a részt s mondjuk nem értem pontosan mit takar a 674. sorban lévő regexp, de úgy tűnik, hogy ha hibás feliratot tartalmaz az utolsó sor, akkor a ciklus végén az else ág érvényesül, ezáltal a bufferFull érték 1 lesz, emiatt igaz lesz a 684. sorban lévő if feltétel is, ahol meghívja a checkToKeepSub rutin, aminek a végén a next viszont az if feltételhez térne vissza ami a while-al ellentétben nem "loop block" s szerintem ez miatt kapom a hibaüzenetet.
Ha a 685. sort kikommentezem akkor rendesen lefut, de nem tudom, hogy ez nekem minden esetben jó-e, nem fog-e ez előbb utóbb egy másik hibát generálni.

Hogyan lehet a perl debuggert úgy futtatni, hogy a változókat behelyettesítse, hasonlóan mint mikor a bash-t a "-x" kapcsolóval fut?
Ha látnám mikor mit tartalmaznak a változók lehet jobban megérteném az egészet.

Ez szerintem semmiképp nem jó megoldás, mivel ha azokat nem törli lehet gondok lesznek az asztali dvd-n való lejátszásnál, plusz mi van ha nem 9999-el kezdődik és mégis problémás?

Úgy néz ki időközben sikerült megoldanom, bevezettem egy loopblock nevű változót és csak akkor hajtja végre a next-et ha 1 az értéke:

sub loadFromFile {
    my $loadFile = shift;
    if ($loadFile !~ /\.[Ss][Rr][Tt]$/) {
        die "It is only possible to open files with a srt extension!\n";
    }
    open(SUBFILE, "<".$loadFile) || die "Can't open subtitle file '$loadFile'.\n"; 

    my $filtered;
    my $bufferFull = 0;
    $loopblock = 1;
    while (<SUBFILE>) {    
        $filtered = filterText($_);
        if ($filtered =~ /^\s*\r\n$/) { # We reached a new subtitle unit
            checkToKeepSub();
            $bufferFull = 0;
        } else {
            $total .= $filtered;
            $bufferFull = 1;
        }
    }
    
    #Check if buffer is still full. If so check is content is valid
    if ($bufferFull) {
       $loopblock = 0;
       checkToKeepSub();
       $bufferFull = 0;
    }
    
    close(SUBFILE);
}

sub checkToKeepSub {
    my $lastTime = "00:00:00,000";
    if (!isRealSub($total)) {   # Total empty string no subtitle unit
        if (!$quietMode) {
            print "Removing bogus subtitle unit after subtitle unit " . 
                getSubNumber($sublist[$counter-1]) . " \n" .
                "Containing the following:\n[$total]\n" ;
        }
        $total = '';
        next if ($loopblock);
    }

Biztosan pontosabban is meg lehetett volna fogalmazni, de pl. amire te kíváncsi voltál(input) az lényegtelen volt a hiba szempontjából, már maga a hibaüzenet sem arra utalt.
Plusz már volt olyan, hogy hosszan, részletesen ecseteltem egy hibát, aztán a kérdésekből kiderült, hogy van aki végig sem olvasta, ezért törekedtem inkább csak a lényegre koncentrálni.

Mindenesetre azért köszönöm, hogy foglalkoztál a problémámmal.

Akkor is lényegtelen, azzal, hogy láttad az input-ot csak ennél az egy fájlban lévő hibát ismerted meg(csak arra is írtál megoldást), nem azt, hogy a szkript összességében miket érzékel hibának.
A lényeg az volt, hogy ha a szkript az input utolsó soraiban egy általa szabálytalannak érzékelt tartalmat talál, akkor hibára fut, mindegy, hogy mit kapott inputnak, hisz nem arra panaszkodott, a lényeg, hogy szabálytalannak érzékeli.