mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 12:23:24 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			244 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			244 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{$Mode objfpc}
 | 
						|
{$H+}
 | 
						|
program fpcsubst;
 | 
						|
 | 
						|
uses SysUtils,Classes,Usubst;
 | 
						|
 | 
						|
Const
 | 
						|
  BuildVersion={$I %FPCVERSION%};
 | 
						|
  BuildTarget={$I %FPCTARGET%};
 | 
						|
 | 
						|
Resourcestring
 | 
						|
  SUsage00 = 'Usage: %s [options]';
 | 
						|
  SUsage10 = 'Where options is one or more of';
 | 
						|
  SUSage20 = '  -i filename   Set input file. Default is standard input';
 | 
						|
  SUSage30 = '  -o filename   Set output file. Default is standard output.';
 | 
						|
  SUsage40 = '  -d name=value define name=value pair.';
 | 
						|
  SUsage50 = '  -h            show this help and exit.';
 | 
						|
  SUsage60 = '  -u name       remove name from list of name/value pairs.';
 | 
						|
  SUsage70 = '  -l filename   read name/value pairs from filename';
 | 
						|
  SUsage80 = '  -b            show builtin list and exit.';
 | 
						|
  SUsage90 = '  -v            be verbose.';
 | 
						|
  SErrUnknownOption = 'Error: Unknown option.';
 | 
						|
  SErrArgExpected = 'Error: Option "%s" requires an argument.';
 | 
						|
  SErrNoSuchFile = 'Error: File "%s" does not exist.';
 | 
						|
  SErrBackupFailed = 'Error: Backup of file "%s" to "%s" failed.';
 | 
						|
  SErrDelBackupFailed = 'Error: Delete of old backup file "%s" failed.';
 | 
						|
  SWarnIgnoringFile = 'Warning: Ignoring non-existent file: ';
 | 
						|
  SWarnIgnoringPair = 'Warning: ignoring wrong name/value pair: ';
 | 
						|
  SStats = 'Replaced %d placeholders in %d lines.';
 | 
						|
  SSubstInLine = 'Replaced %s placeholders in line %d.';
 | 
						|
  SWarningDeprecated = 'Warning: This utility is deprecated and will be removed from fpc in the future. Please use fpcmkcfg instead.';
 | 
						|
 | 
						|
 | 
						|
Var
 | 
						|
  List : TStringList;
 | 
						|
  InputFileName : String;
 | 
						|
  OutputFileName : String;
 | 
						|
  Verbose : Boolean;
 | 
						|
  SkipBackup : Boolean;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
procedure Init;
 | 
						|
 | 
						|
begin
 | 
						|
  Verbose:=False;
 | 
						|
  List:=TStringList.Create;
 | 
						|
  AddToList(List,'FPCVERSION',BuildVersion);
 | 
						|
  AddToList(List,'FPCTARGET',BuildTarget);
 | 
						|
  AddToList(List,'PWD',GetCurrentDir);
 | 
						|
  AddToList(List,'BUILDDATE',DateToStr(Date));
 | 
						|
  AddToList(List,'BUILDTIME',TimeToStr(Time));
 | 
						|
end;
 | 
						|
 | 
						|
Procedure Done;
 | 
						|
 | 
						|
begin
 | 
						|
  FreeAndNil(List);
 | 
						|
end;
 | 
						|
 | 
						|
Procedure Usage;
 | 
						|
 | 
						|
begin
 | 
						|
  Writeln(Format(SUsage00,[ExtractFileName(Paramstr(0))]));
 | 
						|
  Writeln(SUsage10);
 | 
						|
  Writeln(SUsage20);
 | 
						|
  Writeln(SUsage30);
 | 
						|
  Writeln(SUsage40);
 | 
						|
  Writeln(SUsage50);
 | 
						|
  Writeln(SUsage60);
 | 
						|
  Writeln(SUsage70);
 | 
						|
  Writeln(SUsage80);
 | 
						|
  Writeln(SUsage90);
 | 
						|
  Halt(1);
 | 
						|
end;
 | 
						|
 | 
						|
Procedure ShowBuiltIns;
 | 
						|
 | 
						|
var
 | 
						|
  I : Integer;
 | 
						|
 | 
						|
begin
 | 
						|
  for I:=0 to List.Count-1 do
 | 
						|
    Writeln(List[i]);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Procedure AddFromFile(FN : String);
 | 
						|
 | 
						|
Var
 | 
						|
  F : Text;
 | 
						|
  S : String;
 | 
						|
 | 
						|
begin
 | 
						|
  If Not FileExists(FN) then
 | 
						|
    begin
 | 
						|
    Writeln(StdErr,SWarnIgnoringFile,FN);
 | 
						|
    Exit;
 | 
						|
    end;
 | 
						|
  Assign(F,FN);
 | 
						|
  Reset(F);
 | 
						|
  Try
 | 
						|
    While not EOF(F) do
 | 
						|
      begin
 | 
						|
      ReadLn(F,S);
 | 
						|
      If (Length(S)>0) and (not (S[1] in ['#',';'])) then
 | 
						|
        If not AddPair(List,S) then
 | 
						|
         If Verbose then
 | 
						|
           Writeln(StdErr,SWarnIgnoringPair,S)
 | 
						|
      end;
 | 
						|
  finally
 | 
						|
    Close(F);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
