/*------------------------------------------------------------------------ Procedure: SaveText ID:1 Purpose: Saves the contents of the session transcript. It will loop for each line and write it to the specified file Input: The name of the file where the session will be saved Output: The session is saved Errors: If it can't open the file for writing it will show an error box -------------------------------------------------------------------------- Edit History: 06 Oct 2003 - Chris Watford [email protected] - Corrected wsprintf error ------------------------------------------------------------------------*/ static void SaveText(char *fname) { int i,len; HWND hEdit = (HWND)GetWindowLongPtr(hwndSession,DWLP_USER); int linesCount = SendMessage(hEdit,EM_GETLINECOUNT,0,0); FILE *f; char *buf = SafeMalloc(8192); f = fopen(fname,"wb"); if (f == NULL) { // corrected error using wsprintf wsprintf(buf, "Impossible to open %s for writing", fname); ShowDbgMsg(buf); return; } for (i = 0; i < linesCount; i++) { *(unsigned short *)buf = 8100; len = SendMessage(hEdit, EM_GETLINE, i, (LPARAM)buf); buf[len] = '\0'; fprintf(f, "%s\r\n", buf+1); //fwrite(buf,1,len+2,f); } fclose(f); free(buf); }
static int RegistryError(void) { char buf[512]; wsprintf(buf,"Error %d writing to the registry",GetLastError()); ShowDbgMsg(buf); return 0; }
/*------------------------------------------------------------------------ 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 WINAPI DoStartOcaml(LPVOID param) { HWND hwndParent = (HWND) param; 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: SaveML ID:1 Author: Chris Watford [email protected] Purpose: Saves the ML source to a file, commenting out functions that contained errors Input: The name of the file where the session will be saved Output: The session is saved Errors: If it can't open the file for writing it will show an error box ------------------------------------------------------------------------*/ static void SaveML(char *fname) { FILE *f; char *buf = SafeMalloc(8192); f = fopen(fname, "wb"); if(f == NULL) { wsprintf(buf, "Impossible to open %s for writing", fname); ShowDbgMsg(buf); return; } fprintf(f, "(* %s *)\r\n\r\n", fname); if(History != NULL) { StatementHistory *h = NULL; EditBuffer *stmt = NULL; // get to the end for(h = History; h->Next != NULL; h = h->Next); // go back :( // this is NOT the fastest method, BUT this is the easiest // on the subsystem for(; h != NULL; h = h->Prev) { stmt = h->Statement; if(stmt != NULL) { // comment out incorrect lines if(stmt->isCorrect) { char *buff = editbuffer_getasbuffer(stmt); fprintf(f, "%s\r\n", buff); free(buff); } else { char *buff = editbuffer_getasbuffer(stmt); fprintf(f, "(* Syntax Error or Unbound Value\r\n%s\r\n *)\r\n", buff); free(buff); } } fprintf(f, "\r\n"); } } fclose(f); free(buf); }
/*------------------------------------------------------------------------ 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; while (( !ReadRegistry(HKEY_CURRENT_USER, "Software", "Objective Caml", "InterpreterPath", path) && !ReadRegistry(HKEY_LOCAL_MACHINE, "Software", "Objective Caml", "InterpreterPath", path)) || _access(path, 0) != 0) { /* Registry key doesn't exist or contains invalid path */ /* 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); /* Iterate to validate 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; }