This file is indexed.

/usr/src/castle-game-engine-4.1.1/base/castleutils_program_exit.inc is in castle-game-engine-src 4.1.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
{
  Copyright 2002-2013 Michalis Kamburelis.

  This file is part of "Castle Game Engine".

  "Castle Game Engine" is free software; see the file COPYING.txt,
  included in this distribution, for details about the copyright.

  "Castle Game Engine" is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  ----------------------------------------------------------------------------
}

{ Things related to exiting the program.
  Some important things are set up here,

  If your program ends with an exception (that is, the main @code(begin..end.)
  of program code exits because exception) we want to output some nice
  error message for user. This is done here by registering our own
  exception handler for SysUtils.ExceptProc.

  @unorderedList(
    @item(In non-debug mode, in case of exception,
      we will output nice message by OutputException and will Halt with
      HaltCodeOnException code.)

    @item(Unless the DEBUG symbold is defined, then we (after showing the nice
      error by OutputException) pass the control to default SysUtils.ExceptProc.
      This way we allow FPC to print nice backtrace of the exception,
      which is useful.)

    @item(When you cause program exit by special BreakProgram exception
      class, then have special behavior. In this case we don't output
      any exception description (like OutputException),
      and we will exit with code you gave to BreakProgram.HaltCode
      (ignoring HaltCodeOnException).

      This BreakProgram behavior is done regardless of DEBUG or not.

      This way you can use @code(raise BreakProgram.Create(123))
      instead or @code(Halt(123)) to exit the program with given status.
      BreakProgram will exit more gracefully than Halt, as all
      the "finally" clauses will execute.)
  ) }

{$ifdef read_interface}

var
  { Additional message output when you end program with an exception. }
  BonusErrorMessg: string ='';

type
  { Class of exceptions that will not have ClassName displayed by
    various routines. ExceptMessage, OutputException will not show exception
    class. Sometimes useful, when you know that exception message
    is good enough, and showing exception class is not needed. }
  EWithHiddenClassName = class(Exception);

{ Nice exception description. Contains ApplicationName, exception ClassName
  (if not descends from EWithHiddenClassName), exception Message (if
  descends from Exception), and ExceptAddr (and not-nil, and this is compiled
  with -dDEBUG), and BonusErrorMesssg. }
function ExceptMessage(E: TObject; ExceptAddr: Pointer = nil): string; overload;

{ Show nice exception description on console or (for GUI Windows programs)
  by a message box. Equivalent to ErrorWrite(ExceptMessage(E)). }
procedure OutputException(E: TObject; ExceptAddr: Pointer = nil); overload;

