home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
gnu
/
gawk-2.15.5-src.lha
/
gawk-2.15.5
/
vms
/
vms_args.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-04
|
15KB
|
413 lines
/*
* vms_args.c -- command line parsing, to emulate shell i/o redirection.
* [ Escape sequence parsing now suppressed. ]
*/
/*
* Copyright (C) 1991-1993 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Progamming Language.
*
* GAWK is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GAWK is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GAWK; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* [.vms]vms_arg_fixup - emulate shell's command line processing: handle
* stdio redirection, backslash escape sequences, and file wildcard
* expansion. Should be called immediately upon image startup.
*
* Pat Rankin, Nov'89
* rankin@eql.Caltech.EDU
*
* <ifile - open 'ifile' (readonly) as 'stdin'
* >nfile - create 'nfile' as 'stdout' (stream-lf format)
* >>ofile - append to 'ofile' for 'stdout'; create it if necessary
* >&efile - point 'stderr' (SYS$ERROR) at 'efile', but don't open
* >$vfile - create 'vfile' as 'stdout', using rms attributes
* appropriate for a standard text file (variable length
* records with implied carriage control)
* 2>&1 - special case: direct error messages into output file
* 1>&2 - special case: direct output data to error destination
* <<sentinal - error; reading stdin until 'sentinal' not supported
* <-, >- - error: stdin/stdout closure not implemented
* | anything - error; pipes not implemented
* & <end-of-line> - error; background execution not implemented
*
* any\Xany - convert 'X' as appropriate; \000 will not work as
* intended since subsequent processing will misinterpret
*
* any*any - perform wildcard directory lookup to find file(s)
* any%any - " " ('%' is vms wildcard for '?' [ie, /./])
* any?any - treat like 'any%any' unless no files match
* *, %, ? - if no file(s) match, leave original value in arg list
*
*
* Notes: a redirection operator can have optional white space between it
* and its filename; the operator itself *must* be preceded by white
* space so that it starts a separate argument. '<' is ambiguous
* since "<dir>file" is a valid VMS file specification; leading '<' is
* assumed to be stdin--use "\<dir>file" to override. '>$' is local
* kludge to force stdout to be created with text file RMS attributes
* instead of stream format; file sharing is disabled for stdout
* regardless. Multiple instances of stdin or stdout or stderr are
* treated as fatal errors rather than using the first or last. If a
* wildcard file specification is detected, it is expanded into a list
* of filenames which match; if there are no matches, the original
* file-spec is left in the argument list rather than having it expand
* into thin air. No attempt is made to identify and make $(var)
* environment substitutions--must draw the line somewhere!
*
* Oct'91, gawk 2.13.3
* Open '<' with full sharing allowed, so that we can read batch logs
* and other open files. Create record-format output ('>$') with read
* sharing permited, so that others can read our output file to check
* progess. For stream output ('>' or '>>'), sharing is disallowed
* (for performance reasons).
*/
#include "awk.h" /* really "../awk.h" */
#include "vms.h"
#include <lnmdef.h>
void v_add_arg(int, const char *);
static char *skipblanks(const char *);
static void vms_expand_wildcards(const char *);
static u_long vms_define(const char *, const char *);
static char *t_strstr(const char *, const char *);
#define strstr t_strstr /* strstr() missing from vaxcrtl for V4.x */
static int v_argc, v_argz = 0;
static char **v_argv;
/* vms_arg_fixup() - scan argv[] for i/o redirection and wildcards and also */
/* rebuild it with those removed or expanded, respectively */
void
vms_arg_fixup( int *pargc, char ***pargv )
{
const char *f_in, *f_out, *f_err,
*out_mode, *rms_rfm, *rms_shr, *rms_mrs;
char **argv = *pargv;
int i, argc = *pargc;
int err_to_out_redirect = 0, out_to_err_redirect = 0;
#ifdef CHECK_DECSHELL /* don't define this if linking with DECC$SHR */
if (shell$is_shell())
return; /* don't do anything if we're running DEC/Shell */
#endif
#ifndef NO_DCL_CMD
for (i = 1; i < argc ; i++) /* check for dash or other non-VMS args */
if (strchr("->\\|", *argv[i])) break; /* found => (i < argc) */
if (i >= argc && (v_argc = vms_gawk()) > 0) { /* vms_gawk => dcl_parse */
/* if we successfully parsed the command, replace original argv[] */
argc = v_argc, argv = v_argv;
v_argz = v_argc = 0, v_argv = NULL;
}
#endif
v_add_arg(v_argc = 0, argv[0]); /* store arg #0 (image name) */
f_in = f_out = f_err = NULL; /* stdio setup (no filenames yet) */
out_mode = "w"; /* default access for stdout */
rms_rfm = "rfm=stmlf"; /* stream_LF format */
rms_shr = "shr=nil"; /* no sharing (for '>' output file) */
rms_mrs = "mrs=0"; /* no maximum record size */
for (i = 1; i < argc; i++) {
char *p, *fn;
int is_arg;
is_arg = 0; /* current arg does not begin with dash */
p = argv[i]; /* current arg */
switch (*p) {
case '<': /* stdin */
/*[should try to determine whether this is really a directory
spec using <>; for now, force user to quote them with '\<']*/
if ( f_in ) {
fatal("multiple specification of '<' for stdin");
} else if (*++p == '<') { /* '<<' is not supported */
fatal("'<<' not available for stdin");
} else {
p = skipblanks(p);
fn = (*p ? p : argv[++i]); /* use next arg if necessary */
if (i >= argc || *fn == '-')
fatal("invalid i/o redirection, null filespec after '<'");
else
f_in = fn; /* save filename for stdin */
}
break;
case '>': { /* stdout or stderr */
/*[vms-specific kludge '>$' added to force stdout to be created
as record-oriented text file instead of in stream-lf format]*/
int is_out = 1; /* assume stdout */
if (*++p == '>') /* '>>' => append */
out_mode = "a", p++;
else if (*p == '&') /* '>&' => stderr */
is_out = 0, p++;
else if (*p == '$') /* '>$' => kludge for record format */
rms_rfm = "rfm=var", rms_shr = "shr=get,upi",
rms_mrs = "mrs=32767", p++;
else /* '>' => create */
{} /* use default values initialized prior to loop */
p = skipblanks(p);
fn = (*p ? p : argv[++i]); /* use next arg if necessary */
if (i >= argc || *fn == '-') {
fatal("invalid i/o redirection, null filespec after '>'");
} else if (is_out) {
if (out_to_err_redirect)
fatal("conflicting specifications for stdout");
else if (f_out)
fatal("multiple specification of '>' for stdout");
else
f_out = fn; /* save filename for stdout */
} else {
if (err_to_out_redirect)
fatal("conflicting specifications for stderr");
else if (f_err)
fatal("multiple specification of '>&' for stderr");
else
f_err = fn; /* save filename for stderr */
}
} break;
case '2': /* check for ``2>&1'' special case'' */
if (strcmp(p, "2>&1") != 0)
goto ordinary_arg;
else if (f_err || out_to_err_redirect)
fatal("conflicting specifications for stderr");
else {
err_to_out_redirect = 1;
f_err = "SYS$OUTPUT:";
} break;
case '1': /* check for ``1>&2'' special case'' */
if (strcmp(p, "1>&2") != 0)
goto ordinary_arg;
else if (f_out || err_to_out_redirect)
fatal("conflicting specifications for stdout");
else {
out_to_err_redirect = 1;
f_out =