/*------------------------------------------------------------------------ Procedure: HistoryDlgProc ID:1 Purpose: Shows the history of the session. Only input lines are shown. A double click in a line will make this dialog box procedure return the index of the selected line (1 based). If the windows is closed (what is equivalent to cancel), the return value is zero. Input: Normal windows callback Output: Errors: -------------------------------------------------------------------------- Edit History: 15 Sept 2003 - Chris Watford [email protected] - Added support for my StatementHistory structure - Added the ability to export it as its exact entry, rather than just a 1 liner ------------------------------------------------------------------------*/ static BOOL CALLBACK HistoryDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { StatementHistory *histentry; int idx; RECT rc; switch (message) { case WM_INITDIALOG: SendDlgItemMessage(hDlg,IDLIST,WM_SETFONT,(WPARAM)ProgramParams.hFont,0); histentry = History; // get our statement history object idx = 0; // loop through each history entry adding it to the dialog while (histentry != NULL) { SendDlgItemMessage(hDlg,IDLIST,LB_INSERTSTRING,0,(LPARAM)editbuffer_getasline(histentry->Statement)); SendDlgItemMessage(hDlg,IDLIST,LB_SETITEMDATA,0,(LPARAM)idx); histentry = histentry->Next; idx++; } SendDlgItemMessage(hDlg,IDLIST,LB_SETCURSEL,(LPARAM)idx-1,0); return 1; case WM_COMMAND: switch(LOWORD(wParam)) { case IDLIST: switch(HIWORD(wParam)) { case LBN_DBLCLK: idx = SendDlgItemMessage(hDlg,IDLIST,LB_GETCURSEL,0,0); if (idx == LB_ERR) break; idx = SendDlgItemMessage(hDlg,IDLIST,LB_GETITEMDATA,idx,0); EndDialog(hDlg,idx+1); return 1; } break; } break; case WM_SIZE: GetClientRect(hDlg,&rc); MoveWindow(GetDlgItem(hDlg,IDLIST),0,0,rc.right,rc.bottom,1); break; case WM_CLOSE: EndDialog(hDlg,0); break; } return 0; }
/*------------------------------------------------------------------------ Procedure: SendingFullCommand ID:1 Author: Chris Watford [email protected] Purpose: Returns if the command being sent Input: The edit control window handle Output: None explicit Errors: None -------------------------------------------------------------------------- Edit History: 7 Aug 2004 - Chris Watford [email protected] - Fixed bug #2932 where many carraige returns were sent and it came back with a null pointer error due to a fault of not checking if the line returned was NULL 13 Oct 2003 - Chris Watford [email protected] - Solved the error when you have a malformed comment in the buffer ------------------------------------------------------------------------*/ BOOL SendingFullCommand(void) { // if there is a ;; on the line, return true char *line = editbuffer_getasline(CurrentEditBuffer); char *firstComment, *firstSemiColonSemiColon, *firstQuote; if(line == NULL) { return FALSE; } firstComment = strstr(line, "(*"); firstSemiColonSemiColon = strstr(line, ";;"); firstQuote = strstr(line, "\""); // easy case :D if(firstSemiColonSemiColon == NULL) { free(line); return FALSE; } // if there are no comments if(firstComment == NULL) { // if there are no quotations used if(firstQuote == NULL) { BOOL r = (firstSemiColonSemiColon != NULL); free(line); return r; } else { // we need to first check if the ;; is before the \", since the \" // won't matter if its before the semicolonsemicolon if(firstQuote < firstSemiColonSemiColon) { // the quote is before the ;;, we need to make sure its terminated // also we have to check for escaped quotes, le sigh! char *c = firstQuote+1; BOOL in_quote = TRUE; // in-quote determiner loop while(c[0] != '\0') { // are we a backslash? if(c[0] == '\\') { // ignore the next character c++; } else { // are we a quote? if(c[0] == '"') { in_quote = !in_quote; } } c++; } free(line); return !in_quote; } else { BOOL r = (firstSemiColonSemiColon != NULL); free(line); return r; } } } else { // we have to search through finding all comments // a neat little trick we can do is compare the point at which // the ;; is and where the first (* can be found, if the ;; is // before the (* ocaml.exe ignores the comment if((unsigned int)firstSemiColonSemiColon < (unsigned int)firstComment) { free(line); return TRUE; } else { // time to search and find if the endline is inside a comment or not // start at the first comment, and move forward keeping track of the // nesting level, if the nest level is 0, i.e. outside a comment // and we find the ;; return TRUE immediately, otherwise keep searching // if we end with a nest level >0 return FALSE char *c = firstComment+2; // firstComment[0] is the '(', firstComment[1] is the '*' int nestLevel = 1; // we have a (* // in-comment determiner loop while(c[0] != '\0') { // are we an endline if((c[0] == ';') && (c[1] == ';')) { // if we are NOT in a comment, its a full line if(nestLevel <= 0) { free(line); return TRUE; } } // are we in a comment? if((c[0] == '(') && (c[1] == '*')) { nestLevel++; // watch out we may go past the end if(c[2] == '\0') { free(line); return FALSE; } // c needs to advance past the *, cause (*) is NOT the start/finish of a comment c++; } // adjust the nesting down a level if((c[0] == '*') && (c[1] == ')')) nestLevel--; // next char c++; } // not a full line free(line); return FALSE; } } // weird case ;) free(line); return FALSE; }