Hlavní navigace

Makro procesor GNU m4 (10)

Michal Burda

Dnešní díl věnujeme dočasnému ukládání výstupu zpracování textu do paměti pro pozdější použití.

Dočasné přesměrování výstupu do paměti

Podobně, jako si můžete uschovat vstup pro pozdější čtení, si můžete uložit do paměti i výsledky zpracování části souboru s tím, že si sami určíte, kdy je chcete poslat na výstup. Uschovávané texty se ukládají do očíslovaných bufferů v paměti. Pokud nebude mít m4 dostatek místa pro uchování v paměti, začne výstupy ukládat do pomocných souborů. Z toho vyplývá, že počet bufferů je teoreticky limitován jen počtem volných souborových deskriptorů – a takové množství nevyčerpá asi nikdo.

Přesměrování výstupu do bufferu se nastartuje takto:

divert[číslo])

kde číslo je označení bufferu, do kterého chcete výstup odklonit. Pokud číslo vynecháte, implicitně se použije 0, což je vlastně označení standardního výstupu.

Po zpracování celého zdrojového souboru odešle m4 na výstup obsahy všech použitých bufferů v pořadí daném jejich čísly.

   Tohle jde přímo na výstup.
=> Tohle jde přímo na výstup.
   divert(1)
   Tento text je uložen do bufferu číslo 1.
   divert(0)
=>
   A tohle jde už zase přímo na výstup
=> A tohle jde už zase přímo na výstup
   divert(2)
   Naplníme i buffer 2
   divert(3)
   ...a buffer 3.
   divert(0)
=>
   ^D
=>
=> Tento text je uložen do bufferu číslo 1.
=>
=> Naplníme i buffer 2
=>
=> ...a buffer 3.

V ukázce jsme nejprve volali makro divert(1), čímž jsme makro procesoru m4 řekli, že všechno od tohoto místa nemá posílat na výstup, ale uchovávat do paměti do „chlívku“ s označením 1. Použitím makra divert(0) pak dáváme najevo své přání, že vše následující se má psát zase na standardní výstup. Následuje zápis do bufferů 2 a 3. Text uložený v bufferech se na výstup dostane automaticky po přečtení celého vstupního souboru. Aby se ale zapsal na standardní výstup, musíme se na něj před koncem souboru přepnout (divert(0)).

Vícenásobné použití divert na stejný buffer existující text nepřepisuje, nýbrž k němu nové řetězce přidává.

   divert(1)
   text1
   divert
=>
   text2
=> text2
   divert(1)
   text3
   divert
=>
   text4
=> text4
   ^D
=>
=> text1
=>
=> text3

V ukázce už zkušeně píšeme místo divert(0) pouze divert, což je to samé.

K označení bufferů slouží pouze kladná čísla. Jak už víme, číslo 0 je vyhrazeno k označení standardního výstupu a všechna záporná čísla jsou neexistující buffery. Můžete si představit, že jakýkoliv buffer se záporným číslem je napojen přímo na /dev/null – vše, co do něj zapíšete, se ihned zapomene. Taková vlastnost se dá použít k odfiltrování nežádoucích výstupů při zpracování souborů s definicemi maker:

   divert(-1)
   Velice užitečné makro:
   define(`pozdrav', `Ahoj `$1'!')

   Další skvělá věc:
   define(`nesmysl', `sakdljkask')

   ...atd.
   divert
=>
   pozdrav(Jozko)
=> Ahoj Jozko!

A je to. Máme definována všechna makra a přitom nás na výstupu ne neotravují žádná nechtěná odřádkování a podobně. Dokonce si ke každému makru můžeme připsat nějakou poznámku…

Abyste uložený text dostali na výstup, nemusíte čekat na konec vstupního souboru. Buffer může být kdykoliv „ručně“ požádán o zaslání svého obsahu na výstup použitím vestavěného makra undivert:

undivert([číslo], ...)

Jako argumenty makra se uvádějí čísla bufferů, které chcete dostat na výstup. Věc se má tak, že undivertovaný text není znovu makroprocesorem čten (ani není výsledkem expanze), ale je jaksi ihned poslán na aktuální výstup.

Vypsáním textu z bufferu se tento buffer automaticky maže, takže není možné uložený text odeslat na výstup vícekrát než jednou.

   divert(1)
   Tento text ukládáme do prvního bufferu.
   divert
=>
   undivert(1)
=>
=> Tento text ukládáme do prvního bufferu.
=>
   Dvakrát na výstup jej dostat nelze:
=> Dvakrát na výstup jej dostat nelze:
   undivert(1)
=>
   divert(1)
   Tento text putuje do vyprázdněného bufferu 1.
   divert
=>
   undivert(1)
=>
=> Tento text putuje do vyprázdněného bufferu 1.

Pokus přiřadit nějakému makru text uložený v bufferu selže:

   divert(1)
   Nějaký text.
   divert
=>
   define(`makro', undivert(1))
=>
=> Nějaký text.
=>
   makro
=>

Zavoláním undivert se uložený text okamžitě poslal přímo na výstup a makro makro se definovalo na prázdný řetězec.

Pokusy undivertovat aktuálně používaný buffer jsou ignorovány.

Zavoláte-li undivert bez parametrů, odešlou se na výstup uchované texty všech bufferů:

   divert(1)
   Jedna
   divert(3)
   Tři
   divert(2)
   Dvě
   divert
=>
   undivert
=>
=> Jedna
=>
=> Dvě
=>
=> Tři
=>

Makro undivert má ještě jednu vlastnost. Předáte-li mu jako argument jméno souboru, vloží ho nezpracovaný na výstup. Rozdíl mezi undivert s názvem souboru jako parametrem a makrem include je nejlépe vidět na následujícím příkladu. Pro jeho účely předpokládejme, že soubor soubor.txt obsahuje řetězec „makro“:

   define(`makro', `ahoj')
=>
   undivert(`soubor.txt')
=> makro
=>
   include(`soubor.txt')
=> ahoj
=>

Vymazání obsahu bufferu, aniž by se cokoliv vypsalo na výstup, se dělá takto:

   divert(1)
   Nějaký text...
   divert
=>
   Nyní se rozhodneme, že text uložený v bufferu 1 nepotřebujeme.
=> Nyní se rozhodneme, že text uložený v bufferu 1 nepotřebujeme.
   divert(-1)
   undivert(1)
   divert
=>
   A je to...
=> A je to...
   undivert(1)
=>

Zjištění čísla aktuálního bufferu

…provedete pomocí makra

divnum

Příklad:

   divnum
=> 0
   divert(1)
   Jedna: divnum
   divert(2)
   Dvě: divnum
   divert
=>
   undivert
=>
=> jedna: 1
=>
=> dvě: 2
=>

Pokračování příště…

Našli jste v článku chybu?
Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

DigiZone.cz: TV Philips a Android verze 6.0

TV Philips a Android verze 6.0

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Měšec.cz: Jak levně odeslat balík přímo z domu?

Jak levně odeslat balík přímo z domu?

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Vitalia.cz: Když přijdete o oko, přijdete na rok o řidičák

Když přijdete o oko, přijdete na rok o řidičák

120na80.cz: Na ucho teplý, nebo studený obklad?

Na ucho teplý, nebo studený obklad?

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?