001/****************************************************************************
002 *
003 * For this source the LGPL Lesser General Public License,
004 * published by the Free Software Foundation is valid.
005 * It means:
006 * 1) You can use this source without any restriction for any desired purpose.
007 * 2) You can redistribute copies of this source to everybody.
008 * 3) Every user of this source, also the user of redistribute copies
009 *    with or without payment, must accept this license for further using.
010 * 4) But the LPGL ist not appropriate for a whole software product,
011 *    if this source is only a part of them. It means, the user
012 *    must publish this part of source,
013 *    but don't need to publish the whole source of the own product.
014 * 5) You can study and modify (improve) this source
015 *    for own using or for redistribution, but you have to license the
016 *    modified sources likewise under this LGPL Lesser General Public License.
017 *    You mustn't delete this Copyright/Copyleft inscription in this source file.
018 *
019 * @author JcHartmut: hartmut.schorrig@vishia.de
020 * @version 2008-04-06  (year-month-day)
021 * list of changes:
022 * 2008-04-06 JcHartmut: some correction
023 * 2008-03-15 JcHartmut: creation
024 *
025 ****************************************************************************/
026package org.vishia.java2C;
027
028import java.io.File;
029import java.text.ParseException;
030import java.util.Iterator;
031import java.util.LinkedList;
032import java.util.List;
033import java.util.Set;
034import java.util.TreeMap;
035import java.util.Map;
036
037import org.vishia.mainCmd.Report;
038import org.vishia.util.FileSystem;
039
040
041
042import java.io.BufferedWriter;
043import java.io.FileNotFoundException;
044import java.io.FileOutputStream;
045import java.io.IOException;
046import java.io.OutputStreamWriter;
047
048import org.vishia.util.StringPartFromFileLines;
049import org.vishia.util.StringPartScan;
050import org.vishia.xmlSimple.SimpleXmlOutputter;
051import org.vishia.xmlSimple.XmlNode;
052import org.vishia.zbnf.ZbnfJavaOutput;
053import org.vishia.zbnf.ZbnfParseResultItem;
054import org.vishia.zbnf.ZbnfParser;
055
056
057/**This class is the main class of translation Java2C. 
058 * It is used from the command line call-implementation class {@link Java2C}.  
059 * @author JcHartmut
060 *
061 */
062public class Java2C_Main implements RunRequiredFirstPass_ifc
063{
064
065  /**Version, history and license.
066   * <ul>
067   * <li>2014-09-05 Hartmut bugfix close() from 2014-08-16 is executed before inputs are read on parser error, shift to execution after that. 
068   * <li>2014-08-16 Hartmut bugfix missing close() for opened parsed files. The close was executed on end of running the Java command in JVM from operation system.
069   *   It is possible, but not nice to have, to late.
070   * <li>2008 Hartmut created:    
071   * </ul>
072   * <br><br>
073   * <b>Copyright/Copyleft</b>:
074   * For this source the LGPL Lesser General Public License,
075   * published by the Free Software Foundation is valid.
076   * It means:
077   * <ol>
078   * <li> You can use this source without any restriction for any desired purpose.
079   * <li> You can redistribute copies of this source to everybody.
080   * <li> Every user of this source, also the user of redistribute copies
081   *    with or without payment, must accept this license for further using.
082   * <li> But the LPGL is not appropriate for a whole software product,
083   *    if this source is only a part of them. It means, the user
084   *    must publish this part of source,
085   *    but don't need to publish the whole source of the own product.
086   * <li> You can study and modify (improve) this source
087   *    for own using or for redistribution, but you have to license the
088   *    modified sources likewise under this LGPL Lesser General Public License.
089   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
090   * </ol>
091   * If you are intent to use this sources without publishing its usage, you can get
092   * a second license subscribing a special contract with the author. 
093   * 
094   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
095   */
096  public final static String sVersion = "2014-09-05"; 
097
098  
099  /**Aggregation to the Console implementation class.*/
100  Report console;
101
102  /**One file entry to translate. Instances of this class are created while processing 
103   * {@link org.vishia.util.FileSystem#addFileToList(String, org.vishia.util.FileSystem.AddFileToList)}
104   * calling {@link }
105   * called in {@link #addInputFilemask(String sMask, String, String)}
106   * evaluating the input arguments of command line call.
107   * 
108   * @author JcHartmut
109   *
110   */
111  private static class FileIn
112  { final File file; 
113    final String sPrefix, sPostfix;
114    
115    private boolean bTranslated = false;
116    
117    FileIn(File file, String sPrefix, String sPostfix){ this.file = file; this.sPrefix = sPrefix; this.sPostfix = sPostfix; }
118    
119    public void setTranslated(){ bTranslated = true; }
120    
121    public boolean isTranslated(){ return bTranslated; }
122  }
123  
124  
125  /**Helper class to create instances of {@link Java2C_Main.FileIn} for each detect input file. 
126   * The class holds informations for pre- and postfixes for the C-filenames.
127   * This class implements the {@link org.vishia.util.FileSystem.AddFileToList}-interface.
128   * <br>
129   * using:
130   * <ul>
131   * <li>Only one private instances {@link Java2C_Main#listFileIn} is created in the outer class 
132   * {@link Java2C_Main}. 
133   * <li>The instance is used  processing all input files. That is either on any <code>-i:INPUT</code>-argument
134   * or evaluating a given <code>-if:INPFILE</code> inside {@link #readConfigFile(String)}.
135   * <li>Both routines call {@link #addInputFilemask(String sMask, String sCPrefix, String sCPostfix)}.
136   * <li>Inside that routine 
137   * {@link org.vishia.util.FileSystem#addFileToList(String, org.vishia.util.FileSystem.AddFileToList)}
138   * is called with this instance. 
139   * <li>Inside <code>addFileToList</code> the interface method 
140   * {@link org.vishia.util.FileSystem.AddFileToList#add(File)} is called. 
141   * This routine is implemented here and adds instances of {@link Java2C_Main.FileIn} per detected file.
142   * 
143   * @author JcHartmut
144   *
145   */
146  private static class ListFileIn implements FileSystem.AddFileToList
147  {
148    /**List of all files, which are inputs for Java2C-translation. */
149    private final List<FileIn> listFileIn = new LinkedList<FileIn>();
150    
151    /**Prefix and Postfix for actual parsing. It is temporary used. The Prefix and Postfix 
152     * for translated C-Files is stored in {@link FileIn#sCName} using this informations.
153     */
154    private String sPrefix = "", sPostfix = "";
155    
156    
157    /**Adds a file called in {@link org.vishia.util.FileSystem#addFileToList(String, org.vishia.util.FileSystem.AddFileToList)}.
158     * @see org.vishia.util.FileSystem.AddFileToList#add(java.io.File)
159     */
160    public void add(File file)
161    { String sJavaFileName = file.getName();
162      //String sCName = sPrefix + sJavaFileName + sPostfix;
163      listFileIn.add(new FileIn(file, sPrefix, sPostfix));
164    }
165
166    /**Sets the pre- and postfix for the next detected files. */
167    public void setPrePostfix(String sPrefix, String sPostfix)
168    { this.sPrefix = sPrefix == null ? "" : sPrefix; 
169      this.sPostfix = sPostfix == null ? "" : sPostfix;
170    }
171    
172  }
173  
174  /**The gotten arguments from the command line are hold in this extra static class. 
175   * It is created before the instance of the main class will be created. 
176   * Firstly, the arguments are separated in an easily comprehensible class.
177   * Secondly, it is possible to give the arguments with another way than calling as command line.
178   * Thirdly, the instance of Java2C_Main can be created with known arguments. 
179   * Thereby, the constructor can access the parameters and some fields can be initialized,
180   * so they can be final. 
181   */
182  public static class CmdlineArgs
183  {
184    /**Path to file given with command line argument <code>-if:INPFILE</code>.*/
185    private String sConfigFile;
186    
187    /**Path to the syntax-zbnf files, given with cmd line argument <code>-syntax:SYNTAXDIR</code>. */
188    private String sSyntaxPath;
189
190    /**Path to the *.c output files, given with cmd line argument <code>-o:OUTPUT</code>. */
191    private String sPathOutCfiles;
192
193    /**Path to the *.h output files, given with cmd line argument <code>-o:OUTPUT</code>. */
194    private String sPathOutHeader;
195
196    /**Path to the *.stc output files, given with cmd line argument <code>-o:OUTPUT</code>. */
197    private String sPathOutStcFiles;
198
199    /**If not null then any parsed java file will outputted its parse result as XML. Option -checkXML=*/
200    private File dirPathOutXmlParseResult;
201    
202    /**Sets the file given with cmd line argument <code>-if:CFGFILE</code>.
203     * The syntax of the config file is described in ZBNF with:
204     * <pre>
205           "input::={ " 
206         + "   stcPath : <stcPath?> ;" 
207         + " | srcPath : <srcPath?> ; " 
208         + " | replace : <packageReplacement> ; " 
209         + " | translate : <*\\s;?srcToTranslate> ;" 
210         + "} \\e. "
211         + "packageReplacement::=<* ;=?inputpath> =: <* ;*(?cfile_prefix> [*<* ;?cfile_suffix>] "
212         + " [ ( <* ;*)?cname_prefix>[*<* ;)?cname_suffix>])]."
213         + "stcPath::=<?>{ <\"\"?stcPath>| <*\\s:,;?stcPath> ? : | , }."  //write path with spaces or : or ; in quotion.
214         + "srcPath::=<?>{ <\"\"?srcPath>| <*\\s:,;?srcPath> ? : | ,  }."  
215     * </pre>
216     * The elements are:
217     * <table>
218     * <tr><td><code>stcPath</code></td>
219     * <td>Path where stc-files are located. A path may be absolute or relative from the current directory.
220     *   A stc-File may located in the addressed directory, and than in that sub-dir,
221     *   where the package replacement of the appropriate java file is located.
222     *   If a stc-file is searched, it may be contained in any of this paths. The first location
223     *   in the order of paths in the configFile are used, independent of the content of other concurrently existent stc-files.<br>
224     *   <br>
225     *   This entry can be written in the config file more as one time. 
226     *   Any entry can contain more as one path like represented in the syntax. 
227     * </td></tr>  
228     * <tr><td><code>srcPath</code></td>
229     * <td>Path where Java source-files are located. A path may be absolute or relative from the current directory.
230     *   A Java-File may located in the addressed directory, and than in the package sub-dir,
231     *   If a Java-file is searched, it may be contained in any of this paths.The first location
232     *   in the order of paths in the configFile are used, independent of the content of other concurrently existent java-files.<br>
233     *   <br>
234     *   This entry can be written in the config file more as one time. 
235     *   Any entry can contain more as one path like represented in the syntax. 
236     * </td></tr>  
237     * <tr><td><code>packageReplacement</code></td>
238     * <td>Rule how a package structure is mapped to a C-, Header- and stc-file-structure and the names in C. 
239     * </td></tr>  
240     * <tr><td><code>packageReplacement .inputpath</code></td>
241     * <td>java package/file-path written adequate like <code>import</code>-statement. 
242     *   Either with <code>.*</code> on end or <code>.javaFile</code> on end, than without extension <code>.java</code>.
243     *   In opposite to the <code>import</code>-statement it is possible too 
244     *   to use <code>/</code> or <code>\</code> as separator between directories of the path and the <code>/javaFile</code>.
245     * </td></tr>  
246     * <tr><td><code>packageReplacement .cfile_prefix</code></td>
247     * <td>directory and/or prefix for file names at C-side, written with <code>/</code> as separators. 
248     *   at example <code>c_dir/pre</code> if the file should stored in the output sub-dir <code>c_dir</code>
249     *   and all filenames should start with <code>pre</code>.
250     * </td></tr>  
251     * <tr><td><code>packageReplacement .cfile_suffix</code></td>
252     * <td>suffix for file names at C-side. If the option isn't use, it means no <code>*</code> is written,
253     *   than the <code>packageReplacement.cfile_prefix</code> is the whole file name. Normally the C-filename
254     *   is built with prefix, the Java-file-name and the suffix.   
255     * </td></tr>  
256     * <tr><td><code>packageReplacement .cname_prefix</code></td>
257     * <td>prefix for class identifier at C-side. If this option isn't use, the file-prefix is used as name-prefix.
258     *   
259     * </td></tr>  
260     * <tr><td><code>packageReplacement .cname_suffix</code></td>
261     * <td>suffix for names at C-side. If the option isn't use, it means no <code>*</code> is written,
262     *   than the <code>packageReplacement.cname_prefix</code> is the whole name of the class at C-side. 
263     *   Normally the class-name is built with prefix, the Java-class-name and the suffix. The class-name
264     *   is the name of the <code>struct</code> containing the data and the suffix of all C-routines 
265     *   and other identifier associated to the Java-class.
266     *   <br><br>
267     *   If the whole option <code>(prefix*suffix)</code> isn't use, the file-prefix and suffix are used instead.
268     *   That should be the standard usage, because the files and classes should built normally with the same pre-
269     *   and suffixes, see examples.
270     * </td></tr>  
271     * <tr><td><code>srcToTranslate</code></td>
272     * <td>The sources to translate have to be named in its package tree, not with the full path.
273     *   The here named sources will be translated, if the Java-files are newer against the c-, header and stc-files.
274     *   Java-files, which are not named here, won't be translated. If their type-informations are necessary,
275     *   the appropriate stc-file is red, independent of the timestamp of the Java file in comparision with the C-file.
276     *   This is, because a translated version of the Java-file may be contained in a used C-library, 
277     *   the stc-file is matching to the library more closed as to the Java-File.
278     * </td>
279     * </table>
280     * Example: It is the content of the example to test Java2C.
281     * <pre>
282      stcPath: ../../CRuntimeJavalike, "../../CRuntimeJavalike/J1c" , "../../CRuntimeJavalike/stc"; 
283      
284      srcPath: ../../srcJava,../../srcJava.zbnf,../positionControl/srcJava;
285      
286      replace: java.lang.Exception =: Fwc/fw_Exception;
287      replace: java.lang.* =: Jc/*Jc;
288      replace: java.util.* =: Jc/*Jc;
289      replace: org.vishia/bridgeC.*  =: Jc/*Jc; 
290      replace: org/vishia/byteData/* =: Jc/*Jc; 
291      replace: org/vishia/mainCmd/*  =: Jc/*Jc; 
292      replace: org.vishia.util/*     =: J1c/*Jc;
293      replace: org/vishia/java2C/test/* =: *_Test;
294      replace: org/vishia/java2C/test/ImplIfc =: Java2cTest/ImplTest (Test_IfcImpl);
295      
296      replace: org/vishia/exampleJava2C/emulationEnv/* =: PositionCtrl/test/*_PosCtrl; 
297      replace: org/vishia/exampleJava2C/java4c/* =: PositionCtrl/*_PosCtrl; 
298      
299      #import: iRequireMainController =: testenv; 
300      
301      translate: org/vishia/java2C/test/*.java;
302      translate: org/vishia/util/StringPart.java
303
304     * </pre> 
305     */
306    public void setConfigFile(String s){ sConfigFile = s; }
307    
308    public void setPathOut(String path)
309    { path = path.replace("\\", "/");
310      if(!path.endsWith("/")){ path+= "/"; }
311      sPathOutCfiles = path;
312    }
313
314
315    public void setPathOutHeader(String path)
316    { path = path.replace("\\", "/");
317      if(!path.endsWith("/")){ path+= "/"; }
318      sPathOutHeader = path;
319    }
320
321
322    public void setPathOutStcFiles(String path)
323    { path = path.replace("\\", "/");
324      if(!path.endsWith("/")){ path+= "/"; }
325      sPathOutStcFiles = path;
326    }
327
328    public void setPathOutJavaXml(String path)
329    { path = path.replace("\\", "/");
330      dirPathOutXmlParseResult = new File(path);
331    }
332
333
334    public void setSyntaxPath(String path)
335    { sSyntaxPath = path;
336    }
337
338
339    public boolean checkArguments()
340    { boolean bOk = true;
341        if(sPathOutHeader == null){ sPathOutHeader = sPathOutCfiles; }
342        if(sPathOutStcFiles == null){ sPathOutStcFiles = sPathOutCfiles; }
343      if(sPathOutCfiles == null){ bOk = false; }
344      return bOk;
345    }
346    
347        
348  }
349  
350  private final CmdlineArgs args;
351  
352  
353  /**Instance of {@link Java2C_Main.ListFileIn}. */
354  private final ListFileIn listFileIn = new ListFileIn();
355
356  
357  /**List of all source pathes given either in command line option <code>-srcpath:</code> 
358   * or in the input config file given with given with command line argument <code>-if:INPFILE</code>,
359   * see {@link #setConfigFile(String)}.
360   */
361  private final List<String> listJavaSrcpath = new LinkedList<String>();
362  
363  /**List of all java sources which are to translate  given either in command line option<code>-i</code> 
364   * or in the input config file given with given with command line argument <code>-if:INPFILE</code>,
365   * see {@link #setConfigFile(String)}.
366   * <br>
367   * It is possible to declare whole packages or singe files to translate. Packages have / as separator and on end.
368   */
369  private final List<String> listInputToTranslate = new LinkedList<String>();
370  
371  final JavaSources javaSources = new JavaSources();
372  
373  /**The parser for *.java input files. The parser is initialized with syntax 
374   * from file <code>Java2C.zbnf</code> in directory given with cmd line args 
375   * <code>-syntax:SYNTAXDIR</code> in the routine {@link #init()} 
376   * called in {@link #execute()}. */
377  final ZbnfParser parser;
378  
379  /**Writer for a file containing all enhanced references. */
380  BufferedWriter fileRef;
381
382  /**List of known types. */
383  final TreeMap<String, ClassData> xxxallClassData = new TreeMap<String, ClassData>();
384  //final AllData pkgIdents;
385
386  /**List of all files processed in the first pass to consider in the second pass. */
387  private final List<GenerateFile> allJavaFilesToRunSecondPass = new LinkedList<GenerateFile>();
388
389  /**Access to the input configuration set with cmdLine option -if:INPUTCFG. @Uml=aggregate. */ 
390  ConfigSrcPathPkg_ifc inputCfg; 
391  
392  //private String sAllReferenceFilePath;
393
394  /**Assignment between an import statement and a Headerfile. */
395  private final Map<String, String> importHeaders = new TreeMap<String, String>();
396  
397  /**Contains all types 
398   * which are searched but not found in the Java2C translation. If a type is necessary but not known,
399   * a unknown type is created. It is possible that the type isn't known in the given pool of Java files.
400   * Typically it may be a Type which may existent at the C-side because it is manually written.
401   * Another problem may be, it is an unregistered standard type.
402   * <br><br>
403   * This types are automatic created and are accessible in all scopes. The reportfile contains
404   * the list of all here registered types.  
405   */
406  public final static LocalIdents externalTypes = new LocalIdents("extern/");
407  
408  /**Instance with all {@link ClassData} and {@link LocalIdents} for the classes 
409   * appropriated in the CRuntimeJavalike C runtime environment. All this {@link ClassData}
410   * are stored in {@link #stdTypes}, which is the base of all {@link LocalIdents}, 
411   * therefore this types are accessible in all scopes.
412   * <br>
413   * The content of this class is used directly if {@link ClassData} of this standard types are need, 
414   * the access is done via the {@link Java2C_Main#singleton}.standardClassData.  
415   */
416  public CRuntimeJavalikeClassData standardClassData;
417  
418  /**A CCodeInfo instance useable as dummy for local variable. There havn't a reference. */
419  public final CCodeData localReferenceDummy = new CCodeData("", null, '%', 0);
420  
421  /**A CCodeInfo instance useable as dummy for static variable. There havn't a reference. */
422  public final CCodeData staticReferenceDummy = new CCodeData("", null, '%', 0);
423  
424  
425  //fault, because recurcively call
426  //fault: private final ReadStructure readStructure;
427  
428  /**Recursion respectively deepness of recursive call of {@link #runFirstPassFile(JavaSrcTreeFile, int)}.
429   * 
430   */
431  private int recursion;
432  
433  private final String spaces = "                                                  ";
434  
435  public boolean addInputFilemask(String sMask, String sCPrefix, String sCPostfix)
436  { boolean bOk = true;
437    listFileIn.setPrePostfix(sCPrefix, sCPostfix);
438    bOk = FileSystem.addFileToList(sMask, listFileIn); 
439    return bOk;
440  }
441
442  
443  
444  /**The instance of this class is filled with the result of parsing an input file 
445   * given with <code>-if:INPFILE</code> cmd line calling argument. 
446   * The instance is created and used
447   * inside the routine {@link Java2C_Main#readConfigFile(String sFileName)}. 
448   * That routine parses the result and calls 
449   * {@link org.vishia.zbnf.ZbnfJavaOutput#setOutputStrict(Object result, ZbnfParseResultItem, Report)}.
450   * The result is this instance.
451   * <br>
452   * All inner elements follows the syntax.zbnf, see explaination on {@link Java2C#main(String[])}
453   * 
454   */ 
455  public static final class InputFileParseResult implements ConfigSrcPathPkg_ifc
456  { 
457    /**Subclass to pour in the result of the <code>set::=...</code> subsyntax.
458     * Any instance is created if a <code>&lt;set></code> is parsed with syntax 
459     * <pre>
460     * set::=<* ;=?inputpath>[ =: [[ <* ;*?Cname_prefix>]*] <* ;?Cname_postfix>].
461     * </pre>.
462     */
463    public static final class Set implements ConfigSrcPathPkg_ifc.Set
464    { /**ZBNF-parser-result: Ingests semantic for inputpath. &lt;* ;=?inputpath>. */
465      private String inputpath; 
466      
467      /**ZBNF-parser-result: Ingests semantic for Cname_prefix. &lt;* ;*?Cname_prefix>. */
468      public String cfile_prefix;
469      
470      /**ZBNF-parser-result: Ingests semantic Cname_postfix. &lt;* ;?Cname_postfix>. */
471      public String cfile_suffix = null; 
472      
473      /**ZBNF-parser-result: Ingests semantic for Cname_prefix. &lt;* ;*?Cname_prefix>. */
474      public String cname_prefix = null;
475      
476      /**ZBNF-parser-result: Ingests semantic Cname_postfix. &lt;* ;?Cname_postfix>. */
477      public String cname_suffix = null;
478      
479      public String stcFile = null;
480      
481      public void set_inputpath(String value)
482      { { inputpath = value; }
483      }
484      
485      @Override
486      public String toString()
487      { return inputpath + " =: " + cfile_prefix + "*" + cfile_suffix
488               + (cname_prefix == null ? "" 
489                 : "(" + cname_prefix
490                   + (cname_suffix == null ? "" : "*" + cname_suffix)
491                   + ")"
492                 ); 
493      }
494    
495      /* (non-Javadoc)
496       * @see org.vishia.java2C.ConfigSrcPathPkg_ifc.Set#getFilePrefix()
497       */
498      public String getFilePrefix(){ return cfile_prefix == null ? "" : cfile_prefix; }
499      
500      /* (non-Javadoc)
501       * @see org.vishia.java2C.ConfigSrcPathPkg_ifc.Set#getFileSuffix()
502       */
503      public String getFileSuffix() { return cfile_suffix; } //may be null.
504      
505      /* (non-Javadoc)
506       * @see org.vishia.java2C.ConfigSrcPathPkg_ifc.Set#getNamePrefix()
507       */
508      public String getNamePrefix()
509      { if(cname_prefix != null) return cname_prefix;
510        else if(cfile_prefix == null) return "";
511        else{
512          int posSeparator = cfile_prefix.lastIndexOf('/');
513          if(posSeparator <0){ return cfile_prefix; }
514          else return cfile_prefix.substring(posSeparator+1);
515        }
516      }
517      
518      /* (non-Javadoc)
519       * @see org.vishia.java2C.ConfigSrcPathPkg_ifc.Set#getNameSuffix()
520       */
521      public String getNameSuffix() 
522      { return cname_prefix == null    //TRICKY: its correct, test prefix, than a expression (pre[*post]) is given. 
523        ? getFileSuffix() : cname_suffix; //cname_postfix is null if it isn't parsed, return null is correct
524      }
525    
526      @Override public String getInputPath() { return inputpath; }
527      @Override public String getStcFile() { return stcFile; }
528
529      
530    }
531
532    
533    /**Set from semantic. */
534    //public String fileAllReferences = "allReferences.h";
535    
536    /**ZBNF-parser-result: Creates an appropriate instance  for semantic set. <code>&lt;set></code> */
537    public Set new_set(){ return new Set(); }
538    /**ZBNF-parser-result: Adds the instance after it is filled with the content of a <code>&lt;set></code>. */ 
539    public void add_srcToTranslate(String value)
540    { value = value.replace('\\', '/');
541      value = value.replace('.', '/');
542      int zValue = value.length();
543      if(value.endsWith("*/java")){ //input is *.java
544        value = value.substring(0, zValue-6); //an package, ends with /
545      }
546      else if(value.endsWith("/java")){
547        value = value.substring(0, zValue-5) + ".java"; //correct the extension
548      }
549      else{ //posExt <0, no extension .java
550        if(!value.endsWith("/")){
551          value = value + "/";
552        }
553      }
554      srcToTranslate.add(value); 
555    }
556    
557    /**ZBNF-parser-result: adds an element <code>&lt;...?stcPsth></code>. */ 
558    public void add_stcPath(String value){ listStcPath.add(value); }
559    
560    /**ZBNF-parser-result: adds an element <code>&lt;...?stcPsth></code>. */ 
561    public void add_srcPath(String value){ listSrcPath.add(value); }
562    
563    /**List to hold all <code>&lt;set></code>. */
564    private final List<String> srcToTranslate = new LinkedList<String>();
565
566    /**List to hold all stcPath. <code>&lt;...?stcPath></code>. */
567    private final List<String> listStcPath = new LinkedList<String>();
568    
569    /**List to hold all stcPath. <code>&lt;...?stcPath></code>. */
570    private final List<String> listSrcPath = new LinkedList<String>();
571  
572    public List<String> getStcPathes(){ return listStcPath; }
573
574    public List<String> getSrcPathes(){ return listSrcPath; }
575  
576    /**List to hold all <code>&lt;set></code>. */
577    private final Map<String, ConfigSrcPathPkg_ifc.Set> packageReplacement = new TreeMap<String, ConfigSrcPathPkg_ifc.Set>();
578    
579    /**ZBNF-parser-result: new component <code>&lt;...?packageReplacement></code>. */ 
580    public Set new_packageReplacement(){ return new Set(); }
581    
582    
583    /**ZBNF-parser-result: adds a component<code>&lt;...?packageReplacement></code>. */ 
584    public void add_packageReplacement(Set value)
585    { final String key;
586      final String sValue1 = value.inputpath.replace('.', '/'); 
587      if(     sValue1.endsWith("/*")){ key = sValue1.substring(0, sValue1.length()-2); }
588      else if(sValue1.endsWith("/")) { key = sValue1.substring(0, sValue1.length()-1); }
589      else                           { key = sValue1; }
590      packageReplacement.put(key, value);
591  }
592    
593    
594    public ConfigSrcPathPkg_ifc.Set getCPathPrePostfixForPackage(String javaPackagePath)
595    { if(javaPackagePath.endsWith("/")){
596        javaPackagePath = javaPackagePath.substring(0, javaPackagePath.length()-1);
597      }
598      
599      return packageReplacement.get(javaPackagePath);
600    }
601    
602    public java.util.Set<Map.Entry<String, ConfigSrcPathPkg_ifc.Set>> getListPackageReplacements(){
603        return packageReplacement.entrySet();
604    }
605    
606    
607    
608    public List<String> getSrcToTranslate()
609    {
610      return srcToTranslate;
611    }
612    
613    
614    public void reportConfig(Report report, int reportLevel)
615    {
616      report.reportln(reportLevel, "===Config-File===");
617      report.reportln(reportLevel, "====Package-Replacement====");
618      for(ConfigSrcPathPkg_ifc.Set entry: packageReplacement.values()){
619        report.reportln(reportLevel, entry.toString());
620      }
621      //TODO rest
622    }
623  }
624      
625  
626  /**The singleton instance of this class. */
627  public static Java2C_Main singleton;
628  
629  /**The create routine for the singleton. */
630  public static void instanciateSingleton(CmdlineArgs args, Report report)
631  { try{ singleton = new Java2C_Main(args, report); }
632    catch (Exception exc)
633    {
634      System.out.println("Exception");
635    }
636  }
637  
638  
639  /**Private Constructor for singleton.  
640   * @throws InstantiationException 
641   * @throws IllegalAccessException 
642   * @throws IOException 
643   * @throws IllegalArgumentException 
644   * @throws FileNotFoundException 
645   * @throws ParseException */
646  private Java2C_Main(CmdlineArgs args, Report report) 
647  throws FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException, ParseException
648  { this.console = report;
649    this.args = args;
650    singleton = this;
651    //stdTypes = new LocalIdents();
652    //userTypes = new LocalIdents(stdTypes);
653  
654    parser = new ZbnfParser(console, 10);
655    parser.setReportIdents(Report.error, Report.info, Report.fineDebug, Report.fineDebug);
656
657    //readStructure = new ReadStructure(this, console, args.sSyntaxPath);
658    
659    //pkgIdents = new AllData();
660  }
661
662
663  /**Parses the given File and build the input file information for translating.
664   * This method is called in the phase of evaluating the calling parameters. 
665   * The content of the file will be parsed with ZBNF parsing with the fix syntax:
666   * <pre>
667   * input::={ translate: <set> ;}. 
668   * set::=<* ;=?inputpath>[ =: [*<* ;?Cname_prefix>|<**?Cname_postfix>*]].</pre>
669   * A example of file content:
670   * <pre>
671   * srcJava/org/vishia/exampleJava2C/java4c/*.java = *_PosCtrl; //the files for position control
672   * ..//TODO
673   * </pre>
674   * @param sFileName
675   * @return true if successful, false if any error.
676   * @throws ParseException 
677   */
678  private static ConfigSrcPathPkg_ifc readConfigFile(ListFileIn listFileIn, String sFileName, Report console) 
679  throws ParseException
680  { boolean bOk = true;
681    ConfigSrcPathPkg_ifc inputCfg = null;
682    File fInput = new File(sFileName);
683    StringPartScan spInput = null;
684    try{ spInput = new StringPartFromFileLines(fInput,10000, null, null); }
685    catch(Exception exc)
686    { console.writeError("fault input file", exc);
687      bOk = false;
688    }
689    if(bOk)
690    { ZbnfParser parserInput = new ZbnfParser(console, 10);
691      parserInput.setSkippingEndlineComment("#", false);
692      String syntaxInput = 
693         "input::={ " 
694       + "   stcPath : <stcPath?> ;" 
695       + " | srcPath : <srcPath?> ; " 
696       + " | replace : <packageReplacement> ; " 
697       + " | translate : <*\\s;?srcToTranslate> ;" 
698       + "} \\e. "
699       + "packageReplacement::=<* ;=?inputpath> =: <* ;*(,?cfile_prefix> [*<* ;(,?cfile_suffix>] "
700       + " [ ( <* ;*)?cname_prefix>[*<* ;)?cname_suffix>])][ , stc = <* ;?stcFile>]."
701       + "stcPath::=<?>{ <\"\"?stcPath>| <*\\s:,;?stcPath> ? : | , }."  //write path with spaces or : or ; in quotion.
702       + "srcPath::=<?>{ <\"\"?srcPath>| <*\\s:,;?srcPath> ? : | ,  }."  
703       ;
704      try{ parserInput.setSyntax(syntaxInput);} 
705      catch(ParseException exc){ throw new RuntimeException(exc); }
706      
707      //parse the config file:
708      bOk = parserInput.parse(spInput, null);
709      spInput.close();
710      if(bOk)
711      { InputFileParseResult parseResult = new InputFileParseResult();
712        parserInput.reportStore(console, Report.debug, sFileName);
713        try{ ZbnfJavaOutput.setOutputStrict(parseResult, parserInput.getFirstParseResult(), console);}
714        catch(Exception exc){ throw new RuntimeException(exc); }
715        //sAllReferenceFilePath = parseResult.fileAllReferences;
716        /*
717        for(InputFileParseResult.Set set: parseResult.srcToTranslate)
718        { 
719          listFileIn.setPrePostfix(set.cname_prefix, set.cname_postfix);
720          try{ bOk = FileSystem.addFileToList(set.inputpath, listFileIn); }
721          catch(FileNotFoundException exc)
722          { bOk = false;
723            console.writeError("not found: " + set.inputpath);
724          }
725        }
726        */
727        inputCfg = parseResult;
728      }
729      else throw new ParseException(parserInput.getSyntaxErrorReport(),0);
730    }
731    return inputCfg;
732  }
733  
734  
735  /**Executes the translation for all files. 
736   * @throws ParseException 
737   * @throws InstantiationException 
738   * @throws IllegalAccessException 
739   * @throws IOException 
740   * @throws IllegalArgumentException 
741   * @throws FileNotFoundException 
742   */
743  public void execute() throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
744  { boolean bOk = true;
745    initZbnfParser();
746    if(bOk && args.sConfigFile != null)
747    { inputCfg = readConfigFile(listFileIn, args.sConfigFile, console);
748      /**Adds all source pathes from inputCfg. */
749      for(String srcPath: inputCfg.getSrcPathes()){
750        listJavaSrcpath.add(srcPath); 
751      }
752      for(String srcToTranslate: inputCfg.getSrcToTranslate()){
753        listInputToTranslate.add(srcToTranslate); 
754      }
755      for(Map.Entry<String, ConfigSrcPathPkg_ifc.Set> setPkgReplacement: inputCfg.getListPackageReplacements()){
756        String sPkg = setPkgReplacement.getKey();
757        ConfigSrcPathPkg_ifc.Set info = setPkgReplacement.getValue();
758        createJavaPkgFileTreeFromCfg(info.getInputPath(), info);  //create packages for stc-files only.
759      }
760    }
761    inputCfg.reportConfig(console, Report.info);
762    //NOTE: inputCfg is necessary yet, because pkg-C-FilePath assignment.
763    standardClassData = new CRuntimeJavalikeClassData(this);
764    JavaSrcTreeGetter getterAllSourcefiles = new JavaSrcTreeGetter(javaSources, inputCfg, listInputToTranslate, console);
765    //getterAllSourcefiles.gatherAllJavaSrcFiles(standardClassData.stdTypes, listJavaSrcpath);
766    getterAllSourcefiles.gatherAllJavaSrcFiles(javaSources.javaSrcTree.getPkgLevelIdents(), listJavaSrcpath);
767    
768    if(bOk)
769    { for(JavaSrcTreeFile javaSrc: javaSources.listJavaSrcFilesToTranslate)
770      { if(javaSrc.isTranslated())
771        { console.writeInfoln("* input file, first pass already processed, was depended: " + javaSrc.getPublicClassName()); 
772        }
773        else
774        { //console.writeInfoln( file.file.getAbsolutePath() + "* processing..."); 
775          recursion = 0;
776          GenerateFile genFile = runFirstPassFile(javaSrc);
777                if(genFile != null){
778            genFile.runSecondPassFile();
779                        //allJavaFilesToRunSecondPass.add(genFile);
780                }
781        }
782      }
783      for(GenerateFile genFile : allJavaFilesToRunSecondPass)
784      { genFile.runSecondPassFile(); //userTypes); //pkgIdents);
785      }
786      //writeFileRef();
787      console.writeInfoln("...done.");
788    }
789  }
790
791
792  /**Creates the package tree for all package replacements found in the configuration file.
793   * It is assumed firstly, that a java-file isn't existing.
794   * Therefore the stc-file should be used.
795   * <br><br>
796   * If a java-file is found later in the java-source-path, it is replaced.
797   * @param sPkgPath The path given in config-file replace:-statement.
798   *        The pathes can be separated with / or dot.
799   */
800  private void createJavaPkgFileTreeFromCfg(String sPkgPath, ConfigSrcPathPkg_ifc.Set info){
801        String sIdent = sPkgPath.replace('/','.');  //NOTE: if '/' isn't contain, the method is optimized.
802    if(sPkgPath.equals("java.lang.*"))
803        stop();
804        JavaSrcTreePkg pkg = javaSources.javaSrcTree;
805        String sPkgPath1 = "";
806    int posDot;
807    while( (posDot = sIdent.indexOf('.')) >=0){
808      String sEnvIdent = sIdent.substring(0, posDot);
809      sIdent = sIdent.substring(posDot+1);
810      sPkgPath1 += sEnvIdent + "/";
811      
812      if(sIdent.charAt(0) =='*'){
813        //add the replacing info to the whole package
814        pkg = pkg.getOrAddPkg(sPkgPath1, sEnvIdent, info);
815      } else {
816        //normal: no replacing info for pre-packages.
817        //Note: The package may be existing.
818        pkg = pkg.getOrAddPkg(sPkgPath1, sEnvIdent, null);
819      }
820    }
821    //assume that the java-file doesn't exist, use stc:
822    if(sIdent.charAt(0) !='*'){
823        //add a Java-file only if it is named in the replace-string.
824            String sJavaFile = sIdent;  //Name without .java is used to select stc-file. May be '*' here.
825            String stcPath = info.getStcFile();
826            JavaSrcTreeFile javaFile = new JavaSrcTreeFile(pkg, null, null, sJavaFile, info 
827                        , stcPath, false);      
828            pkg.getPkgLevelIdents().putClassType(sIdent, javaFile);  //will be replaced if a java-source is found.
829    }
830  }
831  
832  //String getFileAllReferences(){ return sAllReferenceFilePath; }
833  
834  //String getIdentAllReferences()
835  //{  String sIdent1 = sAllReferenceFilePath.replaceAll("\\W", "_");
836  //   return sIdent1;
837  //}
838  
839  public String getPathOutCfiles(){ return args.sPathOutCfiles; }
840  
841  public String getPathOutHeader(){ return args.sPathOutHeader; }
842  
843  public String getPathOutStcFiles(){ return args.sPathOutStcFiles; }
844  
845  
846  /**Initializes before {@link #execute()}.
847   * <ul>
848   * <li>Reads the {@link #sConfigFile} if an cmd line argument <code>-if:INPFILE</code> is given.
849   * <li>Initializes the {@link #parser} with the syntax file <code>Java2C.zbnf</code>
850   *     using the path from cmd line argument <code>-syntax:PATH</code>.
851   * <li>Initializes the {@link #parserStruct} with the syntax file <code>Java2Cstc.zbnf</code>
852   *     using the path from cmd line argument <code>-syntax:PATH</code>.
853   * </ul>       
854   * @return true if successful.
855   * @throws ParseException
856   * @throws FileNotFoundException
857   * @throws IOException
858   * @throws InstantiationException 
859   * @throws IllegalAccessException 
860   * @throws IllegalArgumentException 
861   */
862  boolean initZbnfParser()
863  throws ParseException, FileNotFoundException, IOException, IllegalArgumentException, IllegalAccessException, InstantiationException
864  { boolean bOk = true;
865    if(bOk)
866    { File fileSyntaxJava = null;
867      fileSyntaxJava= new File(args.sSyntaxPath + "/Java2C.zbnf"); //"../../srcJava/org/vishia/Java2C/Java2C.zbnf");
868      String sSyntaxJava;
869      sSyntaxJava = FileSystem.readFile(fileSyntaxJava);
870      if(sSyntaxJava == null)
871      { console.writeError("syntaxfile not found, error arg -syntax:" + args.sSyntaxPath + "/Java2C.zbnf");
872        bOk = false;
873      }
874      else
875      { parser.setSyntax(sSyntaxJava);
876        //parser.reportSyntax(console);
877      }
878    }  
879    return bOk;
880  }
881
882
883
884  /**parses and translates one java file. It is called 
885   * <ul>
886   * <li> either from {@link execute()} for any given input file,
887   * <li> or from {@link runRequestedFirstPass(String sClassName)} for any depended file.
888   * </ul>
889   * The following actions are done:
890   * <ul>
891   * <li>Tests whether the destination file exists and the source isn't newer. In this case 
892   *     {@link readStructToClassData(String)} is called, and nothing else. This produces the 
893   *     {@link ClassData for using the informations of this file.}
894   * <li>If the destination file doesn't exists or the source is newer:
895   * <li>Reads the file content in a {@link org.vishia.util.StringPartFromFileLines}.
896   * <li>Parses the file with the {@link #parser}.
897   * <li>Creates an instance of {@link GenerateFile} and adds it to {@link allJavaFilesToRunSecondPass}.
898   *     This list will be processed for second path of translation.
899   * <li>Calls {@link GenerateFile#runFirstPass(ZbnfParseResultItem, LocalIdents, String)}
900   *     to build the {@link ClassData} of all contained classes.
901   * </ul>            
902   * @throws InstantiationException 
903   * @throws IllegalAccessException 
904   * @throws IllegalArgumentException 
905   * */
906  private GenerateFile runFirstPassFile(JavaSrcTreeFile javaSrc)
907  throws FileNotFoundException, IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
908  { recursion +=1;
909        GenerateFile genFile = null;
910        assert(!javaSrc.isTranslated());
911    final boolean shouldTranslate;
912    final File javaFile = javaSrc.getFileJava();
913    String sFileNameC = javaSrc.getFileNameC();
914    final String sPublicClassName = javaSrc.getPublicClassName();
915    final LocalIdents pkgIdents = javaSrc.getPkgLevelTypes();
916    if(sPublicClassName.equals("OS_TimeStamp"))
917      stop();
918    File fileStc;
919    if(javaSrc.isToTranslate()){
920      fileStc = new File(args.sPathOutStcFiles + sFileNameC + ".stc");  //stc-File at regular output path.
921      long dateJavaFile = javaFile.lastModified();
922      File fileC = new File(args.sPathOutCfiles + sFileNameC + ".c");
923      File fileH = new File(args.sPathOutHeader + sFileNameC + ".h");
924      //TODO search it in a search path.
925      if(fileC.exists() && fileH.exists() && fileStc.exists())
926      { long dateCfile = fileC.lastModified();
927        long dateHfile = fileH.lastModified();
928        long dateSfile = fileStc.lastModified();
929        shouldTranslate = dateJavaFile > dateCfile || dateJavaFile > dateHfile || dateJavaFile > dateSfile;
930      }
931      else{ shouldTranslate = true; } //because file not exists
932      if(shouldTranslate){
933        fileC.renameTo(new File(fileC.getAbsolutePath()+".bak"));
934        fileH.renameTo(new File(fileH.getAbsolutePath()+".bak"));
935        fileStc.renameTo(new File(fileStc.getAbsolutePath()+".bak"));
936        console.writeInfoln( (recursion==1 ? "* input file" : spaces.subSequence(0, 2* recursion) + "* depending type") +", first pass, parse: " + sPublicClassName + " ... ");
937        StringPartScan spInput = null;
938        //if(pkgIdents.get(sFileName) == null)
939        if(sPublicClassName.equals("PID_controller"))
940          stop();
941        int lenBuffer = (int)javaFile.length();
942        assert(lenBuffer < 1000000);  //max. 1 MByte source.java
943        spInput = new StringPartFromFileLines(javaFile,lenBuffer, null, null);
944        //parse the input.java-file
945        boolean bOk = parser.parse(spInput);
946        if(!bOk)
947        { CharSequence sError = parser.getFoundedInputOnError();
948          console.writeError(sError.toString());
949          sError = parser.getExpectedSyntaxOnError();
950          console.writeError(sError.toString());
951          sError = parser.getSyntaxErrorReport();
952          console.writeError(sError.toString());
953        }
954        else
955        { parser.reportStore(console, Report.debug, javaFile.getPath());
956          console.writeInfo(" OK parsing ...");
957          ZbnfParseResultItem resultItem = parser.getFirstParseResult();
958          if(args.dirPathOutXmlParseResult !=null){
959            XmlNode xmlParseResult = parser.getResultTree();
960            SimpleXmlOutputter xmlOutputter = new SimpleXmlOutputter();
961            File fileXml = new File(args.dirPathOutXmlParseResult, javaSrc.getPublicClassName() + ".java.xml");
962            OutputStreamWriter xmlWriter = new OutputStreamWriter(new FileOutputStream(fileXml));
963            xmlOutputter.write(xmlWriter, xmlParseResult);
964            xmlWriter.close();
965          }
966          if(resultItem.getSemantic().equals("JavaSrc"))
967          { //the new instance is returned and stored then in {@link allJavaFilesToRunSecondPass}.
968                genFile = new GenerateFile(javaSources, javaSrc, this, fileStc, console);
969            //parsing and first pass:
970            console.writeInfo("OK.");
971            //LocalIdents pkgTypes = javaSrc.getPkgLevelTypes();
972            genFile.runFirstPassFile(
973                        resultItem, javaSrc.getClassCNamePrefix(), javaSrc.getClassCNameSuffix());
974          
975          }
976        }
977        spInput.close();
978      }
979      else
980      { //not to translate
981        console.writeInfoln( (recursion==1 ? "* input file" : spaces.subSequence(0, 2* recursion) + "* depending type") +", is actual, read stc, parse: " + sPublicClassName + " ... ");
982        //Note: This routine may be called recursively, use an own instance of ReadStructure!
983        ReadStructure readStructure = new ReadStructure(this, console, args.sSyntaxPath);
984        readStructure.readStructToClassData(javaSrc, sPublicClassName, fileStc); //ClassData will be created and assigned to pkgIdents  
985        console.writeInfo("OK.");
986      }
987    }
988    else{
989      /**The java file is not an input. The stc-File should be used to input the structure informations for ClassData.
990       * But the stc-file may be at another position in structure path as the regular output. Search it!
991       */
992      console.writeInfoln( (recursion==1 ? "* input file:" : spaces.subSequence(0, 2* recursion) + "* depending type:") + sPublicClassName + ", not to translate, ");
993      String sStcPath = javaSrc.getStcPath();
994      if(sStcPath.equals("J1c/AssertJc.stc"))
995        stop();
996      fileStc = searchFileStc(sStcPath);
997      if(fileStc == null)
998        throw new IllegalArgumentException("stc-File not found:" + sStcPath + " for: " 
999            + javaSrc.getFileJava()+ ", fileC: " + javaSrc.getFileNameC());
1000      //Note: This routine may be called recursively, use an own instance of ReadStructure!
1001      ReadStructure readStructure = new ReadStructure(this, console, args.sSyntaxPath);
1002      readStructure.readStructToClassData(javaSrc, sPublicClassName, fileStc); //ClassData will be created and assigned to pkgIdents  
1003      console.writeInfo("OK.");
1004    }
1005    recursion -=1;
1006    return genFile;  //may be null
1007  }
1008
1009
1010  
1011  
1012  /**Creates a external type because no informations are available.
1013   * @param name
1014   * @param pkg
1015   * @return the created type. It is put also in the global userTypes:
1016   */
1017  public final static ClassData createExternalType(String name, String pkg)
1018  {
1019    ClassData classData = new ClassData("external-auto-created", null, null, pkg, name, name, name, 'L', null, null, null, null, '*', "", 'x');
1020    //Java2C_Main.singleton.userTypes.putClassType(classData);
1021    Java2C_Main.singleton.standardClassData.stdTypes.putClassType(classData);
1022    return classData;
1023  }
1024  
1025  
1026  /**Creates or searches a package which is a root package.
1027   * Inside the returned package, the method {@link JavaSrcTreePkg#getOrAddPkg(String, String)}
1028   * can be invoked to get or add a sub package or the method
1029   * {@link JavaSrcTreePkg#setFileJava(String, File, String, String, String, String, String, String, boolean)
1030   * can be invoked.
1031   * @param sName The name of the root package
1032   * @return The root package management instance.
1033   */
1034  public final static JavaSrcTreePkg getOrAddRootPkg(String sName){
1035        return Java2C_Main.singleton.javaSources.javaSrcTree.getOrAddPkg(sName +"/", sName, null);
1036  }
1037  
1038  /**Searches a package which is a root package.
1039   * @param sName The name of the root package
1040   * @return The root package management instance.
1041   */
1042  public final static JavaSrcTreePkg getRootPkg(String sName){
1043        return Java2C_Main.singleton.javaSources.javaSrcTree.getChild(sName);
1044  }
1045  
1046  /**Gets the FileLevelidents of the root level. It are such as the packages "org" or "java".
1047   * @return The fileLevelIdents for the root level.
1048   */
1049  public final static LocalIdents getRootLevelIdents(){
1050        return Java2C_Main.singleton.javaSources.javaSrcTree.getPkgLevelIdents();
1051  }
1052  
1053
1054  /**It's a debug helper. The method is empty, but it is a mark to set a breakpoint. */
1055  void stop()
1056  { //debug
1057  }
1058
1059
1060  /**Runs the first pass. Searches the file and build the ClassData parsing and converting the file.
1061   * This method is called if an unknown type is used yet.
1062   * @param sClassName The name of the type in Java. The filename should be the same.
1063   *        The file is searched in any package given as input parameter calling java2C.
1064   * @return null if no file found. Otherwise the built ClassData. 
1065   *         This ClassData are registered in the list {@link Java2C_Main#userTypes}.
1066   * @throws ParseException 
1067   * @see org.vishia.java2C.RunRequiredFirstPass_ifc#runRequestedFirstPass(java.lang.String)
1068   */
1069  public ClassData runRequestedFirstPass(final JavaSrcTreeFile javaSrc, final String sPkgClassName) //, String sPkgName) 
1070  throws FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException, ParseException
1071  {
1072    if(javaSrc != null){ 
1073        /**Translate the java-file or read the stc-file. */
1074      GenerateFile genFile = runFirstPassFile(javaSrc);
1075        if(genFile != null){
1076        //NOTE: The secondPass must not run immediately, because the first pass
1077                // of the file, which needs this firts pass, isn't ready yet. 
1078                //If this file needs something from the first file in its second pass,
1079                //it is wrong.
1080                //doNot: genFile.runSecondPassFile(console);
1081                //instead: save the file to run the second pass after finishing the first pass of the first file.
1082                allJavaFilesToRunSecondPass.add(genFile);
1083        }
1084      if(sPkgClassName.equals("InspcDataExchange") || sPkgClassName.equals("LogMessage"))
1085                stop();
1086        /**The ClassData of all classes in this file should be posed in the package of the javaSrc. */
1087      LocalIdents pkgIdents = javaSrc.getPkgLevelTypes();
1088        final JavaSources.ClassDataOrJavaSrcFile infos = pkgIdents.getTypeInfo(sPkgClassName, null);  //fileLevelIdents = null, because it are the fileLevelIdents.
1089      assert(infos !=null);
1090      ClassData retClassData = infos.getClassData();
1091      return retClassData;
1092      //return pkgIdents.getType(sPkgClassName, null);  //fileLevelIdents = null, because it are the fileLevelIdents.
1093    }
1094    else{
1095      throw new IllegalArgumentException("no javaSrc available for. " + sPkgClassName);
1096      //return xxxrunRequestedFirstPass(null,sPkgClassName, sPkgName);
1097    }
1098  }
1099  
1100  
1101  /**Searches a class in any *.stc-File. This method is called if a yet translated ClassData
1102   * isn't found and a source to runfirstpass isn't found too. 
1103   * @param sClassName
1104   * @return
1105   */
1106  private File searchFileStc(String sFileNameStc)
1107  {
1108    if(sFileNameStc.equals("Jc/StringBufferJc.stc"))
1109      stop();
1110    File fileStc = null;
1111
1112    Iterator<String> stcPathes = inputCfg.getStcPathes().iterator();
1113    while(fileStc == null && stcPathes.hasNext())
1114    { String stcPath = stcPathes.next();
1115      String sFile = stcPath + "/" + sFileNameStc;
1116      fileStc = new File(sFile);
1117      if(!fileStc.exists())
1118      { fileStc = null;
1119      }
1120    }
1121    if(fileStc != null)
1122    { stop();
1123      
1124    }
1125    return fileStc;
1126  }
1127  
1128  
1129 
1130}