more eol-style
[xonotic/netradiant.git] / radiant / error.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #define UNICODE
23 #include "stdafx.h"
24
25 #if defined (__linux__) || defined (__APPLE__)
26 #include <unistd.h>
27 #endif
28
29 /*
30 =================
31 Error
32
33 For abnormal program terminations
34 =================
35 */
36
37 /*!
38 \todo 
39 FIXME the prompt wether to do prefs dialog, may not even be possible 
40 if the crash happens before the game is loaded
41 */
42
43 void Error (const char *error, ...)
44 {
45   va_list argptr;
46   char  text[4096];
47
48   va_start (argptr,error);
49   vsprintf (text, error,argptr);
50   va_end (argptr);
51
52   strcat( text, "\n" );
53
54 #if defined (__linux__) || defined (__APPLE__)
55   if (errno != 0)
56   {
57     strcat( text, "errno: " );
58     strcat( text, strerror (errno));
59     strcat( text, "\n");
60   }
61 #endif
62
63 #ifdef _WIN32
64   if (GetLastError() != 0)
65   {
66     LPVOID lpMsgBuf;
67     FormatMessage( 
68       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
69       FORMAT_MESSAGE_FROM_SYSTEM | 
70       FORMAT_MESSAGE_IGNORE_INSERTS,
71       NULL,
72       GetLastError(),
73       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
74       (LPTSTR) &lpMsgBuf,
75       0,
76       NULL 
77       );
78     strcat( text, "GetLastError: " );
79     /*
80     Gtk will only crunch 0<=char<=127
81     this is a bit hackish, but I didn't find useful functions in win32 API for this
82     http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=516
83     */
84     TCHAR *scan, *next = (TCHAR*)lpMsgBuf;
85     do
86     {
87       scan = next;
88       text[strlen(text)+1] = '\0';
89       if ((scan[0] >= 0) && (scan[0] <= 127))
90         text[strlen(text)] = scan[0];
91       else
92         text[strlen(text)] = '?';
93       next = CharNext(scan);
94     } while (next != scan);
95     strcat( text, "\n");
96     LocalFree( lpMsgBuf );
97   }
98 #endif
99
100   // we need to have a current context to call glError()
101   if (g_qeglobals_gui.d_glBase != NULL)
102   {
103     // qglGetError .. can record several errors, clears after calling
104     //++timo TODO: be able to deal with several errors if necessary, for now I'm just warning about pending error messages
105     // NOTE: forget that, most boards don't seem to follow the OpenGL standard
106     GLenum iGLError = qglGetError();
107     if (iGLError != GL_NO_ERROR)
108     {
109       // use our own gluErrorString
110       strcat( text, "qgluErrorString: " );
111       strcat( text, (char*)qgluErrorString( iGLError ) );
112       strcat( text, "\n" );
113     }
114   }
115
116   strcat (text, "An unrecoverable error has occured.\n"
117           "Would you like to edit Preferences before exiting Radiant?");
118
119   Sys_Printf(text);
120
121   if (gtk_MessageBox(NULL, text, "Error", MB_YESNO) == IDYES)
122   {
123     Sys_Printf("Doing prefs..\n");
124     g_PrefsDlg.LoadPrefs ();
125     g_PrefsDlg.DoModal();
126   }
127
128   QGL_Shutdown();
129
130   g_PrefsDlg.Destroy ();
131   g_dlgSurface.Destroy ();
132   g_dlgFind.Destroy ();
133
134   // force close logging if necessary
135   g_PrefsDlg.mGamesDialog.m_bLogConsole = false;
136         Sys_LogFile();
137
138   _exit (1);
139 }
140
141 void WINAPI Error (char *error, ...)
142 {
143   va_list argptr;
144   char  text[1024];
145
146   va_start (argptr,error);
147   vsprintf (text, error,argptr);
148   va_end (argptr);
149         
150         Error((const char *)text);
151 }