program DebChangelogUpdate; {$APPTYPE CONSOLE} {$R 'ExecutionLevelAsInvokerManifest.res' 'ExecutionLevelAsInvokerManifest.rc'} uses Windows, Classes, SysUtils; type EIdFailedToRetreiveTimeZoneInfo = class(Exception); const RSFailedTimeZoneInfo = 'Failed to obtain timezone'; const wdays: array[1..7] of string = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); {do not localize} monthnames: array[1..12] of string = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', {do not localize} 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); {do not localize} procedure WriteStringToStream(AStream: TStream; const AStr: string); var LLen : Integer; begin LLen := Length(AStr); if LLen>0 then begin AStream.Write(AStr[1],LLen); end; end; function GetEnglishSetting: TFormatSettings; inline; begin Result.CurrencyFormat := $00; // 0 = '$1' Result.NegCurrFormat := $00; //0 = '($1)' Result.CurrencyString := '$'; Result.CurrencyDecimals := 2; Result.ThousandSeparator := ','; Result.DecimalSeparator := '.'; Result.DateSeparator := '/'; Result.ShortDateFormat := 'M/d/yyyy'; Result.LongDateFormat := 'dddd, MMMM dd, yyyy'; Result.TimeSeparator := ':'; Result.TimeAMString := 'AM'; Result.TimePMString := 'PM'; Result.LongTimeFormat := 'h:mm:ss AMPM'; Result.ShortTimeFormat := 'h:mm AMPM'; Result.ShortMonthNames[1] := monthnames[1]; //'Jan'; Result.ShortMonthNames[2] := monthnames[2]; //'Feb'; Result.ShortMonthNames[3] := monthnames[3]; //'Mar'; Result.ShortMonthNames[4] := monthnames[4]; //'Apr'; Result.ShortMonthNames[5] := monthnames[5]; //'May'; Result.ShortMonthNames[6] := monthnames[6]; //'Jun'; Result.ShortMonthNames[7] := monthnames[7]; //'Jul'; Result.ShortMonthNames[8] := monthnames[8]; //'Aug'; Result.ShortMonthNames[9] := monthnames[9]; //'Sep'; Result.ShortMonthNames[10] := monthnames[10];// 'Oct'; Result.ShortMonthNames[11] := monthnames[11]; //'Nov'; Result.ShortMonthNames[12] := monthnames[12]; //'Dec'; Result.LongMonthNames[1] := 'January'; Result.LongMonthNames[2] := 'February'; Result.LongMonthNames[3] := 'March'; Result.LongMonthNames[4] := 'April'; Result.LongMonthNames[5] := 'May'; Result.LongMonthNames[6] := 'June'; Result.LongMonthNames[7] := 'July'; Result.LongMonthNames[8] := 'August'; Result.LongMonthNames[9] := 'September'; Result.LongMonthNames[10] := 'October'; Result.LongMonthNames[11] := 'November'; Result.LongMonthNames[12] := 'December'; Result.ShortDayNames[1] := wdays[1]; //'Sun'; Result.ShortDayNames[2] := wdays[2]; //'Mon'; Result.ShortDayNames[3] := wdays[3]; //'Tue'; Result.ShortDayNames[4] := wdays[4]; //'Wed'; Result.ShortDayNames[5] := wdays[5]; //'Thu'; Result.ShortDayNames[6] := wdays[6]; //'Fri'; Result.ShortDayNames[7] := wdays[7]; //'Sat'; Result.LongDayNames[1] := 'Sunday'; Result.LongDayNames[2] := 'Monday'; Result.LongDayNames[3] := 'Tuesday'; Result.LongDayNames[4] := 'Wednesday'; Result.LongDayNames[5] := 'Thursday'; Result.LongDayNames[6] := 'Friday'; Result.LongDayNames[7] := 'Saturday'; Result.ListSeparator := ','; end; function IndyFormat(const AFormat: string; const Args: array of const): string; begin Result := SysUtils.Format(AFormat, Args, GetEnglishSetting); end; function DateTimeToGmtOffSetStr(ADateTime: TDateTime; SubGMT: Boolean): string; var AHour, AMin, ASec, AMSec: Word; begin if (ADateTime = 0.0) and SubGMT then begin Result := 'GMT'; {do not localize} Exit; end; DecodeTime(ADateTime, AHour, AMin, ASec, AMSec); Result := IndyFormat(' %0.2d%0.2d', [AHour, AMin]); {do not localize} if ADateTime < 0.0 then begin Result[1] := '-'; {do not localize} end else begin Result[1] := '+'; {do not localize} end; end; function OffsetFromUTC: TDateTime; var iBias: Integer; tmez: TTimeZoneInformation; begin case GetTimeZoneInformation(tmez) of TIME_ZONE_ID_INVALID: begin raise EIdFailedToRetreiveTimeZoneInfo.Create(RSFailedTimeZoneInfo); end; TIME_ZONE_ID_UNKNOWN : iBias := tmez.Bias; TIME_ZONE_ID_DAYLIGHT : iBias := tmez.Bias + tmez.DaylightBias; TIME_ZONE_ID_STANDARD : iBias := tmez.Bias + tmez.StandardBias; else begin raise EIdFailedToRetreiveTimeZoneInfo.Create(RSFailedTimeZoneInfo); end; end; {We use ABS because EncodeTime will only accept positive values} Result := EncodeTime(Abs(iBias) div 60, Abs(iBias) mod 60, 0, 0); {The GetTimeZone function returns values oriented towards converting a GMT time into a local time. We wish to do the opposite by returning the difference between the local time and GMT. So I just make a positive value negative and leave a negative value as positive} if iBias > 0 then begin Result := 0 - Result; end; end; {This should never be localized} function DateTimeToInternetStr(const Value: TDateTime; const AIsGMT : Boolean = False) : String; var wDay, wMonth, wYear: Word; begin DecodeDate(Value, wYear, wMonth, wDay); Result := IndyFormat('%s, %d %s %d %s %s', {do not localize} [wdays[DayOfWeek(Value)], wDay, monthnames[wMonth], wYear, FormatDateTime('HH":"nn":"ss', Value), {do not localize} DateTimeToGmtOffSetStr(OffsetFromUTC, AIsGMT)]); end; var GFileName : String; GVer : String; GFileContents : TStrings; GPkgName : String; i : Integer; GF : TFileStream; begin try { TODO -oUser -cConsole Main : Insert code here } //parameters if ParamCount < 5 then begin WriteLn(ExtractFileName(ParamStr(0))+' dir major_ver minor_ver point_ver'); WriteLn(''); WriteLn('dir - directory changlog is located in'); WriteLn('pkg_name = name of Debian package'); WriteLn('major_ver - major version of package'); WriteLn('minor_ver - minor version of package'); WriteLn('point_ver - point version of package'); ReadLn; Exit; end else begin GFileName := ParamStr(1)+'\changelog'; end; GPkgName := ParamStr(2); GVer := IntToStr(StrToIntDef(ParamStr(3),0)); GVer := GVer + '.' + IntToStr(StrToIntDef(ParamStr(4),0)); GVer := GVer + '.0.' + IntToStr(StrToIntDef(ParamStr(5),0)); GFileContents := TStringList.Create; try GFileContents.LoadFromFile(GFileName); if Pos(GPkgName + ' ('+GVer,GFileContents.Text) = 0 then begin GFileContents.Insert(0,''); GFileContents.Insert(0,''); GFileContents.Insert(0,' -- J. Peter Mugaas ' + DateTimeToInternetStr(Now) ); GFileContents.Insert(0,''); GFileContents.Insert(0,' * '+GVer); GFileContents.Insert(0,''); GFileContents.Insert(0,GPkgName+' ('+GVer+'-1) unstable; urgency=low'); GF := TFileStream.Create(GFileName,fmCreate,fmShareExclusive); //We don't use GFileContents.SaveToFile because we want a LF line-ending //not a CRLF. After all, the Debian changelog is for Unix-like operating systems try for i := 0 to GFileContents.Count - 1 do begin WriteStringToStream(GF,TrimRight(GFileContents[i])+#10); end; finally FreeAndNil(GF); end; WriteLn('changelog updated.') end else begin WriteLn('changelog did not need update.'); end; finally FreeAndNil(GFileContents); end; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end.