+
+ void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
+ generateOptionalHeader(headers);
+ //GENERATE STRUCTS
+ output.println("#include \"optionalstruct.h\"\n\n");
+ output.println("#include \"stdlib.h\"\n");
+
+ HashSet processedcd = new HashSet();
+ int maxotd=0;
+ Enumeration e = safeexecution.keys();
+ while (e.hasMoreElements()) {
+ int numotd=0;
+ //get the class
+ ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
+ Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
+
+ //Generate the struct of optionals
+ Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
+ numotd = c_otd.size();
+ if(maxotd<numotd) maxotd = numotd;
+ if( !c_otd.isEmpty() ){
+ for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
+ OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
+
+ //generate the int arrays for the predicate
+ Predicate predicate = otd.predicate;
+ int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
+ TreeSet<Integer> fsset=new TreeSet<Integer>();
+ //iterate through possible FSes corresponding to
+ //the state when entering
+
+ for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();){
+ FlagState fs = (FlagState)fses.next();
+ int flagid=0;
+ for(Iterator flags = fs.getFlags(); flags.hasNext();){
+ FlagDescriptor flagd = (FlagDescriptor)flags.next();
+ int id=1<<((Integer)flaginfo.get(flagd)).intValue();
+ flagid|=id;
+ }
+ fsset.add(new Integer(flagid));
+ //tag information not needed because tag
+ //changes are not tolerated.
+ }
+
+ output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+ boolean needcomma=false;
+ for(Iterator<Integer> it=fsset.iterator();it.hasNext();) {
+ if(needcomma)
+ output.print(", ");
+ output.println(it.next());
+ }
+
+ output.println("};\n");
+
+
+ //generate optionaltaskdescriptor that actually
+ //includes exit fses, predicate and the task
+ //concerned
+ output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+ output.println("&task_"+otd.td.getSafeSymbol()+",");
+ output.println("/*index*/"+otd.getIndex()+",");
+ output.println("/*number of enter flags*/"+fsset.size()+",");
+ output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+ output.println("/*number of members */"+predicateindex+",");
+ output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+ output.println("};\n");
+ }
+ } else
+ continue;
+ // if there are no optionals, there is no need to build the rest of the struct
+
+ output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
+ c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
+ if( !c_otd.isEmpty() ){
+ boolean needcomma=false;
+ for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
+ OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
+ if(needcomma)
+ output.println(",");
+ needcomma=true;
+ output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+ }
+ }
+ output.println("};\n");
+
+ //get all the possible flagstates reachable by an object
+ Hashtable hashtbtemp = safeexecution.get(cdtemp);
+ int fscounter = 0;
+ TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
+ fsts.addAll(hashtbtemp.keySet());
+ for(Iterator fsit=fsts.iterator();fsit.hasNext();) {
+ FlagState fs = (FlagState)fsit.next();
+ fscounter++;
+
+ //get the set of OptionalTaskDescriptors corresponding
+ HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
+ //iterate through the OptionalTaskDescriptors and
+ //store the pointers to the optionals struct (see on
+ //top) into an array
+
+ output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
+ for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();){
+ OptionalTaskDescriptor mm = mos.next();
+ if(!mos.hasNext())
+ output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
+ else
+ output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+ }
+
+ output.println("};\n");
+
+ //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
+
+ int flagid=0;
+ for(Iterator flags = fs.getFlags(); flags.hasNext();){
+ FlagDescriptor flagd = (FlagDescriptor)flags.next();
+ int id=1<<((Integer)flaginfo.get(flagd)).intValue();
+ flagid|=id;
+ }
+
+ //process tag information
+
+ int tagcounter = 0;
+ boolean first = true;
+ Enumeration tag_enum = fs.getTags();
+ output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
+ while(tag_enum.hasMoreElements()){
+ tagcounter++;
+ TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
+ if(first==true)
+ first = false;
+ else
+ output.println(", ");
+ output.println("/*tagid*/"+state.getTagId(tagd));
+ }
+ output.println("};");
+
+ Set<TaskIndex> tiset=sa.getTaskIndex(fs);
+ for(Iterator<TaskIndex> itti=tiset.iterator();itti.hasNext();) {
+ TaskIndex ti=itti.next();
+ if (ti.isRuntime())
+ continue;
+
+ Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
+
+ output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
+ boolean needcomma=false;
+ for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator();otdit.hasNext();) {
+ OptionalTaskDescriptor otd=otdit.next();
+ if(needcomma)
+ output.print(", ");
+ needcomma=true;
+ output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+ }
+ output.println("};");
+
+ output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
+ output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
+ output.print(ti.getIndex()+", ");
+ output.print(otdset.size()+", ");
+ output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
+ output.println("};");
+ }
+
+ tiset=sa.getTaskIndex(fs);
+ boolean needcomma=false;
+ int runtimeti=0;
+ output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
+ for(Iterator<TaskIndex> itti=tiset.iterator();itti.hasNext();) {
+ TaskIndex ti=itti.next();
+ if (ti.isRuntime()) {
+ runtimeti++;
+ continue;
+ }
+ if (needcomma)
+ output.print(", ");
+ needcomma=true;
+ output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
+ }
+ output.println("};\n");
+
+ //Store the result in fsanalysiswrapper
+
+ output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
+ output.println("/*flag*/"+flagid+",");
+ output.println("/* number of tags*/"+tagcounter+",");
+ output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+ output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
+ output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+ output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
+ output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
+ output.println("};\n");
+
+ }
+
+ //Build the array of fsanalysiswrappers
+ output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
+ boolean needcomma=false;
+ for(int i = 0; i<fscounter; i++){
+ if (needcomma) output.print(",");
+ output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
+ needcomma=true;