Procedure UnknownOption(Const S : String);
 | 
						|
 | 
						|
begin
 | 
						|
  Writeln(SErrUnknownOption,S);
 | 
						|
  Usage;
 | 
						|
end;
 | 
						|
 | 
						|
Procedure ProcessCommandline;
 | 
						|
 | 
						|
Var
 | 
						|
  I : Integer;
 | 
						|
  S : String;
 | 
						|
 | 
						|
  Function GetOptArg : String;
 | 
						|
 | 
						|
  begin
 | 
						|
    If I=ParamCount then
 | 
						|
      begin
 | 
						|
      Writeln(StdErr,Format(SErrArgExpected,[S]));
 | 
						|
      Halt(1);
 | 
						|
      end;
 | 
						|
    inc(I);
 | 
						|
    Result:=ParamStr(I);
 | 
						|
  end;
 | 
						|
 | 
						|
begin
 | 
						|
  I:=1;
 | 
						|
  While( I<=ParamCount) do
 | 
						|
    begin
 | 
						|
    S:=Paramstr(i);
 | 
						|
    If (Length(S)<=1) or (S[1]<>'-') then
 | 
						|
      UnknownOption(S)
 | 
						|
    else
 | 
						|
      case S[2] of
 | 
						|
        'v' : Verbose:=True;
 | 
						|
        'h' : Usage;
 | 
						|
        'b' : begin
 | 
						|
              ShowBuiltins;
 | 
						|
              halt(0);
 | 
						|
              end;
 | 
						|
        'l' : AddFromFile(GetOptArg);
 | 
						|
        'd' : AddPair(List,GetOptArg);
 | 
						|
        'u' : AddPair(List,GetOptArg+'=');
 | 
						|
        'i' : InputFileName:=GetOptArg;
 | 
						|
        'o' : OutputFileName:=GetoptArg;
 | 
						|
        's' : SkipBackup:=True;
 | 
						|
      else
 | 
						|
        UnknownOption(S);
 | 
						|
      end;
 | 
						|
    Inc(I);
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Procedure DoFile;
 | 
						|
 | 
						|
Var
 | 
						|
  Fin,Fout : Text;
 | 
						|
  S,BFN : String;
 | 
						|
  N,LCount,RCount : Integer;
 | 
						|
 | 
						|
 | 
						|
begin
 | 
						|
  If (InputFileName<>'') and not FileExists(InputFIleName) then
 | 
						|
    begin
 | 
						|
    Writeln(StdErr,Format(SErrNoSuchFile,[InputFileName]));
 | 
						|
    Halt(1)
 | 
						|
    end;
 | 
						|
  If (OutputFileName<>'')
 | 
						|
     and FileExists(OutputFileName)
 | 
						|
     and not SkipBackup then
 | 
						|
    begin
 | 
						|
    BFN:=ChangeFileExt(OutputFileName,'.bak');
 | 
						|
    If FileExists(BFN) and not DeleteFile(BFN) then
 | 
						|
      begin
 | 
						|
      Writeln(StdErr,Format(SErrDelBackupFailed,[BFN]));
 | 
						|
      Halt(1);
 | 
						|
      end;
 | 
						|
    If not RenameFile(OutputFileName,BFN) then
 | 
						|
      begin
 | 
						|
      Writeln(StdErr,Format(SErrBackupFailed,[OutputFileName,BFN]));
 | 
						|
      Halt(1);
 | 
						|
      end;
 | 
						|
    end;
 | 
						|
  Assign(Fin,InputFileName);
 | 
						|
  Assign(Fout,OutputFileName);
 | 
						|
  Reset(Fin);
 | 
						|
  Try
 | 
						|
    Rewrite(FOut);
 | 
						|
    Try
 | 
						|
      LCount:=0;
 | 
						|
      RCount:=0;
 | 
						|
      While Not EOF(Fin) do
 | 
						|
        begin
 | 
						|
        Inc(LCount);
 | 
						|
        ReadLn(Fin,S);
 | 
						|
        N:=DoSubstitutions(List,S);
 | 
						|
        If Verbose and (N>0) then
 | 
						|
          Writeln(StdErr,Format(SSubstInLine,[N,LCount]));
 | 
						|
        Inc(RCount,N);
 | 
						|
        Writeln(Fout,S);
 | 
						|
        end;
 | 
						|
     If Verbose then
 | 
						|
       Writeln(StdErr,Format(SStats,[RCount,LCount]));
 | 
						|
    Finally
 | 
						|
      Close(Fout);
 | 
						|
    end;
 | 
						|
  Finally
 | 
						|
    Close(Fin);
 | 
						|
  end;
 | 
						|
 | 
						|
end;
 | 
						|
 | 
						|
begin
 | 
						|
  WriteLn(StdErr,SWarningDeprecated);
 | 
						|
  Init;
 | 
						|
  Try
 | 
						|
    ProcessCommandLine;
 | 
						|
    DoFile;
 | 
						|
  Finally
 | 
						|
    Done;
 | 
						|
  end;
 | 
						|
end.
 |