Browse Source

pastojs: added option -vz, -ic, -io, -it, fixed -va writing used files, fixed -o. -Jc, -vt now writes used unit scopes

git-svn-id: trunk@38957 -
Mattias Gaertner 7 years ago
parent
commit
e283024ad7

+ 17 - 0
packages/pastojs/src/fppas2js.pp

@@ -344,6 +344,13 @@ Works:
 - typecast byte(longword) -> value & $ff
 - typecast byte(longword) -> value & $ff
 
 
 ToDos:
 ToDos:
+- -SI<x>     Set interface style to <x>
+         -SIcom     COM compatible interface (default)
+         -SIcorba   CORBA compatible interface
+-Sm        Support macros like C (global)
+-Sy        @<pointer> returns a typed pointer, same as $T+
+- writestr(out s: string; args); varargs;
+- widestrings + FPC_HAS_FEATURE_WIDESTRINGS + FPC_WIDESTRING_EQUAL_UNICODESTRING
 - check rtl.js version
 - check rtl.js version
 - 'new', 'Function' -> class var use .prototype
 - 'new', 'Function' -> class var use .prototype
 - btArrayLit
 - btArrayLit
@@ -360,6 +367,7 @@ ToDos:
 - interfaces
 - interfaces
   - array of interface
   - array of interface
   - record member interface
   - record member interface
+- remove cmsIgnoreInterfaces from codetools
 
 
 Not in Version 1.0:
 Not in Version 1.0:
 - make records more lightweight
 - make records more lightweight
@@ -381,6 +389,9 @@ Not in Version 1.0:
 - constref
 - constref
 - option overflow checking -Co
 - option overflow checking -Co
   +, -, *, Succ, Pred, Inc, Dec
   +, -, *, Succ, Pred, Inc, Dec
+  -Co   : Overflow checking of integer operations
+  -CO   : Check for possible overflow of integer operations
+-C3 : Turn on ieee error checking for constants
 - optimizations:
 - optimizations:
   - move rtl.js functions to system.pp
   - move rtl.js functions to system.pp
   - less brackets on logical and/or/xor, add
   - less brackets on logical and/or/xor, add
@@ -394,6 +405,8 @@ Not in Version 1.0:
   - skip clone array for new array and arraysetlength
   - skip clone array for new array and arraysetlength
   - SetLength(scope.a,l) -> read scope only once, same for
   - SetLength(scope.a,l) -> read scope only once, same for
     Include, Exclude, Inc, Dec, +=, -=, *=, /=
     Include, Exclude, Inc, Dec, +=, -=, *=, /=
+  - inline  -Si
+  - autoinline
   -O1 insert local/unit vars for global type references:
   -O1 insert local/unit vars for global type references:
       at start of intf var $r1=null;
       at start of intf var $r1=null;
       at end of impl: $r1=path;
       at end of impl: $r1=path;
@@ -401,6 +414,10 @@ Not in Version 1.0:
   -O1 no function Result var when assigned only once
   -O1 no function Result var when assigned only once
   -O1 replace constant expression with result
   -O1 replace constant expression with result
   -O1 pass array element by ref: when index is constant, use that directly
   -O1 pass array element by ref: when index is constant, use that directly
+  -O1 case-of with 6+ elements as binary tree
+  -O2 removeemptyprocs
+  -O2 CSE
+  -O3 DFA
 - objects
 - objects
 - advanced records
 - advanced records
   - TPasClassRecordType as ancestor
   - TPasClassRecordType as ancestor

+ 87 - 23
packages/pastojs/src/pas2jscompiler.pp

@@ -72,6 +72,7 @@ const
   nSrcMapSourceRootIs = 134; sSrcMapSourceRootIs = 'source map "sourceRoot" is %s';
   nSrcMapSourceRootIs = 134; sSrcMapSourceRootIs = 'source map "sourceRoot" is %s';
   nSrcMapBaseDirIs = 135; sSrcMapBaseDirIs = 'source map "local base directory" is %s';
   nSrcMapBaseDirIs = 135; sSrcMapBaseDirIs = 'source map "local base directory" is %s';
   nUnitFileNotFound = 136; sUnitFileNotFound = 'unit file not found "%s"';
   nUnitFileNotFound = 136; sUnitFileNotFound = 'unit file not found "%s"';
+  // Note: error numbers 201+ are used by Pas2jsFileCache
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 // Options
 // Options
@@ -79,6 +80,7 @@ type
   TP2jsCompilerOption = (
   TP2jsCompilerOption = (
     coSkipDefaultConfigs,
     coSkipDefaultConfigs,
     coBuildAll,
     coBuildAll,
+    // verbosity
     coShowLogo,
     coShowLogo,
     coShowErrors,
     coShowErrors,
     coShowWarnings,
     coShowWarnings,
@@ -86,25 +88,33 @@ type
     coShowHints,
     coShowHints,
     coShowInfos,
     coShowInfos,
     coShowLineNumbers,
     coShowLineNumbers,
+    coShowTriedUsedFiles,
     coShowConditionals,
     coShowConditionals,
     coShowUsedTools,
     coShowUsedTools,
     coShowMessageNumbers, // not in "show all"
     coShowMessageNumbers, // not in "show all"
     coShowDebug,    // not in "show all"
     coShowDebug,    // not in "show all"
+    // checks
     coOverflowChecks,
     coOverflowChecks,
     coRangeChecks,
     coRangeChecks,
     coObjectChecks,
     coObjectChecks,
     coAssertions,
     coAssertions,
+    // features
     coAllowCAssignments,
     coAllowCAssignments,
+    // output
     coLowerCase,
     coLowerCase,
+    coUseStrict,
+    coWriteMsgToStdErr,
+    // optimizations
     coEnumValuesAsNumbers,
     coEnumValuesAsNumbers,
     coKeepNotUsedPrivates,
     coKeepNotUsedPrivates,
     coKeepNotUsedDeclarationsWPO,
     coKeepNotUsedDeclarationsWPO,
+    // source map
     coSourceMapCreate,
     coSourceMapCreate,
     coSourceMapInclude,
     coSourceMapInclude,
-    coSourceMapXSSIHeader,
-    coUseStrict
+    coSourceMapXSSIHeader
     );
     );
   TP2jsCompilerOptions = set of TP2jsCompilerOption;
   TP2jsCompilerOptions = set of TP2jsCompilerOption;
+  TP2jsOptimization = coEnumValuesAsNumbers..coKeepNotUsedDeclarationsWPO;
 const
 const
   DefaultP2jsCompilerOptions = [coShowErrors,coSourceMapXSSIHeader,coUseStrict];
   DefaultP2jsCompilerOptions = [coShowErrors,coSourceMapXSSIHeader,coUseStrict];
   coShowAll = [coShowErrors..coShowUsedTools];
   coShowAll = [coShowErrors..coShowUsedTools];
@@ -112,7 +122,7 @@ const
   coO1Disable = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO];
   coO1Disable = [coKeepNotUsedPrivates,coKeepNotUsedDeclarationsWPO];
 
 
   p2jscoCaption: array[TP2jsCompilerOption] of string = (
   p2jscoCaption: array[TP2jsCompilerOption] of string = (
-    // only used by experts, no need for resourcestrings
+    // only used by experts or programs parsing the pas2js output, no need for resourcestrings
     'Skip default configs',
     'Skip default configs',
     'Build all',
     'Build all',
     'Show logo',
     'Show logo',
@@ -122,6 +132,7 @@ const
     'Show hints',
     'Show hints',
     'Show infos',
     'Show infos',
     'Show line numbers',
     'Show line numbers',
+    'Show tried/used files',
     'Show conditionals',
     'Show conditionals',
     'Show used tools',
     'Show used tools',
     'Show message numbers',
     'Show message numbers',
@@ -132,13 +143,14 @@ const
     'Assertions',
     'Assertions',
     'Allow C assignments',
     'Allow C assignments',
     'Lowercase identifiers',
     'Lowercase identifiers',
+    'Use strict',
+    'Write messages to StdErr',
     'Enum values as numbers',
     'Enum values as numbers',
     'Keep not used private declarations',
     'Keep not used private declarations',
     'Keep not used declarations (WPO)',
     'Keep not used declarations (WPO)',
     'Create source map',
     'Create source map',
     'Include Pascal sources in source map',
     'Include Pascal sources in source map',
-    'Prepend XSSI protection )]} to source map',
-    'Use strict'
+    'Prepend XSSI protection )]} to source map'
     );
     );
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
@@ -375,6 +387,7 @@ type
     function GetSrcMapEnable: boolean;
     function GetSrcMapEnable: boolean;
     function GetSrcMapInclude: boolean;
     function GetSrcMapInclude: boolean;
     function GetSrcMapXSSIHeader: boolean;
     function GetSrcMapXSSIHeader: boolean;
+    function GetWriteMsgToStdErr: boolean;
     function OnMacroCfgDir(Sender: TObject; var Params: string; Lvl: integer
     function OnMacroCfgDir(Sender: TObject; var Params: string; Lvl: integer
       ): boolean;
       ): boolean;
     function OnMacroEnv(Sender: TObject; var Params: string; Lvl: integer
     function OnMacroEnv(Sender: TObject; var Params: string; Lvl: integer
@@ -395,6 +408,7 @@ type
     procedure SetSrcMapXSSIHeader(const AValue: boolean);
     procedure SetSrcMapXSSIHeader(const AValue: boolean);
     procedure SetTargetPlatform(const AValue: TPasToJsPlatform);
     procedure SetTargetPlatform(const AValue: TPasToJsPlatform);
     procedure SetTargetProcessor(const AValue: TPasToJsProcessor);
     procedure SetTargetProcessor(const AValue: TPasToJsProcessor);
+    procedure SetWriteMsgToStdErr(const AValue: boolean);
   private
   private
     FPrecompileInitialFlags: TPCUInitialFlags;
     FPrecompileInitialFlags: TPCUInitialFlags;
     procedure AddDefinesForTargetPlatform;
     procedure AddDefinesForTargetPlatform;
@@ -497,6 +511,7 @@ type
     property TargetPlatform: TPasToJsPlatform read FTargetPlatform write SetTargetPlatform;
     property TargetPlatform: TPasToJsPlatform read FTargetPlatform write SetTargetPlatform;
     property TargetProcessor: TPasToJsProcessor read FTargetProcessor write SetTargetProcessor;
     property TargetProcessor: TPasToJsProcessor read FTargetProcessor write SetTargetProcessor;
     property WPOAnalyzer: TPas2JSWPOptimizer read FWPOAnalyzer; // Whole Program Optimization
     property WPOAnalyzer: TPas2JSWPOptimizer read FWPOAnalyzer; // Whole Program Optimization
+    property WriteMsgToStdErr: boolean read GetWriteMsgToStdErr write SetWriteMsgToStdErr;
     property ExitCode: longint read GetExitCode write SetExitCode;
     property ExitCode: longint read GetExitCode write SetExitCode;
   end;
   end;
 
 
@@ -1098,7 +1113,8 @@ begin
     HandleEPCUReader(EPas2JsReadError(E))
     HandleEPCUReader(EPas2JsReadError(E))
   else if E is EFileNotFoundError then
   else if E is EFileNotFoundError then
   begin
   begin
-    Log.Log(mtFatal,E.Message);
+    if (E.Message<>'') or (Log.LastMsgType<>mtFatal) then
+      Log.Log(mtFatal,E.Message);
     Compiler.Terminate(ExitCodeFileNotFound);
     Compiler.Terminate(ExitCodeFileNotFound);
   end
   end
   else if E is EPas2jsFileCache then
   else if E is EPas2jsFileCache then
@@ -2334,7 +2350,15 @@ begin
     if (aFile.JSFilename='') and (FileCache.MainJSFile='.') then
     if (aFile.JSFilename='') and (FileCache.MainJSFile='.') then
     begin
     begin
       // write to stdout
       // write to stdout
-      Log.LogRaw(aFileWriter.AsAnsistring);
+      if FreeWriter then
+      begin
+        Log.WriteMsgToStdErr:=false;
+        try
+          Log.LogRaw(aFileWriter.AsAnsistring);
+        finally
+          Log.WriteMsgToStdErr:=coWriteMsgToStdErr in Options;
+        end;
+      end;
     end else if FreeWriter then
     end else if FreeWriter then
     begin
     begin
       // write to file
       // write to file
@@ -2504,7 +2528,7 @@ end;
 
 
 function TPas2jsCompiler.GetShowTriedUsedFiles: boolean;
 function TPas2jsCompiler.GetShowTriedUsedFiles: boolean;
 begin
 begin
-  Result:=FileCache.ShowTriedUsedFiles;
+  Result:=coShowTriedUsedFiles in FOptions;
 end;
 end;
 
 
 function TPas2jsCompiler.GetShowUsedTools: boolean;
 function TPas2jsCompiler.GetShowUsedTools: boolean;
@@ -2537,6 +2561,11 @@ begin
   Result:=coSourceMapXSSIHeader in FOptions;
   Result:=coSourceMapXSSIHeader in FOptions;
 end;
 end;
 
 
+function TPas2jsCompiler.GetWriteMsgToStdErr: boolean;
+begin
+  Result:=coWriteMsgToStdErr in FOptions;
+end;
+
 procedure TPas2jsCompiler.SetCompilerExe(AValue: string);
 procedure TPas2jsCompiler.SetCompilerExe(AValue: string);
 begin
 begin
   if AValue<>'' then
   if AValue<>'' then
@@ -2561,6 +2590,7 @@ begin
   FOptions:=AValue;
   FOptions:=AValue;
   Log.ShowMsgNumbers:=coShowMessageNumbers in FOptions;
   Log.ShowMsgNumbers:=coShowMessageNumbers in FOptions;
   Log.ShowMsgTypes:=GetShownMsgTypes;
   Log.ShowMsgTypes:=GetShownMsgTypes;
+  FileCache.ShowTriedUsedFiles:=coShowTriedUsedFiles in FOptions;
 end;
 end;
 
 
 procedure TPas2jsCompiler.SetShowDebug(AValue: boolean);
 procedure TPas2jsCompiler.SetShowDebug(AValue: boolean);
@@ -2584,6 +2614,7 @@ end;
 procedure TPas2jsCompiler.SetShowTriedUsedFiles(AValue: boolean);
 procedure TPas2jsCompiler.SetShowTriedUsedFiles(AValue: boolean);
 begin
 begin
   FileCache.ShowTriedUsedFiles:=AValue;
   FileCache.ShowTriedUsedFiles:=AValue;
+  SetOption(coShowTriedUsedFiles,AValue);
 end;
 end;
 
 
 procedure TPas2jsCompiler.SetShowUsedTools(AValue: boolean);
 procedure TPas2jsCompiler.SetShowUsedTools(AValue: boolean);
@@ -2634,6 +2665,12 @@ begin
   AddDefinesForTargetProcessor;
   AddDefinesForTargetProcessor;
 end;
 end;
 
 
+procedure TPas2jsCompiler.SetWriteMsgToStdErr(const AValue: boolean);
+begin
+  SetOption(coWriteMsgToStdErr,AValue);
+  Log.WriteMsgToStdErr:=AValue;
+end;
+
 procedure TPas2jsCompiler.AddDefinesForTargetPlatform;
 procedure TPas2jsCompiler.AddDefinesForTargetPlatform;
 begin
 begin
   AddDefine(PasToJsPlatformNames[TargetPlatform]);
   AddDefine(PasToJsPlatformNames[TargetPlatform]);
@@ -2923,9 +2960,9 @@ var
   EnabledFlags, DisabledFlags, Identifier, Value, aFilename, ErrorMsg: string;
   EnabledFlags, DisabledFlags, Identifier, Value, aFilename, ErrorMsg: string;
   i: Integer;
   i: Integer;
   c: Char;
   c: Char;
-  aProc: TPasToJsProcessor;
+  aProc, pr: TPasToJsProcessor;
   Enable, Found: Boolean;
   Enable, Found: Boolean;
-  aPlatform: TPasToJsPlatform;
+  aPlatform, pl: TPasToJsPlatform;
   PF: TPas2JSPrecompileFormat;
   PF: TPas2JSPrecompileFormat;
 begin
 begin
   //writeln('TPas2jsCompiler.ReadParam ',Param,' ',Quick,' ',FromCmdLine);
   //writeln('TPas2jsCompiler.ReadParam ',Param,' ',Quick,' ',FromCmdLine);
@@ -2998,12 +3035,28 @@ begin
                 ParamFatal('unknown info option S"'+p^+'" in "'+Param+'".');
                 ParamFatal('unknown info option S"'+p^+'" in "'+Param+'".');
               end;
               end;
               end;
               end;
+            'c':
+              // write list of supported JS processors
+              for pr in TPasToJsProcessor do
+                Log.LogPlain(PasToJsProcessorNames[pr]);
+            'o':
+              begin
+              // write list of optimizations
+              Log.LogPlain('EnumNumbers');
+              Log.LogPlain('RemoveNotUsedPrivates');
+              Log.LogPlain('RemoveNotUsedDeclarations');
+              end;
+            't':
+              // write list of supported targets
+              for pl in TPasToJsPlatform do
+                Log.LogPlain(PasToJsPlatformNames[pl]);
             else
             else
               ParamFatal('unknown info option "'+p^+'" in "'+Param+'".');
               ParamFatal('unknown info option "'+p^+'" in "'+Param+'".');
             end;
             end;
             inc(p);
             inc(p);
           until false;
           until false;
-          Log.LogPlain(Value);
+          if Value<>'' then
+            Log.LogPlain(Value);
           Terminate(0);
           Terminate(0);
         end;
         end;
       'B','l','n':
       'B','l','n':
@@ -3332,10 +3385,8 @@ begin
       if not FromCmdLine then
       if not FromCmdLine then
         CfgSyntaxError('invalid parameter');
         CfgSyntaxError('invalid parameter');
       if FileCache.MainSrcFile<>'' then
       if FileCache.MainSrcFile<>'' then
-        ParamFatal('Two Pascal files. Only one Pascal file is supported.');
+        ParamFatal('Only one Pascal file is supported, but got "'+FileCache.MainSrcFile+'" and "'+Param+'".');
       aFilename:=ExpandFileNameUTF8(Param,FileCache.BaseDirectory);
       aFilename:=ExpandFileNameUTF8(Param,FileCache.BaseDirectory);
-      if not DirectoryCache.FileExists(aFilename) then
-        ParamFatal('Pascal file not found: "'+Param+'"');
       FileCache.MainSrcFile:=aFilename;
       FileCache.MainSrcFile:=aFilename;
     end;
     end;
   end;
   end;
@@ -3468,6 +3519,7 @@ begin
     'd': ShowDebug:=true;
     'd': ShowDebug:=true;
     'q': Options:=Options+[coShowMessageNumbers];
     'q': Options:=Options+[coShowMessageNumbers];
     'x': Options:=Options+[coShowUsedTools];
     'x': Options:=Options+[coShowUsedTools];
+    'z': WriteMsgToStdErr:=true;
     end;
     end;
   end;
   end;
   for i:=1 to length(Disabled) do begin
   for i:=1 to length(Disabled) do begin
@@ -3486,6 +3538,7 @@ begin
     'd': ShowDebug:=false;
     'd': ShowDebug:=false;
     'q': Options:=Options-[coShowMessageNumbers];
     'q': Options:=Options-[coShowMessageNumbers];
     'x': Options:=Options-[coShowUsedTools];
     'x': Options:=Options-[coShowUsedTools];
+    'z': WriteMsgToStdErr:=false;
     end;
     end;
   end;
   end;
 end;
 end;
@@ -3704,6 +3757,7 @@ begin
   AddDefinesForTargetProcessor;
   AddDefinesForTargetProcessor;
   // add FPC compatibility flags
   // add FPC compatibility flags
   AddDefine('FPC_HAS_FEATURE_CLASSES');
   AddDefine('FPC_HAS_FEATURE_CLASSES');
+  AddDefine('FPC_HAS_FEATURE_INIT');
   AddDefine('FPC_HAS_FEATURE_DYNARRAYS');
   AddDefine('FPC_HAS_FEATURE_DYNARRAYS');
   AddDefine('FPC_HAS_FEATURE_EXCEPTIONS');
   AddDefine('FPC_HAS_FEATURE_EXCEPTIONS');
   AddDefine('FPC_HAS_FEATURE_EXITCODE');
   AddDefine('FPC_HAS_FEATURE_EXITCODE');
@@ -3769,6 +3823,8 @@ begin
 
 
   if FileCache.MainSrcFile='' then
   if FileCache.MainSrcFile='' then
     ParamFatal('No source file name in command line');
     ParamFatal('No source file name in command line');
+  if not DirectoryCache.FileExists(FileCache.MainSrcFile) then
+    ParamFatal('Pascal file not found: "'+FileCache.MainSrcFile+'"');
 
 
   // compile
   // compile
   try
   try
@@ -3857,19 +3913,24 @@ begin
   l('  -B      : Rebuild all');
   l('  -B      : Rebuild all');
   l('  -d<x>   : Defines the symbol <x>. Optional: -d<x>:=<value>');
   l('  -d<x>   : Defines the symbol <x>. Optional: -d<x>:=<value>');
   l('  -i<x>   : Write information and halt. <x> is a combination of the following:');
   l('  -i<x>   : Write information and halt. <x> is a combination of the following:');
-  l('    D     : Write compiler date');
-  l('    SO    : Write compiler OS');
-  l('    SP    : Write compiler host processor');
-  l('    TO    : Write target platform');
-  l('    TP    : Write target processor');
-  l('    V     : Write short compiler version');
-  l('    W     : Write full compiler version');
+  l('    -iD   : Write compiler date');
+  l('    -iSO  : Write compiler OS');
+  l('    -iSP  : Write compiler host processor');
+  l('    -iTO  : Write target platform');
+  l('    -iTP  : Write target processor');
+  l('    -iV   : Write short compiler version');
+  l('    -iW   : Write full compiler version');
+  l('    -ic   : Write list of supported JS processors usable by -P<x>');
+  l('    -io   : Write list of supported optimizations usable by -Oo<x>');
+  l('    -it   : Write list of supported targets usable by -T<x>');
   l('  -C<x>   : Code generation options. <x> is a combination of the following letters:');
   l('  -C<x>   : Code generation options. <x> is a combination of the following letters:');
-  l('    o     : Overflow checking');
+  // -C3        Turn on ieee error checking for constants
+  l('    o     : Overflow checking of integer operations');
+  // -CO        Check for possible overflow of integer operations
   l('    r     : Range checking');
   l('    r     : Range checking');
   l('    R     : Object checks. Verify method calls and object type casts.');
   l('    R     : Object checks. Verify method calls and object type casts.');
   l('  -F...   Set file names and paths:');
   l('  -F...   Set file names and paths:');
-  l('   -Fe<x> : Redirect output to <x>. UTF-8 encoded.');
+  l('   -Fe<x> : Redirect output to file <x>. UTF-8 encoded.');
   l('   -Fi<x> : Add <x> to include paths');
   l('   -Fi<x> : Add <x> to include paths');
   l('   -FN<x> : add <x> to namespaces. Namespaces with trailing - are removed.');
   l('   -FN<x> : add <x> to namespaces. Namespaces with trailing - are removed.');
   l('            Delphi calls this flag "unit scope names".');
   l('            Delphi calls this flag "unit scope names".');
@@ -3944,6 +4005,7 @@ begin
   l('    d     : show debug notes and info, enables -vni');
   l('    d     : show debug notes and info, enables -vni');
   l('    q     : show message numbers');
   l('    q     : show message numbers');
   l('    x     : show used tools');
   l('    x     : show used tools');
+  l('    z     : write messages to stderr, -o. still uses stdout.');
   l('  -vm<x>,<y>: Do not show messages numbered <x> and <y>.');
   l('  -vm<x>,<y>: Do not show messages numbered <x> and <y>.');
   l('  -?      : Show this help');
   l('  -?      : Show this help');
   l('  -h      : Show this help');
   l('  -h      : Show this help');
@@ -4029,6 +4091,8 @@ begin
     WriteFolder('foreign unit path',FileCache.ForeignUnitPaths[i]);
     WriteFolder('foreign unit path',FileCache.ForeignUnitPaths[i]);
   for i:=0 to FileCache.UnitPaths.Count-1 do
   for i:=0 to FileCache.UnitPaths.Count-1 do
     WriteFolder('unit path',FileCache.UnitPaths[i]);
     WriteFolder('unit path',FileCache.UnitPaths[i]);
+  for i:=0 to FileCache.Namespaces.Count-1 do
+    Log.LogMsgIgnoreFilter(nUsingPath,['unit scope',FileCache.Namespaces[i]]);
   for i:=0 to FileCache.IncludePaths.Count-1 do
   for i:=0 to FileCache.IncludePaths.Count-1 do
     WriteFolder('include path',FileCache.IncludePaths[i]);
     WriteFolder('include path',FileCache.IncludePaths[i]);
   WriteFolder('unit output path',FileCache.UnitOutputPath);
   WriteFolder('unit output path',FileCache.UnitOutputPath);

+ 8 - 1
packages/pastojs/src/pas2jsfilecache.pp

@@ -35,6 +35,7 @@ const // Messages
   nSearchingFileFound = 203; sSearchingFileFound = 'Searching file: %s... found';
   nSearchingFileFound = 203; sSearchingFileFound = 'Searching file: %s... found';
   nSearchingFileNotFound = 204; sSearchingFileNotFound = 'Searching file: %s... not found';
   nSearchingFileNotFound = 204; sSearchingFileNotFound = 'Searching file: %s... not found';
   nDuplicateFileFound = 205; sDuplicateFileFound = 'Duplicate file found: "%s" and "%s"';
   nDuplicateFileFound = 205; sDuplicateFileFound = 'Duplicate file found: "%s" and "%s"';
+  nCustomJSFileNotFound = 206; sCustomJSFileNotFound = 'custom JS file not found: "%s"';
 
 
 type
 type
   EPas2jsFileCache = class(Exception);
   EPas2jsFileCache = class(Exception);
@@ -271,6 +272,7 @@ type
     FMainJSFile: string;
     FMainJSFile: string;
     FMainJSFileResolved: string; // only valid if cfsMainJSFileResolved in FStates
     FMainJSFileResolved: string; // only valid if cfsMainJSFileResolved in FStates
     FMainSrcFile: string;
     FMainSrcFile: string;
+    FMainSrcFileShort: string;
     FNamespaces: TStringList;
     FNamespaces: TStringList;
     FNamespacesFromCmdLine: integer;
     FNamespacesFromCmdLine: integer;
     FOnReadFile: TPas2jsReadFileEvent;
     FOnReadFile: TPas2jsReadFileEvent;
@@ -338,6 +340,7 @@ type
     property InsertFilenames: TStringList read FInsertFilenames;
     property InsertFilenames: TStringList read FInsertFilenames;
     property Log: TPas2jsLogger read FLog;
     property Log: TPas2jsLogger read FLog;
     property MainJSFile: string read FMainJSFile write SetMainJSFile;
     property MainJSFile: string read FMainJSFile write SetMainJSFile;
+    property MainSrcFileShort: string read FMainSrcFileShort write FMainSrcFileShort;
     property MainSrcFile: string read FMainSrcFile write FMainSrcFile;
     property MainSrcFile: string read FMainSrcFile write FMainSrcFile;
     property Namespaces: TStringList read FNamespaces;
     property Namespaces: TStringList read FNamespaces;
     property NamespacesFromCmdLine: integer read FNamespacesFromCmdLine;
     property NamespacesFromCmdLine: integer read FNamespacesFromCmdLine;
@@ -1505,6 +1508,7 @@ begin
   Log.RegisterMsg(mtInfo,nSearchingFileFound,sSearchingFileFound);
   Log.RegisterMsg(mtInfo,nSearchingFileFound,sSearchingFileFound);
   Log.RegisterMsg(mtInfo,nSearchingFileNotFound,sSearchingFileNotFound);
   Log.RegisterMsg(mtInfo,nSearchingFileNotFound,sSearchingFileNotFound);
   Log.RegisterMsg(mtFatal,nDuplicateFileFound,sDuplicateFileFound);
   Log.RegisterMsg(mtFatal,nDuplicateFileFound,sDuplicateFileFound);
+  Log.RegisterMsg(mtFatal,nCustomJSFileNotFound,sCustomJSFileNotFound);
 end;
 end;
 
 
 function TPas2jsFilesCache.GetAllJSIntoMainJS: Boolean;
 function TPas2jsFilesCache.GetAllJSIntoMainJS: Boolean;
@@ -1977,7 +1981,10 @@ begin
     for i:=0 to InsertFilenames.Count-1 do begin
     for i:=0 to InsertFilenames.Count-1 do begin
       Filename:=FileResolver.FindCustomJSFileName(ResolveDots(InsertFilenames[i]));
       Filename:=FileResolver.FindCustomJSFileName(ResolveDots(InsertFilenames[i]));
       if Filename='' then
       if Filename='' then
-        raise EFileNotFoundError.Create('invalid custom JS file name "'+InsertFilenames[i]+'"');
+      begin
+        Log.LogMsg(nCustomJSFileNotFound,[InsertFilenames[i]]);
+        raise EFileNotFoundError.Create('');
+      end;
       aFile:=LoadFile(Filename);
       aFile:=LoadFile(Filename);
       if aFile.Source='' then continue;
       if aFile.Source='' then continue;
       aWriter.WriteFile(aFile.Source,Filename);
       aWriter.WriteFile(aFile.Source,Filename);

+ 6 - 1
packages/pastojs/src/pas2jslogger.pp

@@ -76,6 +76,7 @@ type
     FShowMsgNumbers: boolean;
     FShowMsgNumbers: boolean;
     FShowMsgTypes: TMessageTypes;
     FShowMsgTypes: TMessageTypes;
     FSorted: boolean;
     FSorted: boolean;
+    FWriteMsgToStdErr: boolean;
     function GetMsgCount: integer;
     function GetMsgCount: integer;
     function GetMsgNumberDisabled(MsgNumber: integer): boolean;
     function GetMsgNumberDisabled(MsgNumber: integer): boolean;
     function GetMsgs(Index: integer): TPas2jsMessage; inline;
     function GetMsgs(Index: integer): TPas2jsMessage; inline;
@@ -124,6 +125,7 @@ type
     property OutputFilename: string read FOutputFilename write SetOutputFilename;
     property OutputFilename: string read FOutputFilename write SetOutputFilename;
     property ShowMsgNumbers: boolean read FShowMsgNumbers write FShowMsgNumbers;
     property ShowMsgNumbers: boolean read FShowMsgNumbers write FShowMsgNumbers;
     property ShowMsgTypes: TMessageTypes read FShowMsgTypes write FShowMsgTypes;
     property ShowMsgTypes: TMessageTypes read FShowMsgTypes write FShowMsgTypes;
+    property WriteMsgToStdErr: boolean read FWriteMsgToStdErr write FWriteMsgToStdErr;
     property Sorted: boolean read FSorted write SetSorted;
     property Sorted: boolean read FSorted write SetSorted;
     property OnLog: TPas2jsLogEvent read FOnLog write FOnLog;
     property OnLog: TPas2jsLogEvent read FOnLog write FOnLog;
     property LastMsgType: TMessageType read FLastMsgType write FLastMsgType;
     property LastMsgType: TMessageType read FLastMsgType write FLastMsgType;
@@ -541,7 +543,10 @@ begin
     // prevent codepage conversion magic
     // prevent codepage conversion magic
     SetCodePage(RawByteString(S), CP_OEMCP, False);
     SetCodePage(RawByteString(S), CP_OEMCP, False);
     {AllowWriteln}
     {AllowWriteln}
-    writeln(S);
+    if WriteMsgToStdErr then
+      writeln(StdErr,S)
+    else
+      writeln(S);
     {AllowWriteln-}
     {AllowWriteln-}
     end;
     end;
 end;
 end;

+ 14 - 9
utils/pas2js/docs/translation.html

@@ -122,20 +122,23 @@ Put + after a boolean switch option to enable it, - to disable it
   @&lt;x&gt;    : Read compiler options from file &lt;x&gt; in addition to the default pas2js.cfg
   @&lt;x&gt;    : Read compiler options from file &lt;x&gt; in addition to the default pas2js.cfg
   -B      : Rebuild all
   -B      : Rebuild all
   -d&lt;x&gt;   : Defines the symbol &lt;x&gt;. Optional: -d&lt;x&gt;:=&lt;value&gt;
   -d&lt;x&gt;   : Defines the symbol &lt;x&gt;. Optional: -d&lt;x&gt;:=&lt;value&gt;
-  -i&lt;x&gt;   : Write information and halt. &lt;x&gt; is a combination of the following letters:
-    D     : Write compiler date
-    SO    : Write compiler OS
-    SP    : Write compiler host processor
-    TO    : Write target platform
-    TP    : Write target processor
-    V     : Write short compiler version
-    W     : Write full compiler version
+  -i&lt;x&gt;   : Write information and halt. &lt;x&gt; is a combination of the following:
+    -iD   : Write compiler date
+    -iSO  : Write compiler OS
+    -iSP  : Write compiler host processor
+    -iTO  : Write target platform
+    -iTP  : Write target processor
+    -iV   : Write short compiler version
+    -iW   : Write full compiler version
+    -ic   : Write list of supported JS processors usable by -P&lt;x&gt;
+    -io   : Write list of supported optimizations usable by -Oo&lt;x&gt;
+    -it   : Write list of supported targets usable by -T&lt;x&gt;
   -C&lt;x&gt;   : Code generation options. &lt;x&gt; is a combination of the following letters:
   -C&lt;x&gt;   : Code generation options. &lt;x&gt; is a combination of the following letters:
     o     : Overflow checking
     o     : Overflow checking
     r     : Range checking
     r     : Range checking
     R     : Object checks. Verify method calls and object type casts.
     R     : Object checks. Verify method calls and object type casts.
   -F...   Set file names and paths:
   -F...   Set file names and paths:
-   -Fe&lt;x&gt; : Redirect output to &lt;x&gt;
+   -Fe&lt;x&gt; : Redirect output to file &lt;x&gt;. UTF-8 encoded.
    -Fi&lt;x&gt; : Add &lt;x&gt; to include paths
    -Fi&lt;x&gt; : Add &lt;x&gt; to include paths
    -FN&lt;x&gt; : add &lt;x&gt; to namespaces. Namespaces with trailing - are removed.
    -FN&lt;x&gt; : add &lt;x&gt; to namespaces. Namespaces with trailing - are removed.
                   Delphi calls this flag "unit scope names".
                   Delphi calls this flag "unit scope names".
@@ -148,6 +151,7 @@ Put + after a boolean switch option to enable it, - to disable it
      -Jeconsole : Console codepage. Default.
      -Jeconsole : Console codepage. Default.
      -Jesystem  : System codepage. On non Windows console and system are the same.
      -Jesystem  : System codepage. On non Windows console and system are the same.
      -Jeutf-8   : Unicode UTF-8. Default when using -Fe.
      -Jeutf-8   : Unicode UTF-8. Default when using -Fe.
+     -JeJSON    : Output compiler messages as JSON. Logo etc are outputted as-is.
    -Ji&lt;x&gt; : Insert JS file &lt;x&gt; into main JS file. E.g. -Jirtl.js. Can be given multiple times.
    -Ji&lt;x&gt; : Insert JS file &lt;x&gt; into main JS file. E.g. -Jirtl.js. Can be given multiple times.
    -Jl    : lower case identifiers
    -Jl    : lower case identifiers
    -Jm    : generate source maps
    -Jm    : generate source maps
@@ -201,6 +205,7 @@ Put + after a boolean switch option to enable it, - to disable it
     d     : show debug notes and info, enables -vni
     d     : show debug notes and info, enables -vni
     q     : show message numbers
     q     : show message numbers
     x     : show used tools
     x     : show used tools
+    z     : write messages to stderr, -o. still uses stdout.
   -vm&lt;x&gt;,&lt;y&gt;: Do not show messages numbered &lt;x&gt; and &lt;y&gt;.
   -vm&lt;x&gt;,&lt;y&gt;: Do not show messages numbered &lt;x&gt; and &lt;y&gt;.
   -?      : Show this help
   -?      : Show this help
   -h      : Show this help
   -h      : Show this help