• Local Versus Global Command Options

    From Lawrence D'Oliveiro@21:1/5 to All on Thu Feb 13 22:52:44 2025
    One thing about DCL syntax is its ability to specify options (what it
    calls “qualifiers”) either globally for the command, or locally to a particular command argument:

    «cmd»/«global-options» «arg1» «arg2» ...

    where each «arg» can take the form

    «subarg1»/«local-options-1»,«subarg2»/«local-options-2», ...

    and then I think you can have plus signs as well as commas, to denote
    another level of concatenation. And then you can put spaces
    before/after commas and plus signs, and those are ignored and not
    considered separators between arguments. So the presence or absence of
    a comma or plus sign can become quite significant.

    The traditional *nix command syntax never had provision for this. Most
    commands take the fairly simple form

    «cmd» «options» «args»

    where each of «options» and «args», if nonempty consists of one or
    more space-separated items, and all «options» are assumed to have
    global effect, though some can add quite a lot of elaboration on this
    where necessary.

    (Did somebody say “dd”? Passing arguments by keyword, anybody?)

    What’s the most complex *nix command you’ve come across? I think it
    has to be ffmpeg. This looks broadly like

    ffmpeg «local-input-options-1» -i «infile-1» \
    «local-input-options-2» -i «infile-2» ... \
    «local-output-options-1» «outfile-1» \
    «local-output-options-2» «outfile-2» ...

    The convention is that options apply to the immediately following file specification: this is prefixed with “-i” for an input file, and is a
    plain argument for an output file. Note the lack of “global” options:
    all settings apply to a particular file.

    But that’s not where it ends. Certain of the options can specify “filtergraphs”, which are entire chains of effects operations to be
    applied to a particular video or audio stream. The man page talks
    about “simple” versus “complex” filtergraphs, but even the “simple” ones can be pretty complex.

    Filtergraphs can also be used during real-time playback, with the
    “ffplay” command. For example:

    ffplay -autoexit -vf scale=1152:864,setsar=0.9 \
    'Sun Is Shining (Official Video).mp4'

    That “-vf” option specifies a sequence of video filters, first to
    scale up the video to make more use of my screen, and “setsar” (“Set Source Aspect Ratio”) to fix distortion in the shape of the image
    (everybody looking squashed) from the original digitization of the
    video.

    What would DCL-style syntax for ffmpeg look like? I suppose one
    obvious equivalence would be

    ffmpeg -
    «infile-1»/«local-input-options-1»,«infile-2»/«local-input-options-2»,... -
    «outfile-1»/«local-output-options-1»,«outfile-2»/«local-output-options-2»,... -

    (being very careful about where the commas go), but what about the
    syntax for filtergraphs? Would it be something like

    /vf=(«filter-name-1»=«filter-params-1»,«filter-name-2»=«filter-params-2»...)

    Does DCL have provision for this sort of complexity?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Thu Feb 13 20:06:47 2025
    On 2/13/2025 5:52 PM, Lawrence D'Oliveiro wrote:
    What would DCL-style syntax for ffmpeg look like? I suppose one
    obvious equivalence would be

    ffmpeg -
    «infile-1»/«local-input-options-1»,«infile-2»/«local-input-options-2»,... -
    «outfile-1»/«local-output-options-1»,«outfile-2»/«local-output-options-2»,... -

    (being very careful about where the commas go), but what about the
    syntax for filtergraphs? Would it be something like

    /vf=(«filter-name-1»=«filter-params-1»,«filter-name-2»=«filter-params-2»...)

    Does DCL have provision for this sort of complexity?

    You can do quite a bit with CDU, CLD and CLI$:

    $ type fun.cld
    define verb fun
    image "sys$disk:[]fun"
    parameter p1, value(type=$file)
    parameter p2, value(type=$file)
    parameter p3, value(type=$file)
    parameter p4, value(type=$file)
    parameter p5, value(type=$file)
    parameter p6, value(type=$file)
    parameter p7, value(type=$file)
    parameter p8, value(type=$file)
    qualifier q1, placement=local
    qualifier q2, value(type=a_and_b, list, required), placement=local
    define type a_and_b
    keyword a, value(type=$number, required)
    keyword b, value(type=$number, required)
    $ type fun.pas
    [inherit('sys$library:pascal$cli_routines')]
    program fun(input,output);

    type
    pstr = varying [255] of char;

    procedure check(pn : pstr);

    var
    fnm, a, b : pstr;

    begin
    if odd(cli$present(pn)) then begin
    cli$get_value(pn, fnm.body, fnm.length);
    write(pn, '=', fnm);
    if odd(cli$present('Q1')) then begin
    write(' Q1=present')
    end else begin
    write(' Q1=notpresent')
    end;
    if odd(cli$present('Q2')) then begin
    cli$get_value('Q2.A', a.body, a.length);
    write(' A=', a);
    cli$get_value('Q2.B', b.body, b.length);
    write(' B=', b);
    end;
    writeln;
    end;
    end;

    begin
    check('P1');
    check('P2');
    check('P3');
    check('P4');
    check('P5');
    check('P6');
    check('P7');
    check('P8');
    end.
    $ pas fun
    $ lin fun
    $ set comm fun
    $ fun x.dat /q2=(a:1,b:2) y.dat /q1 /q2=(a:3,b:4) z.dat /q2=(a:5,b:6)
    P1=x.dat Q1=notpresent A=1 B=2
    P2=y.dat Q1=present A=3 B=4
    P3=z.dat Q1=notpresent A=5 B=6

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Thu Feb 13 21:37:04 2025
    On 2/13/2025 8:06 PM, Arne Vajhøj wrote:
    On 2/13/2025 5:52 PM, Lawrence D'Oliveiro wrote:
    What would DCL-style syntax for ffmpeg look like? I suppose one
    obvious equivalence would be

         ffmpeg -
             «infile-1»/«local-input-options-1»,«infile-2»/«local-input-
    options-2»,... -
             «outfile-1»/«local-output-options-1»,«outfile-2»/«local-
    output-options-2»,... -

    (being very careful about where the commas go), but what about the
    syntax for filtergraphs? Would it be something like

         /vf=(«filter-name-1»=«filter-params-1»,«filter-name-2»=«filter-
    params-2»...)

    Does DCL have provision for this sort of complexity?

    You can do quite a bit with CDU, CLD and CLI$:

    $ type fun.cld
    define verb fun
        image "sys$disk:[]fun"
        parameter p1, value(type=$file)
        parameter p2, value(type=$file)
        parameter p3, value(type=$file)
        parameter p4, value(type=$file)
        parameter p5, value(type=$file)
        parameter p6, value(type=$file)
        parameter p7, value(type=$file)
        parameter p8, value(type=$file)
    qualifier q1, placement=local
    qualifier q2, value(type=a_and_b, list, required), placement=local
    define type a_and_b
        keyword a, value(type=$number, required)
        keyword b, value(type=$number, required)
    $ type fun.pas
    [inherit('sys$library:pascal$cli_routines')]
    program fun(input,output);

    type
       pstr = varying [255] of char;

    procedure check(pn : pstr);

    var
       fnm, a, b : pstr;

    begin
       if odd(cli$present(pn)) then begin
          cli$get_value(pn, fnm.body, fnm.length);
          write(pn, '=', fnm);
          if odd(cli$present('Q1')) then begin
             write(' Q1=present')
          end else begin
             write(' Q1=notpresent')
          end;
          if odd(cli$present('Q2')) then begin
             cli$get_value('Q2.A', a.body, a.length);
             write(' A=', a);
             cli$get_value('Q2.B', b.body, b.length);
             write(' B=', b);
          end;
          writeln;
       end;
    end;

    begin
       check('P1');
       check('P2');
       check('P3');
       check('P4');
       check('P5');
       check('P6');
       check('P7');
       check('P8');
    end.
    $ pas fun
    $ lin fun
    $ set comm fun
    $ fun x.dat /q2=(a:1,b:2) y.dat /q1 /q2=(a:3,b:4) z.dat /q2=(a:5,b:6) P1=x.dat Q1=notpresent A=1 B=2
    P2=y.dat Q1=present A=3 B=4
    P3=z.dat Q1=notpresent A=5 B=6

    Or with a P1 list:

    $ type fun2.cld
    define verb fun2
    image "sys$disk:[]fun2"
    parameter p1, value(type=$file, list, required)
    qualifier q1, placement=local
    qualifier q2, value(type=a_and_b, list, required), placement=local
    define type a_and_b
    keyword a, value(type=$number, required)
    keyword b, value(type=$number, required)
    $ type fun2.pas
    [inherit('sys$library:pascal$cli_routines')]
    program fun2(input,output);

    type
    pstr = varying [255] of char;

    var
    fnm, a, b : pstr;

    begin
    while odd(cli$get_value('P1', fnm.body, fnm.length)) do begin
    write(fnm);
    if odd(cli$present('Q1')) then begin
    write(' Q1=present')
    end else begin
    write(' Q1=notpresent')
    end;
    if odd(cli$present('Q2')) then begin
    cli$get_value('Q2.A', a.body, a.length);
    write(' A=', a);
    cli$get_value('Q2.B', b.body, b.length);
    write(' B=', b);
    end;
    writeln;
    end;
    end.
    $ pas fun2
    $ lin fun2
    $ set comm fun2
    $ fun2 x.dat/q2=(a:1,b:2), y.dat/q1/q2=(a:3,b:4), z.dat/q2=(a:5,b:6)
    x.dat Q1=notpresent A=1 B=2
    y.dat Q1=present A=3 B=4
    z.dat Q1=notpresent A=5 B=6

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to Lawrence D'Oliveiro on Fri Feb 14 13:38:59 2025
    On 2025-02-13, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:

    What?s the most complex *nix command you?ve come across? I think it
    has to be ffmpeg. This looks broadly like

    ffmpeg local-input-options-1 -i infile-1 \
    local-input-options-2 -i infile-2 ... \
    local-output-options-1 outfile-1 \
    local-output-options-2 outfile-2 ...

    The convention is that options apply to the immediately following file specification: this is prefixed with ?-i? for an input file, and is a
    plain argument for an output file. Note the lack of ?global? options:
    all settings apply to a particular file.

    But that?s not where it ends. Certain of the options can specify ?filtergraphs?, which are entire chains of effects operations to be
    applied to a particular video or audio stream. The man page talks
    about ?simple? versus ?complex? filtergraphs, but even the ?simple?
    ones can be pretty complex.

    Filtergraphs can also be used during real-time playback, with the
    ?ffplay? command. For example:

    ffplay -autoexit -vf scale=1152:864,setsar=0.9 \
    'Sun Is Shining (Official Video).mp4'

    That ?-vf? option specifies a sequence of video filters, first to
    scale up the video to make more use of my screen, and ?setsar? (?Set
    Source Aspect Ratio?) to fix distortion in the shape of the image
    (everybody looking squashed) from the original digitization of the
    video.

    What would DCL-style syntax for ffmpeg look like? I suppose one
    obvious equivalence would be

    ffmpeg -
    infile-1/local-input-options-1,infile-2/local-input-options-2,... -
    outfile-1/local-output-options-1,outfile-2/local-output-options-2,... -

    (being very careful about where the commas go), but what about the
    syntax for filtergraphs? Would it be something like

    /vf=(filter-name-1=filter-params-1,filter-name-2=filter-params-2...)

    Does DCL have provision for this sort of complexity?

    Not in any meaningful way. There's no way to validate the syntax or
    parameters of a filter or other ffmpeg syntax with DCL. For a simple
    example, when merging two files, one with an audio stream and one with
    a video stream, into a MP4 output container then specifying the input and output video stream numbers would be a parameter along the lines of "0:v:0".

    How would you even specify in DCL the first and last fields are numbers
    and the middle field is a letter from a list of valid values ?

    You can use DCL syntax in the way you specify, but the vast majority
    of the parsing would still have to be done in ffmpeg as it is at the
    moment. DCL syntax doesn't really give you anything extra.

    Similar comments apply to mplayer BTW, and to make something clear to
    people reading this (which is only implied above), the filters MUST be
    executed in the order given. For example, with mplayer, I might first
    use a crop filter to get rid of black bars within a frame and then
    apply a scale filter to the resulting frame.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Fri Feb 14 11:33:32 2025
    On 2/14/2025 8:38 AM, Simon Clubley wrote:
    On 2025-02-13, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:
    What would DCL-style syntax for ffmpeg look like? I suppose one
    obvious equivalence would be

    ffmpeg -
    «infile-1»/«local-input-options-1»,«infile-2»/«local-input-options-2»,... -
    «outfile-1»/«local-output-options-1»,«outfile-2»/«local-output-options-2»,... -

    (being very careful about where the commas go), but what about the
    syntax for filtergraphs? Would it be something like

    /vf=(«filter-name-1»=«filter-params-1»,«filter-name-2»=«filter-params-2»...)

    Does DCL have provision for this sort of complexity?

    Not in any meaningful way. There's no way to validate the syntax or parameters of a filter or other ffmpeg syntax with DCL. For a simple
    example, when merging two files, one with an audio stream and one with
    a video stream, into a MP4 output container then specifying the input and output video stream numbers would be a parameter along the lines of "0:v:0".

    How would you even specify in DCL the first and last fields are numbers
    and the middle field is a letter from a list of valid values ?

    You can use DCL syntax in the way you specify, but the vast majority
    of the parsing would still have to be done in ffmpeg as it is at the
    moment. DCL syntax doesn't really give you anything extra.

    You can define a bit in CLD. Including specifying that
    something is a number and something else is from an
    enumeration list.

    $ type fun3.cld
    define verb fun3
    image "sys$disk:[]fun3"
    parameter p1, value(type=$file, list, required)
    qualifier q, value(type=threeitems, list, required), placement=local
    define type threeitems
    keyword a, value(type=$number, required)
    keyword b, value(type=$quoted_string, required)
    keyword c, value(type=myenum, required)
    define type myenum
    keyword x
    keyword y
    keyword z
    $ type fun3.pas
    [inherit('sys$library:pascal$cli_routines')]
    program fun3(input,output);

    type
    pstr = varying [255] of char;

    var
    fnm, a, b, c : pstr;

    begin
    while odd(cli$get_value('P1', fnm.body, fnm.length)) do begin
    write(fnm);
    if odd(cli$present('Q')) then begin
    cli$get_value('Q.A', a.body, a.length);
    write(' A=', a);
    cli$get_value('Q.B', b.body, b.length);
    write(' B=', b);
    cli$get_value('Q.C', c.body, c.length);
    write(' C=', c);
    end;
    writeln;
    end;
    end.
    $ pas fun3
    $ lin fun3
    $ set comm fun3
    $ fun3 x.dat/q=(a:1,b:"This is x",c:x), y.dat/q=(a:2,b:"This is y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    x.dat A=1 B="This is x" C=X
    y.dat A=2 B="This is y" C=Y
    z.dat A=3 B="This is z" C=Z
    $ on error then continue
    $ fun3 x.dat/q=(a:x,b:"This is x",c:x), y.dat/q=(a:2,b:"This is y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    %DCL-W-NUMBER, invalid numeric value - supply an integer
    \X\
    $ fun3 x.dat/q=(a:1,b:"This is x",c:xdat), y.dat/q=(a:2,b:"This is
    y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    %DCL-W-IVKEYW, unrecognized keyword - check validity and spelling
    \XDAT\

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Fri Feb 14 19:02:47 2025
    On 2025-02-14, Arne Vajhj <arne@vajhoej.dk> wrote:

    You can define a bit in CLD. Including specifying that
    something is a number and something else is from an
    enumeration list.

    $ type fun3.cld
    define verb fun3
    image "sys$disk:[]fun3"
    parameter p1, value(type=$file, list, required)
    qualifier q, value(type=threeitems, list, required), placement=local
    define type threeitems
    keyword a, value(type=$number, required)
    keyword b, value(type=$quoted_string, required)
    keyword c, value(type=myenum, required)
    define type myenum
    keyword x
    keyword y
    keyword z
    $ type fun3.pas
    [inherit('sys$library:pascal$cli_routines')]
    program fun3(input,output);

    type
    pstr = varying [255] of char;

    var
    fnm, a, b, c : pstr;

    begin
    while odd(cli$get_value('P1', fnm.body, fnm.length)) do begin
    write(fnm);
    if odd(cli$present('Q')) then begin
    cli$get_value('Q.A', a.body, a.length);
    write(' A=', a);
    cli$get_value('Q.B', b.body, b.length);
    write(' B=', b);
    cli$get_value('Q.C', c.body, c.length);
    write(' C=', c);
    end;
    writeln;
    end;
    end.
    $ pas fun3
    $ lin fun3
    $ set comm fun3
    $ fun3 x.dat/q=(a:1,b:"This is x",c:x), y.dat/q=(a:2,b:"This is y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    x.dat A=1 B="This is x" C=X
    y.dat A=2 B="This is y" C=Y
    z.dat A=3 B="This is z" C=Z
    $ on error then continue
    $ fun3 x.dat/q=(a:x,b:"This is x",c:x), y.dat/q=(a:2,b:"This is y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    %DCL-W-NUMBER, invalid numeric value - supply an integer
    \X\
    $ fun3 x.dat/q=(a:1,b:"This is x",c:xdat), y.dat/q=(a:2,b:"This is
    y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    %DCL-W-IVKEYW, unrecognized keyword - check validity and spelling
    \XDAT\


    But it is no longer ffmpeg syntax, but convoluted DCL syntax. It also
    doesn't help you with the main problem I mentioned, which is parsing
    and validating the filter syntax. To give you an idea of the scale of
    the problem, here is the mplayer man page (which I know a lot better
    than the ffmpeg filters):

    https://linux.die.net/man/1/mplayer

    That is a _very_ long man page, so search for "-vf-add" and you should
    be in a section marked "Video Filters". In that section are the list of available filters, starting with the crop one I mentioned earlier.

    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.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Fri Feb 14 18:49:13 2025
    On 2/14/2025 2:02 PM, Simon Clubley wrote:
    On 2025-02-14, Arne Vajhøj <arne@vajhoej.dk> wrote:

    You can define a bit in CLD. Including specifying that
    something is a number and something else is from an
    enumeration list.
    ...
    $ fun3 x.dat/q=(a:1,b:"This is x",c:x), y.dat/q=(a:2,b:"This is y",c:y),
    z.dat/q=(a:3,b:"This is z",c:z)
    x.dat A=1 B="This is x" C=X
    y.dat A=2 B="This is y" C=Y
    z.dat A=3 B="This is z" C=Z
    $ on error then continue
    $ fun3 x.dat/q=(a:x,b:"This is x",c:x), y.dat/q=(a:2,b:"This is y",c:y),
    z.dat/q=(a:3,b:"This is z",c:z)
    %DCL-W-NUMBER, invalid numeric value - supply an integer
    \X\
    $ fun3 x.dat/q=(a:1,b:"This is x",c:xdat), y.dat/q=(a:2,b:"This is
    y",c:y), z.dat/q=(a:3,b:"This is z",c:z)
    %DCL-W-IVKEYW, unrecognized keyword - check validity and spelling
    \XDAT\


    But it is no longer ffmpeg syntax, but convoluted DCL syntax.

    DCL use DCL syntax. That is how it is.

    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

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Fri Feb 14 20:02:20 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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Berryman@21:1/5 to All on Sat Feb 15 12:22:59 2025
    On 2/14/25 6:02 PM, Arne Vajhøj wrote:
    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

    Way back when an Alpha workstation was my desktop, it had a good
    graphics card and a sound card. During this time I got mplayer running
    on VMS and was even able to use it to play DVDs. Sadly, subsequent to
    that time, itanium was too noisy for a desktop and VMS on x86 has no
    multimedia support.

    On *nix, one's program can define any command syntax desired since the command-line parsing is done entirely within the program. The shell
    doesn't really do anything except try to expand unquoted wildcards
    (which somewhat limits the use of wildcards since the program cannot differentiate between a source wildcard and a destination wildcard). On
    VMS, DCL can do it either way. One can define a syntax that allows DCL
    to do the parsing as Arne has shown, or one can tell DCL to simply pass
    the command line to the program and let the program do all of the
    parsing. One advantage of the former is that if the command-line fails
    to parse, the program never even has to be activated.

    So, IMHO, DCL is superior in this regard. The one thing I wish it had,
    in regards to command-line parsing, was a setting that meant "set the
    PIPE command as default". I am one of those users who only has ODS-5
    disks, always has parse_style set to extended, and all my utilities
    still using *nix syntax use lib$initialize.

    Mark Berryman

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Mark Berryman on Sat Feb 15 15:20:40 2025
    On 2/15/2025 2:22 PM, Mark Berryman wrote:
    On *nix, one's program can define any command syntax desired since the command-line parsing is done entirely within the program.  The shell
    doesn't really do anything except try to expand unquoted wildcards
    (which somewhat limits the use of wildcards since the program cannot differentiate between a source wildcard and a destination wildcard).  On VMS, DCL can do it either way.  One can define a syntax that allows DCL
    to do the parsing as Arne has shown, or one can tell DCL to simply pass
    the command line to the program and let the program do all of the
    parsing.  One advantage of the former is that if the command-line fails
    to parse, the program never even has to be activated.

    A VMS program has choices:
    1A) SET COMM and CLI$
    1B) SET COMM/OBJ, LIB$GET_FOREIGN and CLI$
    2) LIB$GET_FOREIGN and custom parsing
    3) Language specific way to get individual arguments

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Mark Berryman on Sat Feb 15 21:32:22 2025
    On Sat, 15 Feb 2025 12:22:59 -0700, Mark Berryman wrote:

    So, IMHO, DCL is superior in this regard.

    Unfortunately, no. The fundamental problem with DEC OSes (and this
    includes Windows) is that the command line is passed to the program as a
    single string buffer. On *nix systems, it is passed as an array of
    strings.

    You should be familiar with the well-known problem of one program invoking another with a command that might include characters with special meanings
    to a shell. On a *nix system, there is a simple way to avoid those special meanings: the first program invokes the second program directly, without
    going through a shell.

    Nowadays, there is even a simple library call to do this <https://manpages.debian.org/posix_spawn(3)>.

    This is not so easy to do with a DEC-style command line.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Sat Feb 15 20:21:12 2025
    On 2/15/2025 4:32 PM, Lawrence D'Oliveiro wrote:
    On Sat, 15 Feb 2025 12:22:59 -0700, Mark Berryman wrote:
    So, IMHO, DCL is superior in this regard.

    Unfortunately, no. The fundamental problem with DEC OSes (and this
    includes Windows) is that the command line is passed to the program as a single string buffer. On *nix systems, it is passed as an array of
    strings.

    You should be familiar with the well-known problem of one program invoking another with a command that might include characters with special meanings
    to a shell. On a *nix system, there is a simple way to avoid those special meanings: the first program invokes the second program directly, without going through a shell.

    Nowadays, there is even a simple library call to do this <https://manpages.debian.org/posix_spawn(3)>.

    This is not so easy to do with a DEC-style command line.

    How do you get those "characters with special meanings
    to a shell" interpreted instead of passed on VMS?

    All my trivial attempts failed:

    $ type self.pas
    [inherit('sys$library:pascal$lib_routines', 'sys$library:starlet')]
    program self(input,output);

    [external]
    function decc$system(%immed cmd : c_str_t) : integer; external;

    type
    pstr = varying [255] of char;

    var
    cmdlin : pstr;

    begin
    lib$get_foreign(cmdlin.body, , cmdlin.length);
    if cmdlin <> '' then begin
    writeln(cmdlin);
    end else begin
    decc$system(malloc_c_str('mcr sys$disk:[]self ''a'' ''b'' ''c'''));
    lib$spawn('mcr sys$disk:[]self ''a'' ''b'' ''c''');
    lib$do_command('mcr sys$disk:[]self ''a'' ''b'' ''c''');
    end;
    end.
    $ pas self
    $ link self
    $ a = 1
    $ b = 2
    $ c = 3
    $ mcr sys$disk:[]self 'a' 'b' 'c'
    1 2 3
    $ r self
    'a' 'b' 'c'
    'a' 'b' 'c'
    'a' 'b' 'c'

    $ type self2.c
    #include <stdio.h>
    #include <stdlib.h>

    #include <descrip.h>
    #include <lib$routines.h>

    int main(int argc, char *argv[])
    {
    $DESCRIPTOR(cmddesc, "mcr sys$disk:[]self2 'a' 'b' 'c'");
    if(argc > 1)
    {
    for(int i = 1; i < argc; i++) printf(" %s", argv[i]);
    printf("\n");
    }
    else
    {
    system("mcr sys$disk:[]self2 'a' 'b' 'c'");
    lib$spawn(&cmddesc);
    lib$do_command(&cmddesc);
    }
    return 0;
    }

    $ cc self2
    $ link self2
    $ a = 1
    $ b = 2
    $ c = 3
    $ mcr sys$disk:[]self 'a' 'b' 'c'
    1 2 3
    $ r self2
    'a' 'b' 'c'
    'a' 'b' 'c'
    'a' 'b' 'c'

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Berryman@21:1/5 to Lawrence D'Oliveiro on Sun Feb 16 15:52:23 2025
    On 2/15/25 2:32 PM, Lawrence D'Oliveiro wrote:
    On Sat, 15 Feb 2025 12:22:59 -0700, Mark Berryman wrote:

    So, IMHO, DCL is superior in this regard.

    Unfortunately, no. The fundamental problem with DEC OSes (and this
    includes Windows) is that the command line is passed to the program as a single string buffer. On *nix systems, it is passed as an array of
    strings.

    On *nix systems, the shell parses the command line into an array of
    strings using unquoted spaces as the separator which is then passed to
    the created process.

    On VMS, the crtl does the same parsing which means the program still
    sees an array of strings the same as on a *nix system.

    If I choose to use DCL, DCL does all of the parsing for me and the
    nature of the command-line is irrelevant.


    You should be familiar with the well-known problem of one program invoking another with a command that might include characters with special meanings
    to a shell. On a *nix system, there is a simple way to avoid those special meanings: the first program invokes the second program directly, without going through a shell.

    Nowadays, there is even a simple library call to do this <https://manpages.debian.org/posix_spawn(3)>.

    This is not so easy to do with a DEC-style command line.

    Incorrect. Programs on DEC OSes can invoke other programs directly and
    have been able to at least since the days of the PDP-11 (which somewhat predates the advent of posix_spawn). The nature of the command-line is completely up to the program depending on what function is used to call
    the new program.

    Mark Berryman

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Mark Berryman on Mon Feb 17 00:43:35 2025
    On Sun, 16 Feb 2025 15:52:23 -0700, Mark Berryman wrote:

    On *nix systems, the shell parses the command line into an array of
    strings using unquoted spaces as the separator which is then passed to
    the created process.

    If you don’t go through a shell, then you pass an array of already-
    separated words and you don’t have to worry about shell specials.

    On VMS, the crtl does the same parsing which means the program still
    sees an array of strings the same as on a *nix system.

    Consider what happens: if you pass unquoted text to program X, DCL
    converts it to uppercase, and I think also normalizes multiple spaces to a single space. If you don’t want the text to be uppercased or space- normalized, you put it in pairs of double quotes. But then these double
    quotes also get passed as part of the command line. So the receiving
    program has to do some non-trivial parsing just to get simple literal text
    via the command line.

    So now, how do you invoke program X directly from your own program Y,
    without going through DCL? For consistency, you have to mimic all the same misbehaviour of DCL to get the command line in the right format. If you
    don’t want to do that, then you need some option to tell program X to
    bypass all that special processing, and just accept the command line as
    is. So it needs to distinguish between two ways of being invoked: directly
    or via DCL!

    If I choose to use DCL, DCL does all of the parsing for me and the
    nature of the command-line is irrelevant.

    If you don’t use DCL, then how do you invoke a program that expects DCL to parse its command line for it? What happens to all of Arne’s lovingly- crafted .CLD files?

    Programs on DEC OSes can invoke other programs directly and
    have been able to at least since the days of the PDP-11 ...

    Yes, and there have been quite a few pitfalls with that, as I mentioned
    above. Windows suffers from the same drawback, and this has even led to security holes with Windows programs.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Berryman@21:1/5 to Lawrence D'Oliveiro on Mon Feb 17 12:02:37 2025
    On 2/16/25 5:43 PM, Lawrence D'Oliveiro wrote:
    On Sun, 16 Feb 2025 15:52:23 -0700, Mark Berryman wrote:

    On *nix systems, the shell parses the command line into an array of
    strings using unquoted spaces as the separator which is then passed to
    the created process.

    If you don’t go through a shell, then you pass an array of already- separated words and you don’t have to worry about shell specials.

    On VMS, the crtl does the same parsing which means the program still
    sees an array of strings the same as on a *nix system.

    Consider what happens: if you pass unquoted text to program X, DCL
    converts it to uppercase, and I think also normalizes multiple spaces to a single space. If you don’t want the text to be uppercased or space- normalized, you put it in pairs of double quotes. But then these double quotes also get passed as part of the command line. So the receiving
    program has to do some non-trivial parsing just to get simple literal text via the command line.

    So, so, so very wrong. You are *way* behind the times.

    I *never* have to quote arguments when using programs that still use
    *nix syntax on VMS. My arguments' case is never changed.

    Here is the entry point to any C program on VMS:

    int main (int argc, char *argv[], char *envp[]);

    See? Argument passing works the same on VMS as it does on *nix, as
    described above.

    Let's see, what's a good example? Ah, here's one:

    $ gs -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile=<something>.pdf <something>.ps

    Again, see? No quoting. No case conversion. Ghostscript sees the
    command exactly as I typed it and I typed it exactly as I would on a
    *nix system.


    So now, how do you invoke program X directly from your own program Y,
    without going through DCL? For consistency, you have to mimic all the same misbehaviour of DCL to get the command line in the right format. If you don’t want to do that, then you need some option to tell program X to bypass all that special processing, and just accept the command line as
    is. So it needs to distinguish between two ways of being invoked: directly
    or via DCL!

    Wrong again. There are a number of ways to invoke a program without
    going through DCL. Since you seem to be a Linux fan, look up the
    various exec functions for starters. (Note, there are other ways).


    If I choose to use DCL, DCL does all of the parsing for me and the
    nature of the command-line is irrelevant.

    If you don’t use DCL, then how do you invoke a program that expects DCL to parse its command line for it? What happens to all of Arne’s lovingly- crafted .CLD files?

    You apparently know as little about VMS as you do programming in
    general. The Docs are online. Go read them. They will answer your
    questions.


    Programs on DEC OSes can invoke other programs directly and
    have been able to at least since the days of the PDP-11 ...

    Yes, and there have been quite a few pitfalls with that, as I mentioned above. Windows suffers from the same drawback, and this has even led to security holes with Windows programs.

    Hmmm, first you tout that invoking programs directly eliminates pitfalls
    then you claim that doing so causes them. So, which is it?

    Mark Berryman

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Mark Berryman on Mon Feb 17 21:49:50 2025
    On Mon, 17 Feb 2025 12:02:37 -0700, Mark Berryman wrote:

    On 2/16/25 5:43 PM, Lawrence D'Oliveiro wrote:

    Consider what happens: if you pass unquoted text to program X, DCL
    converts it to uppercase, and I think also normalizes multiple spaces
    to a single space. If you don’t want the text to be uppercased or
    space- normalized, you put it in pairs of double quotes. But then these
    double quotes also get passed as part of the command line. So the
    receiving program has to do some non-trivial parsing just to get simple
    literal text via the command line.

    So, so, so very wrong. You are *way* behind the times.

    I *never* have to quote arguments when using programs that still use
    *nix syntax on VMS. My arguments' case is never changed.

    Prove it. It seems to me what you are claiming would break backward compatibility with the way VMS used to work.

    Here is the entry point to any C program on VMS:

    int main (int argc, char *argv[], char *envp[]);

    See? Argument passing works the same on VMS as it does on *nix, as
    described above.

    Let's see, what's a good example? Ah, here's one:

    $ gs -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile=<something>.pdf <something>.ps

    Again, see? No quoting. No case conversion. Ghostscript sees the
    command exactly as I typed it and I typed it exactly as I would on a
    *nix system.

    Can you show us a simple C program that just prints out its command
    arguments, and how it responds to some sample command lines?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert A. Brooks@21:1/5 to bill on Mon Feb 17 16:42:10 2025
    On 2/17/2025 4:09 PM, bill wrote:
    On 2/17/2025 2:02 PM, Mark Berryman wrote:
    On 2/16/25 5:43 PM, Lawrence D'Oliveiro wrote:

    If I choose to use DCL, DCL does all of the parsing for me and the
    nature of the command-line is irrelevant.

    If you don’t use DCL, then how do you invoke a program that expects DCL to
    parse its command line for it? What happens to all of Arne’s lovingly- >>> crafted .CLD files?

    You apparently know as little about VMS as you do programming in general.  The
    Docs are online.  Go read them.  They will answer your questions.


    Which is why people need to stop feeding the troll!!!!

    +1

    --

    --- Rob

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From jayjwa@21:1/5 to Lawrence D'Oliveiro on Mon Feb 17 18:46:49 2025
    Lawrence D'Oliveiro <ldo@nz.invalid> writes:

    Can you show us a simple C program that just prints out its command arguments, and how it responds to some sample command lines?
    VMS seems to be alone in converting case.

    ✔≻ cat cmdlin.c
    /* A program to demo printing of command line args under various OSs. */ #include <stdio.h>


    int main( int argc, char *argv[] ) {
    printf( "Did I hear you say %s?\n", argv[1] );
    return 0;
    }
    ✔≻ gcc -o cmdlin cmdlin.c
    ✔≻ ./cmdlin Hello World
    Did I hear you say Hello?
    ✔≻ ./cmdlin "Hello World"
    Did I hear you say Hello World?

    @compile cmdlin.c
    KCC: CMDLIN
    "CMDLIN.C", line 9: [Note] Parameter "argc" not used
    (main+4, p.1 l.8): "Did I hear you say %s?\n", argv[1] ); return 0; }

    <JAYJWA.PROGRAMMING>CMDLIN.PRE.1
    <JAYJWA.PROGRAMMING>CMDLIN.FAI.1
    FAIL: CMDLIN
    @load cmdlin
    LINK: Loading
    @save cmdlin
    CMDLIN.EXE.2 Saved
    @cmdlin Hello World
    Did I hear you say Hello?
    @cmdlin "Hello World"
    Did I hear you say Hello World?

    c:\bcc32 -5 -ecmdlin.exe cmdlin.c
    c:\cmdlin Hello World
    Did I hear you say Hello?
    c:\cmdlin "Hello World"
    Did I hear you say Hello World?

    $ cc /version
    Compaq C V6.4-005 on OpenVMS VAX V7.3
    $ cc cmdlin.c
    $ link cmdlin
    $ mcr DUA1:[JAYJWA.PROGRAMMING.C]cmdlin Hello World
    Did I hear you say hello?
    $ mcr DUA1:[JAYJWA.PROGRAMMING.C]cmdlin "Hello World"
    Did I hear you say Hello World?

    This matters with tools like curl (-O vs -o) and zip (-V and -v).

    --
    PGP Key ID: 781C A3E2 C6ED 70A6 B356 7AF5 B510 542E D460 5CAE
    "The Internet should always be the Wild West!"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Mon Feb 17 19:38:57 2025
    On 2/17/2025 4:49 PM, Lawrence D'Oliveiro wrote:
    On Mon, 17 Feb 2025 12:02:37 -0700, Mark Berryman wrote:
    On 2/16/25 5:43 PM, Lawrence D'Oliveiro wrote:
    Consider what happens: if you pass unquoted text to program X, DCL
    converts it to uppercase, and I think also normalizes multiple spaces
    to a single space. If you don’t want the text to be uppercased or
    space- normalized, you put it in pairs of double quotes. But then these
    double quotes also get passed as part of the command line. So the
    receiving program has to do some non-trivial parsing just to get simple
    literal text via the command line.

    So, so, so very wrong. You are *way* behind the times.

    I *never* have to quote arguments when using programs that still use
    *nix syntax on VMS. My arguments' case is never changed.

    Prove it. It seems to me what you are claiming would break backward compatibility with the way VMS used to work.

    Here is the entry point to any C program on VMS:

    int main (int argc, char *argv[], char *envp[]);

    See? Argument passing works the same on VMS as it does on *nix, as
    described above.

    Let's see, what's a good example? Ah, here's one:

    $ gs -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr
    -sOutputFile=<something>.pdf <something>.ps

    Again, see? No quoting. No case conversion. Ghostscript sees the
    command exactly as I typed it and I typed it exactly as I would on a
    *nix system.

    Can you show us a simple C program that just prints out its command arguments, and how it responds to some sample command lines?

    Why would we do that?

    Last time you came with those claims I posted (23-May-2024)
    a rather extensive demo with CLI, foreign command, hybrid, C
    and DCL with both /parse=ext and /parse=trad.

    Apparently you did not read it. Which is fine, but don't expect
    anybody to redo the work when you did not read it the first time.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to jayjwa on Mon Feb 17 19:20:57 2025
    On 2/17/2025 6:46 PM, jayjwa wrote:
    VMS seems to be alone in converting case.

    ✔≻ cat cmdlin.c
    /* A program to demo printing of command line args under various OSs. */ #include <stdio.h>


    int main( int argc, char *argv[] ) {
    printf( "Did I hear you say %s?\n", argv[1] );
    return 0;
    }

    $ cc /version
    Compaq C V6.4-005 on OpenVMS VAX V7.3
    $ cc cmdlin.c
    $ link cmdlin
    $ mcr DUA1:[JAYJWA.PROGRAMMING.C]cmdlin Hello World
    Did I hear you say hello?
    $ mcr DUA1:[JAYJWA.PROGRAMMING.C]cmdlin "Hello World"
    Did I hear you say Hello World?

    Yeah. But look at the calendar.

    $ mcr []cmdlin Hello World
    Did I hear you say Hello?
    $ set proc/pars=trad
    $ mcr []cmdlin Hello World
    Did I hear you say hello?
    $ set proc/pars=ext
    $ mcr []cmdlin Hello World
    Did I hear you say Hello?

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Tue Feb 18 01:21:24 2025
    On Mon, 17 Feb 2025 19:38:57 -0500, Arne Vajhøj wrote:

    On 2/17/2025 4:49 PM, Lawrence D'Oliveiro wrote:

    On Mon, 17 Feb 2025 12:02:37 -0700, Mark Berryman wrote:

    $ gs -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr
    -sOutputFile=<something>.pdf <something>.ps

    Again, see? No quoting. No case conversion. Ghostscript sees the
    command exactly as I typed it and I typed it exactly as I would on a
    *nix system.

    Can you show us a simple C program that just prints out its command
    arguments, and how it responds to some sample command lines?

    Why would we do that?

    To prove that Mr Berryman is blowing smoke out his arse.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to jayjwa on Tue Feb 18 01:19:55 2025
    On Mon, 17 Feb 2025 18:46:49 -0500, jayjwa wrote:

    $ mcr DUA1:[JAYJWA.PROGRAMMING.C]cmdlin Hello World
    Did I hear you say hello?

    That demonstrates, does it not, that the C runtime is doing its own
    processing of the command line buffer, to try to mimic POSIX behaviour.
    Which proves my point, does it not.

    That probably includes stripping of quotes as well.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to jayjwa on Tue Feb 18 02:12:00 2025
    On Mon, 17 Feb 2025 18:46:49 -0500, jayjwa wrote:

    $ mcr DUA1:[JAYJWA.PROGRAMMING.C]cmdlin Hello World
    Did I hear you say hello?

    What you forgot to do is SET PROCESS/PARSE_STYLE=EXTENDED. I think this
    was added in VMS v7.2. It does case preservation and disables
    interpretation of some special characters, but there is no mention that I
    can see of what it does to quotation marks.

    OK, the proper test would be a simple program, maybe not in C, that does a LIB$GET_FOREIGN and shows the results of that. Then we can compare giving
    it different command lines and seeing what happens to them.

    Basically, the whole thing smells like a gigantic hack to try to bring
    things a little closer to POSIX behaviour. I doubt it’s very successful.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Mon Feb 17 21:41:07 2025
    On 2/15/2025 3:20 PM, Arne Vajhøj wrote:
    On 2/15/2025 2:22 PM, Mark Berryman wrote:
    On *nix, one's program can define any command syntax desired since the
    command-line parsing is done entirely within the program.  The shell
    doesn't really do anything except try to expand unquoted wildcards
    (which somewhat limits the use of wildcards since the program cannot
    differentiate between a source wildcard and a destination wildcard).
    On VMS, DCL can do it either way.  One can define a syntax that allows
    DCL to do the parsing as Arne has shown, or one can tell DCL to simply
    pass the command line to the program and let the program do all of the
    parsing.  One advantage of the former is that if the command-line
    fails to parse, the program never even has to be activated.

    A VMS program has choices:
    1A) SET COMM and CLI$
    1B) SET COMM/OBJ, LIB$GET_FOREIGN and CLI$
    2) LIB$GET_FOREIGN and custom parsing
    3) Language specific way to get individual arguments

    Pascal demo:

    $ type cl1a.cld
    define verb cl1a
    image "sys$disk:[]cl1a"
    qualifier f, value(type=$file, required)
    $ set comm cl1a
    $ type cl1a.pas
    [inherit('pascal$cli_routines')]
    program cl1a(input,output);

    type
    pstr = varying [255] of char;

    var
    f : pstr;

    begin
    cli$get_value('F', f.body, f.length);
    writeln('Pascal CL1A F=', f);
    end.
    $ pas cl1a
    $ link cl1a
    $ cl1a /f=z.z
    Pascal CL1A F=z.z
    $ type cl1bsup.cld
    module cl1bsup
    define verb cl1b
    qualifier f, value(type=$file, required)
    $ type cl1b.pas
    [inherit('sys$library:pascal$lib_routines',
    'sys$library:pascal$cli_routines')]
    program cl1b(input,output);

    type
    pstr = varying [255] of char;

    var
    cl1bsup : [external] integer;
    cmdlin : pstr;
    f : pstr;
    i : integer;

    begin
    lib$get_foreign(cmdlin.body, , cmdlin.length);
    for i := 1 to length(cmdlin) do begin
    if cmdlin[i] = '-' then begin
    cmdlin[i] := '/';
    end else if cmdlin[i] = ' ' then begin
    cmdlin[i] := '=';
    end;
    end;
    cli$dcl_parse('cl1b ' + cmdlin, cl1bsup);
    cli$get_value('F', f.body, f.length);
    writeln('Pascal CL1B F=', f);
    end.
    $ set comm/obj cl1bsup
    $ pas cl1b
    $ link cl1b + cl1bsup
    $ cl1b :== $sys$disk:[]cl1b
    $ cl1b /f=z.z
    Pascal CL1B F=z.z
    $ cl1b -f z.z
    Pascal CL1B F=z.z
    $ type cl2.pas
    [inherit('sys$library:pascal$lib_routines')]
    program cl1b(input,output);

    type
    pstr = varying [255] of char;

    var
    cmdlin : pstr;
    f : pstr;
    ix : integer;

    begin
    lib$get_foreign(cmdlin.body, , cmdlin.length);
    ix := index(cmdlin, '-f ');
    f := substr(cmdlin, ix + 3, length(cmdlin) - ix - 2);
    writeln('Pascal CL2 F=', f);
    end.
    $ pas cl2
    $ link cl2
    $ cl2 :== $sys$disk:[]cl2
    $ cl2 -f z.z
    Pascal CL2 F=z.z

    C demo:

    $ type cl1a.cld
    define verb cl1a
    image "sys$disk:[]cl1a"
    qualifier f, value(type=$file, required)
    $ set comm cl1a
    $ type cl1a.c
    #include <stdio.h>
    #include <stdint.h>

    #include <descrip.h>
    #include <cli$routines.h>

    int main()
    {
    char f[255];
    int16_t flen;
    $DESCRIPTOR(fnamedesc, "F");
    $DESCRIPTOR(fdesc, f);
    cli$get_value(&fnamedesc, &fdesc, &flen);
    f[flen] = 0;
    printf("C CL1A F=%s\n", f);
    return 0;
    }

    $ cc cl1a
    $ link cl1a
    $ cl1a /f=z.z
    C CL1A F=z.z
    $ type cl1bsup.cld
    module cl1bsup
    define verb cl1b
    qualifier f, value(type=$file, required)
    $ type cl1b.c
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>

    #include <descrip.h>
    #include <lib$routines.h>
    #include <cli$routines.h>

    globalvalue int32_t cl1bsup;

    int main()
    {
    char cmdlin[256];
    int16_t cmdlinlen;
    $DESCRIPTOR(cmdlindesc, cmdlin);
    lib$get_foreign(&cmdlindesc, 0, &cmdlinlen);
    cmdlin[cmdlinlen] = 0;
    for(int i = 0; i < cmdlinlen; i++)
    {
    if(cmdlin[i] == '-') cmdlin[i] = '/';
    if(cmdlin[i] == ' ') cmdlin[i] = '=';
    }
    char cmdlin2[256];
    $DESCRIPTOR(cmdlin2desc, cmdlin2);
    strcpy(cmdlin2, "CL1B ");
    strcat(cmdlin2, cmdlin);
    cmdlin2desc.dsc$w_length = strlen(cmdlin2);
    cli$dcl_parse(&cmdlin2desc, cl1bsup);
    char f[256];
    int16_t flen;
    $DESCRIPTOR(fnamedesc, "F");
    $DESCRIPTOR(fdesc, f);
    cli$get_value(&fnamedesc, &fdesc, &flen);
    f[flen] = 0;
    printf("C CL1B F=%s\n", f);
    return 0;
    }

    $ set comm/obj cl1bsup
    $ cc cl1b
    $ link cl1b + cl1bsup
    $ cl1b :== $sys$disk:[]cl1b
    $ cl1b /f=z.z
    C CL1B F=z.z
    $ cl1b -f z.z
    C CL1B F=z.z
    $ type cl2.c
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>

    #include <descrip.h>
    #include <lib$routines.h>

    int main()
    {
    char cmdlin[256];
    int16_t cmdlinlen;
    $DESCRIPTOR(cmdlindesc, cmdlin);
    lib$get_foreign(&cmdlindesc, 0, &cmdlinlen);
    cmdlin[cmdlinlen] = 0;
    char *p = strstr(cmdlin, "-f");
    char f[256];
    strcpy(f, p + 3);
    printf("C CL2 F=%s\n", f);
    return 0;
    }

    $ cc cl2
    $ link cl2
    $ cl2 :== $sys$disk:[]cl2
    $ cl2 -f z.z
    C CL2 F=z.z
    $ type cl3.c
    #include <stdio.h>
    #include <string.h>
    #include <stdbool.h>

    int main(int argc, char *argv[])
    {
    char *f = "";
    bool fnext = false;
    for(int i = 0; i < argc; i++)
    {
    if(fnext) f = argv[i];
    fnext = strcmp(argv[i], "-f") == 0;
    }
    printf("C CL3 F=%s\n", f);
    return 0;
    }
    $ cc cl3
    $ link cl3
    $ cl3 :== $sys$disk:[]cl3
    $ cl3 -f z.z
    C CL3 F=z.z

    Python demo:

    $ type cl3.py
    import sys

    f = ''
    fnext = False
    for arg in sys.argv:
    if fnext:
    f = arg
    fnext = arg == '-f'
    print(f"Python C3 F={f}")
    $ python cl3.py -f z.z
    Python C3 F=z.z

    (the CL2 parsing examples are not robust, but that is another
    topic)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Berryman@21:1/5 to Lawrence D'Oliveiro on Mon Feb 17 19:23:07 2025
    On 2/17/25 2:49 PM, Lawrence D'Oliveiro wrote:
    On Mon, 17 Feb 2025 12:02:37 -0700, Mark Berryman wrote:

    On 2/16/25 5:43 PM, Lawrence D'Oliveiro wrote:

    Consider what happens: if you pass unquoted text to program X, DCL
    converts it to uppercase, and I think also normalizes multiple spaces
    to a single space. If you don’t want the text to be uppercased or
    space- normalized, you put it in pairs of double quotes. But then these
    double quotes also get passed as part of the command line. So the
    receiving program has to do some non-trivial parsing just to get simple
    literal text via the command line.

    So, so, so very wrong. You are *way* behind the times.

    I *never* have to quote arguments when using programs that still use
    *nix syntax on VMS. My arguments' case is never changed.

    Prove it. It seems to me what you are claiming would break backward compatibility with the way VMS used to work.

    $ gs -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr
    -sOutputFile=<something>.pdf <something>.ps

    I'm pretty sure this just did.

    And no, no breakage. Each user on each VMS system can choose how they
    want to things to work. I could easily set things up to work the way
    you think they should work but that would be so '90s; pretty much what
    the poster from VAX/VMS showed. I prefer to operate in the 21st century
    and take advantage of what VMS offers today, something of which you have
    proven yourself completely ignorant.

    .
    .
    .
    Can you show us a simple C program that just prints out its command arguments, and how it responds to some sample command lines?

    Easily.

    $ type proof.c
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
    for (int i=1; i<argc; i++)
    printf("%s\n", argv[i]);
    }


    $ mcr []proof These Are The Arguments
    These
    Are
    The
    Arguments

    $ mcr []proof These Are The "Arguments"
    These
    Are
    The
    Arguments


    Now, please crawl back into your hole. Trolls don't do well in sunlight
    and your extreme ... obtuseness ... is showing.

    Everyone else: Yes, I've once again been forced to face the fact that
    you can't fix stupid. I won't be responding anymore.

    Mark Berryman

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Mark Berryman on Wed Feb 19 01:58:52 2025
    On Mon, 17 Feb 2025 19:23:07 -0700, Mark Berryman wrote:

    On 2/17/25 2:49 PM, Lawrence D'Oliveiro wrote:

    Can you show us a simple C program that just prints out its command
    arguments, and how it responds to some sample command lines?

    Easily.

    Try some more subtle examples. On a proper POSIX-type system:

    QUOTE='"'
    ./test "Hello World" ${QUOTE}Hello World${QUOTE}
    Hello World
    "Hello
    World"

    Try to get the equivalent in DCL:

    quote = """"
    «rigmarole equivalent to ./test» "Hello World" 'quote'Hello World'quote'

    What’s it going to print?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Tue Feb 18 21:56:51 2025
    On 2/18/2025 8:58 PM, Lawrence D'Oliveiro wrote:
    On Mon, 17 Feb 2025 19:23:07 -0700, Mark Berryman wrote:
    On 2/17/25 2:49 PM, Lawrence D'Oliveiro wrote:
    Can you show us a simple C program that just prints out its command
    arguments, and how it responds to some sample command lines?

    Easily.

    Try some more subtle examples. On a proper POSIX-type system:

    QUOTE='"'
    ./test "Hello World" ${QUOTE}Hello World${QUOTE}
    Hello World
    "Hello
    World"

    Try to get the equivalent in DCL:

    quote = """"
    «rigmarole equivalent to ./test» "Hello World" 'quote'Hello World'quote'

    What’s it going to print?

    This is more of a shell question than an OS question.

    bash and DCL are different.

    $ bash
    bash-4.4$ QUOTE='"'
    bash-4.4$ ./test "Hello World" ${QUOTE}Hello World${QUOTE}
    Hello World
    "Hello
    World"
    bash-4.4$ exit
    exit

    $ quote = """"""
    $ mcr sys$disk:[]test "Hello World" "''quote'"Hello World"''quote'"
    Hello World
    "Hello
    World"

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Feb 19 03:03:16 2025
    In article <67b54873$0$709$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 2/18/2025 8:58 PM, Lawrence D'Oliveiro wrote:
    On Mon, 17 Feb 2025 19:23:07 -0700, Mark Berryman wrote:
    On 2/17/25 2:49 PM, Lawrence D'Oliveiro wrote:
    Can you show us a simple C program that just prints out its command
    arguments, and how it responds to some sample command lines?

    Easily.

    Try some more subtle examples. On a proper POSIX-type system:

    QUOTE='"'
    ./test "Hello World" ${QUOTE}Hello World${QUOTE}
    Hello World
    "Hello
    World"

    Try to get the equivalent in DCL:

    quote = """"
    «rigmarole equivalent to ./test» "Hello World" 'quote'Hello >World'quote'

    What’s it going to print?

    This is more of a shell question than an OS question.

    bash and DCL are different.

    $ bash
    bash-4.4$ QUOTE='"'
    bash-4.4$ ./test "Hello World" ${QUOTE}Hello World${QUOTE}
    Hello World
    "Hello
    World"
    bash-4.4$ exit
    exit

    $ quote = """"""
    $ mcr sys$disk:[]test "Hello World" "''quote'"Hello World"''quote'"
    Hello World
    "Hello
    World"

    I am utterly baffled as to why you continue to regularly
    engage with this troll. It's your choice, of course, but
    getting the backsplatter is unpleasant for rest of us who
    have already plonked him.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert A. Brooks@21:1/5 to Dan Cross on Tue Feb 18 23:24:53 2025
    On 2/18/2025 10:03 PM, Dan Cross wrote:

    I am utterly baffled as to why you continue to regularly
    engage with this troll. It's your choice, of course, but
    getting the backsplatter is unpleasant for rest of us who
    have already plonked him.

    +1!

    --

    --- Rob

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Robert A. Brooks on Wed Feb 19 16:06:10 2025
    On 2/18/2025 11:24 PM, Robert A. Brooks wrote:
    On 2/18/2025 10:03 PM, Dan Cross wrote:
    I am utterly baffled as to why you continue to regularly
    engage with this troll.  It's your choice, of course, but
    getting the backsplatter is unpleasant for rest of us who
    have already plonked him.

    +1!

    I have a different perspective.

    The code posted, which I ran on VMS as:

    $ bash
    bash-4.4$ QUOTE='"'
    bash-4.4$ ./test "Hello World" ${QUOTE}Hello World${QUOTE}
    Hello World
    "Hello
    World"
    bash-4.4$ exit
    exit

    (using VSI's recent VMS x86-64 GNV kit)

    may not be something used in the real world, but it does raise the
    question of how to do it in DCL.

    And I came up with:

    $ quote = """"""
    $ mcr sys$disk:[]test "Hello World" "''quote'"Hello World"''quote'"
    Hello World
    "Hello
    World"

    There may be better solutions.

    (if anyone knows one please post!)

    But it is definitely on topic for c.o.v/I-V.

    And maybe (just maybe) it is useful for a current or a future reader.

    I do not care much about who raised the question. It doesn't change
    being on topic or potential usefulness.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Feb 19 21:53:17 2025
    In article <67b647c3$0$712$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 2/18/2025 11:24 PM, Robert A. Brooks wrote:
    On 2/18/2025 10:03 PM, Dan Cross wrote:
    I am utterly baffled as to why you continue to regularly
    engage with this troll.  It's your choice, of course, but
    getting the backsplatter is unpleasant for rest of us who
    have already plonked him.

    +1!

    I have a different perspective.

    [snip]

    But it is definitely on topic for c.o.v/I-V.

    And maybe (just maybe) it is useful for a current or a future reader.

    I do not care much about who raised the question. It doesn't change
    being on topic or potential usefulness.

    Be that as it may, the person you are responding to, and that
    you regularly interact with at length, has shown repeatedly that
    he is not acting in good faith.

    Technical answers to technical questions, and even spirited
    debates with vigorous disagreement, are all well and good as
    long as all parties are at least attempting to honor a collegial
    spirit of cooperation. But in this case, as with most cases
    involving Lawrence, the base conditions in which to have the
    discussion are simply not met.

    This is the sort of thing that ought to be in an FAQ.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Feb 19 23:43:10 2025
    On Wed, 19 Feb 2025 16:06:10 -0500, Arne Vajhøj wrote:

    And I came up with:

    $ quote = """"""
    $ mcr sys$disk:[]test "Hello World" "''quote'"Hello World"''quote'"
    Hello World
    "Hello
    World"

    Did you notice that DCL (and therefore the receiving program) cannot tell
    the difference between substituting the “quote” variable versus entering a literal quote?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Feb 19 23:20:11 2025
    On Tue, 18 Feb 2025 21:56:51 -0500, Arne Vajhøj wrote:

    This is more of a shell question than an OS question.

    bash and DCL are different.

    It’s a fundamental difference in how the OSes handle the command line.

    Remember, the DEC model (and also that of Microsoft Windows) is that of a simple string buffer. The POSIX model is an array of strings (words).

    To emulate the POSIX way of doing things when a program A spawns a program
    B without going through the shell, in the DEC/Microsoft model program A
    has to encode the words as though they were being fed to a shell. And correspondingly, program B has to decode the result in the same way, as
    though it were receiving the command as a shell. This is a complex and
    fragile process, with ample opportunities for error.

    Try that example again, the way I wrote it, and you should get a better
    idea of what I mean.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stephen Hoffman@21:1/5 to Dan Cross on Fri Feb 21 16:42:56 2025
    On 2025-02-19 21:53:17 +0000, Dan Cross said:

    Be that as it may, the person you are responding to, and that you
    regularly interact with at length, has shown repeatedly that he is not
    acting in good faith.

    Technical answers to technical questions, and even spirited debates
    with vigorous disagreement, are all well and good as long as all
    parties are at least attempting to honor a collegial spirit of
    cooperation. But in this case, as with most cases involving Lawrence,
    the base conditions in which to have the discussion are simply not met.

    This is the sort of thing that ought to be in an FAQ.

    Is it feasible for DCL? Sure. Though it'll likely involve passing some
    of the syntax to lib$table_parse or ilk for parsing, as do a few DCL
    commands I've encountered (or have written) over the years. Or can go
    directly to lib$table_parse for the rest of the command, for that
    matter.

    There've also been a few discussions about providing getopt_long()-like
    support with DCL parsing "underneath" the classic C parsing, and work
    to overhaul the DCL CLD APIs, but the results of that design and
    development effort never seemed compelling.

    There are commands around that have four or more interfaces, too:
    getopt() or getopt_long() foreign command, SET COMMAND and DCL
    invocation, RUN with prompting, and callable API. Adding a DCL parsing
    loop inside the app is feasible, too. (There's at least one in OpenVMS
    itself with the first four.)

    The whole area of command parsing, command options and syntax, saving
    and maintaining app-related preferences data storage and management,
    and related details within OpenVMS are all disjoint and ad-hoc at best,
    and as has been discussed before.

    The size of the audience for DCL command syntax for FFmpeg is also approximately zero. A similar discussion and realization arose with the
    IP network diagnostic tool command syntax. The folks using those tools
    expected the syntax they expected, while very few sought out the DCL
    syntax.

    To Dan's point quoted above: Will the OP learn anything from this
    thread? Probably not. That seems about as likely as re-hosting OpenVMS
    onto the Linux kernel, as the OP had repeatedly proposed.



    --
    Pure Personal Opinion | HoffmanLabs LLC

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Stephen Hoffman on Fri Feb 21 22:18:27 2025
    On Fri, 21 Feb 2025 16:42:56 -0500, Stephen Hoffman wrote:

    Is it feasible for DCL? Sure. Though it'll likely involve passing some
    of the syntax to lib$table_parse or ilk for parsing, as do a few DCL
    commands I've encountered (or have written) over the years.

    What happens when you bypass DCL? So one program directly spawns another
    and gives it a command to execute. Can the receiving program behave the
    same in that case as if it were invoked from a shell?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Schenkenberger@21:1/5 to Simon Clubley on Fri Feb 21 19:02:20 2025
    On 2025-02-14 13:38:59 +0000, Simon Clubley said:

    On 2025-02-13, Lawrence D'Oliveiro <ldo@nz.invalid> wrote:

    What?s the most complex *nix command you?ve come across? I think it
    has to be ffmpeg. This looks broadly like

    ffmpeg «local-input-options-1» -i «infile-1» \
    «local-input-options-2» -i «infile-2» ... \
    «local-output-options-1» «outfile-1» \
    «local-output-options-2» «outfile-2» ...

    The convention is that options apply to the immediately following file
    specification: this is prefixed with ?-i? for an input file, and is a
    plain argument for an output file. Note the lack of ?global? options:
    all settings apply to a particular file.

    But that?s not where it ends. Certain of the options can specify
    ?filtergraphs?, which are entire chains of effects operations to be
    applied to a particular video or audio stream. The man page talks
    about ?simple? versus ?complex? filtergraphs, but even the ?simple?
    ones can be pretty complex.

    Filtergraphs can also be used during real-time playback, with the
    ?ffplay? command. For example:

    ffplay -autoexit -vf scale=1152:864,setsar=0.9 \
    'Sun Is Shining (Official Video).mp4'

    That ?-vf? option specifies a sequence of video filters, first to
    scale up the video to make more use of my screen, and ?setsar? (?Set
    Source Aspect Ratio?) to fix distortion in the shape of the image
    (everybody looking squashed) from the original digitization of the
    video.

    What would DCL-style syntax for ffmpeg look like? I suppose one
    obvious equivalence would be

    ffmpeg -
    «infile-1»/«local-input-options-1»,«infile-2»/«local-input-options-2»,... -
    «outfile-1»/«local-output-options-1»,«outfile-2»/«local-output-options-2»,... -

    (being very careful about where the commas go), but what about the
    syntax for filtergraphs? Would it be something like

    /vf=(«filter-name-1»=«filter-params-1»,«filter-name-2»=«filter-params-2»...)

    Does DCL have provision for this sort of complexity?

    Not in any meaningful way. There's no way to validate the syntax or parameters of a filter or other ffmpeg syntax with DCL. For a simple
    example, when merging two files, one with an audio stream and one with
    a video stream, into a MP4 output container then specifying the input and output video stream numbers would be a parameter along the lines of "0:v:0".

    How would you even specify in DCL the first and last fields are numbers
    and the middle field is a letter from a list of valid values ?

    You can use DCL syntax in the way you specify, but the vast majority
    of the parsing would still have to be done in ffmpeg as it is at the
    moment. DCL syntax doesn't really give you anything extra.

    Similar comments apply to mplayer BTW, and to make something clear to
    people reading this (which is only implied above), the filters MUST be executed in the order given. For example, with mplayer, I might first
    use a crop filter to get rid of black bars within a frame and then
    apply a scale filter to the resulting frame.

    Simon.

    If you want to maintain the klunky un*x command syntax, employ a finite
    state parsing table and LIB$T(ABLE)_PARSE. Otherwise, devise a better
    and more sane syntax to specify and pass myriaD arguments with
    qualifiers and parameters thereto.

    Your anti-VMS sentiments are one of the reasons why my life has been so
    much more enjoyable because I haven't been reading c.o.v daily.

    – VAXman

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Feb 21 19:45:05 2025
    On 2/21/2025 5:18 PM, Lawrence D'Oliveiro wrote:
    On Fri, 21 Feb 2025 16:42:56 -0500, Stephen Hoffman wrote:
    Is it feasible for DCL? Sure. Though it'll likely involve passing some
    of the syntax to lib$table_parse or ilk for parsing, as do a few DCL
    commands I've encountered (or have written) over the years.

    What happens when you bypass DCL? So one program directly spawns another
    and gives it a command to execute. Can the receiving program behave the
    same in that case as if it were invoked from a shell?

    This is where the difference in *nix and VMS process model
    get into the picture.

    A "normal" process on VMS got the CLI (DCL) in P1 and
    the running image in P0 and/or P2.

    Most ways to activate another image (lib$spawn, C system,
    C exec* etc.) end up creating a process with CLI mapped.

    It is possible to start a process without CLI (sys$creprc
    or run process - with an image that is not loginout.exe).

    In that case I don't think there are a concept of arguments.
    I don't see a way to pass arguments. Arguments are something
    CLI provide to image, so no CLI means no arguments.

    Such processes exist, but I would consider them relative
    rare. There are some limitations on such processes - some
    LIB$ functions will return LIB$_NOCLI.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Brian Schenkenberger on Sat Feb 22 00:38:08 2025
    On Fri, 21 Feb 2025 19:02:20 -0500, Brian Schenkenberger wrote:

    Otherwise, devise a better and more sane syntax to specify and pass
    myriaD arguments with qualifiers and parameters thereto.

    What would you propose, that is suitably respectful of traditional VMS
    values?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Feb 22 03:09:31 2025
    On Fri, 21 Feb 2025 19:45:05 -0500, Arne Vajhøj wrote:

    It is possible to start a process without CLI (sys$creprc or run process
    - with an image that is not loginout.exe).

    In that case I don't think there are a concept of arguments.
    I don't see a way to pass arguments. Arguments are something CLI provide
    to image, so no CLI means no arguments.

    Mr Berryman, further up this thread, was so insistent that I was talking through my hat. Remember he said:

    ] Wrong again. There are a number of ways to invoke a program without
    ] going through DCL.

    and furthermore

    ] You apparently know as little about VMS as you do programming in
    ] general.

    as well as

    ] Everyone else: Yes, I've once again been forced to face the fact
    ] that you can't fix stupid.

    He couldn’t have made a mistake, could he?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Feb 21 23:15:42 2025
    On 2/21/2025 10:09 PM, Lawrence D'Oliveiro wrote:
    On Fri, 21 Feb 2025 19:45:05 -0500, Arne Vajhøj wrote:
    It is possible to start a process without CLI (sys$creprc or run process
    - with an image that is not loginout.exe).

    In that case I don't think there are a concept of arguments.
    I don't see a way to pass arguments. Arguments are something CLI provide
    to image, so no CLI means no arguments.

    Mr Berryman, further up this thread, was so insistent that I was talking through my hat. Remember he said:

    ] Wrong again. There are a number of ways to invoke a program without
    ] going through DCL.

    and furthermore

    ] You apparently know as little about VMS as you do programming in
    ] general.

    as well as

    ] Everyone else: Yes, I've once again been forced to face the fact
    ] that you can't fix stupid.

    He couldn’t have made a mistake, could he?

    I don't see any indication of that.

    There are some ways to start a process with a DCL command
    (and therefore DCL mapped).

    There are some ways to start a process without specifying a DCL
    command and still getting a process with DCL mapped.

    There are some ways to start a process without DCL mapped.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Sat Feb 22 00:53:37 2025
    On 2/21/2025 11:15 PM, Arne Vajhøj wrote:
    On 2/21/2025 10:09 PM, Lawrence D'Oliveiro wrote:
    On Fri, 21 Feb 2025 19:45:05 -0500, Arne Vajhøj wrote:
    It is possible to start a process without CLI (sys$creprc or run process >>> - with an image that is not loginout.exe).

    In that case I don't think there are a concept of arguments.
    I don't see a way to pass arguments. Arguments are something CLI provide >>> to image, so no CLI means no arguments.

    Mr Berryman, further up this thread, was so insistent that I was talking
    through my hat. Remember he said:

    ] Wrong again. There are a number of ways to invoke a program without
    ] going through DCL.

    and furthermore

    ] You apparently know as little about VMS as you do programming in
    ] general.

    as well as

    ] Everyone else: Yes, I've once again been forced to face the fact
    ] that you can't fix stupid.

    He couldn’t have made a mistake, could he?

    I don't see any indication of that.

    There are some ways to start a process with a DCL command
    (and therefore DCL mapped).

    There are some ways to start a process without specifying a DCL
    command and still getting a process with DCL mapped.

    There are some ways to start a process without DCL mapped.

    Arne




    Now I'm confused. Were we discussing starting an image in an existing process, or starting a new process?

    VMS has the capability of writing and reading to/from some process memory that is independent of any images.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Lawrence D'Oliveiro on Sat Feb 22 00:47:04 2025
    On 2/21/2025 5:18 PM, Lawrence D'Oliveiro wrote:
    On Fri, 21 Feb 2025 16:42:56 -0500, Stephen Hoffman wrote:

    Is it feasible for DCL? Sure. Though it'll likely involve passing some
    of the syntax to lib$table_parse or ilk for parsing, as do a few DCL
    commands I've encountered (or have written) over the years.

    What happens when you bypass DCL? So one program directly spawns another
    and gives it a command to execute. Can the receiving program behave the
    same in that case as if it were invoked from a shell?


    Well, that depends upon the requirements and design, right?

    I've done quite a bit of such, but, I never depended on some set design, never even considered it, I designed what I needed and implemented it.

    Don't know why anyone would ever do anything else ??????

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Lawrence D'Oliveiro on Sat Feb 22 00:58:27 2025
    On 2/21/2025 7:38 PM, Lawrence D'Oliveiro wrote:
    On Fri, 21 Feb 2025 19:02:20 -0500, Brian Schenkenberger wrote:

    Otherwise, devise a better and more sane syntax to specify and pass
    myriaD arguments with qualifiers and parameters thereto.

    What would you propose, that is suitably respectful of traditional VMS values?


    VMS values ????????????????????

    Design and implement what the requirements call for ...

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Feb 22 06:15:40 2025
    On Fri, 21 Feb 2025 23:15:42 -0500, Arne Vajhøj wrote:

    There are some ways to start a process without DCL mapped.

    Yes, we know. But you yourself have said there is no way to pass a command
    line that way.

    Hasn’t it been clear all along that I was talking about ways to pass a command line to the program being invoked?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dave Froble on Sat Feb 22 08:53:16 2025
    On 2/22/2025 12:53 AM, Dave Froble wrote:
    On 2/21/2025 11:15 PM, Arne Vajhøj wrote:
    There are some ways to start a process with a DCL command
    (and therefore DCL mapped).

    There are some ways to start a process without specifying a DCL
    command and still getting a process with DCL mapped.

    There are some ways to start a process without DCL mapped.

    Now I'm confused.  Were we discussing starting an image in an existing process, or starting a new process?

    Starting a new process.

    Because it is about a program running another program. And that
    indicate starting a new process.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Sat Feb 22 09:29:59 2025
    On 2/22/2025 8:53 AM, Arne Vajhøj wrote:
    On 2/22/2025 12:53 AM, Dave Froble wrote:
    On 2/21/2025 11:15 PM, Arne Vajhøj wrote:
    There are some ways to start a process with a DCL command
    (and therefore DCL mapped).

    There are some ways to start a process without specifying a DCL
    command and still getting a process with DCL mapped.

    There are some ways to start a process without DCL mapped.

    Now I'm confused.  Were we discussing starting an image in an existing
    process, or starting a new process?

    Starting a new process.

    Because it is about a program running another program. And that
    indicate starting a new process.

    Unless LIB$DO_COMMAND which is special.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Sat Feb 22 16:57:23 2025
    In article <vpboct$3r1ga$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 2/21/2025 5:18 PM, Lawrence D'Oliveiro wrote:
    On Fri, 21 Feb 2025 16:42:56 -0500, Stephen Hoffman wrote:

    Is it feasible for DCL? Sure. Though it'll likely involve passing some
    of the syntax to lib$table_parse or ilk for parsing, as do a few DCL
    commands I've encountered (or have written) over the years.

    What happens when you bypass DCL? So one program directly spawns another
    and gives it a command to execute. Can the receiving program behave the
    same in that case as if it were invoked from a shell?

    Well, that depends upon the requirements and design, right?

    I've done quite a bit of such, but, I never depended on some set design, never >even considered it, I designed what I needed and implemented it.

    Don't know why anyone would ever do anything else ??????

    In the context of this thread, they probably wouldn't.

    This discussion, which Arne is jumping into as a willing
    participant, is not about technical enlightenment or discussion,
    but rather a vehicle for the troll OP to preen and strut around,
    imaging himself oh-so-very-clever indeed, while making snide
    comments about systems he doesn't even attempt to appreciate.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Sat Feb 22 11:40:22 2025
    On 2/22/2025 9:29 AM, Arne Vajhøj wrote:
    On 2/22/2025 8:53 AM, Arne Vajhøj wrote:
    On 2/22/2025 12:53 AM, Dave Froble wrote:
    On 2/21/2025 11:15 PM, Arne Vajhøj wrote:
    There are some ways to start a process with a DCL command
    (and therefore DCL mapped).

    There are some ways to start a process without specifying a DCL
    command and still getting a process with DCL mapped.

    There are some ways to start a process without DCL mapped.

    Now I'm confused. Were we discussing starting an image in an existing
    process, or starting a new process?

    Starting a new process.

    Because it is about a program running another program. And that
    indicate starting a new process.

    Unless LIB$DO_COMMAND which is special.

    Arne


    I recall that that starts a subprocess. If I remember correctly. Which would be a new process.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Townley@21:1/5 to Dan Cross on Sat Feb 22 18:50:46 2025
    On 22/02/2025 16:57, Dan Cross wrote:


    In the context of this thread, they probably wouldn't.

    This discussion, which Arne is jumping into as a willing
    participant, is not about technical enlightenment or discussion,
    but rather a vehicle for the troll OP to preen and strut around,
    imaging himself oh-so-very-clever indeed, while making snide
    comments about systems he doesn't even attempt to appreciate.

    - Dan C.


    +1

    --
    Chris

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dave Froble on Sat Feb 22 15:10:30 2025
    On 2/22/2025 11:40 AM, Dave Froble wrote:
    On 2/22/2025 9:29 AM, Arne Vajhøj wrote:
    On 2/22/2025 8:53 AM, Arne Vajhøj wrote:
    On 2/22/2025 12:53 AM, Dave Froble wrote:
    On 2/21/2025 11:15 PM, Arne Vajhøj wrote:
    There are some ways to start a process with a DCL command
    (and therefore DCL mapped).

    There are some ways to start a process without specifying a DCL
    command and still getting a process with DCL mapped.

    There are some ways to start a process without DCL mapped.

    Now I'm confused.  Were we discussing starting an image in an existing >>>> process, or starting a new process?

    Starting a new process.

    Because it is about a program running another program. And that
    indicate starting a new process.

    Unless LIB$DO_COMMAND which is special.

    I recall that that starts a subprocess.  If I remember correctly.  Which would be a new process.

    LIB$SPAWN starts a new subprocess.

    LIB$DO_COMMAND exits current image and execute the command
    within the same process.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Feb 22 21:34:09 2025
    On Sat, 22 Feb 2025 09:29:59 -0500, Arne Vajhøj wrote:

    Unless LIB$DO_COMMAND which is special.

    Which still won’t work unless DCL is present, will it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to Brian Schenkenberger on Mon Feb 24 18:52:22 2025
    On 2025-02-21, Brian Schenkenberger <mail@SendSpamHere.ORG> wrote:
    On 2025-02-14 13:38:59 +0000, Simon Clubley said:

    Your anti-VMS sentiments are one of the reasons why my life has been so
    much more enjoyable because I haven't been reading c.o.v daily.


    No Brian, I point out where VMS is lacking compared to other operating
    systems and also point out where VMS is better than other operating
    systems.

    $ set response/mode=good_natured

    Nice to see that you are still your usual cheerful self. :-)

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Mar 5 21:17:39 2025
    On Thu, 13 Feb 2025 22:52:44 -0000 (UTC), I wrote:

    What’s the most complex *nix command you’ve come across? I think it has to be ffmpeg.

    For example, here’s a command I came up with for using ffmpeg to
    convert an audio file for playback through the Asterisk telephony
    engine. The sample rate has to be 8kHz, so to make sure there are no
    aliasing artifacts, you have to make sure there are no frequency
    components above about 3kHz. To achieve this, I apply a first-order
    low-pass filter 16 times in a row, to produce a “brick wall” cutoff at
    that frequency:

    ffmpeg -i in.wav -f s16le -acodec pcm_s16le -ar 8000 \
    -af $(sep=""; for i in $(seq 16); do echo -n ${sep}lowpass=f=3000; sep=","; done) \
    out.slin

    Note the substitution of the output of one command inside another, not
    just to one, but two levels of nesting.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)