summaryrefslogtreecommitdiffstats
path: root/win32caml/startocaml.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32caml/startocaml.c')
-rw-r--r--win32caml/startocaml.c533
1 files changed, 270 insertions, 263 deletions
diff --git a/win32caml/startocaml.c b/win32caml/startocaml.c
index 37ebde1c2..578d407cb 100644
--- a/win32caml/startocaml.c
+++ b/win32caml/startocaml.c
@@ -10,49 +10,55 @@
/* */
/***********************************************************************/
+/***********************************************************************/
+/* Changes made by Chris Watford to enhance the source editor */
+/* Began 14 Sept 2003 - watford@uiuc.edu */
+/***********************************************************************/
+
/* $Id$ */
#include <windows.h>
#include <stdio.h>
-#include <direct.h>
#include <io.h>
+#include <direct.h>
#include "inria.h"
+extern int _get_osfhandle(int);
PROCESS_INFORMATION pi;
#define BUFSIZE 4096
STARTUPINFO startInfo;
/*------------------------------------------------------------------------
- Procedure: ShowDbgMsg ID:1
- Purpose: Puts up a dialog box with a message, forcing it to
- the foreground.
- Input:
- Output:
- Errors:
+Procedure: ShowDbgMsg ID:1
+Purpose: Puts up a dialog box with a message, forcing it to
+the foreground.
+Input:
+Output:
+Errors:
------------------------------------------------------------------------*/
void ShowDbgMsg(char *str)
{
- HWND hWnd;
- char p[20], message[255];
- hWnd = hwndMain;
- if (IsIconic(hWnd)){
- ShowWindow(hWnd,SW_RESTORE);
- }
- strncpy(message, str, 254);
- message[254] = 0;
- strcpy(p, "Error");
- MessageBox(hWnd, message, p, MB_OK | MB_ICONHAND|MB_TASKMODAL|MB_SETFOREGROUND);
+ HWND hWnd;
+ char p[20], message[255];
+ hWnd = hwndMain;
+ if (IsIconic(hWnd)){
+ ShowWindow(hWnd,SW_RESTORE);
+ }
+ strncpy(message, str, 254);
+ message[254] = 0;
+ strcpy(p, "Error");
+ MessageBox(hWnd, message, p, MB_OK | MB_ICONHAND|MB_TASKMODAL|MB_SETFOREGROUND);
}
int AskYesOrNo(char *msg)
{
- HWND hwnd;
- int r;
-
- hwnd = hwndMain;
- r = MessageBox(hwnd, msg, "Ocaml", MB_YESNO | MB_SETFOREGROUND);
- if (r == IDYES)
- return (TRUE);
- return (FALSE);
+ HWND hwnd;
+ int r;
+
+ hwnd = hwndMain;
+ r = MessageBox(hwnd, msg, "Ocaml", MB_YESNO | MB_SETFOREGROUND);
+ if (r == IDYES)
+ return (TRUE);
+ return (FALSE);
}
@@ -60,305 +66,306 @@ static DWORD OcamlStatus;
static int RegistryError(void)
{
- char buf[512];
+ char buf[512];
- wsprintf(buf,"Error %d writing to the registry",GetLastError());
- ShowDbgMsg(buf);
- return 0;
+ wsprintf(buf,"Error %d writing to the registry",GetLastError());
+ ShowDbgMsg(buf);
+ return 0;
}
static int ReadRegistry(HKEY hroot,
- char * p1, char * p2, char * p3,
- char dest[1024])
+ char * p1, char * p2, char * p3,
+ char dest[1024])
{
- HKEY h1, h2;
- DWORD dwType;
- unsigned long size;
- LONG ret;
-
- if (RegOpenKeyExA(hroot, p1, 0, KEY_QUERY_VALUE, &h1) != ERROR_SUCCESS)
- return 0;
- if (RegOpenKeyExA(h1, p2, 0, KEY_QUERY_VALUE, &h2) != ERROR_SUCCESS) {
- RegCloseKey(h1);
- return 0;
- }
- dwType = REG_SZ;
- size = 1024;
- ret = RegQueryValueExA(h2, p3, 0, &dwType, dest, &size);
- RegCloseKey(h2);
- RegCloseKey(h1);
- return ret == ERROR_SUCCESS;
+ HKEY h1, h2;
+ DWORD dwType;
+ unsigned long size;
+ LONG ret;
+
+ if (RegOpenKeyExA(hroot, p1, 0, KEY_QUERY_VALUE, &h1) != ERROR_SUCCESS)
+ return 0;
+ if (RegOpenKeyExA(h1, p2, 0, KEY_QUERY_VALUE, &h2) != ERROR_SUCCESS) {
+ RegCloseKey(h1);
+ return 0;
+ }
+ dwType = REG_SZ;
+ size = 1024;
+ ret = RegQueryValueExA(h2, p3, 0, &dwType, dest, &size);
+ RegCloseKey(h2);
+ RegCloseKey(h1);
+ return ret == ERROR_SUCCESS;
}
static int WriteRegistry(HKEY hroot,
- char * p1, char * p2, char * p3,
- char data[1024])
+ char * p1, char * p2, char * p3,
+ char data[1024])
{
- HKEY h1, h2;
- DWORD disp;
- LONG ret;
-
- if (RegOpenKeyExA(hroot, p1, 0, KEY_QUERY_VALUE, &h1) != ERROR_SUCCESS)
- return 0;
- if (RegCreateKeyExA(h1, p2, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &h2, &disp)
- != ERROR_SUCCESS) {
- RegCloseKey(h1);
- return 0;
- }
- ret = RegSetValueEx(h2, p3, 0, REG_SZ, data, strlen(data) + 1);
- RegCloseKey(h2);
- RegCloseKey(h1);
- return ret == ERROR_SUCCESS;
+ HKEY h1, h2;
+ DWORD disp;
+ LONG ret;
+
+ if (RegOpenKeyExA(hroot, p1, 0, KEY_QUERY_VALUE, &h1) != ERROR_SUCCESS)
+ return 0;
+ if (RegCreateKeyExA(h1, p2, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &h2, &disp)
+ != ERROR_SUCCESS) {
+ RegCloseKey(h1);
+ return 0;
+ }
+ ret = RegSetValueEx(h2, p3, 0, REG_SZ, data, strlen(data) + 1);
+ RegCloseKey(h2);
+ RegCloseKey(h1);
+ return ret == ERROR_SUCCESS;
}
/*------------------------------------------------------------------------
- Procedure: GetOcamlPath ID:1
- Purpose: Read the registry key
- HKEY_LOCAL_MACHINE\Software\Objective Caml
- or
- HKEY_CURRENT_USER\Software\Objective Caml,
- and creates it if it doesn't exists.
- If any error occurs, i.e. the
- given path doesn't exist, or the key didn't exist, it
- will put up a browse dialog box to allow the user to
- enter the path. The path will be verified that it
- points to a file that exists. If that file is in a
- directory called 'bin', it will look for another
- directory in the same level called lib' and set the
- Lib path to that.
- Input: None explicit
- Output: 1 means sucess, zero failure
- Errors: Almost all system calls will be verified
+Procedure: GetOcamlPath ID:1
+Purpose: Read the registry key
+HKEY_LOCAL_MACHINE\Software\Objective Caml
+or
+HKEY_CURRENT_USER\Software\Objective Caml,
+and creates it if it doesn't exists.
+If any error occurs, i.e. the
+given path doesn't exist, or the key didn't exist, it
+will put up a browse dialog box to allow the user to
+enter the path. The path will be verified that it
+points to a file that exists. If that file is in a
+directory called 'bin', it will look for another
+directory in the same level called lib' and set the
+Lib path to that.
+Input: None explicit
+Output: 1 means sucess, zero failure
+Errors: Almost all system calls will be verified
------------------------------------------------------------------------*/
int GetOcamlPath(void)
{
- char path[1024], *p;
-
- again:
- if (! ReadRegistry(HKEY_CURRENT_USER,
- "Software", "Objective Caml",
- "InterpreterPath", path)
- &&
- ! ReadRegistry(HKEY_LOCAL_MACHINE,
- "Software", "Objective Caml",
- "InterpreterPath", path)) {
- /* Key doesn't exist? Ask user */
- path[0] = '\0';
- if (!BrowseForFile("Ocaml interpreter|ocaml.exe", path)) {
- ShowDbgMsg("Impossible to find ocaml.exe. I quit");
- exit(0);
- }
- WriteRegistry(HKEY_CURRENT_USER,
- "Software", "Objective Caml",
- "InterpreterPath", path);
- }
- /* Check if file exists */
- if (_access(path, 0) != 0) {
- char *errormsg = malloc(1024);
- wsprintf(errormsg,"Incorrect path for ocaml.exe:\n%s", path);
- ShowDbgMsg(errormsg);
- free(errormsg);
- path[0] = 0;
- WriteRegistry(HKEY_CURRENT_USER,
- "Software", "Objective Caml",
- "InterpreterPath", path);
- goto again;
- }
- strcpy(OcamlPath, path);
- p = strrchr(OcamlPath,'\\');
- if (p) {
- *p = 0;
- strcpy(LibDir,OcamlPath);
- *p = '\\';
- p = strrchr(LibDir,'\\');
- if (p && !stricmp(p,"\\bin")) {
- *p = 0;
- strcat(LibDir,"\\lib");
- }
- }
- return 1;
+ char path[1024], *p;
+
+again:
+ if (! ReadRegistry(HKEY_CURRENT_USER,
+ "Software", "Objective Caml",
+ "InterpreterPath", path)
+ &&
+ ! ReadRegistry(HKEY_LOCAL_MACHINE,
+ "Software", "Objective Caml",
+ "InterpreterPath", path)) {
+ /* Key doesn't exist? Ask user */
+ if (!BrowseForFile("Ocaml interpreter|ocaml.exe", path)) {
+ ShowDbgMsg("Impossible to find ocaml.exe. I quit");
+ exit(0);
+ }
+ WriteRegistry(HKEY_CURRENT_USER,
+ "Software", "Objective Caml",
+ "InterpreterPath", path);
+ }
+ /* Check if file exists */
+ if (_access(path, 0) != 0) {
+ char *errormsg = malloc(1024);
+ wsprintf(errormsg,"Incorrect path for ocaml.exe:\n%s", path);
+ ShowDbgMsg(errormsg);
+ free(errormsg);
+ path[0] = 0;
+ WriteRegistry(HKEY_CURRENT_USER,
+ "Software", "Objective Caml",
+ "InterpreterPath", path);
+ goto again;
+ }
+ strcpy(OcamlPath, path);
+ p = strrchr(OcamlPath,'\\');
+ if (p) {
+ *p = 0;
+ strcpy(LibDir,OcamlPath);
+ *p = '\\';
+ p = strrchr(LibDir,'\\');
+ if (p && !stricmp(p,"\\bin")) {
+ *p = 0;
+ strcat(LibDir,"\\lib");
+ }
+ }
+ return 1;
}
static HANDLE hChildStdinRd, hChildStdinWr,hChildStdoutRd, hChildStdoutWr;
/*------------------------------------------------------------------------
- Procedure: IsWindowsNT ID:1
- Purpose: Returns 1 if we are running under windows NT, zero
- otherwise.
- Input: None
- Output: 1 or zero
- Errors:
+Procedure: IsWindowsNT ID:1
+Purpose: Returns 1 if we are running under windows NT, zero
+otherwise.
+Input: None
+Output: 1 or zero
+Errors:
------------------------------------------------------------------------*/
int IsWindowsNT(void)
{
- OSVERSIONINFO osv;
+ OSVERSIONINFO osv;
- osv.dwOSVersionInfoSize = sizeof(osv);
- GetVersionEx(&osv);
- return(osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
+ osv.dwOSVersionInfoSize = sizeof(osv);
+ GetVersionEx(&osv);
+ return(osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
/*------------------------------------------------------------------------
- Procedure: DoStartOcaml ID:1
- Purpose: Starts the ocaml interpreter ocaml.exe. The standard
- input of the interpreter will be connected to a pipe,
- and the standard output and standard error to another
- pipe. The interpreter starts as a hidden process,
- showing only in the task list. Since this is in an
- own thread, its workings are independent of the rest
- of the program. After starting the interpreter, the
- thread waits in case the interpreter exits, for
- instance if the user or some program types #quit;;.
- In this case, the waiting thread awakens and exits
- the user interface.
- Input: Not used. It uses the OcamlPath global variable, that
- is supposed to be correct, no test for its validity
- are done here.
- Output: None visible
- Errors: If any system call for whatever reason fails, the
- thread will exit. No error message is shown.
+Procedure: DoStartOcaml ID:1
+Purpose: Starts the ocaml interpreter ocaml.exe. The standard
+input of the interpreter will be connected to a pipe,
+and the standard output and standard error to another
+pipe. The interpreter starts as a hidden process,
+showing only in the task list. Since this is in an
+own thread, its workings are independent of the rest
+of the program. After starting the interpreter, the
+thread waits in case the interpreter exits, for
+instance if the user or some program types #quit;;.
+In this case, the waiting thread awakens and exits
+the user interface.
+Input: Not used. It uses the OcamlPath global variable, that
+is supposed to be correct, no test for its validity
+are done here.
+Output: None visible
+Errors: If any system call for whatever reason fails, the
+thread will exit. No error message is shown.
------------------------------------------------------------------------*/
-DWORD _stdcall DoStartOcaml(LPVOID param)
+int _stdcall DoStartOcaml(HWND hwndParent)
{
- char *cmdline;
- int processStarted;
- LPSECURITY_ATTRIBUTES lpsa=NULL;
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
- HWND hwndParent = (HWND) param;
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- // Under windows NT/2000/Whistler we have to initialize the security descriptors
- // This is not necessary under windows 98/95.
- if (IsWindowsNT()) {
- InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = &sd;
- lpsa = &sa;
- }
- memset(&startInfo,0,sizeof(STARTUPINFO));
- startInfo.cb = sizeof(STARTUPINFO);
- // Create a pipe for the child process's STDOUT.
- if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
- return 0;
- // Create a pipe for the child process's STDIN.
- if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa, 0))
- return 0;
- // Setup the start info structure
- startInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
- startInfo.wShowWindow = SW_HIDE;
- startInfo.hStdOutput = hChildStdoutWr;
- startInfo.hStdError = hChildStdoutWr;
- startInfo.hStdInput = hChildStdinRd;
- cmdline = OcamlPath;
- // Set the OCAMLLIB environment variable
- SetEnvironmentVariable("OCAMLLIB", LibDir);
- // Let's go: start the ocaml interpreter
- processStarted = CreateProcess(NULL,cmdline,lpsa,lpsa,1,
- CREATE_NEW_PROCESS_GROUP|NORMAL_PRIORITY_CLASS,
- NULL,ProgramParams.CurrentWorkingDir,&startInfo,&pi);
- if (processStarted) {
- WaitForSingleObject(pi.hProcess,INFINITE);
- GetExitCodeProcess(pi.hProcess,(unsigned long *)&OcamlStatus);
- CloseHandle(pi.hProcess);
- PostMessage(hwndMain,WM_QUITOCAML,0,0);
- }
- else {
- char *msg = malloc(1024);
- wsprintf(msg,"Impossible to start ocaml.exe in:\n%s",cmdline);
- ShowDbgMsg(msg);
- free(msg);
- }
- return 0;
+ char *cmdline;
+ int processStarted;
+ LPSECURITY_ATTRIBUTES lpsa=NULL;
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ // Under windows NT/2000/Whistler we have to initialize the security descriptors
+ // This is not necessary under windows 98/95.
+ if (IsWindowsNT()) {
+ InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
+ SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = &sd;
+ lpsa = &sa;
+ }
+ memset(&startInfo,0,sizeof(STARTUPINFO));
+ startInfo.cb = sizeof(STARTUPINFO);
+ // Create a pipe for the child process's STDOUT.
+ if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
+ return 0;
+ // Create a pipe for the child process's STDIN.
+ if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa, 0))
+ return 0;
+ // Setup the start info structure
+ startInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ startInfo.wShowWindow = SW_HIDE;
+ startInfo.hStdOutput = hChildStdoutWr;
+ startInfo.hStdError = hChildStdoutWr;
+ startInfo.hStdInput = hChildStdinRd;
+ cmdline = OcamlPath;
+ // Set the OCAMLLIB environment variable
+ SetEnvironmentVariable("OCAMLLIB", LibDir);
+ // Let's go: start the ocaml interpreter
+ processStarted = CreateProcess(NULL,cmdline,lpsa,lpsa,1,
+ CREATE_NEW_PROCESS_GROUP|NORMAL_PRIORITY_CLASS,
+ NULL,ProgramParams.CurrentWorkingDir,&startInfo,&pi);
+ if (processStarted) {
+ WaitForSingleObject(pi.hProcess,INFINITE);
+ GetExitCodeProcess(pi.hProcess,(unsigned long *)&OcamlStatus);
+ CloseHandle(pi.hProcess);
+ PostMessage(hwndMain,WM_QUITOCAML,0,0);
+ }
+ else {
+ char *msg = malloc(1024);
+ wsprintf(msg,"Impossible to start ocaml.exe in:\n%s",cmdline);
+ ShowDbgMsg(msg);
+ free(msg);
+ }
+ return 0;
}
/*------------------------------------------------------------------------
- Procedure: WriteToPipe ID:1
- Purpose: Writes the given character string to the standard
- input of the interpreter
- Input: The character string (zero terminated) to be written
- Output: The number of characters written or zero if an error
- occurs
- Errors: None
+Procedure: WriteToPipe ID:1
+Purpose: Writes the given character string to the standard
+input of the interpreter
+Input: The character string (zero terminated) to be written
+Output: The number of characters written or zero if an error
+occurs
+Errors: None
------------------------------------------------------------------------*/
int WriteToPipe(char *data)
{
- DWORD dwWritten;
- if (! WriteFile(hChildStdinWr, data, strlen(data),
- &dwWritten, NULL))
- return 0;
- return dwWritten;
+ DWORD dwWritten;
+
+ if (! WriteFile(hChildStdinWr, data, strlen(data), &dwWritten, NULL))
+ return 0;
+
+ return dwWritten;
}
/*------------------------------------------------------------------------
- Procedure: ReadFromPipe ID:1
- Purpose: Reads from the standard output of the interpreter and
- stores the data in the given buffer up to the given
- length. This is done in a non-blocking manner, i.e.
- it is safe to call this even if there is no data
- available.
- Input: The buffer to be used and its length.
- Output: Returns the number of characters read from the pipe.
- Errors: None explicit
+Procedure: ReadFromPipe ID:1
+Purpose: Reads from the standard output of the interpreter and
+stores the data in the given buffer up to the given
+length. This is done in a non-blocking manner, i.e.
+it is safe to call this even if there is no data
+available.
+Input: The buffer to be used and its length.
+Output: Returns the number of characters read from the pipe.
+Errors: None explicit
------------------------------------------------------------------------*/
int ReadFromPipe(char *data,int len)
{
- DWORD dwRead;
+ DWORD dwRead;
- PeekNamedPipe(hChildStdoutRd,data,len,NULL,&dwRead,NULL);
- if (dwRead == 0)
- return 0;
+ PeekNamedPipe(hChildStdoutRd,data,len,NULL,&dwRead,NULL);
+ if (dwRead == 0)
+ return 0;
- // Read output from the child process, and write to parent's STDOUT.
- if( !ReadFile( hChildStdoutRd, data, len, &dwRead,
- NULL) || dwRead == 0)
- return 0;
- return dwRead;
+ // Read output from the child process, and write to parent's STDOUT.
+ if( !ReadFile( hChildStdoutRd, data, len, &dwRead, NULL) || dwRead == 0)
+ return 0;
+
+ return dwRead;
}
static DWORD tid;
/*------------------------------------------------------------------------
- Procedure: StartOcaml ID:1
- Purpose: Starts the thread that will call the ocaml.exe
- program.
- Input:
- Output:
- Errors:
+Procedure: StartOcaml ID:1
+Purpose: Starts the thread that will call the ocaml.exe
+program.
+Input:
+Output:
+Errors:
------------------------------------------------------------------------*/
int StartOcaml(void)
{
- getcwd(ProgramParams.CurrentWorkingDir,sizeof(ProgramParams.CurrentWorkingDir));
- CreateThread(NULL,0,DoStartOcaml,hwndMain,0,&tid);
- return 1;
+ getcwd(ProgramParams.CurrentWorkingDir,sizeof(ProgramParams.CurrentWorkingDir));
+ CreateThread(NULL,0,DoStartOcaml,hwndMain,0,&tid);
+ return 1;
}
void *SafeMalloc(int size)
{
- void *result;
+ void *result;
- if (size < 0) {
- char message[1024];
+ if (size < 0) {
+ char message[1024];
error:
- sprintf(message,"Can't allocate %d bytes",size);
- MessageBox(NULL,message,"Ocaml",MB_OK);
- exit(-1);
- }
- result = malloc(size);
- if (result == NULL)
- goto error;
- return result;
+ sprintf(message,"Can't allocate %d bytes",size);
+ MessageBox(NULL, message, "Ocaml", MB_OK);
+ exit(-1);
+ }
+ result = malloc(size);
+
+ if (result == NULL)
+ goto error;
+
+ return result;
}
void InterruptOcaml(void)
{
- if (! GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pi.dwProcessId)) {
- char message[1024];
- sprintf(message, "GenerateConsole failed: %ld\n", GetLastError());
- MessageBox(NULL, message, "Ocaml", MB_OK);
- }
- WriteToPipe(" ");
+ if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pi.dwProcessId)) {
+ char message[1024];
+ sprintf(message, "GenerateConsole failed: %d\n", GetLastError());
+ MessageBox(NULL, message, "Ocaml", MB_OK);
+ }
+ WriteToPipe(" ");
}