Unita GetOpts podruhé - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kdo je autorem výstavy obrazových fotografií „Očima Hanse Christiana Andersena“?

V dnešní soutěži hrajeme o:



Delphi

Unita GetOpts podruhé

12. září 2001, 00.00 | Dnes se podíváme na to, jak s pomocí unity GetOpts zpracovávat dlouhé (tj. vícepísmenné) volby na příkazovém řádku.

V minulém dílu jsme se naučili zvládnout pomocí unity GetOpts tzv. krátké (čili jednopísmenné) volby. Dnes se podíváme na volby dlouhé (které jsou vícepísmenné a navíc začínají dvěma pomlčkami místo jedné). Pokud jste si minulý díl nepřečetli, raději tak učiňte teď, protože ten dnešní z něj do značné míry vychází.

Zpracování dlouhých voleb

Klíčem k dlouhým volbám je struktura TOption, popisující každou jednotlivou volbu. Vunitě GetOpts je deklarovaná takto:

TOption = record
  Name: String;     // jméno volby
  Has_Arg: Integer; // zda má volby argumenty
  Flag: PChar;      // ukazatel na znak, který se při
  Value: Char;      // "spatření" volby nastaví na hodnotu Value
end;

Struktura je poměrně logická. Jako hodnoty položky Has_Arg můžeme uvést jednu ze tří konstant (opět deklarovaných v unitě GetOpts):

const
  No_Argument = 0;       // žádný argument
  Required_Argument = 1; // povinný argument
  Optional_Argument = 2; // nepovinný argument

Položky struktury Flag a Value většinou nejsou potřeba.

Vlastní procházení voleb uskutečníme pomocí funkce GetLongOpts. Jejím prvním parametrem je řetězec popisující jednopísmenné volby. Jeho formát je úplně stejný, jako u funkce GetOpt, probírané v předchozím dílu seriálu.

Druhý parametr je ukazatel pole záznamů typu TOption. Jinými slovy seznam specifikací dlouhých voleb programu. Poslední záznam v poli musí mít nastaven položku Name na prázdný řetězec - označujeme tím, že seznam zde končí.

Poslední parametr je ukazatel na proměnnou typu LongInt. Jeho význam osvětlíme za chvilku.

Funkce GetLongOpts se chová velmi podobně jako funkce GetOpt. Prochází tedy postupně jednotlivé volby programu, a pokud jsou to krátké volby, její návratovou hodnotou je písmeno dané volby. Když projde všechny volby zadané na příkazové řádce, vrátí konstantu EndOfOptions. Pokud narazí na dlouhou volbu, vrátí hodnotu #0 a do proměnné, na kterou odkazujeme ve třetím parametru funkce, zapíše pořadí volby v seznamu. Tak můžeme dlouhou volbu jednoznačně identifikovat a dále se podle toho zařídit. Případné argumenty voleb se předávají stejně jako u GetOpt v proměnné OptArg; i hlášení chyb probíhá shodným způsobem.

Příklad

Jako ukázku využití unity si můžete prostudovat následující příklad. Je to variace na příklad z minulého dílu, rozšířená o možnost zpracování dlouhých voleb. Pro ty, kteří nedisponují Free Pascalem je k dispozici i zkompilovaná verze, na které si chování programu můžete vyzkoušet.

{ Program umí zpracovat volby --alfa, --beta a --gama, přičemž
  --beta a --gama mají argument (u --gama nepovinný). Včechny
  volby mají i své zkrácené varianty (-a, -b a -g). Za volbami
  můžeme uvést libovolné množství souborů. Program nedělá nic,
  než že přehledně vypíše všechny parametry, se kterými byl
  volán. }
program GetOptsTest;

uses GetOpts;

var
  Ch: Char;
  I: Integer;
  Options: array[1..4] of TOption;
  OptionIndex: Longint;
begin
  // inicializujeme data o volbách
  with Options[1] do
  begin
    Name := 'alfa';
    Has_Arg := No_Argument;
    Flag := nil;
    Value := #0;
  end;
  with Options[2] do
  begin
    Name := 'beta';
    Has_Arg := Required_Argument;
    Flag := nil;
    Value := #0;
  end;
  with Options[3] do
  begin
    Name := 'gama';
    Has_Arg := Optional_Argument;
    Flag := nil;
    Value := #0;
  end;
  Options[4].Name := ''; // prázdné jméno = konec seznamu

  // opakujeme dokud nenačteme všechny volby
  repeat
    Ch := GetLongOpts('ab:g::', @Options[1], OptionIndex);
    case Ch of
      'a': Writeln('Pouzita volba "-a".');
      'b': Writeln('Pouzita volba "-b" s argumentem "', OptArg, '".');
      'g': Writeln('Pouzita volba "-g" s argumentem "', OptArg, '".');
      #0:
        case OptionIndex of
          1: Writeln('Pouzita volba "--alfa".');
          2: Writeln('Pouzita volba "--beta" s argumentem "', OptArg, '".');
          3: Writeln('Pouzita volba "--gama" s argumentem "', OptArg, '".');
        end;
      '?': Writeln('Pouziti: getopts [--alfa|-a] [--beta|-b arg]'
           + ' [--gama|-g [arg]] [soubor1, soubor2,...]');
    end;
  until Ch = EndOfOptions;
  // Po skončení bude v proměnné OptInd index prvního parametru, který
  // není volbou (je to tedy soubor).
  for I := OptInd to ParamCount do
    Writeln('Soubor "', ParamStr(I), '"');
end.

Co nás čeká příště?

Téma zpracovávání voleb na příkazovém řádku jsme tímto dílem seriálu vyčerpali, příště se začneme věnovat spojení Free Pascalu a XML, takže se máte na co těšit.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: