instantfpc.pas 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. { Compile and run a pascal program.
  2. Copyright (C) 2011 Mattias Gaertner [email protected]
  3. This source is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free
  5. Software Foundation; either version 2 of the License, or (at your option)
  6. any later version.
  7. This code is distributed in the hope that it will be useful, but WITHOUT ANY
  8. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. details.
  11. A copy of the GNU General Public License is available on the World Wide Web
  12. at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
  13. to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  14. MA 02111-1307, USA.
  15. }
  16. program instantfpc;
  17. {$mode objfpc}{$H+}
  18. uses
  19. Classes, SysUtils, InstantFPTools;
  20. const
  21. Version = '1.0';
  22. var
  23. i: Integer;
  24. p: String;
  25. Filename: String;
  26. Src: TStringList;
  27. CacheDir: String;
  28. CacheFilename: String;
  29. OutputFilename: String;
  30. ExeExt: String;
  31. E : String;
  32. begin
  33. Filename:='';
  34. { For example:
  35. /usr/bin/instantfpc -MObjFpc -Sh ./envvars.pas param1
  36. }
  37. for i:=1 to Paramcount do begin
  38. p:=ParamStr(i);
  39. //writeln('Param: ',i,' ',p);
  40. if p='' then
  41. continue
  42. else if p='-v' then begin
  43. writeln('instantfpc '+Version);
  44. Halt(1);
  45. end
  46. else if p='-h' then begin
  47. writeln('instantfpc '+Version);
  48. writeln;
  49. writeln('instantfpc -h');
  50. writeln(' This help message.');
  51. writeln;
  52. writeln('instantfpc -v');
  53. writeln(' Print version and exit.');
  54. writeln;
  55. writeln('instantfpc [compiler options] <source file> [program parameters]');
  56. writeln(' Compiles source and runs program.');
  57. writeln(' Source is compared with the cache. If cache is not valid then');
  58. writeln(' source is copied to cache with the shebang line commented and');
  59. writeln(' cached source is compiled.');
  60. writeln(' If compilation fails the fpc output is written to stdout and');
  61. writeln(' instantfpc exits with error code 1.');
  62. writeln(' If compilation was successful the program is executed.');
  63. writeln(' If the compiler options contains -B the program is always');
  64. writeln(' compiled.');
  65. writeln;
  66. writeln('instantfpc --get-cache');
  67. writeln(' Prints cache directory to stdout.');
  68. writeln;
  69. writeln('instantfpc --compiler=<path to compiler>');
  70. writeln(' Normally fpc is searched in PATH and used as compiler.');
  71. writeln;
  72. writeln('Normal usage is to add as first line ("shebang") "#!/usr/bin/instantfpc"');
  73. writeln('to a program source file. Then you can execute the source like a script.');
  74. Halt(0);
  75. end else if p='--get-cache' then begin
  76. CacheDir:=GetCacheDir;
  77. write(CacheDir);
  78. Halt(0);
  79. end else if (p[1]<>'-') then begin
  80. // the first non flag parameter is the file name of the script
  81. // followed by the parameters for the script
  82. Filename:=p;
  83. break;
  84. end;
  85. end;
  86. if Filename='' then begin
  87. writeln('missing source file');
  88. Halt(1);
  89. end;
  90. CheckSourceName(Filename);
  91. Src:=TStringList.Create;
  92. try
  93. Src.LoadFromFile(Filename);
  94. CommentShebang(Src);
  95. CacheDir:=GetCacheDir;
  96. // check cache
  97. CacheFilename:=CacheDir+ExtractFileName(Filename);
  98. E:=LowerCase(ExtractFileExt(CacheFileName));
  99. if (E<>'.pp') and (E<>'.pas') and (E<>'.lpr') then
  100. CacheFileName:=CacheFileName+'.pas';
  101. ExeExt:='';
  102. OutputFilename:=CacheDir+ChangeFileExt(ExtractFileName(Filename),ExeExt);
  103. if not IsCacheValid(Src,CacheFilename,OutputFilename) then begin
  104. // save source in cache to find out next time if something changed
  105. Src.SaveToFile(CacheFilename);
  106. Compile(CacheFilename,OutputFilename);
  107. end;
  108. // run
  109. Run(OutputFilename);
  110. finally
  111. // memory is freed by OS, but for debugging puposes you can do it manually
  112. {$IFDEF IFFreeMem}
  113. Proc.Free;
  114. Src.Free;
  115. {$ENDIF}
  116. end;
  117. end.