home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.os.vms      DEC's VAX* line of computers & VMS.      264,096 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 262,402 of 264,096   
   =?UTF-8?Q?Arne_Vajh=C3=B8j?= to All   
   Re: Local Versus Global Command Options   
   17 Feb 25 21:41:07   
   
   From: arne@vajhoej.dk   
      
   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    
   #include    
      
   #include    
   #include    
      
   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    
   #include    
   #include    
      
   #include    
   #include    
   #include    
      
   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    
   #include    
   #include    
      
   #include    
   #include    
      
   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    
   #include    
   #include    
      
   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-DOS v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca