pkgglobals.pp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. {$mode objfpc}
  2. {$h+}
  3. unit pkgglobals;
  4. interface
  5. uses
  6. SysUtils,
  7. Classes;
  8. Const
  9. {$ifdef unix}
  10. ExeExt = '';
  11. AllFiles='*';
  12. {$else unix}
  13. ExeExt = '.exe';
  14. AllFiles='*.*';
  15. {$endif unix}
  16. Type
  17. TVerbosity = (vError,vWarning,vInfo,vCommands,vDebug);
  18. TVerbosities = Set of TVerbosity;
  19. EPackagerError = class(Exception);
  20. // Logging
  21. Function StringToVerbosity (S : String) : TVerbosity;
  22. Function VerbosityToString (V : TVerbosity): String;
  23. Procedure Log(Level: TVerbosity;Msg : String);
  24. Procedure Log(Level: TVerbosity;Fmt : String; const Args : array of const);
  25. Procedure Error(Msg : String);
  26. Procedure Error(Fmt : String; const Args : array of const);
  27. // Utils
  28. function maybequoted(const s:string):string;
  29. Function FixPath(const S : String) : string;
  30. Procedure DeleteDir(const ADir:string);
  31. Procedure SearchFiles(SL:TStringList;const APattern:string);
  32. Function GetCompilerInfo(const ACompiler,AOptions:string):string;
  33. var
  34. Verbosity : TVerbosities;
  35. Implementation
  36. // define use_shell to use sysutils.executeprocess
  37. // as alternate to using 'process' in getcompilerinfo
  38. {$IFDEF GO32v2}
  39. {$DEFINE USE_SHELL}
  40. {$ENDIF GO32v2}
  41. {$IFDEF WATCOM}
  42. {$DEFINE USE_SHELL}
  43. {$ENDIF WATCOM}
  44. {$IFDEF OS2}
  45. {$DEFINE USE_SHELL}
  46. {$ENDIF OS2}
  47. uses
  48. typinfo,
  49. {$IFNDEF USE_SHELL}
  50. process,
  51. {$ENDIF USE_SHELL}
  52. contnrs,
  53. uriparser,
  54. pkgmessages;
  55. function StringToVerbosity(S: String): TVerbosity;
  56. Var
  57. I : integer;
  58. begin
  59. I:=GetEnumValue(TypeInfo(TVerbosity),'v'+S);
  60. If (I<>-1) then
  61. Result:=TVerbosity(I)
  62. else
  63. Raise EPackagerError.CreateFmt(SErrInvalidVerbosity,[S]);
  64. end;
  65. Function VerbosityToString (V : TVerbosity): String;
  66. begin
  67. Result:=GetEnumName(TypeInfo(TVerbosity),Integer(V));
  68. Delete(Result,1,1);// Delete 'v'
  69. end;
  70. procedure Log(Level:TVerbosity;Msg: String);
  71. var
  72. Prefix : string;
  73. begin
  74. if not(Level in Verbosity) then
  75. exit;
  76. Prefix:='';
  77. if Level=vWarning then
  78. Prefix:=SWarning;
  79. Writeln(stdErr,Prefix,Msg);
  80. end;
  81. Procedure Log(Level:TVerbosity; Fmt:String; const Args:array of const);
  82. begin
  83. Log(Level,Format(Fmt,Args));
  84. end;
  85. procedure Error(Msg: String);
  86. begin
  87. Raise EPackagerError.Create(Msg);
  88. end;
  89. procedure Error(Fmt: String; const Args: array of const);
  90. begin
  91. Raise EPackagerError.CreateFmt(Fmt,Args);
  92. end;
  93. function maybequoted(const s:string):string;
  94. const
  95. {$IFDEF MSWINDOWS}
  96. FORBIDDEN_CHARS = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
  97. '{', '}', '''', '`', '~'];
  98. {$ELSE}
  99. FORBIDDEN_CHARS = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
  100. '{', '}', '''', ':', '\', '`', '~'];
  101. {$ENDIF}
  102. var
  103. s1 : string;
  104. i : integer;
  105. quoted : boolean;
  106. begin
  107. quoted:=false;
  108. s1:='"';
  109. for i:=1 to length(s) do
  110. begin
  111. case s[i] of
  112. '"' :
  113. begin
  114. quoted:=true;
  115. s1:=s1+'\"';
  116. end;
  117. ' ',
  118. #128..#255 :
  119. begin
  120. quoted:=true;
  121. s1:=s1+s[i];
  122. end;
  123. else begin
  124. if s[i] in FORBIDDEN_CHARS then
  125. quoted:=True;
  126. s1:=s1+s[i];
  127. end;
  128. end;
  129. end;
  130. if quoted then
  131. maybequoted:=s1+'"'
  132. else
  133. maybequoted:=s;
  134. end;
  135. Function FixPath(const S : String) : string;
  136. begin
  137. If (S<>'') then
  138. Result:=IncludeTrailingPathDelimiter(S)
  139. else
  140. Result:='';
  141. end;
  142. Procedure DeleteDir(const ADir:string);
  143. var
  144. Info : TSearchRec;
  145. begin
  146. if FindFirst(ADir+PathDelim+AllFiles,faAnyFile, Info)=0 then
  147. try
  148. repeat
  149. if (Info.Attr and faDirectory)=faDirectory then
  150. begin
  151. if (Info.Name<>'.') and (Info.Name<>'..') then
  152. DeleteDir(ADir+PathDelim+Info.Name)
  153. end
  154. else
  155. DeleteFile(ADir+PathDelim+Info.Name);
  156. until FindNext(Info)<>0;
  157. finally
  158. FindClose(Info);
  159. end;
  160. end;
  161. Procedure SearchFiles(SL:TStringList;const APattern:string);
  162. var
  163. Info : TSearchRec;
  164. ADir : string;
  165. begin
  166. ADir:=ExtractFilePath(APattern);
  167. if FindFirst(APattern,faAnyFile, Info)=0 then
  168. try
  169. repeat
  170. if (Info.Attr and faDirectory)=faDirectory then
  171. begin
  172. if (Info.Name<>'.') and (Info.Name<>'..') then
  173. SearchFiles(SL,ADir+Info.Name+PathDelim+ExtractFileName(APattern))
  174. end;
  175. SL.Add(ADir+Info.Name);
  176. until FindNext(Info)<>0;
  177. finally
  178. FindClose(Info);
  179. end;
  180. end;
  181. //
  182. // if use_shell defined uses sysutils.executeprocess else uses 'process'
  183. //
  184. function GetCompilerInfo(const ACompiler,AOptions:string):string;
  185. const
  186. BufSize = 1024;
  187. var
  188. {$IFDEF USE_SHELL}
  189. TmpFileName, ProcIDStr: shortstring;
  190. TmpFile: file;
  191. CmdLine2: string;
  192. {$ELSE USE_SHELL}
  193. S: TProcess;
  194. {$ENDIF USE_SHELL}
  195. Buf: array [0..BufSize - 1] of char;
  196. Count: longint;
  197. begin
  198. {$IFDEF USE_SHELL}
  199. Str (GetProcessID, ProcIDStr);
  200. TmpFileName := GetEnvironmentVariable ('TEMP');
  201. if TmpFileName <> '' then
  202. TmpFileName := TmpFileName + DirectorySeparator + 'fppkgout.' + ProcIDStr
  203. else
  204. TmpfileName := 'fppkgout.' + ProcIDStr;
  205. CmdLine2 := '/C ' + ACompiler + ' ' + AOptions + ' > ' + TmpFileName;
  206. SysUtils.ExecuteProcess (GetEnvironmentVariable ('COMSPEC'), CmdLine2);
  207. Assign (TmpFile, TmpFileName);
  208. Reset (TmpFile, 1);
  209. BlockRead (TmpFile, Buf, BufSize, Count);
  210. Close (TmpFile);
  211. {$ELSE USE_SHELL}
  212. S:=TProcess.Create(Nil);
  213. S.Commandline:=ACompiler+' '+AOptions;
  214. S.Options:=[poUsePipes,poNoConsole];
  215. S.execute;
  216. Count:=s.output.read(buf,BufSize);
  217. S.Free;
  218. {$ENDIF USE_SHELL}
  219. SetLength(Result,Count);
  220. Move(Buf,Result[1],Count);
  221. end;
  222. end.