001/****************************************************************************
002 * Copyright/Copyleft:
003 *
004 * For this source the LGPL Lesser General Public License,
005 * published by the Free Software Foundation is valid.
006 * It means:
007 * 1) You can use this source without any restriction for any desired purpose.
008 * 2) You can redistribute copies of this source to everybody.
009 * 3) Every user of this source, also the user of redistribute copies
010 *    with or without payment, must accept this license for further using.
011 * 4) But the LPGL is not appropriate for a whole software product,
012 *    if this source is only a part of them. It means, the user
013 *    must publish this part of source,
014 *    but don't need to publish the whole source of the own product.
015 * 5) You can study and modify (improve) this source
016 *    for own using or for redistribution, but you have to license the
017 *    modified sources likewise under this LGPL Lesser General Public License.
018 *    You mustn't delete this Copyright/Copyleft inscription in this source file.
019 *
020 * @author Hartmut Schorrig: hartmut.schorrig@vishia.de, www.vishia.org
021 * @version 0.93 2011-01-05  (year-month-day)
022 *******************************************************************************/ 
023package org.vishia.java2C;
024
025
026/**This class holds the data of one variable in a local context respectively a field of a class, 
027 * see {@link LocalIdents} 
028 * or describe the access to a instance, see {@link CCodeData}.
029 */
030public class FieldData
031{
032  /**version, history and license.
033   * <ul>
034   * <li>2014-09-05 Hartmut new: {@link #modeAccess} can have value 'M' for a PtrVal access. Regarded for C-generation.
035   * <li>2008 Hartmut created:    
036   * </ul>
037   * 
038   * <b>Copyright/Copyleft</b>:
039   * For this source the LGPL Lesser General Public License,
040   * published by the Free Software Foundation is valid.
041   * It means:
042   * <ol>
043   * <li> You can use this source without any restriction for any desired purpose.
044   * <li> You can redistribute copies of this source to everybody.
045   * <li> Every user of this source, also the user of redistribute copies
046   *    with or without payment, must accept this license for further using.
047   * <li> But the LPGL is not appropriate for a whole software product,
048   *    if this source is only a part of them. It means, the user
049   *    must publish this part of source,
050   *    but don't need to publish the whole source of the own product.
051   * <li> You can study and modify (improve) this source
052   *    for own using or for redistribution, but you have to license the
053   *    modified sources likewise under this LGPL Lesser General Public License.
054   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
055   * </ol>
056   * If you are intent to use this sources without publishing its usage, you can get
057   * a second license subscribing a special contract with the author. 
058   * 
059   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
060   * 
061   * 
062   */
063  public final static String sVersion = "2014-09-05";
064
065  
066  /**The name of the identifier. <code>null</code> if it is the description of an access to an unnamed instance. */
067  private final String sName;
068  
069  /**The type respectively reference type of the field. */
070  public final ClassData typeClazz;
071  
072  /**The type of a key if it is a generic container type of keys and values. Elsewhere null. */
073  public ClassData keyClazz;
074  
075  /**The type of a elements of a generic container type. Elsewhere null. */
076  public ClassData elementClazz;
077  
078  /**If this field is set, the instance referenced in the described field is guaranteed an instance
079   * of that type, nor from a derived type. It means, no dynamic linked call is necessary,
080   * methods can called static using this instance type. This property saves some calculation times,
081   * while calling override-able methods of the referenced class.
082   * <br>
083   * If references are used as interface references for Java test and software design (including
084   * the documentation aspect), but the implementation uses the named instance in any case, 
085   * this feature should be used.
086   * <br>
087   * For a reference variable this behavior is possible to control with @ java2c=instanceType:TYPE.
088   * This behavior is also set at embedded instance automatically. 
089   * This field is null, if the instance isn't predefined.
090   */
091  public final ClassData instanceClazz;
092  
093  /**The class where the identifier is member of, null if it is a local identifier. */
094  public final ClassData declaringClazz;
095  
096  /**Char to indicate the location and kind of definition.
097   * <ul><li>'S' static constant
098   *     <li>'s' static non constant
099   *     <li>'d' immediate constant with define
100   *     <li>'n' stack-locally Field which stores a reference to a new created instance, to activate for garbage collection.
101   *     <li>'r' nonPersistent.
102   *     <li>'t' not used, TODO used 'r' String, which may be non persistent. Maybe return value with buffer in Thread-Context.
103   *     <li>'.' non static, no special functionality.
104   * </ul>     
105   */
106  public final char modeStatic;
107  
108  /**If the identifier is an array with fix size, programmed in java in form of
109   * <pre>
110   * Type[][] myArray = new Type[expr][expr];
111   * </pre>
112   * The <code>expr</code> translated in C-Form are stored here. This expr should be a simple value
113   * in C. There are used to generate the initialization of an array.
114   * <br>
115   * <code>null</code> if it isn't an array or it is a dynamic array.
116   */
117  public final String[] fixArraySizes;
118  
119  /**0 if it isn't an array. 1.. if it is an array. 
120   * if modeArrayElement=='B' it is the fix size of a StringBuffer with direct char*.
121   */
122  private final int dimensionArrayOrFixSize;
123  
124  
125  /**Kind of the access to an element, if it is an array.
126   * The adequate chars are used see {@link #modeAccess}.
127   * Special case: If it is 'B', the field describes a <code>StringBufferJc</code> with a fix size.
128   * In that case the {@link #dimensionArrayOrFixSize} contains the number of chars inclusive the 4 chars
129   * storing in the <code>StringBufferJc</code>-instance with immediate buffer.
130   */
131  public final char modeArrayElement;
132  
133  /**Kind of the instance. For non-arrays:
134   * <table>
135   * <tr><td>$</td><td>an embedded struct</td></tr>
136   * <tr><td>%</td><td>a variable of basic primitive type such as int32, float, char,
137   *                   but also an embedded indivisible struct like StringJc, MemC, OS_TimeStamp,
138   *                   whose elements aren't accessed in Java. </td></tr>
139   * <tr><td>*</td><td>a simple reference, pointer in C, used for non-GC-controlled associations.</td></tr>
140   * <tr><td>@</td><td>an enhanced reference, for GC (garbage collector) -controlled associations.</td></tr>
141   * <tr><td>m</td><td>an method table-reference.</td></tr>
142   * <tr><td>t</td><td>a StringJc, it is an enhanced reference ~REF also, but with special accesses</td></tr>
143   * <tr><td>&</td><td>an method-table reference ~MTB, containing C-jump-table with index.
144   *                   This type is only used for stack-local variables. GC is not possible</td></tr>
145   * <tr><td>~</td><td>ythis as reference (call own method</td></tr>
146   * <tr><td>+</td><td>A variable argument list</td></tr>
147   * </table>
148   * if {@link #dimensionArrayOrFixSize} >0, this element describes the access to the array head. 
149   * The kind of elements respectively the access to the data of the elements are described in {@link #modeArrayElement}.
150   * with the same key chars as shown above. Independent of the kind of referencing the array
151   * the elements may be embedded struct ('$'), references ('*') etc., see {@link #modeArrayElement}.
152   * <table>
153   * <tr><td>M</td><td>Reference to an array with a PtrVal in C. A PtrVal is a <code>struct { Type* ptr__; int32 value__}</code>
154   *                   whereby <code>Type</code> is the type of the reference. The <code>value__</code> contains the number of elements
155   *                   of the array. The array is 1-dimensional.
156   *                   In Java it is any array <code>@Java4C=PtrVal Type[]</code>.
157   * <tr><td>B</td><td>A ByteStringJc. It is similar as StringJc, but it references bytes, not chars.
158   *                   In Java it is a byte[] with java2c=ByteStringJc-designation.
159   *                   Hint: A ByteStringJc is designated in this class with {@link #dimensionArrayOrFixSize}=1.
160   *                   It is an array with 1 dimension. 
161   *                   It is similar MemC (pointer to memory and size). </td></tr>
162   * <tr><td>P</td><td>A simple reference to the array elements without head, pointer in C, 
163   *                   used for non-GC-controlled associations.</td></tr>
164   * <tr><td>Q</td><td>An embedded array without head. All elements are embedded. 
165   *                   The {@link #fixArraySize} is set.</td></tr>
166   * <tr><td>X</td><td>A simple reference to <code>ObjectArrayJc</code> head informations, pointer in C, to an array type, used for non-GC-controlled associations.</td></tr>
167   * <tr><td>Y</td><td>An embedded array with <code>ObjectArrayJc</code> head informations. 
168   *                   All elements are embedded. The {@link #fixArraySize} is set.</td></tr>
169   * <tr><td>@</td><td>an enhanced reference to an array type, starting with ObjectArrayJc, 
170   *                   for GC (garbage collector) -controlled associations.</td></tr>
171   * </table>
172   */
173  public final char modeAccess;
174  
175  /**see {@link getClassLevel()}*/
176  int nClassLevel;
177
178  /**see {@link getOuterLevel()}. Note: this private member is set in the outer class, 
179   * see {@link putClassElement(String, String, ClassData, String, ClassData)}
180   * or  {@link putLocalElement(String, String, ClassData, String)} 
181   */
182  int nOuterLevel;
183  
184  /**Name of an associated StringBuilder. 
185   * It is relevant only if the field is a StringJc-variable and it is temporary. */
186  String sStringBuilderName;
187  
188  /**initializes the instance node. */
189  FieldData
190  ( String sName
191  , ClassData typeClazz
192  , ClassData instanceClass
193  , ClassData elementClass
194  , ClassData keyClass
195  , char staticMode
196  , char accessMode
197  , int dimensionArray
198  , String[] fixArraySizes
199  , char modeArrayElement
200  , ClassData declaringClazz
201  )
202  { this.sName = sName;
203    if(sName !=null && sName.equals("rxBuffer"))
204        stop();
205    if(instanceClass!=null && instanceClass.sClassNameJava.equals("AnswerComm_ifc"))
206        stop();
207        assert(".?%*~$&@mXYPQMt+B".indexOf(accessMode)>=0);
208    this.modeAccess = accessMode;
209    //this.sModifier = sModifier; 
210    this.fixArraySizes = fixArraySizes; 
211    this.declaringClazz = declaringClazz; 
212    if(typeClazz==null) throw new IllegalArgumentException("typeClazz = null for:" + sName);
213    
214    this.typeClazz = typeClazz;
215    this.instanceClazz = instanceClass;
216    this.elementClazz = elementClass;
217    this.keyClazz = keyClass;
218    this.dimensionArrayOrFixSize = dimensionArray;  //NOTE: if modeArrayElement=='B' it is the fix size of a StringBuffer
219    //assert(dimensionArray == 0 || dimensionArray == 1);
220    if(modeArrayElement == '$')
221      stop();
222    assert(".%t*$&@B".indexOf(modeArrayElement)>=0);
223    this.modeArrayElement = modeArrayElement;
224    assert("sSdrn.".indexOf(staticMode)>=0);
225    this.modeStatic = staticMode;
226  }
227  
228  
229  
230  
231
232  /**Copies given FieldData, but modify with given parameters
233   * @param parent //the parent
234   * @param classLevelAdd Adds the class level, 0: keep from parent. To copy instances for super classes
235   * @param outerLevelAdd Adds the outer level, 0: keep from parent. To copy instances for inner classes
236   * @param modeAccessP if '.' than keep parent.modeAccess, else take that.
237   */
238  FieldData(FieldData parent, int classLevelAdd, int outerLevelAdd, char modeAccessP, char modeStaticP)
239  { this.sName = parent.sName;
240    if(sName.equals("searchTrc") )//&& outerLevelAdd == 1)
241        stop();
242        this.modeAccess = modeAccessP == '.' ? parent.modeAccess : modeAccessP;
243    this.declaringClazz = parent.declaringClazz; 
244    this.typeClazz = parent.typeClazz;
245    this.instanceClazz = parent.instanceClazz;
246    this.keyClazz = parent.keyClazz;
247    this.elementClazz = parent.elementClazz;
248    this.dimensionArrayOrFixSize = parent.dimensionArrayOrFixSize; 
249    this.fixArraySizes = parent.fixArraySizes;
250    this.modeArrayElement = parent.modeArrayElement;
251    this.modeStatic = modeStaticP=='.' ? parent.modeStatic: modeStaticP;
252    this.nClassLevel = parent.nClassLevel + classLevelAdd;
253    this.nOuterLevel = parent.nOuterLevel + outerLevelAdd;
254  }
255  
256  
257  /*
258  FieldData(FieldData parent, int dimensionArrayOrFixSize)
259  { //this.sTypeIdent = parent.sTypeIdent; 
260    this.sName = parent.sName;
261    this.modeAccess = parent.modeAccess;
262    //this.sModifier = sModifier; 
263    this.fixArraySizes = parent.fixArraySizes; 
264    this.clazz = parent.clazz; 
265    this.typeClazz = parent.typeClazz;
266    this.dimensionArray = (byte)dimensionArrayOrFixSize; 
267    this.modeArrayElement = parent.modeArrayElement;
268    this.modeStatic = parent.modeStatic;
269  }
270  */
271  
272  /**level of the affiliation to a class in the inheritance level.
273   * 0= it is a local visible variable. 1=element of this class, 2=element of super class etc.
274   */
275  public int getClassLevel(){ return nClassLevel; }
276  
277  
278  /**Returns 0 if it isn't an array, 1.. for number of array dimension.*/
279  public int getDimensionArray(){ return ".B".indexOf(modeArrayElement) <0 ? dimensionArrayOrFixSize : 0; }
280
281  
282  /**Returns the size >0 if the type is a StringBuffer with a immediate String with fix size, else 0.
283   */
284  public int getFixSizeStringBuffer(){return modeArrayElement=='B'? dimensionArrayOrFixSize : 0; }
285  
286  /**level of the affiliation to a class in the outer class relation.
287   * 0= it is a local visible variable. 1=element of this class, 2=element of outer class etc.
288   */
289  public int getOuterLevel(){ return nOuterLevel; }
290  
291  /**returns the name of the element. */
292  public String getName(){ return sName; }
293
294  /**returns the name of the type of the element. */
295  public String getTypeName(){ return typeClazz.getClassCtype_s(); }
296  
297  public String getTypeChar()
298  { return "" + typeClazz.cVaArgIdent;
299  }
300  
301 
302  
303  
304  /**Generates the C type declaration appropriate to the type info in this FieldData.
305   * It is the type code used for definition of the variable.
306   * <ul>
307   * <li>Simple embedded Arrays: At example type int. It returns only <code>int</code> because
308   *     the complete definition is <code>int name[123]</code> or <code>int name[] = { 1, 2, 3}</code> 
309   * </ul>
310   * <br>
311   * If it is an simple array, the type code designating the pointer to the elements requires an additional '*'
312   * @return String with C type declaration.
313   */
314  public String gen_Declaration(iWriteContent generateFile)
315  { final String sPreModifier;
316    if(sName != null && sName.equals("int32")) 
317      stop();
318    if(modeStatic == 'S') {
319      sPreModifier = "const ";
320    } else {
321      sPreModifier = ""; 
322    }
323    final String sTypeReturn; //  .sTypeIdent;
324    switch(modeAccess)
325    { case 'B':
326        case '$':
327      case 't':
328      case '%': sTypeReturn = typeClazz.getClassCtype_s(); break;
329      case 'C':
330      case '*': { sTypeReturn = "struct " + typeClazz.getClassIdentName() 
331                            + (typeClazz.isConstant ? "_t const*":"_t*"); 
332        generateFile.addStructForwardType(typeClazz);
333        } break;
334      case '@': sTypeReturn = typeClazz.getClassIdentName() + "REF"; break;
335      case '&': sTypeReturn = typeClazz.getClassIdentName() + "MTB"; break;
336      case '+': sTypeReturn = "char const*"; break;
337      case 'X': //reference to an ObjectArrayJc, reference or not of elements in modeArrayElement 
338        sTypeReturn = typeClazz.getClassIdentName() + (typeClazz.isConstant ? "_Y const*":"_Y*"); break;
339      case 'Y': //instance of an ObjectArrayJc, reference or not of elements in modeArrayElement
340        sTypeReturn = typeClazz.getClassIdentName() + "_Y"; break;
341      case 'M': 
342        sTypeReturn = "PtrVal_" + typeClazz.getClassIdentName(); break;
343      case 'P': 
344      { switch(modeArrayElement)
345        { case '$':
346          case 't':
347          case '%': sTypeReturn = typeClazz.getClassCtype_s() + "*"; ; break;
348          case '*': sTypeReturn = "struct " + typeClazz.getClassIdentName() 
349                                + (typeClazz.isConstant ? "_t const**":"_t**"); break;
350          case '@': sTypeReturn = typeClazz.getClassIdentName() + "REF*"; break;
351          default: sTypeReturn = null;
352        }  
353      } break;
354      case 'Q': 
355      { /**embedded array. to use in declaration, at ex. int name[] is produced, here only int.*/
356        switch(modeArrayElement)
357        { case '$':
358          case 't':
359          case '%': sTypeReturn = typeClazz.getClassCtype_s() + ""; ; break;
360          case '*': sTypeReturn = "struct " + typeClazz.getClassIdentName() 
361                                + (typeClazz.isConstant ? "_t const*":"_t*"); break;
362          case '@': sTypeReturn = typeClazz.getClassIdentName() + "REF"; break;
363          default: sTypeReturn = null;
364        }  
365      } break;
366      default: sTypeReturn = null;
367    }
368    assert(sTypeReturn != null);
369    return sPreModifier + sTypeReturn;
370    
371  }
372
373  /**generates the code for a variable definition of the given FieldInfo.
374   * @return code for definition of the variable, without ";" on end.
375   * This method is only called inside {@link GenerateClass#gen_variableDefinition(org.vishia.zbnf.ZbnfParseResultItem, org.vishia.zbnf.ZbnfParseResultItem, LocalIdents, java.util.List, char)}
376   * It supplies all informations which are able to gotten in this class.
377   */
378  String gen_VariableDefinition(char intension, iWriteContent generateFile)
379  {
380    if(sName.equals("clazz"))
381      stop();
382    
383    final String sNameC = "Ssd".indexOf(modeStatic)>=0 
384                        ? sName + "_" + declaringClazz.getClassIdentName()
385                        : sName;  //static variable with _Classname
386    String typeCode = gen_Declaration(generateFile);
387    if(sName.equals("singleton"))
388      stop();
389    String ret = "???";
390    if(dimensionArrayOrFixSize >0)
391    { final String elementType;
392      switch(modeArrayElement)
393      { case '%': case 't': case '$': elementType = typeClazz.getClassCtype_s(); break;
394        case '*': elementType = "struct " + typeClazz.getClassIdentName() 
395                  + (typeClazz.isConstant ? "_t const*":"_t*"); break;
396        case '@': elementType = typeClazz.getClassIdentName() + "REF"; break;
397        case '&': elementType = typeClazz.getClassIdentName() + "MTB"; break;
398        case 'B': elementType =null; assert(modeAccess == '$'); break;
399        default: elementType =null; assert(false);
400      }
401      switch(modeAccess){
402        case 'M': {
403          ret = "PtrVal_" + typeClazz.getClassIdentName() + " " + sNameC;
404      } break;
405        case 'B': {
406          ret = "ByteStringJc " + sNameC;
407      } break;
408      case 'Y':
409        { /**A fix size embedded array, but with head: */
410          ret = "struct " + sNameC + "_Y {"
411                 + " ObjectArrayJc head; " + elementType + " data[" + fixArraySizes[0] + "]; }"
412                 + sNameC;  //NOTE: the ";" after definition is set outside.
413        }break;
414        case 'Q':
415        { /**An simple fix embedded array: */
416          if(fixArraySizes != null)
417          { ret = typeCode + " " + sNameC;
418            for(String fixArraySize: fixArraySizes)
419            { ret += "[" + fixArraySize + "]"; 
420            }
421          }
422          else assert(false);  //it have to be fixArraySizes!    
423        }break;
424        case 'X':
425        { ret = typeCode + " " + sNameC;
426          //TODO arrays with more as one dimension.
427        } break;
428        case '$':
429        {
430          assert(modeArrayElement == 'B');
431          { /**Its a fix String buffer. */
432            ret = "struct SbY_" + sNameC + "_t {"
433                 + " StringBufferJc sb; char _b[" + (dimensionArrayOrFixSize-4) + "]; }"
434                 + sNameC;  //NOTE: the ";" after definition is set outside.
435            
436          }
437          
438        }break;
439        case 'p':
440        case 'P':{
441                ret = elementType+ "* " + sNameC;
442        } break;
443        default: assert(false);  
444      }
445    }
446    else {
447      if(modeStatic == 'd'){
448        ret = "#define " + sNameC + " " + fixArraySizes[0];    
449      }
450      else {
451        ret = typeCode + " " + sNameC;
452        if(modeAccess == '+'){
453                ret += ", ...";
454        }
455      }
456    }
457    return ret;  
458  }
459
460  /**Writes the structure of this instance to a <code>*.stc</code>-file. 
461   * It is an class level identifier, see {@link ClassData#classLevelIdents}, 
462   * or a return type or argument of a method,
463   * because only for such FieldData this method is called. 
464   * See {@link LocalIdents#writeStruct(int)} and {@link ClassData.Method#writeStruct()}
465   * @return The content to write to <code>*.stc</code>-file. The form of string is the same
466   * described in the syntax <code>Java2Cstc.zbnf</code>.
467   */
468  public String xxxwriteStruct() 
469  { 
470    if(typeClazz == null)
471      assert(false);
472    if(typeClazz.sClassNameJava.equals("InnerTest"))
473      stop();
474    
475    
476    
477    String out = "field:{ ";
478
479    //out += typeClazz.sPackage;
480    ClassData outerClazz = typeClazz; //start with it.
481    while( (outerClazz = outerClazz.outerClazz) != null)
482    { //insert left:
483      //out += outerClazz.sClassNameJava + "." ;
484      stop();
485    }
486    //out += typeClazz.sClassNameJava;
487    out += typeClazz.sClassNameJavaFullqualified;
488    
489    if(keyClazz != null){
490      out += "<" + keyClazz.sClassNameJavaFullqualified + "," + elementClazz.sClassNameJavaFullqualified + ">";
491    }
492    else if(elementClazz != null){
493      out += "<" + elementClazz.sClassNameJavaFullqualified + ">";
494    }
495    
496    if(instanceClazz != null){
497      out += " (instance=" + instanceClazz.sClassNameJavaFullqualified + ")";
498    }
499    out += " "
500          + modeAccess 
501          + modeArrayElement 
502          + modeStatic;
503    assert(typeClazz.sPackage.length() == 0 || typeClazz.sPackage.endsWith("/"));
504    if(modeArrayElement == 'B'){
505      out += "-fixBufferSize[" + dimensionArrayOrFixSize + "]"; 
506    }
507    else {
508      /**Array may be with fix size.Either show [??] per size or the size. */
509      for(int ii=0; ii<dimensionArrayOrFixSize; ii++)
510      { final String sFixArraySize = 
511          fixArraySizes == null ? "??"
512          : fixArraySizes[ii] == null ? "?"
513          : fixArraySizes[ii];
514        out += "[" + sFixArraySize + "]";
515      }
516    }  
517    out += " "+ sName + "; ";
518    out += "/*info"
519        + dimensionArrayOrFixSize
520        + nClassLevel + nOuterLevel
521        + "*/ }";
522    //if()
523    return out;
524  }    
525          
526  
527  /**Writes the structure of this instance to a <code>*.stc</code>-file. 
528   * It is an class level identifier, see {@link ClassData#classLevelIdents}, 
529   * or a return type or argument of a method,
530   * because only for such FieldData this method is called. 
531   * See {@link LocalIdents#writeStruct(int)} and {@link ClassData.Method#writeStruct()}
532   * @return The content to write to <code>*.stc</code>-file. The form of string is the same
533   * described in the syntax <code>Java2Cstc.zbnf</code>.
534   */
535  public String writeStruct() 
536  { 
537    StringBuilder out = new StringBuilder(30);
538        if(typeClazz == null)
539      assert(false);
540    ClassData outerClazz = typeClazz; //start with it.
541    while( (outerClazz = outerClazz.outerClazz) != null)
542    { //insert left:
543      //out += outerClazz.sClassNameJava + "." ;
544      stop();
545    }
546    //out += typeClazz.sClassNameJava;
547    out.append(typeClazz.sClassNameJavaFullqualified);
548    
549    if(keyClazz != null){
550      out.append("<" + keyClazz.sClassNameJavaFullqualified + "," + elementClazz.sClassNameJavaFullqualified + ">");
551    }
552    else if(elementClazz != null){
553      out.append("<" + elementClazz.sClassNameJavaFullqualified + ">");
554    }
555    if(modeArrayElement != 'B'){
556      /**Array may be with fix size.Either show [??] per size or the size. */
557      for(int ii=0; ii<dimensionArrayOrFixSize; ii++)
558      { final String sFixArraySize = 
559          fixArraySizes == null ? "??"
560          : fixArraySizes[ii] == null ? "?"
561          : fixArraySizes[ii];
562        out.append( "[" + sFixArraySize + "]");
563      }
564    }  
565    //additional informations:
566    String sSeparator = "(";
567    if(instanceClazz != null){
568      out.append(sSeparator).append( "instance=").append(instanceClazz.sClassNameJavaFullqualified);
569      sSeparator = ", ";
570    }
571    if(modeArrayElement == 'B'){
572        out.append(sSeparator).append("fixBufferSize=").append(dimensionArrayOrFixSize ); 
573    }
574    if(!sSeparator.equals("(")){ out.append(")");} //any content
575    
576    out.append( " ")
577       .append( modeAccess) 
578       .append( modeArrayElement) 
579       .append( modeStatic);
580         //.append(" c").append(nClassLevel)
581             //.append(" o").append(nOuterLevel);
582   assert(typeClazz.sPackage.length() == 0 || typeClazz.sPackage.endsWith("/"));
583    out.append( " ").append(sName);
584    return out.toString();
585  }    
586          
587  
588  /**Tests whether a cast to the given FieldData type is necessary and executes it.
589   * The cast consists of two parts:
590   * <ul><li>cast of type, for example to a base class type or another cast-able type
591   * <li>cast of access, for example from an enhanced reference to the reference
592   * </ul>
593   * If srcType is the same as this, no cast occurs, the value is returned direct.
594   * If srcType is a derive-able type of this, the cast is get with TODO.
595   * <br><br>
596   * The cast of access is gotten calling {@link #testAndChangeAccess(char, String, char)}.
597   * <br><br>
598   * This method prepares the access to a value. For assignments this method is used too, but the assignment has to produce code for setting,
599   * see {@link StatementBlock#gen_AssignCheckCast(CCodeData, String, CCodeData)}.
600   * <br><br>
601   *  
602   * @param srcType The type of the value
603   * @param value The value string.
604   * @return The value itself if no cast is necessary
605   * @param src The Expression with its type and access modes
606   * @param modeAccessDst A deviating mode of access for the destination or '.'. If '.', the {@link #modeAcess} 
607   *        of this is valid.
608   * @return String, either src.cCode if no cast is necessary, or the casted expression.
609   */
610  public String testAndcast(CCodeData src, char modeAccessDst)
611  { if(src.cCode.equals("REFJc(ythis->implifc2)"))
612      stop();
613    
614    final String sRet;
615    if(modeAccessDst == '.'){ modeAccessDst = this.modeAccess; }
616    assert(modeAccessDst != '&' || src.modeAccess == '&'); //no access conversion to Type_MTB
617    if(false && modeAccessDst == '&'){  //it doesn't work anytime.
618        /**A method-table-reference is need: */
619        /**TypeMTBL is need. */
620        final String sSrc2;
621        switch(src.modeAccess){
622        case '*': sSrc2 = src.cCode; break;
623        case '$': sSrc2 = "&(" + src.cCode + ")"; break;
624        default: sSrc2 = "XXX"; assert(false);
625        }
626        sRet = "(" + typeClazz.getClassIdentName() + "MTB)mtblRef_ObjectJc(&(" + sSrc2 
627             + ")->base.object, sign_Mtbl_" +  typeClazz.getClassIdentName() + ")";
628    } else {
629            if( src.cCode.equals("null"))
630            { //a null-pointer should be compatible with all except StringJc.
631                if(typeClazz.bEmbedded && dimensionArrayOrFixSize == 0) {
632                //Any embedded type should have a null_Name-instance, that content is assigned.
633                sRet = "null_" + typeClazz.getClassIdentName();
634              } else if(typeClazz.sClassNameC.equals("StringJc")
635                && dimensionArrayOrFixSize == 0 //if >0, it is a String[] referenced.
636                ) {
637                assert(false);  //condition above is met.
638                sRet = "null_StringJc"; 
639              } else if('B' == modeAccess){
640                //a Byte-String represents a byte[], dimensionArrayOrFixSize =1 typical, not tested.
641                //extension for future: use 'B' for more direct referenced types of arrays,
642                //adequate to a MemC.
643                sRet = "null_OS_PtrValue";
644              }else  {
645                sRet = "null"; 
646              } 
647            }
648            else {
649              
650              if(src.cCode.startsWith("requireWay1Sensor_iRequireMainController(broker, _thCxt)"))
651                stop();
652              
653              
654              ClassData.CastInfo castInfo;
655              if(  this.typeClazz == src.identInfo.typeClazz
656                || src.identInfo.typeClazz == CRuntimeJavalikeClassData.clazz_unknown  //unknown type, don't cast, it is okay:
657                || src.modeAccess == '?'                       //unknown type, don't cast, it is okay:
658                || this.typeClazz == CRuntimeJavalikeClassData.clazz_unknown  //unknown type, don't cast, it is okay:
659                || this.typeClazz == CRuntimeJavalikeClassData.clazz_void  //void as argument is a void*
660                || this.typeClazz == CRuntimeJavalikeClassData.clazz_va_argRaw  //any type is valid
661                ) {
662                sRet = testAndChangeAccess(modeAccessDst, src.cCode, src.modeAccess);
663              }
664              else if( (castInfo = src.identInfo.typeClazz.getCastInfoToType(typeClazz.sClassNameC)) != null
665                     ||(castInfo = typeClazz.getCastInfoFromType(src.identInfo.typeClazz.sClassNameC)) != null
666                     ){
667                /**cast src to this type: */
668                String sSrcCasted = testAndChangeAccess(castInfo.modeAccessSrc, src.cCode, src.modeAccess);
669                String sSrc1 = castInfo.pre + sSrcCasted + castInfo.post;
670                sRet = testAndChangeAccess(modeAccessDst, sSrc1, castInfo.modeAccessDst);
671              }
672          else if(src.modeAccess =='X' && this.typeClazz==CRuntimeJavalikeClassData.singleton.clazzMemC){
673            /**Cast of a array to MemC: */
674            sRet = testAndChangeAccess(modeAccessDst, "buildFromArrayX_MemC(&(" + src.cCode + ")->head) ", '$');
675          }
676          else if(src.modeAccess =='Q' && this.typeClazz==CRuntimeJavalikeClassData.singleton.clazzMemC){
677            /**Cast of a array to MemC: */
678            sRet = testAndChangeAccess(modeAccessDst, "build_MemC(&(" + src.cCode + "), " + src.identInfo.dimensionArrayOrFixSize + ") ", '$');
679          }
680              else if(src.modeAccess =='M' && this.typeClazz==CRuntimeJavalikeClassData.singleton.clazzMemC){
681            /**A PtrVal is the same as MemC in C.  */
682            sRet = "build_MemC(" + src.cCode + ".ptr__, " + src.cCode + ".value__ )";  //hint: Usage of MemC instead PtrVal is an older form. pointer type is not precise. 
683          }
684          else if(src.modeAccess =='Y' && this.typeClazz==CRuntimeJavalikeClassData.singleton.clazzMemC){
685                /**Cast of a array to MemC: */
686                sRet = testAndChangeAccess(modeAccessDst, "buildFromArrayY_MemC(&(" + src.cCode + ")->head) ", '$');
687              }
688              else if(src.modeAccess =='X' && this.typeClazz==CRuntimeJavalikeClassData.clazzObjectJc){
689                /**Cast of a array to Object reference: */
690                sRet = testAndChangeAccess(modeAccessDst, "(" + src.cCode + ")->head.object", '$');
691              }
692              else if(src.modeAccess =='Y' && this.typeClazz==CRuntimeJavalikeClassData.clazzObjectJc){
693                /**Cast of a array to Object reference: */
694                sRet = testAndChangeAccess(modeAccessDst, "(" + src.cCode + ").head.object", '$');
695              }
696              else {
697                /**No castInfo, but the types are different. It is a derivation. */
698                String sClassNameDst = typeClazz.sClassNameC;
699                if(typeClazz.isPrimitiveType()){
700                  String sSrcCasted = testAndChangeAccess('%', src.cCode, src.modeAccess);
701                  sRet = "((/*J2C:cast% from "+src.identInfo.getTypeName()+"*/" + sClassNameDst + ")(" + sSrcCasted + "))";
702                } 
703                else if("t$".indexOf(typeClazz.classTypeInfo.modeAccess) >=0){
704                  /**The dst should be a value (embedded). */
705                  String sSrcCasted = testAndChangeAccess('$', src.cCode, src.modeAccess);
706                  sRet = "((/*J2C:cast$ from "+src.identInfo.getTypeName()+"*/" + sClassNameDst + ")(" + sSrcCasted + "))";
707                } 
708                else {
709                  /**Normal pointer cast. */
710                  String sSrcCasted = testAndChangeAccess('*', src.cCode, src.modeAccess);
711                  sRet = "((/*J2C:cast from "+src.identInfo.getTypeName()+"*/" + sClassNameDst + "*)(" + sSrcCasted + "))";
712                }
713              }
714            }
715    }
716    return sRet;
717    
718  }
719
720  
721  
722  String testAndCastInitializer(CCodeData src)
723  { String sRet;
724    if( src.cCode.equals("null"))
725    { //a null-pointer should be compatible with all expect StringJc.
726      if(typeClazz.sClassNameC.equals("StringJc")
727        && dimensionArrayOrFixSize == 0
728        )
729      { 
730        sRet = "NULL_StringJc"; }
731      else {
732        sRet = "null"; } 
733    }
734    else {
735      if(src.cCode.startsWith("xxx"))
736        stop();
737      ClassData.CastInfo castInfo;
738      if(  this.typeClazz == src.identInfo.typeClazz
739        || src.identInfo.typeClazz == CRuntimeJavalikeClassData.clazz_unknown  //unknown type, don't cast, it is okay:
740        || src.modeAccess == '?'                       //unknown type, don't cast, it is okay:
741        || this.typeClazz == CRuntimeJavalikeClassData.clazz_unknown  //unknown type, don't cast, it is okay:
742        || this.typeClazz == CRuntimeJavalikeClassData.clazz_void  //void as argument is a void*
743        || this.typeClazz == CRuntimeJavalikeClassData.clazz_va_argRaw  //any type is valid
744        ) {
745        sRet = src.cCode;
746      } else if( 
747                  (castInfo = typeClazz.getCastInitializerFromType(src.identInfo.typeClazz.sClassNameC)) != null
748                ||(castInfo = src.identInfo.typeClazz.getCastInfoToType(typeClazz.sClassNameC)) != null
749          ||(castInfo = typeClazz.getCastInfoFromType(src.identInfo.typeClazz.sClassNameC)) != null
750          ){
751        if(castInfo.pre.equals("CONST_z_StringJc("))
752                stop();  //TODO count number of chars.
753        sRet = castInfo.pre + src.cCode + castInfo.post;
754      } else{
755        sRet = src.cCode + "/*J2C: no cast found from " + src.identInfo.typeClazz + "*/";
756      }
757        }
758    return sRet;
759  }
760  
761  
762  
763  /**Changes the access.
764   * The '@' is handled like '*', because the building of enhanced reference is done outside.
765   * @param modeAccessDst Necessary access, ones of chars <code>&*@~%?</code>, see {@link #modeAccess}
766   * @param sSrc1 The cCode of src
767   * @param modeAccessSrc Existing access of sSrc1
768   * @return
769   */
770  public static String testAndChangeAccess(char modeAccessDst, String sSrc1, char modeAccessSrc)
771  { String sAccessParam;
772    if(modeAccessSrc == modeAccessDst || modeAccessSrc == '?' || modeAccessDst == '?' ) {
773      sAccessParam = sSrc1;
774    } else if("&".indexOf(modeAccessSrc)>=0 && "*~".indexOf(modeAccessDst)>=0) {
775      sAccessParam = " (" + sSrc1 + ".ref)";
776    } 
777    else if(modeAccessSrc == '@'){
778      switch(modeAccessDst){
779      case '@': sAccessParam = sSrc1; break;
780      case '*': case '~': sAccessParam = "REFJc(" + sSrc1 + ")"; break;
781      case '$': sAccessParam = "*(REFJc(" + sSrc1 + "))"; break;
782      default: sAccessParam = sSrc1; assert(false);
783      }
784    }
785    else if(modeAccessSrc == 'Q'){  //non-headed embedded array: int x[20] 
786      switch(modeAccessDst){
787        case 'P': case '*': sAccessParam = "&" + sSrc1 + "[0]"; break;  //pointer to first element
788        //case 'M': sAccessParam = "build_MemC( &" + sSrc1 + "[0], sizeof( " + sSrc1 + " ))"; break;  //pointer to first element
789        case 'M': sAccessParam = sSrc1; break;  //pointer and length initializer.
790        default: sAccessParam = sSrc1; 
791        throw new IllegalArgumentException("cannot assign access-type '" + modeAccessDst 
792                + "' to access-type '" + modeAccessSrc + "'. Hint: @Java2C-Annotation to the elements correct?");
793      }
794    }
795    
796    
797    else if("*~&".indexOf(modeAccessSrc)>=0 && "%$".indexOf(modeAccessDst)>=0) {
798      sAccessParam = "* (" + sSrc1 + ")";
799    } else if("%$".indexOf(modeAccessSrc)>=0 && "@*~&".indexOf(modeAccessDst) >=0){
800      sAccessParam = "& (" + sSrc1 + ")";
801    } else if("*~&".indexOf(modeAccessSrc)>=0 && "*~&".indexOf(modeAccessDst) >=0){
802      /**Reference and this-reference are compatible. */
803      sAccessParam = sSrc1;
804    } else if("%$t".indexOf(modeAccessSrc)>=0 && "%$t".indexOf(modeAccessDst) >=0){
805      /**embedded or primitive type are not different. */
806      sAccessParam = sSrc1;
807    } else if(false && "%$t".indexOf(modeAccessSrc)>=0 && "X".indexOf(modeAccessDst) >=0){
808      /**embedded or primitive type get from an array. */
809      sAccessParam = sSrc1 + "->data[] /*TODO*/";
810    } else if(false && "X".indexOf(modeAccessSrc)>=0 && "$".indexOf(modeAccessDst) >=0){
811      /**embedded or primitive type get from an array. */
812      sAccessParam = sSrc1 + "->data[] /*TODO1*/";
813    } 
814    else {
815      //assert(false);
816        sAccessParam = sSrc1 + "/*J2C-error testAndChangeAccess: " + modeAccessSrc + modeAccessDst + "*/";
817      //sAccessParam = null;
818    } 
819    return sAccessParam;
820  }
821  
822  
823  
824  private String xxxtestAndcast(ClassData srcType, String value)
825  { String sRet;
826    if( value.equals("null"))
827    { //a null-pointer should be compatible with all expect StringJc.
828      if(typeClazz.sClassNameC.equals("StringJc")
829        && dimensionArrayOrFixSize == 0
830        )
831      { 
832        sRet = "null_StringJc"; }
833      else {
834        sRet = value; } 
835    }
836    else
837    { //TODO may be some array tests
838      
839      sRet = typeClazz.xxxtestAndcast(srcType, value, '.');
840    }
841    return sRet;    
842  }
843
844
845  /**builds a String representation especially to test under eclipse. */
846  @Override
847  public String toString()
848  { String sRet = typeClazz.getClassIdentName() + " " + sName + " " + nClassLevel + nOuterLevel + modeAccess + "[" + modeArrayElement + "]" + modeStatic + nClassLevel + nOuterLevel
849           + (declaringClazz != null ? declaringClazz.sClassNameC : " -stacklocal");
850    return sRet;
851  }
852
853
854  
855  
856  /**It's a debug helper. The method is empty, but it is a mark to set a breakpoint. */
857  void stop()
858  { //debug
859  }
860
861
862
863  
864
865}