18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* vms-code.c -- additional VMS-specific support code for flex
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "flexdef.h"
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const char *original_arg0;
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const char default_arg0[] = "flex.exe";
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define IN_FD	0
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define OUT_FD	1
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define ERR_FD	2
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic char *fix_arg0 PROTO((const char *));
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* Command line arguments fixup -- simplify argv[0], and handle `>'
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   output redirection request; called first thing from main().  */
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid argv_fixup( iargc, iargv )
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint *iargc;
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectchar ***iargv;
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char *mode[3], *rfm[3], *name[3];
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char *p;
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int i, oargc, punct, which, append, alt_rfm;
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * Get original argv[0] supplied by run-time library startup code,
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * then replace it with a stripped down one.
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     */
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    original_arg0 = (*iargv)[0];
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    (*iargv)[0] = fix_arg0(original_arg0);
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /*
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *	Check command line arguments for redirection request(s).
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *	For simplicity, if multiple attempts are made, the last one wins.
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     */
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    name[0] = name[1] = name[2] = 0;
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    oargc = 1;	/* number of args caller will see; count includes argv[0] */
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (i = 1; i < *iargc; i++) {
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	p = (*iargv)[i];
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	switch (*p) {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    case '<':
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		/* might be "<dir>file"; then again, perhaps "<<dir>file" */
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		punct = (strchr(p, '>') != 0);
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (p[1] == '<') {
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		    if (!punct || p[2] == '<')
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project			flexerror("<<'sentinel' input not supported.");
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		    punct = 0;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		}
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (punct)	/* the '<' seems to be directory punctuation */
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		    goto arg;	/*GOTO*/
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		mode[IN_FD] = "r";
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		rfm[IN_FD]  = 0;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		name[IN_FD] = ++p;
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (!*p && (i + 1) < *iargc)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		    name[IN_FD] = (*iargv)[++i];
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		break;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    case '>':
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		append = (p[1] == '>');
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (append) ++p;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		alt_rfm = (p[1] == '$');
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (alt_rfm) ++p;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		which = (p[1] == '&' ? ERR_FD : OUT_FD);
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (which == ERR_FD) ++p;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		mode[which] = append ? "a" : "w";
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		rfm[which]  = alt_rfm ? "rfm=var" : "rfm=stmlf";
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		name[which] = ++p;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		if (!*p && (i + 1) < *iargc)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		    name[which] = (*iargv)[++i];
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		break;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    case '|':
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		flexerror("pipe output not supported.");
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		/*NOTREACHED*/
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		break;
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    default:
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project arg:		/* ordinary option or argument */
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		(*iargv)[oargc++] = p;
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		break;
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	}
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* perform any requested redirection; don't bother with SYS$xxx logicals */
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name[IN_FD])
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	if (!freopen(name[IN_FD], mode[IN_FD], stdin))
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    lerrsf("failed to redirect `stdin' from \"%s\"", name[IN_FD]);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name[OUT_FD])
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	if (!freopen(name[OUT_FD], mode[OUT_FD], stdout,
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		     rfm[OUT_FD], "rat=cr", "mbc=32", "shr=nil"))
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    lerrsf("failed to redirect `stdout' to \"%s\"", name[OUT_FD]);
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name[ERR_FD])  /* likely won't see message if this fails; oh well... */
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	if (!freopen(name[ERR_FD], mode[ERR_FD], stderr,
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project		     rfm[ERR_FD], "rat=cr"))
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    lerrsf("failed to redirect `stderr' to \"%s\"", name[ERR_FD]);
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* remove any excess arguments (used up from redirection) */
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (*iargc > oargc)
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	(*iargv)[--*iargc] = 0;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* all done */
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* Pick out the basename of a full filename, and return a pointer
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   to a modifiable copy of it.  */
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic char *fix_arg0( arg0 )
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst char *arg0;
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char *p, *new_arg0;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (arg0) {
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	/* strip off the path */
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	if ((p = strrchr(arg0, ':')) != 0)	/* device punctuation */
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    arg0 = p + 1;
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	if ((p = strrchr(arg0, ']')) != 0)	/* directory punctuation */
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    arg0 = p + 1;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	if ((p = strrchr(arg0, '>')) != 0)	/* alternate dir punct */
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	    arg0 = p + 1;
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!arg0 || !*arg0)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	arg0 = default_arg0;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* should now have "something.exe;#"; make a modifiable copy */
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    new_arg0 = copy_string(arg0);
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* strip off ".exe" and/or ";#" (version number),
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project       unless it ended up as the whole name */
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((p = strchr(new_arg0, '.')) != 0 && (p > new_arg0)
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	&& (p[1] == 'e' || p[1] == 'E')
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	&& (p[2] == 'x' || p[2] == 'X')
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	&& (p[3] == 'e' || p[3] == 'E')
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	&& (p[4] == ';' || p[4] == '.' || p[4] == '\0'))
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	*p = '\0';
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if ((p = strchr(new_arg0, ';')) != 0 && (p > new_arg0))
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project	*p = '\0';
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return new_arg0;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <ssdef.h>
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stsdef.h>
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef exit
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#undef exit
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectextern void exit PROTO((int));	/* <stdlib.h> ended up prototyping vms_exit */
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* Convert zero to VMS success and non-zero to VMS failure.  The latter
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   does not bother trying to distinguish between various failure reasons.  */
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid vms_exit( status )
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint status;
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exit( status == 0 ? SS$_NORMAL : (SS$_ABORT | STS$M_INHIB_MSG) );
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
153