Analiza tekstualnih datoteka

Zadatak

Načiniti program koji će analizirati svaku tekstualnu datoteku zadanu kao argument iz komandne linije. Ako datoteka završava ekstenzijom *.txt tada treba prebrojati riječi u datoteci te izračunati zaštitnu sumu. Ukoliko se radi o *.html datoteci, tada prebrojati "tagove" (samo početne, npr. <b>, ali ne i </b>) te također izračunati zaštitnu sumu. Ostale tipove datoteka treba ignorirati.

U rješenju neka program za svaku datoteku (zadanu u komandnoj liniji) stvori novi proces koji će ju obraditi. U svakom novom procesu stvoriti tri dretve: prva koja će čitati redak po redak iz datoteke i smjestiti ga u međuspremnik MS, druga koja će brojati riječi/tagove u tom retku te treća koja će računati zaštitnu sumu tog retka. Obzirom da će se obrađivati redak po redak dretve treba sinkronizirati. Pseudokod rješenja može izgledati ovako:

glavni program (parametri) {
   za svaki parametar pokreni odgovarajući novi proces koji radi f-ju "analiza"; // jedna vrsta procesa za txt datoteke i druga vrsta procesa za html datoteke
   pričekaj završetak svih procesa;
}

proces analiza(datoteka) {
   otvori datoteku(datoteka);
   pokreni dretvu dohvati;
   pokreni dretvu broji_riječi_tagove;
   pokreni dretvu suma;

   čekaj_završetak_svih_dretvi;
   ispiši_statistiku_za_datoteku;
}

dretva dohvati() {
   g_br = 0; /* globalni brojač retka */

   dok (nije pročitana cijela datoteka) {
      redak = dohvati_redak_iz_datoteke;
      kopiraj_redak_u_MS;

      g_br++;

      dok (d2_br <= g_br || d3_br <= g_br)
         ništa;
   }
   kraj = 1;  
   MS[0] = 0; 
   g_br++;
}
dretva broji_riječi() {
   d2_br = 1;

   dok (kraj != 1) {
      dok (d2_br > g_br)
         ništa;

      broj_rijeci += izbroji_riječi_tagove(MS);

      d2_br++;
   }
}
dretva suma() {
   d3_br = 1;

   dok (kraj != 1) {
      dok (d3_br > g_br)
         ništa;

      za i=0 do duljina_retka(MS) radi
         suma ^= MS(i); /* obična XOR operacija */

      d3_br++;
   }    
}

Komunikacija u predloženom rješenju obavlja se preko dijeljenog spremnika unutar istog procesa: dretve preko međuspremnika i dodatnih varijabli razmjenjuju stanje i podatke. Za sinkronizaciju dretvi koristiti radno čekanje! Dretve različitih procesa u ovom primjeru ne komuniciraju!

Primjer ispisa pokretanja programa

# ./a.out popis.txt sazetak.txt index.html nesto.out
Datoteka "popis.txt" ima 342 rijeci; zastitna suma je: 34
Datoteka "sazetak.txt" ima 24 rijeci; zastitna suma je: 11
Datoteka "index.html" ima 567 tagova; zastitna suma je: 121
Analiza obustavljena za datoteku "nesto.out"!