summaryrefslogtreecommitdiffstats
path: root/WebKitTools/android/flex-2.5.4a/MISC/VMS/vms-code.c
blob: 825a6b3bba884eb35f81983021eac9614a48dcb4 (plain)
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) );
}