{ If Value then Halt(0), else Halt(1).

  It is the standard convention of command-line programs to
  exit with code 0 on success and <> 0 on failure.
  Or (for some programs like `test') exit with code 0 to indicate true result
  and <> 0 to indicate false result.
  So you will probably want to pass here some boolean variable
  indicating "Success" or "TestPassed". }
procedure HaltBool(Value: boolean);

var
  HaltCodeOnException: Integer = 1;

{ Call Proc, catch all exceptions inside the Proc,
  and in case of exception make OutputException and Halt(HaltCode).
  The result is that HaltOnException doesn't
  raise any exception, never. It always deals with exceptions inside
  Proc itself.

  Version without HaltCode parameter uses global HaltCodeOnException value.

  For the special exception class @link(BreakProgram), it does simply
  Halt(BreakProgram(E).ExitCode)) (no OutputException in this case).

  When symbol DEBUG is defined, then HaltOnException works differently
  --- it just calls Proc (and doesn't catch any exceptions).

  This is particularly useful under Delphi/Win32. There main program
  should @italic(never) exit with exception. Because such exception
  (because of Delphi stupidity ?) shows ugly Windows
  dialog box saying something like "Program exited unexpectedly,
  contact with author etc. bullshit". There is no way for me to avoid
  this dialog box, even by my own ExceptProc. }
procedure HaltOnException(proc: TProcedure; HaltCode: integer); overload;
procedure HaltOnException(proc: TProcedure); overload;

type
  { Exception specially handled by my exception handler.
    It will not cause any message to be output, and will cause Halt
    with given code. }
  BreakProgram = class(TCodeBreaker)
  private
    FHaltCode: Integer;
  public
    property HaltCode: Integer read FHaltCode;
    constructor Create(AHaltCode: Integer = 0);
  end;

{ Raise BreakProgram with AHaltCode, causing the program to stop with
  given exit code nicely (finalizes all exceptions try..finally and such). }
procedure ProgramBreak(AHaltCode: Integer = 0); overload;

{$endif read_interface}

{$ifdef read_implementation}

function ExceptMessage(E: TObject; ExceptAddr: Pointer): string;
var Message, NiceMessage: string;
begin
 if E is Exception then
 begin
  Message := Exception(E).Message;

  if E is EInOutError then
  begin
   { jezeli wyjatek to EInOutError to zamien [...] nazwy bledow
     "IO Error xxx" na troche lepsze. }
   case EInOutError(E).ErrorCode of
    1..99: NiceMessage := SysErrorMessage(EInOutError(E).ErrorCode);
    100: NiceMessage := 'End of File';
    101: NiceMessage := 'Disk Full';
    102: NiceMessage := 'File variable not assigned';
    103: NiceMessage := 'File not open';
    104: NiceMessage := 'File not open for input';
    105: NiceMessage := 'File not open for output';
    106: NiceMessage := 'Error in formatted input';
    107: NiceMessage := 'File already open';
    else NiceMessage := '';
   end;
   if NiceMessage<>'' then Message := Message +' (' +NiceMessage +')';
  end;

 end else
  Message := '';

 if (E is EWithHiddenClassName) and (Message<>'') then
  result := ApplicationName +': ' +Message else
 begin
  result := ApplicationName +': Exception ' +E.ClassName;
  {$ifdef DEBUG}
  if ExceptAddr<>nil then
   result := result +' (at address ' + PointerToStr(ExceptAddr) + ')';
  {$endif}
  if Message<>'' then result := result +' : ' +nl +Message;
 end;

 if BonusErrorMessg<>'' then result := result +nl +BonusErrorMessg;
end;

procedure OutputException(E: TObject; ExceptAddr: Pointer);
begin
 ErrorWrite(ExceptMessage(E, ExceptAddr));
 { zeby wyswietlic tu message tak jak Delphi/Kylix : ShowException(E, nil) }
end;

procedure HaltBool(Value: boolean);
begin
 if Value then Halt(0) else Halt(1);
end;

procedure HaltOnException(proc: TProcedure; HaltCode: integer);
begin
 {$ifdef DEBUG} proc;
 {$else}
  try Proc;
  except
   on E: TObject do
   begin
    if E is BreakProgram then Halt(BreakProgram(E).HaltCode);
    OutputException(E, nil);
    Halt(HaltCode);
   end;
  end;
 {$endif}
end;

procedure HaltOnException(proc: TProcedure);
begin HaltOnException(proc, HaltCodeOnException); end;

var OldExceptProc: TExceptProc;

procedure CastleUtils_ExceptProc(ExceptObject: TObject;
  ExceptAddr: Pointer; FrameCount: Longint; Frame: PPointer);
begin
 if ExceptObject is BreakProgram then
  Halt(BreakProgram(ExceptObject).HaltCode);

 OutputException(ExceptObject, ExceptAddr);
 {$ifdef DEBUG}
 OldExceptProc(ExceptObject, ExceptAddr, FrameCount, Frame);
 {$else}
 Halt(HaltCodeOnException);
 {$endif}
end;

constructor BreakProgram.Create(AHaltCode: Integer);
begin
 inherited Create;
 FHaltCode := AHaltCode;
end;

procedure ProgramBreak(AHaltCode: Integer);
begin
 raise BreakProgram.Create(AHaltCode);
end;

procedure InitializationProgramExit;
begin
 OldExceptProc := ExceptProc;
 ExceptProc := {$ifdef FPC_OBJFPC} @ {$endif} CastleUtils_ExceptProc;
end;

procedure FinalizationProgramExit;
begin
 ExceptProc := OldExceptProc;
end;

{$endif read_implementation}