[Info-vax] Local Versus Global Command Options

Arne Vajhøj arne at vajhoej.dk
Fri Feb 14 20:02:20 EST 2025


On 2/14/2025 6:49 PM, Arne Vajhøj wrote:
> On 2/14/2025 2:02 PM, Simon Clubley wrote:
>>                                                              It also
>> doesn't help you with the main problem I mentioned, which is parsing
>> and validating the filter syntax. 
> 
>> How would you turn the list of filters, each with their own syntax, into
>> something that can be validated by DCL ? As a reminder, it is critical
>> that the filters are available to the program in the order they were
>> specified on the command line.
> 
> I think that can be define in CLD.
> 
> $ type fun4.cld
> define verb fun4
>      image "sys$disk:[]fun4"
>      parameter p1, value(type=$file, list, required)
> qualifier filter, value(type=filter_type, list, required), placement=local
> define type filter_type
>      keyword filtera, value(type=filtera_type, list, required)
>      keyword filterb, value(type=filterb_type, list, required)
> define type filtera_type
>      keyword a1, value(type=$number, required)
>      keyword a2, value(type=$number, required)
>      keyword x, value(type=$number, required)
> define type filterb_type
>      keyword b1, value(type=$number, required)
>      keyword b2, value(type=$number, required)
>      keyword x, value(type=$number, required)
> $ type fun4.pas
> [inherit('sys$library:pascal$cli_routines')]
> program fun4(input,output);
> 
> type
>     pstr = varying [255] of char;
>     filter_type = (filtera, filterb);
> 
> var
>     filter_list : array [1..100] of filter_type;
>     fnm, filter, a1, a2, b1, b2, x : pstr;
>     nfilters, i : integer;
> 
> begin
>     while odd(cli$get_value('P1', fnm.body, fnm.length)) do begin
>        write(fnm);
>        nfilters := 0;
>        while odd(cli$get_value('FILTER', filter.body, filter.length)) do 
> begin
>           nfilters := nfilters + 1;
>           if index(filter, 'FILTERA') = 1 then
>              filter_list[nfilters] := filtera
>           else if index(filter, 'FILTERB') = 1 then
>              filter_list[nfilters] := filterb
>           else
>              halt;
>        end;
>        for i := 1 to nfilters do begin
>           write(' ', filter_list[i]);
>           case filter_list[i] of
>              filtera:
>                 begin
>                    write(' filtera');
>                    cli$get_value('FILTERA.A1', a1.body, a1.length);
>                    write(' a1=', a1);
>                    cli$get_value('FILTERA.A2', a2.body, a2.length);
>                    write(' a2=', a2);
>                    cli$get_value('FILTERA.X', x.body, x.length);
>                    write(' x=', x);
>                 end;
>              filterb:
>                 begin
>                    write(' filterb');
>                    cli$get_value('FILTERB.B1', b1.body, b1.length);
>                    write(' b1=', b1);
>                    cli$get_value('FILTERB.B2', b2.body, b2.length);
>                    write(' b2=', b2);
>                    cli$get_value('FILTERB.X', x.body, x.length);
>                    write(' x=', x);
>                 end;
>           end;
>        end;
>        writeln;
>     end;
> end.
> $ pas fun4
> $ lin fun4
> $ set comm fun4
> $ fun4 f1.dat/ 
> filter=(filtera=(a1:12,a2:34,x:1234),filterb=(b1:56,b2:78,x:5678)),-
> 
> f2.dat/filter=(filterb=(b2:87,b1:65,x:8765),filtera=(a2:43,a1:21,x:4321))
> f1.dat  FILTERA filtera a1=12 a2=34 x=1234  FILTERB filterb b1=56 b2=78 x=5678
> f2.dat  FILTERB filterb b1=65 b2=87 x=8765  FILTERA filtera a1=21 a2=43 x=4321

But I like this version better:

$ type fun5.cld
define verb fun5
     image "sys$disk:[]fun5"
     parameter p1, value(type=$file, list, required)
qualifier filter, value(type=$quoted_string, list, required), 
placement=local
$ type fun5sup.cld
module fun5sup
define verb fa
     qualifier a1, value(type=$number, required)
     qualifier a2, value(type=$number, required)
     qualifier x, value(type=$number, required)
define verb fb
     qualifier b1, value(type=$number, required)
     qualifier b2, value(type=$number, required)
     qualifier x, value(type=$number, required)
$ type fun5.pas
[inherit('sys$library:pascal$cli_routines')]
program fun5(input,output);

type
    pstr = varying [255] of char;
    finfo = record
               fnm : pstr;
               nfilter : integer;
               filter_list : array [1..100] of pstr;
            end;

var
    fun5sup : [external] integer;

var
    finfo_list : array [1..100] of finfo;
    fnm, filter, a1, a2, b1, b2, x : pstr;
    n, i, j : integer;

begin
    n := 0;
    while odd(cli$get_value('P1', fnm.body, fnm.length)) do begin
       n := n + 1;
       finfo_list[n].fnm := fnm;
       finfo_list[n].nfilter := 0;
       while odd(cli$get_value('FILTER', filter.body, filter.length)) do 
begin
          finfo_list[n].nfilter := finfo_list[n].nfilter + 1;
          finfo_list[n].filter_list[finfo_list[n].nfilter] := 
substr(filter, 2, length(filter) - 2);
       end;
    end;
    for i := 1 to n do begin
       write(finfo_list[i].fnm);
       for j := 1 to finfo_list[i].nfilter do begin
          cli$dcl_parse(finfo_list[i].filter_list[j], fun5sup);
          if index(finfo_list[i].filter_list[j], 'fa') = 1 then begin
             write(' fa');
             cli$get_value('A1', a1.body, a1.length);
             write(' a1=', a1);
             cli$get_value('A2', a2.body, a2.length);
             write(' a2=', a2);
             cli$get_value('X', x.body, x.length);
             write(' x=', x);
          end else if index(finfo_list[i].filter_list[j], 'fb') = 1 then 
begin
             write(' fb');
             cli$get_value('B1', b1.body, b1.length);
             write(' b1=', b1);
             cli$get_value('B2', b2.body, b2.length);
             write(' b2=', b2);
             cli$get_value('X', x.body, x.length);
             write(' x=', x);
          end else begin
             halt;
          end;
       end;
       writeln;
    end;
end.
$ set comm/obj fun5sup
$ pas fun5
$ lin fun5 + fun5sup
$ set comm fun5
$ fun5 f1.dat/filter=("fa /a1=12 /a2:34 /x=1234","fb /b1=56 /b2=78 
/x=5678"),-
        f2.dat/filter=("fb /b2=87 /b1:65 /x:8765","fa /a2=43 /a1=21 
/x=4321")
f1.dat fa a1=12 a2=34 x=1234 fb b1=56 b2=78 x=5678
f2.dat fb b1=65 b2=87 x=8765 fa a1=21 a2=43 x=4321

Arne



More information about the Info-vax mailing list