1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/* vms-code.c -- additional VMS-specific support code for flex
*/
#include "flexdef.h"
static const char *original_arg0;
static const char default_arg0[] = "flex.exe";
#define IN_FD 0
#define OUT_FD 1
#define ERR_FD 2
static char *fix_arg0 PROTO((const char *));
/* Command line arguments fixup -- simplify argv[0], and handle `>'
output redirection request; called first thing from main(). */
void argv_fixup( iargc, iargv )
int *iargc;
char ***iargv;
{
const char *mode[3], *rfm[3], *name[3];
char *p;
int i, oargc, punct, which, append, alt_rfm;
/*
* Get original argv[0] supplied by run-time library startup code,
* then replace it with a stripped down one.
*/
original_arg0 = (*iargv)[0];
(*iargv)[0] = fix_arg0(original_arg0);
/*
* Check command line arguments for redirection request(s).
* For simplicity, if multiple attempts are made, the last one wins.
*/
name[0] = name[1] = name[2] = 0;
oargc = 1; /* number of args caller will see; count includes argv[0] */
for (i = 1; i < *iargc; i++) {
p = (*iargv)[i];
switch (*p) {
case '<':
/* might be "<dir>file"; then again, perhaps "<<dir>file" */
punct = (strchr(p, '>') != 0);
if (p[1] == '<') {
if (!punct || p[2] == '<')
flexerror("<<'sentinel' input not supported.");
punct = 0;
}
if (punct) /* the '<' seems to be directory punctuation */
goto arg; /*GOTO*/
mode[IN_FD] = "r";
rfm[IN_FD] = 0;
name[IN_FD] = ++p;
if (!*p && (i + 1) < *iargc)
name[IN_FD] = (*iargv)[++i];
break;
case '>':
append = (p[1] == '>');
if (append) ++p;
alt_rfm = (p[1] == '$');
if (alt_rfm) ++p;
which = (p[1] == '&' ? ERR_FD : OUT_FD);
if (which == ERR_FD) ++p;
mode[which] = append ? "a" : "w";
rfm[which] = alt_rfm ? "rfm=var" : "rfm=stmlf";
name[which] = ++p;
if (!*p && (i + 1) < *iargc)
name[which] = (*iargv)[++i];
break;
case '|':
flexerror("pipe output not supported.");
/*NOTREACHED*/
break;
default:
arg: /* ordinary option or argument */
(*iargv)[oargc++] = p;
break;
}
}
/* perform any requested redirection; don't bother with SYS$xxx logicals */
if (name[IN_FD])
if (!freopen(name[IN_FD], mode[IN_FD], stdin))
lerrsf("failed to redirect `stdin' from \"%s\"", name[IN_FD]);
if (name[OUT_FD])
if (!freopen(name[OUT_FD], mode[OUT_FD], stdout,
rfm[OUT_FD], "rat=cr", "mbc=32", "shr=nil"))
lerrsf("failed to redirect `stdout' to \"%s\"", name[OUT_FD]);
if (name[ERR_FD]) /* likely won't see message if this fails; oh well... */
if (!freopen(name[ERR_FD], mode[ERR_FD], stderr,
rfm[ERR_FD], "rat=cr"))
lerrsf("failed to redirect `stderr' to \"%s\"", name[ERR_FD]);
/* remove any excess arguments (used up from redirection) */
while (*iargc > oargc)
(*iargv)[--*iargc] = 0;
/* all done */
return;
}
/* Pick out the basename of a full filename, and return a pointer
to a modifiable copy of it. */
static char *fix_arg0( arg0 )
const char *arg0;
{
char *p, *new_arg0;
if (arg0) {
/* strip off the path */
if ((p = strrchr(arg0, ':')) != 0) /* device punctuation */
arg0 = p + 1;
if ((p = strrchr(arg0, ']')) != 0) /* directory punctuation */
arg0 = p + 1;
if ((p = strrchr(arg0, '>')) != 0) /* alternate dir punct */
arg0 = p + 1;
}
if (!arg0 || !*arg0)
arg0 = default_arg0;
/* should now have "something.exe;#"; make a modifiable copy */
new_arg0 = copy_string(arg0);
/* strip off ".exe" and/or ";#" (version number),
unless it ended up as the whole name */
if ((p = strchr(new_arg0, '.')) != 0 && (p > new_arg0)
&& (p[1] == 'e' || p[1] == 'E')
&& (p[2] == 'x' || p[2] == 'X')
&& (p[3] == 'e' || p[3] == 'E')
&& (p[4] == ';' || p[4] == '.' || p[4] == '\0'))
*p = '\0';
else if ((p = strchr(new_arg0, ';')) != 0 && (p > new_arg0))
*p = '\0';
return new_arg0;
}
#include <ssdef.h>
#include <stsdef.h>
#ifdef exit
#undef exit
extern void exit PROTO((int)); /* <stdlib.h> ended up prototyping vms_exit */
#endif
/* Convert zero to VMS success and non-zero to VMS failure. The latter
does not bother trying to distinguish between various failure reasons. */
void vms_exit( status )
int status;
{
exit( status == 0 ? SS$_NORMAL : (SS$_ABORT | STS$M_INHIB_MSG) );
}
|