(root)/
gawk-5.2.2/
vms/
vms_cli.c
       1  /* vms_cli.c -- interface to CLI$xxx routines for fetching command line components
       2  
       3     Copyright (C) 1991-1993, 2003, 2011, 2014, 2016, 2022, 2023,
       4     the Free Software Foundation, Inc.
       5  
       6     This program is free software; you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3, or (at your option)
       9     any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program; if not, write to the Free Software Foundation,
      18     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
      19  
      20  
      21  /*
      22   * vms_cli.c - command line interface routines.
      23   *							Pat Rankin, Nov'89
      24   *	Routines called from vms_gawk.c for DCL parsing.
      25   */
      26  
      27  #include "config.h"	/* in case we want to suppress 'const' &c */
      28  #include "vms.h"
      29  #ifndef _STRING_H
      30  #include <string.h>
      31  #endif
      32  
      33  extern U_Long CLI$PRESENT(const struct dsc$descriptor_s *);
      34  extern U_Long CLI$GET_VALUE(const struct dsc$descriptor_s *,
      35                              struct dsc$descriptor_s *, short *);
      36  extern U_Long CLI$DCL_PARSE(const struct dsc$descriptor_s *, const void *, ...);
      37  extern U_Long SYS$CLI(void *, ...);
      38  extern U_Long SYS$FILESCAN(const struct dsc$descriptor_s *, void *, long *);
      39  extern void  *LIB$ESTABLISH(U_Long (*handler)(void *, void *));
      40  extern U_Long LIB$SIG_TO_RET(void *, void *);	/* condition handler */
      41  
      42  /* Cli_Present() - call CLI$PRESENT to determine whether a parameter or     */
      43  /*		  qualifier is present on the [already parsed] command line */
      44  U_Long
      45  Cli_Present( const char *item )
      46  {
      47      struct dsc$descriptor_s item_dsc;
      48      (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
      49  
      50      item_dsc.dsc$w_length = strlen(item_dsc.dsc$a_pointer = (char *)item);
      51      item_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
      52      item_dsc.dsc$b_class = DSC$K_CLASS_S;
      53      return CLI$PRESENT(&item_dsc);
      54  }
      55  
      56  /* Cli_Get_Value() - call CLI$GET_VALUE to retreive the value of a */
      57  /*		    parameter or qualifier from the command line   */
      58  U_Long
      59  Cli_Get_Value( const char *item, char *result, int size )
      60  {
      61      struct dsc$descriptor_s item_dsc, res_dsc;
      62      U_Long sts;
      63      short len = 0;
      64      (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
      65  
      66      item_dsc.dsc$w_length = strlen(item_dsc.dsc$a_pointer = (char *)item);
      67      item_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
      68      item_dsc.dsc$b_class = DSC$K_CLASS_S;
      69      res_dsc.dsc$w_length = size;
      70      res_dsc.dsc$a_pointer = result;
      71      res_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
      72      res_dsc.dsc$b_class = DSC$K_CLASS_S;
      73      sts = CLI$GET_VALUE(&item_dsc, &res_dsc, &len);
      74      result[len] = '\0';
      75      return sts;
      76  }
      77  
      78  /* Cli_Parse_Command() - use the $CLI system service (undocumented) to	 */
      79  /*			retreive the actual command line (which might be */
      80  /*			"run prog" or "mcr prog [params]") and then call */
      81  /*			CLI$DCL_PARSE to parse it using specified tables */
      82  U_Long
      83  Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
      84  {
      85      struct { short len, code; void *adr; } fscn[2];
      86      struct { char rqtype, rqindx, rqflags, rqstat; unsigned :32;
      87  	     struct dsc$descriptor_s rdesc;
      88               unsigned :32; unsigned :32; unsigned :32; } cmd;
      89      U_Long sts;
      90      int    ltmp;
      91      char   longbuf[8200];
      92      (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
      93  
      94      memset(&cmd, 0, sizeof cmd);
      95      cmd.rqtype = CLI$K_GETCMD;		/* command line minus the verb */
      96      sts = SYS$CLI(&cmd, (void *)0, (void *)0);	/* get actual command line */
      97  
      98      if (vmswork(sts)) {		/* ok => cli available & verb wasn't "RUN" */
      99  	/* invoked via symbol => have command line (which might be empty) */
     100  	/*    [might also be invoked via mcr or dcl; that's ok]		  */
     101  	if (cmd.rqstat == CLI$K_VERB_MCR) {
     102  	    /* need to strip image name from MCR invocation   */
     103  	    memset(fscn, 0, sizeof fscn);
     104  	    fscn[0].code = FSCN$_FILESPEC;	/* full file specification */
     105  	    (void)SYS$FILESCAN(&cmd.rdesc, fscn, (long *)0);
     106  	    cmd.rdesc.dsc$w_length -= fscn[0].len;	/* shrink size */
     107  	    cmd.rdesc.dsc$a_pointer += fscn[0].len;	/* advance ptr */
     108  	}
     109  	/* prepend verb and then parse the command line */
     110  	strcat(strcpy(longbuf, cmd_verb), " "),  ltmp = strlen(longbuf);
     111  	if (cmd.rdesc.dsc$w_length + ltmp > sizeof longbuf)
     112  	    cmd.rdesc.dsc$w_length = sizeof longbuf - ltmp;
     113  	strncpy(&longbuf[ltmp],
     114                  cmd.rdesc.dsc$a_pointer, cmd.rdesc.dsc$w_length);
     115  	cmd.rdesc.dsc$w_length += ltmp,	cmd.rdesc.dsc$a_pointer = longbuf;
     116  	sts = CLI$DCL_PARSE(&cmd.rdesc, cmd_tables);
     117      }
     118  
     119      return sts;
     120  }