sourcepawn/batchtool/uFunc.pas
author David Anderson <dvander@alliedmods.net>
Thu Aug 02 00:19:47 2007 +0000 (2007-08-02)
changeset 1248 ee9f7860e9db
child 1302 63cab5e08c56
permissions -rw-r--r--
added a build of sniperbeamer's batch compiling tool for sourcemod
dvander@1248
     1
(* AMX Mod X
dvander@1248
     2
*    compile.exe
dvander@1248
     3
*
dvander@1248
     4
* by the AMX Mod X Development Team
dvander@1248
     5
*
dvander@1248
     6
*
dvander@1248
     7
*  This program is free software; you can redistribute it and/or modify it
dvander@1248
     8
*  under the terms of the GNU General Public License as published by the
dvander@1248
     9
*  Free Software Foundation; either version 2 of the License, or (at
dvander@1248
    10
*  your option) any later version.
dvander@1248
    11
*
dvander@1248
    12
*  This program is distributed in the hope that it will be useful, but
dvander@1248
    13
*  WITHOUT ANY WARRANTY; without even the implied warranty of
dvander@1248
    14
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dvander@1248
    15
*  General Public License for more details.
dvander@1248
    16
*
dvander@1248
    17
*  You should have received a copy of the GNU General Public License
dvander@1248
    18
*  along with this program; if not, write to the Free Software Foundation,
dvander@1248
    19
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dvander@1248
    20
*
dvander@1248
    21
*  In addition, as a special exception, the author gives permission to
dvander@1248
    22
*  link the code of this program with the Half-Life Game Engine ("HL
dvander@1248
    23
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
dvander@1248
    24
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
dvander@1248
    25
*  respects for all of the code used other than the HL Engine and MODs
dvander@1248
    26
*  from Valve. If you modify this file, you may extend this exception
dvander@1248
    27
*  to your version of the file, but you are not obligated to do so. If
dvander@1248
    28
*  you do not wish to do so, delete this exception statement from your
dvander@1248
    29
*  version.
dvander@1248
    30
*)
dvander@1248
    31
dvander@1248
    32
unit uFunc;
dvander@1248
    33
dvander@1248
    34
interface
dvander@1248
    35
dvander@1248
    36
uses
dvander@1248
    37
  Windows, SysUtils, Classes, Math, IniFiles;
dvander@1248
    38
dvander@1248
    39
resourcestring
dvander@1248
    40
  COMPILER_EXE = 'spcomp.exe';
dvander@1248
    41
dvander@1248
    42
procedure AppExit;
dvander@1248
    43
procedure CompilePlugin(const Name: String);
dvander@1248
    44
function GetAgeFromDat(const FileName: String): Integer;
dvander@1248
    45
procedure SetAgeToDat(const FileName: String; const Age: Integer);
dvander@1248
    46
function GetConsoleOutput(const Command: String; var Output: TStringList): Boolean;
dvander@1248
    47
dvander@1248
    48
implementation
dvander@1248
    49
dvander@1248
    50
procedure AppExit;
dvander@1248
    51
begin
dvander@1248
    52
  WriteLn;
dvander@1248
    53
  Write('Press enter to exit ...');
dvander@1248
    54
  ReadLn;
dvander@1248
    55
  Halt;
dvander@1248
    56
end;
dvander@1248
    57
dvander@1248
    58
procedure CompilePlugin(const Name: String);
dvander@1248
    59
var
dvander@1248
    60
  Output: TStringList;
dvander@1248
    61
  i: Word;
dvander@1248
    62
  cStart,cEnd: Longword;
dvander@1248
    63
  FileName, FilePath, Compiled: String;
dvander@1248
    64
begin
dvander@1248
    65
  FileName := ExtractFileName(Name);
dvander@1248
    66
  FilePath := ExtractFilePath(Name);
dvander@1248
    67
  Compiled := FilePath+'compiled\'+ChangeFileExt(Filename,'.smx');
dvander@1248
    68
  if (FilePath='') then
dvander@1248
    69
    FilePath := ExtractFilePath(ParamStr(0));
dvander@1248
    70
dvander@1248
    71
  WriteLn;
dvander@1248
    72
  WriteLn('//// '+ExtractFileName(FileName));
dvander@1248
    73
dvander@1248
    74
  if FileExists(Compiled) and ( GetAgeFromDat(FileName)=FileAge(Name) ) then
dvander@1248
    75
  begin
dvander@1248
    76
    WriteLn('// Already compiled.');
dvander@1248
    77
    WriteLn('// ----------------------------------------');
dvander@1248
    78
    Exit;
dvander@1248
    79
  end;
dvander@1248
    80
dvander@1248
    81
  Output := TStringList.Create;
dvander@1248
    82
dvander@1248
    83
  try
dvander@1248
    84
    cStart := GetTickCount;
dvander@1248
    85
    if not GetConsoleOutput(ExtractFilePath(ParamStr(0))+COMPILER_EXE+' "'+FilePath+FileName+'" "-o'+Compiled+'"',Output) then
dvander@1248
    86
    begin
dvander@1248
    87
      WriteLn('// Internal error.');
dvander@1248
    88
      AppExit;
dvander@1248
    89
    end;
dvander@1248
    90
    cEnd := GetTickCount;
dvander@1248
    91
dvander@1248
    92
    for i := 3 to (Output.Count-1) do
dvander@1248
    93
    begin
dvander@1248
    94
      WriteLn('// '+Output.Strings[i]);
dvander@1248
    95
    end;
dvander@1248
    96
dvander@1248
    97
    WriteLn('//');
dvander@1248
    98
    WriteLn('// Compilation Time: '+FloatToStr(SimpleRoundTo((cEnd-cStart) / 1000,-2))+' sec');
dvander@1248
    99
    WriteLn('// ----------------------------------------');
dvander@1248
   100
    Output.Free;
dvander@1248
   101
  except
dvander@1248
   102
    WriteLn('// Internal error.');
dvander@1248
   103
    AppExit;
dvander@1248
   104
  end;
dvander@1248
   105
dvander@1248
   106
  SetAgeToDat(FileName,FileAge(Name));
dvander@1248
   107
end;
dvander@1248
   108
dvander@1248
   109
function GetAgeFromDat(const FileName: String): Integer;
dvander@1248
   110
var
dvander@1248
   111
  Ini: TIniFile;
dvander@1248
   112
begin
dvander@1248
   113
  Ini := TIniFile.Create(ExtractFilePath(ParamStr(0))+'compile.dat');
dvander@1248
   114
  Result := Ini.ReadInteger(FileName,'Age',-1);
dvander@1248
   115
  Ini.Free;
dvander@1248
   116
end;
dvander@1248
   117
dvander@1248
   118
procedure SetAgeToDat(const FileName: String; const Age: Integer);
dvander@1248
   119
var
dvander@1248
   120
  Ini: TIniFile;
dvander@1248
   121
begin
dvander@1248
   122
  Ini := TIniFile.Create(ExtractFilePath(ParamStr(0))+'compile.dat');
dvander@1248
   123
  Ini.WriteInteger(FileName,'Age',Age);
dvander@1248
   124
  Ini.UpdateFile;
dvander@1248
   125
  Ini.Free;
dvander@1248
   126
end;
dvander@1248
   127
dvander@1248
   128
function GetConsoleOutput(const Command: String; var Output: TStringList): Boolean;
dvander@1248
   129
var
dvander@1248
   130
  StartupInfo: TStartupInfo;
dvander@1248
   131
  ProcessInfo: TProcessInformation;
dvander@1248
   132
  SecurityAttr: TSecurityAttributes;
dvander@1248
   133
  PipeOutputRead: THandle;
dvander@1248
   134
  PipeOutputWrite: THandle;
dvander@1248
   135
  PipeErrorsRead: THandle;
dvander@1248
   136
  PipeErrorsWrite: THandle;
dvander@1248
   137
  Succeed: Boolean;
dvander@1248
   138
  Buffer: array [0..255] of Char;
dvander@1248
   139
  NumberOfBytesRead: DWORD;
dvander@1248
   140
  Stream: TMemoryStream;
dvander@1248
   141
begin
dvander@1248
   142
  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
dvander@1248
   143
dvander@1248
   144
  FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
dvander@1248
   145
  SecurityAttr.nLength := SizeOf(SecurityAttr);
dvander@1248
   146
  SecurityAttr.bInheritHandle := True;
dvander@1248
   147
  SecurityAttr.lpSecurityDescriptor := nil;
dvander@1248
   148
dvander@1248
   149
  CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
dvander@1248
   150
  CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);
