#Tiedostojen avaamiseen liittyviä rutiineja, Copyright 2000, Daka, Kopioiminen kielletty. #Kaikki rutiinit käyttävät moduulia debug.pl ja sen rutiinia virhetilanne #avaa_tiedosto: avaa tiedoston lukemista, kirjoittamista tai peräänkirjoittamista varten #sisään: kaksi muuttujaa, ensimmäinen on tiedostopolku, toinen on tyhjä, > tai >>, # joiden perusteella tiedosto avataan lukemista, kirjoittamista tai peräänkirjoittamista varten #return: palauttaa tiedostonimen alkuosasta tehdyn tiedostokahvan isoilla kirjaimilla, kts esimerkki #Esimerkki: $kahva = &avaa_tiedosto('/polku.../configure.txt','>') avaa tiedoston kirjoittamista varten. Kahvan arvoksi tulee CONFIGURE sub avaa_tiedosto{ my($kahva); my($sisaan,$moodi,$jatka) = @_;#moodi = >,>> tai ei mitään unless($moodi eq '>' or $moodi eq '>>'){ $moodi = ''; } $kahva=uc($sisaan); $kahva =~ s/.*\///;#poista polku $kahva =~ s/\..*//; #poista pisteen jälkeinen osa if(!open($kahva, $moodi.$sisaan) and $jatka ne "jatka"){ &virhetilanne("Alirutiinissa avaa_tiedosto $sisaan ei auennut kahvaan $kahva. Moodi: $moodi") } return($kahva); } #Esimerkki: &avaa_listaan('/polku../taulu.db) # rutiini jättää jälkeensä globaalit @taulu (tiedosto listana) ja $taulukentat (tiedoston eka rivi) sub avaa_listaan{ #sisään polku/tiedoston nimi, ulos @tiedosto ja TIEDOSTO kahva (pisteestä vasemmalle) my($sisaan,$jatka) = @_; my($kahva,$lista,$a); $kahva=uc($sisaan); $kahva =~ s/.*\///;#poista polku $kahva =~ s/(.+?)\..*/\1/; #poista pisteen jälkeinen osa $lista = lc($kahva); if(!open($kahva, $sisaan)){ ($jatka eq "jatka") || &virhetilanne("Alirutiinissa avaa_listaan $sisaan ei auennut kahvaan $kahva."); return } @$lista = <$kahva>; $a = $lista."kentat"; $$a = $$lista[0]; $$a = s/#(.*)\n/\1/; } #avaa_muuttujaan: avaa tiedoston ja palauttaa sen yhtenä isona muuttujana #sisään: tiedostopolku #return: tiedosto muuttujana #Esimerkki $html = &avaa_muuttujaan('/polku.../index.html') siirtää tiedoston index.html sisällön muuttujaan $html sub avaa_muuttujaan{#sisään polku ja tiedoston nimi. Ulos koko tiedosto yhdessä muuttujassa. my($tiedosto,$jatka) = @_; if(!open(TIEDOSTO, $tiedosto)){ ($jatka eq "jatka") || &virhetilanne("Alirutiinissa avaa_muuttujaan $tiedosto ei auennut."); return } my @tiedosto = ; return(join("", @tiedosto)); } #silpputaulukko avaa taulukon ja sijoittaa sen arvot kaksiulotteiseen silpputaulukkoon (hash table) #Huomaa 1. rivillä kentän nimet, kenttiä erottavat |-merkit #Huomaa Aikaisempiin skripteihin tehdyt samannimiset rutiinit lisäsivät .db tunnuksen automaattisesti, tämä ei tee niin #Esimerkki: myynti.db on kaksirivinen tiedosto: # ------------------------------------- # laskunumero|pvm|summa|laskelma # 130|1.2.2000|900|10 Kirja 90 # ------------------------------------- # &silpputaulukko('/polku.../myynti.db','laskunumero') luo taulusta myynti.db %myynti nimisen taulukon # jossa esimerkiksi $myynti{'130'}{'summa'} on 900 #Return: palauttaa yhtenä muuttujana taulukon ensimmäisen rivin, jossa kenttien nimet #Sisään: taulukon tiedostopolku ja avainkentän nimi tai järjestysnumero (ensimmäinen on nollas) sub silpputaulukko{#sisään taulun nimi ja avainkentän järjestysnumero alk 0 ulos %tapahtumat jne my($taulu,$avain) = @_; my($varmistus); sleep(2) while(-M $taulu < 2/(60*60*24) and $varmistus++ < 60); my $kahva = &avaa_tiedosto($taulu); my ($laskuri,@arvot,$lajittelija, $kentat); $taulu =~s|.*/(.+?)\..*|\1|;#huom. $taulu on tätä ennen koko tiedostopolku, tämän jälkeen pelkkä nimi undef(%$taulu);#nollataan mahdollisesti aiemmin luotu sama silppu $kentat = <$kahva>;#luetaan taulukon ekalta riviltä kenttien nimet chop($kentat); @kentat = split(/\|/,$kentat);#sijoitetaan nimet listaan. @kentat ja $kentat ovat globaaleja!!! $lkm = $#kentat; if(!$kentat[$lkm]) {pop(@kentat);$lkm--}#jos |-merkkiä on käytetty rivien lopussa if($avain =~ /\D/){#jos avain määritelty kentän nimenä eikä järjestysnumerona $i = 0; while($kentat[$i] ne $avain){ &virhetilanne("Kentän nimeä $avain ei löytynyt taulusta $taulu") if($i++ > $lkm); } $avain = $i;#muutetaan avaimen arvo vastaavaksi järjestysnumeroksi } while($rivi = <$kahva>){#käydään taulukko läpi chop($rivi); @arvot = split(/\|/,$rivi);#luetaan rivin arvot $lajittelija=$arvot[$avain];# while(defined($$taulu{$lajittelija}) or !$lajittelija){#estetään avainten päällekkäisyys if($laskuri++>5000){&virhetilanne("sub silpputaulukko jäi luuppiin. Lajittelija:$lajittelija \nRivi:$rivi")} $lajittelija .= $laskuri;#lajittelijan loppuun numeroita erottamaan jo määritellystä } for $solu(0..$lkm){#yhdistetään rivin arvot kenttiin $$taulu{$lajittelija}{$kentat[$solu]} = $arvot[$solu]; } } return($kentat); } #tallenna_silppu tallentaa sub silpputaulukon tekemän taulukon, $kentat on sama mikä tulee returnin mukana sub silpputaulukosta sub tallenna_silppu{#sisään silpun polku ja nimi, kentät yhtenä |-lla eroteltuna rivinä my($tiedosto,$kentat,$tyhja_ok)=@_; #jos $tyhja_ok on "tyhja_ok", tyhjäkin silppu tallennetaan my ($taulu,$polku) = ($tiedosto,$tiedosto); my($varmistus); $taulu =~s|.*?([^/]+)$|\1|;#poistetaan polku $taulu =~s|\..*$|\1|;#poistetaan pisteen jälkeinen osa if(!%$taulu and $tyhja_ok ne "tyhja_ok"){&virhetilanne("Silpputaulukkoa $taulu ei ollut, kun sitä yritettiin tallentaa tiedostoon $tiedosto")} while(-M $tiedosto < 2/(60*60*24) and $varmistus++ < 10){sleep 2;} my $kahva = &avaa_tiedosto($tiedosto,'>'); chomp($kentat);#varmuuden vuoksi print $kahva "$kentat\n"; for $rivi(sort keys %$taulu){ $template = $kentat; $template =~ s/(\||\A)([^|]+)/\1$$taulu{$rivi}{$2}/g;#vaihdetaan kentän nimet arvoihin (tällä tavoin rakenne, kuten rivin lopun mahdollinen | on helpompi säilyttää.) print $kahva "$template\n"; } close($kahva); } 1;