The R Project SVN R

Rev

Rev 83755 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
51536 ripley 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
83755 kalibera 3
 *  Copyright (C) 2010--2023  R Core Team
51536 ripley 4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not,  a copy is available at
68956 ripley 17
 *  https://www.R-project.org/Licenses/
51536 ripley 18
 */
19
 
72846 kalibera 20
#define WIN32_LEAN_AND_MEAN 1
21
#include <windows.h> /* for SetConsoleCtrlHandler */
22
#include <stdlib.h>  /* for exit */
51536 ripley 23
#include <string.h>
24
#include <stdio.h>
25
 
52990 ripley 26
extern char *getRHOME(int); /* in ../rhome.c */
83755 kalibera 27
extern void freeRHOME(char *);
51891 ripley 28
 
81406 kalibera 29
extern size_t quoted_arg_len(const char *arg); /* in rcmdfn.c */
30
extern char *quoted_arg_cat(char *dest, const char *arg);
31
 
52990 ripley 32
static void Usage (char *RCMD, char *arch)
33
{
34
    fprintf(stderr, "%s %s %s", "Usage:", RCMD, "[command args]\n\n");
35
    fprintf(stderr, "%s%s%s",
36
	    "where 'command args' can be\n\n",
37
	    "  --arch n   for n=i386, x64, 32 or 64\n",
38
	    "  any other arguments listed by ");
39
    fprintf(stderr, "%s --arch %s --help\n", RCMD, arch);
40
}
51891 ripley 41
 
84419 kalibera 42
static BOOL WINAPI CtrlHandler(DWORD type)
43
{
44
    /* ignore Ctrl-C; R handles Ctrl+Break the same way (see psignal) */
45
    return (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT);
46
}
47
 
51536 ripley 48
#define CMD_LEN 10000
49
int main (int argc, char **argv)
50
{
51
    int cmdarg = 1;
72846 kalibera 52
    int interactive = 0;
51891 ripley 53
    char arch[10] = R_ARCH, cmd[CMD_LEN], *p;
51536 ripley 54
 
52990 ripley 55
    if (argc > 1 && strcmp(argv[1], "--help") == 0) {
56
	Usage(argv[0], arch);
57
	exit(0);
58
    }
59
 
60
    if (argc > 1 && strcmp(argv[1], "--arch") == 0) {
51536 ripley 61
	cmdarg = 3;
52990 ripley 62
	if(argc < 3) {
63
	    Usage(argv[0], arch);
64
	    exit(0);
65
	}
51536 ripley 66
	strncpy(arch, argv[2], 10); arch[9] = '\0';
67
	if(strcmp(arch, "32") == 0) strcpy(arch, "i386");
68
	if(strcmp(arch, "64") == 0) strcpy(arch, "x64");
69
	if(strcmp(arch, "i386") && strcmp(arch, "x64")) {
70
	    fprintf(stderr, "valid values for --arch are i386, x64, 32, 64\n");
71
	    exit(1);
72
	}
77919 kalibera 73
    } else if ((p = getenv("R_ARCH"))) {
74
	strncpy(arch, p+1, 10 - 1); /* skip leading slash */
75
	arch[10 - 1] = '\0';
76
    }
83755 kalibera 77
 
78
    char *rhome2 = getRHOME(2);
79
    if (!rhome2) {
80
	fprintf(stderr, "Invalid R_HOME\n");
81
	exit(1);
82
    }
51891 ripley 83
    if (stricmp(argv[0] + strlen(argv[0]) - 11, "Rscript.exe") == 0
84
	|| stricmp(argv[0] + strlen(argv[0]) - 7, "Rscript") == 0)
83755 kalibera 85
	snprintf(cmd, CMD_LEN, "\"\"%s\\bin\\%s\\Rscript.exe\"", rhome2, arch);
72846 kalibera 86
    else {
83755 kalibera 87
    	snprintf(cmd, CMD_LEN, "\"\"%s\\bin\\%s\\R.exe\"", rhome2, arch);
72846 kalibera 88
	interactive = 1;
89
    }
83755 kalibera 90
    freeRHOME(rhome2);
51891 ripley 91
 
51536 ripley 92
    for(int i = cmdarg; i < argc; i++) {
72846 kalibera 93
	if (interactive && !strcmp(argv[i], "CMD"))
94
	    interactive = 0;
81406 kalibera 95
	if (strlen(cmd) + quoted_arg_len(argv[i]) + 2 > CMD_LEN) {
96
	    fprintf(stderr, "command line too long\n");
97
	    exit(27);
98
	}
51536 ripley 99
	strcat(cmd, " ");
81406 kalibera 100
	quoted_arg_cat(cmd, argv[i]);
51536 ripley 101
    }
73849 kalibera 102
    /* the outermost double quotes are needed for cmd.exe */
81406 kalibera 103
    if (strlen(cmd) + 1 > CMD_LEN) {
104
	fprintf(stderr, "command line too long\n");
105
	exit(27);
106
    }
73849 kalibera 107
    strcat(cmd, "\"");
72846 kalibera 108
 
109
    if (interactive)
110
	/* Ignore Ctrl-C so that Rterm.exe can handle it */
84419 kalibera 111
	/*   don't SetConsoleCtrlHandler(NULL, TRUE) to preserve
112
	     the current setting of the inheritable attribute */
113
	SetConsoleCtrlHandler(CtrlHandler, TRUE);
51536 ripley 114
 
115
    exit(system(cmd));
116
 }