dvander@1248
   151
dvander@1248
   152
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
dvander@1248
   153
  StartupInfo.cb:=SizeOf(StartupInfo);
dvander@1248
   154
  StartupInfo.hStdInput := 0;
dvander@1248
   155
  StartupInfo.hStdOutput := PipeOutputWrite;
dvander@1248
   156
  StartupInfo.hStdError := PipeErrorsWrite;
dvander@1248
   157
  StartupInfo.wShowWindow := SW_HIDE;
dvander@1248
   158
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
dvander@1248
   159
dvander@1248
   160
  if  CreateProcess(nil, PChar(command), nil, nil, true,
dvander@1248
   161
  CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil,
dvander@1248
   162
  StartupInfo, ProcessInfo) then begin
dvander@1248
   163
    Result := True;
dvander@1248
   164
    CloseHandle(PipeOutputWrite);
dvander@1248
   165
    CloseHandle(PipeErrorsWrite);
dvander@1248
   166
dvander@1248
   167
    Stream := TMemoryStream.Create;
dvander@1248
   168
    try
dvander@1248
   169
      while True do begin
dvander@1248
   170
        Succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
dvander@1248
   171
        if not Succeed then Break;
dvander@1248
   172
        Stream.Write(Buffer, NumberOfBytesRead);
dvander@1248
   173
      end;
dvander@1248
   174
      Stream.Position := 0;
dvander@1248
   175
      Output.LoadFromStream(Stream);
dvander@1248
   176
    finally
dvander@1248
   177
      Stream.Free;
dvander@1248
   178
    end;
dvander@1248
   179
    CloseHandle(PipeOutputRead);
dvander@1248
   180
dvander@1248
   181
    try
dvander@1248
   182
      while True do
dvander@1248
   183
      begin
dvander@1248
   184
        Succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil);
dvander@1248
   185
        if not Succeed then Break;
dvander@1248
   186
      end;
dvander@1248
   187
    finally
dvander@1248
   188
    end;
dvander@1248
   189
    CloseHandle(PipeErrorsRead);
dvander@1248
   190
dvander@1248
   191
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
dvander@1248
   192
    CloseHandle(ProcessInfo.hProcess);
dvander@1248
   193
  end
dvander@1248
   194
  else
dvander@1248
   195
  begin
dvander@1248
   196
    Result := False;
dvander@1248
   197
    CloseHandle(PipeOutputRead);
dvander@1248
   198
    CloseHandle(PipeOutputWrite);
dvander@1248
   199
    CloseHandle(PipeErrorsRead);
dvander@1248
   200
    CloseHandle(PipeErrorsWrite);
dvander@1248
   201
  end;
dvander@1248
   202
end;
dvander@1248
   203
dvander@1248
   204
end.