sourcepawn/batchtool/uFunc.pas
branchsourcemod-1.1.0
changeset 2283 03a67e41afbc
parent 1951 c7b4237fff50
child 2287 017a725c9d17
     1.1 --- a/sourcepawn/batchtool/uFunc.pas	Fri Mar 28 06:21:34 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,224 +0,0 @@
     1.4 -(* AMX Mod X
     1.5 -*    compile.exe
     1.6 -*
     1.7 -* by the AMX Mod X Development Team
     1.8 -*
     1.9 -*
    1.10 -*  This program is free software; you can redistribute it and/or modify it
    1.11 -*  under the terms of the GNU General Public License as published by the
    1.12 -*  Free Software Foundation; either version 2 of the License, or (at
    1.13 -*  your option) any later version.
    1.14 -*
    1.15 -*  This program is distributed in the hope that it will be useful, but
    1.16 -*  WITHOUT ANY WARRANTY; without even the implied warranty of
    1.17 -*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    1.18 -*  General Public License for more details.
    1.19 -*
    1.20 -*  You should have received a copy of the GNU General Public License
    1.21 -*  along with this program; if not, write to the Free Software Foundation,
    1.22 -*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    1.23 -*
    1.24 -*  In addition, as a special exception, the author gives permission to
    1.25 -*  link the code of this program with the Half-Life Game Engine ("HL
    1.26 -*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
    1.27 -*  L.L.C ("Valve"). You must obey the GNU General Public License in all
    1.28 -*  respects for all of the code used other than the HL Engine and MODs
    1.29 -*  from Valve. If you modify this file, you may extend this exception
    1.30 -*  to your version of the file, but you are not obligated to do so. If
    1.31 -*  you do not wish to do so, delete this exception statement from your
    1.32 -*  version.
    1.33 -*)
    1.34 -
    1.35 -unit uFunc;
    1.36 -
    1.37 -interface
    1.38 -
    1.39 -uses
    1.40 -  Windows, SysUtils, Classes, Math, IniFiles;
    1.41 -
    1.42 -resourcestring
    1.43 -  COMPILER_EXE = 'spcomp.exe';
    1.44 -
    1.45 -procedure AppExit;
    1.46 -procedure CompilePlugin(const Name, OutputDir: String);
    1.47 -function GetAgeFromDat(const FileName: String): Integer;
    1.48 -procedure SetAgeToDat(const FileName: String; const Age: Integer);
    1.49 -function GetConsoleOutput(const Command: String; var Output: TStringList): Boolean;
    1.50 -
    1.51 -implementation
    1.52 -
    1.53 -procedure AppExit;
    1.54 -begin
    1.55 -  WriteLn;
    1.56 -  Write('Press enter to exit ...');
    1.57 -  ReadLn;
    1.58 -  Halt;
    1.59 -end;
    1.60 -
    1.61 -procedure CompilePlugin(const Name, OutputDir: String);
    1.62 -var
    1.63 -  Output: TStringList;
    1.64 -  i: Word;
    1.65 -  cStart,cEnd: Longword;
    1.66 -  FileName, FilePath, Compiled: String;
    1.67 -begin
    1.68 -  FileName := ExtractFileName(Name);
    1.69 -  FilePath := ExtractFilePath(Name);
    1.70 -  if (OutputDir = '') then
    1.71 -    Compiled := FilePath+'compiled\'+ChangeFileExt(Filename,'.smx')
    1.72 -  else
    1.73 -    Compiled := OutputDir+ChangeFileExt(Filename,'.smx');
    1.74 -
    1.75 -  if (FilePath='') then
    1.76 -    FilePath := ExtractFilePath(ParamStr(0));
    1.77 -
    1.78 -  WriteLn;
    1.79 -  WriteLn('//// '+ExtractFileName(FileName));
    1.80 -
    1.81 -  if FileExists(Compiled) and ( GetAgeFromDat(Name)=FileAge(Name) ) then
    1.82 -  begin
    1.83 -    WriteLn('// Already compiled.');
    1.84 -    WriteLn('// ----------------------------------------');
    1.85 -    Exit;
    1.86 -  end;
    1.87 -
    1.88 -  Output := TStringList.Create;
    1.89 -
    1.90 -  try
    1.91 -    cStart := GetTickCount;
    1.92 -    if not GetConsoleOutput(ExtractFilePath(ParamStr(0))+COMPILER_EXE+' "'+Name+'" "-o'+Compiled+'"',Output) then
    1.93 -    begin
    1.94 -      WriteLn('// Internal error.');
    1.95 -      AppExit;
    1.96 -    end;
    1.97 -    cEnd := GetTickCount;
    1.98 -
    1.99 -    for i := 3 to (Output.Count-1) do
   1.100 -    begin
   1.101 -      WriteLn('// '+Output.Strings[i]);
   1.102 -    end;
   1.103 -
   1.104 -    WriteLn('//');
   1.105 -    WriteLn('// Compilation Time: '+FloatToStr(SimpleRoundTo((cEnd-cStart) / 1000,-2))+' sec');
   1.106 -    WriteLn('// ----------------------------------------');
   1.107 -    Output.Free;
   1.108 -  except
   1.109 -    WriteLn('// Internal error.');
   1.110 -    AppExit;
   1.111 -  end;
   1.112 -
   1.113 -  SetAgeToDat(Name,FileAge(Name));
   1.114 -end;
   1.115 -
   1.116 -function GetAgeFromDat(const FileName: String): Integer;
   1.117 -var
   1.118 -  Ini: TIniFile;
   1.119 -begin
   1.120 -  Ini := TIniFile.Create(ExtractFilePath(ParamStr(0))+'compile.dat');
   1.121 -  Result := Ini.ReadInteger(FileName,'Age',-1);
   1.122 -  Ini.Free;
   1.123 -end;
   1.124 -
   1.125 -procedure SetAgeToDat(const FileName: String; const Age: Integer);
   1.126 -var
   1.127 -  Ini: TIniFile;
   1.128 -begin
   1.129 -  Ini := TIniFile.Create(ExtractFilePath(ParamStr(0))+'compile.dat');
   1.130 -  Ini.WriteInteger(FileName,'Age',Age);
   1.131 -  Ini.UpdateFile;
   1.132 -  Ini.Free;
   1.133 -  SetFileAttributes(PChar(ExtractFilePath(ParamStr(0))+'compile.dat'), faHidden);
   1.134 -end;
   1.135 -
   1.136 -function GetConsoleOutput(const Command: String; var Output: TStringList): Boolean;
   1.137 -var
   1.138 -  StartupInfo: TStartupInfo;
   1.139 -  ProcessInfo: TProcessInformation;
   1.140 -  SecurityAttr: TSecurityAttributes;
   1.141 -  PipeOutputRead: THandle;
   1.142 -  PipeOutputWrite: THandle;
   1.143 -  PipeErrorsRead: THandle;
   1.144 -  PipeErrorsWrite: THandle;
   1.145 -  Succeed: Boolean;
   1.146 -  Buffer: array [0..255] of Char;
   1.147 -  NumberOfBytesRead: DWORD;
   1.148 -  Stream: TMemoryStream;
   1.149 -  Errors: String;
   1.150 -begin
   1.151 -  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
   1.152 -  FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
   1.153 -
   1.154 -  SecurityAttr.nLength := SizeOf(SecurityAttr);
   1.155 -  SecurityAttr.bInheritHandle := True;
   1.156 -  SecurityAttr.lpSecurityDescriptor := nil;
   1.157 -
   1.158 -  CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
   1.159 -  CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);
   1.160 -
   1.161 -  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
   1.162 -  StartupInfo.cb:=SizeOf(StartupInfo);
   1.163 -  StartupInfo.hStdInput := 0;
   1.164 -  StartupInfo.hStdOutput := PipeOutputWrite;
   1.165 -  StartupInfo.hStdError := PipeErrorsWrite;
   1.166 -  StartupInfo.wShowWindow := SW_HIDE;
   1.167 -  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
   1.168 -
   1.169 -  if  CreateProcess(nil, PChar(command), nil, nil, true, CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then begin
   1.170 -    Result := True;
   1.171 -    CloseHandle(PipeOutputWrite);
   1.172 -    CloseHandle(PipeErrorsWrite);
   1.173 -
   1.174 -    Stream := TMemoryStream.Create;
   1.175 -    try
   1.176 -      while True do begin
   1.177 -        Succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
   1.178 -        if not Succeed then Break;
   1.179 -        Stream.Write(Buffer, NumberOfBytesRead);
   1.180 -      end;
   1.181 -    finally
   1.182 -      // nothing
   1.183 -    end;
   1.184 -    Stream.Position := 0;
   1.185 -    Output.LoadFromStream(Stream);
   1.186 -    Stream.Free;
   1.187 -    CloseHandle(PipeOutputRead);
   1.188 -
   1.189 -    Errors := '';
   1.190 -    try
   1.191 -      while True do
   1.192 -      begin
   1.193 -        Succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil);
   1.194 -        if not Succeed then Break;
   1.195 -        Errors := Errors + Copy(Buffer, 1, NumberOfBytesRead);
   1.196 -      end;
   1.197 -    finally
   1.198 -      // nothing
   1.199 -    end;
   1.200 -    CloseHandle(PipeErrorsRead);
   1.201 -
   1.202 -    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
   1.203 -    CloseHandle(ProcessInfo.hProcess);
   1.204 -  end
   1.205 -  else
   1.206 -  begin
   1.207 -    Result := False;
   1.208 -    CloseHandle(PipeOutputRead);
   1.209 -    CloseHandle(PipeOutputWrite);
   1.210 -    CloseHandle(PipeErrorsRead);
   1.211 -    CloseHandle(PipeErrorsWrite);
   1.212 -  end;
   1.213 -  // error management
   1.214 -  if (Errors <> '') then begin
   1.215 -    if (Output.Count > 1) then begin
   1.216 -      if (Trim(Output[Output.Count -2]) = '') then
   1.217 -        Output.Strings[Output.Count -2] := TrimRight(Errors)
   1.218 -      else
   1.219 -        Output.Insert(Output.Count -1, TrimRight(Errors));
   1.220 -    end
   1.221 -    else
   1.222 -      Output.Add(Errors);
   1.223 -    Output.Text := Output.Text; // pseudo-rearrangement
   1.224 -  end;
   1.225 -end;
   1.226 -
   1.227 -end.