NEURON
neuron.cpp
Go to the documentation of this file.
1 // this is the wrapper that allows one to create shortcuts and
2 // associate hoc files with neuron.exe without having to consider
3 // the issues regarding shells and the rxvt console. The latter
4 // can be given extra arguments in the lib/neuron.sh file which
5 // finally executes nrniv.exe. Nrniv.exe can be run by itself if
6 // it does not need a console or system("command")
7 #include <windows.h>
8 
9 #include "d2upath.h"
10 
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 
15 char* nrnhome;
16 char* nh;
17 
18 static void setneuronhome() {
19  int i, j;
20  char buf[256];
21  GetModuleFileName(NULL, buf, 256);
22  for (i = strlen(buf); i >= 0 && buf[i] != '\\'; --i) {
23  ;
24  }
25  buf[i] = '\0'; // /neuron.exe gone
26  for (i = strlen(buf); i >= 0 && buf[i] != '\\'; --i) {
27  ;
28  }
29  buf[i] = '\0'; // /bin gone
30  nrnhome = new char[strlen(buf) + 1];
31  strcpy(nrnhome, buf);
32 }
33 
34 static char* argstr(int argc, char** argv) {
35  // put args into single string, escaping spaces in args.
36  int i, j, cnt;
37  char* s;
38  char* a;
39  char* u;
40  cnt = 100;
41  for (i = 1; i < argc; ++i) {
42  cnt += strlen(argv[i]) + 20;
43  }
44  s = new char[cnt];
45  j = 0;
46  for (i = 1; i < argc; ++i) {
47  // convert dos to unix path and space to @@
48  // the latter will be converted back to space in src/oc/hoc.c
49  // cygwin 7 need to convert x: and x:/ and x:\ to
50  // /cygdrive/x/
51  u = hoc_dos2unixpath(argv[i]);
52  for (a = u; *a; ++a) {
53  if (*a == ' ') {
54  s[j++] = '@';
55  s[j++] = '@';
56  } else {
57  s[j++] = *a;
58  }
59  }
60  if (i < argc - 1) {
61  s[j++] = ' ';
62  }
63  free(u);
64  }
65  s[j] = '\0';
66  return s;
67 }
68 
69 int main(int argc, char** argv) {
70  int err;
71  char* args;
72 
73 #ifndef MINGW
74  ShowWindow(GetConsoleWindow(), SW_HIDE);
75 #endif
76  setneuronhome();
78  args = argstr(argc, argv);
79  auto const buf_size = strlen(args) + 6 * strlen(nh) + 200;
80  char* const buf = new char[buf_size];
81 #ifdef MINGW
82  std::snprintf(buf,
83  buf_size,
84  "%s\\mingw\\usr\\bin\\bash.exe -i %s/lib/neuron3.sh %s nrngui %s",
85  nrnhome,
86  nh,
87  nh,
88  args);
89 #else
90  std::snprintf(buf,
91  buf_size,
92  "%s\\bin\\mintty -c %s/lib/minttyrc %s/bin/bash --rcfile %s/lib/nrnstart.bsh "
93  "%s/lib/neuron.sh %s %s",
94  nrnhome,
95  nh,
96  nh,
97  nh,
98  nh,
99  nh,
100  args);
101 #endif
102  auto const msg_size = strlen(buf) + 100;
103  char* const msg = new char[msg_size];
104 
105  // Windows 11 exits immediately
106  // https://stackoverflow.com/questions/2255608/force-application-to-wait-until-winexec-has-completed
107  // WinExec is no longer recommended. You can use CreateProcess and WaitForSingleObject as
108  // shown in this example on Creating Processes.
109  STARTUPINFO si;
110  PROCESS_INFORMATION pi;
111  ZeroMemory(&si, sizeof(si));
112  si.cb = sizeof(si);
113  ZeroMemory(&pi, sizeof(pi));
114  // Start the child process.
115  err = CreateProcess(NULL, // No module name (use command line)
116  buf, // Command line
117  NULL, // Process handle not inheritable
118  NULL, // Thread handle not inheritable
119  FALSE, // Set handle inheritance to FALSE
120  0, // No creation flags
121  NULL, // Use parent's environment block
122  NULL, // Use parent's starting directory
123  &si, // Pointer to STARTUPINFO structure
124  &pi); // Pointer to PROCESS_INFORMATION structure
125 
126  if (!err) {
127  std::snprintf(msg, msg_size, "CreateProcess failed (%d). %s\n", GetLastError(), buf);
128  MessageBox(0, msg, "NEURON", MB_OK);
129  return 1;
130  }
131 
132  // Wait until child process exits.
133  WaitForSingleObject(pi.hProcess, INFINITE);
134 
135  // Close process and thread handles.
136  CloseHandle(pi.hProcess);
137  CloseHandle(pi.hThread);
138 
139  return 0;
140 }
#define cnt
Definition: tqueue.hpp:44
#define i
Definition: md1redef.h:19
char * hoc_dos2unixpath(const char *d)
Definition: d2upath.cpp:12
#define FALSE
Definition: grids.h:23
char buf[512]
Definition: init.cpp:13
static int argc
Definition: inithoc.cpp:45
static char ** argv
Definition: inithoc.cpp:46
char * nrnhome
Definition: neuron.cpp:15
int main(int argc, char **argv)
Definition: neuron.cpp:69
static char * argstr(int argc, char **argv)
Definition: neuron.cpp:34
static void setneuronhome()
Definition: neuron.cpp:18
char * nh
Definition: neuron.cpp:16
size_t j
s
Definition: multisend.cpp:521
#define NULL
Definition: spdefs.h:105