unixutil.pp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2013 by the Free Pascal development team
  4. DO NOT ADD ROUTINES TO THIS FILE!
  5. THE ROUTINES IN THIS FILE ARE INTERNAL AND NOT FOR END USER USAGE!
  6. Background: This unit contains leftovers from the unix restructure that
  7. shouldn't be in the interface of unit baseunix/unix, but are needed
  8. in these units. (at the time routines were still being moved
  9. from baseunix to unix, and unit baseunix couldn't depend on unix)
  10. The routines are fairly OS independent but can't move to
  11. OS independent because the lowlevel units baseunix/unix depend
  12. on them. If they need to be generally accessable, copy these
  13. functions to a general purpose, OS independent, supportable unit.
  14. See the file COPYING.FPC, included in this distribution,
  15. for details about the copyright.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  19. **********************************************************************}
  20. unit unixutil;
  21. interface
  22. uses BaseUnix;
  23. type
  24. TTZInfo = record
  25. daylight : boolean;
  26. name : array[boolean] of pchar;
  27. seconds : Longint; // difference from UTC
  28. validsince : int64; // UTC timestamp
  29. validuntil : int64; // UTC timestamp
  30. leap_correct : longint;
  31. leap_hit : longint;
  32. end;
  33. var
  34. Tzinfo : TTZInfo;
  35. ReloadTzinfo : TProcedure;
  36. Function GetTzseconds : Longint;
  37. property Tzseconds : Longint read GetTzseconds;
  38. Function StringToPPChar(S: PChar;ReserveEntries:integer):ppchar;
  39. Function StringToPPChar(Var S:RawByteString;ReserveEntries:integer):ppchar;
  40. function ArrayStringToPPchar(const S:Array of RawByteString;reserveentries:Longint):ppchar; // const ?
  41. Function LocalToEpoch(year,month,day,hour,minute,second:Word):int64; deprecated 'use DateUtils.DateTimeToUnix';
  42. Procedure EpochToLocal(epoch:int64;var year,month,day,hour,minute,second:Word); deprecated 'use DateUtils.UnixToDateTime';
  43. Procedure EpochToUniversal(epoch:int64;var year,month,day,hour,minute,second:Word); deprecated 'use DateUtils.UnixToDateTime';
  44. Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word); deprecated 'use DateUtils.DateTimetoJulianDate';
  45. Function GregorianToJulian(Year,Month,Day:Longint):LongInt; deprecated 'use DateUtils.JulianDateToDateTime';
  46. implementation
  47. Function GetTzseconds : Longint;
  48. var
  49. curtime: time_t;
  50. begin
  51. curtime:=fptime;
  52. if assigned(ReloadTzinfo) and ((curtime<Tzinfo.validsince+Tzinfo.seconds) or (curtime>Tzinfo.validuntil+Tzinfo.seconds)) then
  53. ReloadTzinfo;
  54. GetTzseconds:=Tzinfo.seconds;
  55. end;
  56. function ArrayStringToPPchar(const S:Array of RawByteString;reserveentries:Longint):ppchar; // const ?
  57. // Extra allocate reserveentries pchar's at the beginning (default param=0 after 1.0.x ?)
  58. // Note: for internal use by skilled programmers only
  59. // if "s" goes out of scope in the parent procedure, the pointer is dangling.
  60. var p : ppchar;
  61. i : LongInt;
  62. begin
  63. if High(s)<Low(s) Then Exit(NIL);
  64. Getmem(p,sizeof(pchar)*(high(s)-low(s)+ReserveEntries+2)); // one more for NIL, one more
  65. // for cmd
  66. if p=nil then
  67. begin
  68. {$ifdef xunix}
  69. fpseterrno(ESysEnomem);
  70. {$endif}
  71. exit(NIL);
  72. end;
  73. for i:=low(s) to high(s) do
  74. p[i+Reserveentries]:=pchar(s[i]);
  75. p[high(s)+1+Reserveentries]:=nil;
  76. ArrayStringToPPchar:=p;
  77. end;
  78. Function StringToPPChar(Var S:RawByteString;ReserveEntries:integer):ppchar;
  79. {
  80. Create a PPChar to structure of pchars which are the arguments specified
  81. in the string S. Especially useful for creating an ArgV for Exec-calls
  82. }
  83. begin
  84. StringToPPChar:=StringToPPChar(PChar(S),ReserveEntries);
  85. end;
  86. Function StringToPPChar(S: PChar;ReserveEntries:integer):ppchar;
  87. var
  88. i,nr : longint;
  89. Buf : ^char;
  90. p : ppchar;
  91. begin
  92. buf:=s;
  93. nr:=1;
  94. while (buf^<>#0) do // count nr of args
  95. begin
  96. while (buf^ in [' ',#9,#10]) do // Kill separators.
  97. inc(buf);
  98. inc(nr);
  99. if buf^='"' Then // quotes argument?
  100. begin
  101. inc(buf);
  102. while not (buf^ in [#0,'"']) do // then end of argument is end of string or next quote
  103. inc(buf);
  104. if buf^='"' then // skip closing quote.
  105. inc(buf);
  106. end
  107. else
  108. begin // else std
  109. while not (buf^ in [' ',#0,#9,#10]) do
  110. inc(buf);
  111. end;
  112. end;
  113. getmem(p,(ReserveEntries+nr)*sizeof(pchar));
  114. StringToPPChar:=p;
  115. if p=nil then
  116. begin
  117. {$ifdef xunix}
  118. fpseterrno(ESysEnomem);
  119. {$endif}
  120. exit;
  121. end;
  122. for i:=1 to ReserveEntries do inc(p); // skip empty slots
  123. buf:=s;
  124. while (buf^<>#0) do
  125. begin
  126. while (buf^ in [' ',#9,#10]) do // Kill separators.
  127. begin
  128. buf^:=#0;
  129. inc(buf);
  130. end;
  131. if buf^='"' Then // quotes argument?
  132. begin
  133. inc(buf);
  134. p^:=buf;
  135. inc(p);
  136. p^:=nil;
  137. while not (buf^ in [#0,'"']) do // then end of argument is end of string or next quote
  138. inc(buf);
  139. if buf^='"' then // skip closing quote.
  140. begin
  141. buf^:=#0;
  142. inc(buf);
  143. end;
  144. end
  145. else
  146. begin
  147. p^:=buf;
  148. inc(p);
  149. p^:=nil;
  150. while not (buf^ in [' ',#0,#9,#10]) do
  151. inc(buf);
  152. end;
  153. end;
  154. end;
  155. Const
  156. {Date Translation}
  157. C1970=2440588;
  158. D0 = 1461;
  159. D1 = 146097;
  160. D2 =1721119;
  161. Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word);
  162. Var
  163. YYear,XYear,Temp,TempMonth : LongInt;
  164. Begin
  165. Temp:=((JulianDN-D2) shl 2)-1;
  166. JulianDN:=Temp Div D1;
  167. XYear:=(Temp Mod D1) or 3;
  168. YYear:=(XYear Div D0);
  169. Temp:=((((XYear mod D0)+4) shr 2)*5)-3;
  170. Day:=((Temp Mod 153)+5) Div 5;
  171. TempMonth:=Temp Div 153;
  172. If TempMonth>=10 Then
  173. Begin
  174. inc(YYear);
  175. dec(TempMonth,12);
  176. End;
  177. inc(TempMonth,3);
  178. Month := TempMonth;
  179. Year:=YYear+(JulianDN*100);
  180. end;
  181. Procedure EpochToLocal(epoch:Int64;var year,month,day,hour,minute,second:Word);
  182. {
  183. Transforms Epoch time into local time (hour, minute,seconds)
  184. }
  185. Var
  186. DateNum: LongInt;
  187. Begin
  188. inc(Epoch,TZSeconds);
  189. EpochToUniversal(epoch,year,month,day,hour,minute,second);
  190. End;
  191. Procedure EpochToUniversal(epoch:Int64;var year,month,day,hour,minute,second:Word);
  192. {
  193. Transforms Epoch time into universal time (hour, minute,seconds)
  194. }
  195. Var
  196. DateNum: LongInt;
  197. Begin
  198. Datenum:=(Epoch Div 86400) + c1970;
  199. JulianToGregorian(DateNum,Year,Month,day);
  200. Epoch:=Abs(Epoch Mod 86400);
  201. Hour:=Epoch Div 3600;
  202. Epoch:=Epoch Mod 3600;
  203. Minute:=Epoch Div 60;
  204. Second:=Epoch Mod 60;
  205. End;
  206. Function LocalToEpoch(year,month,day,hour,minute,second:Word):Int64;
  207. {
  208. Transforms local time (year,month,day,hour,minutes,second) to Epoch time
  209. (seconds since 00:00, january 1 1970, corrected for local time zone)
  210. }
  211. Begin
  212. LocalToEpoch:=(Int64(GregorianToJulian(Year,Month,Day)-c1970)*86400)+
  213. (LongInt(Hour)*3600)+(Longint(Minute)*60)+Second-TZSeconds;
  214. End;
  215. Function GregorianToJulian(Year,Month,Day:Longint):LongInt;
  216. Var
  217. Century,XYear: LongInt;
  218. Begin
  219. If Month<=2 Then
  220. Begin
  221. Dec(Year);
  222. Inc(Month,12);
  223. End;
  224. Dec(Month,3);
  225. Century:=(longint(Year Div 100)*D1) shr 2;
  226. XYear:=(longint(Year Mod 100)*D0) shr 2;
  227. GregorianToJulian:=((((Month*153)+2) div 5)+Day)+D2+XYear+Century;
  228. End;
  229. end.