/** * Emits C header code for the FSM map. * * @param map emit Groovy code for this map. */ public void visit(SmcMap map) { String packageName = map.getFSM().getPackage(); String context = map.getFSM().getContext(); String mapName = map.getName(); // If a package has been specified, if (packageName != null && packageName.length() > 0) { context = packageName + "_" + context; } for (SmcState state : map.getStates()) { _source.print("extern const struct "); _source.print(context); _source.print("State "); if (packageName != null && packageName.length() > 0) { _source.print(packageName); _source.print("_"); } _source.print(mapName); _source.print("_"); _source.print(state.getInstanceName()); _source.println(";"); } return; } // end of visit(SmcMap)
/** * Emits C header code for the finite state machine. * * @param fsm emit Groovy code for this finite state machine. */ public void visit(SmcFSM fsm) { String targetfileCaps; String packageName = fsm.getPackage(); String context = fsm.getContext(); String fsmClassName = fsm.getFsmClassName(); String startStateName = fsm.getStartState(); String cState; List<SmcTransition> transList; List<SmcParameter> params; int index; _source.println("/*"); _source.println(" * ex: set ro:"); _source.println(" * DO NOT EDIT."); _source.println(" * generated by smc (http://smc.sourceforge.net/)"); _source.print(" * from file : "); _source.print(_srcfileBase); _source.println(".sm"); _source.println(" */"); _source.println(); // If a package has been specified, if (packageName != null && packageName.length() > 0) { context = packageName + "_" + context; fsmClassName = packageName + "_" + fsmClassName; startStateName = packageName + "_" + startStateName; } // The first two lines in the header file should be: // // #ifndef _<source file name>_H // #define _<source file name>_H // // where the source file name is all in caps. // The last line is: // // #endif // // Make the file name upper case and replace // slashes with underscores. targetfileCaps = _targetfileBase.replace('\\', '_'); targetfileCaps = targetfileCaps.replace('/', '_'); targetfileCaps = targetfileCaps.toUpperCase(); _source.print("#ifndef _"); _source.print(targetfileCaps); _source.println("_H"); _source.print("#define _"); _source.print(targetfileCaps); _source.println("_H"); // Include required standard .h files. _source.println(); _source.println("#include <assert.h>"); if (_debugLevel >= DEBUG_LEVEL_0) { _source.println("#define STATEMAP_DEBUG 1"); } _source.println("#include <statemap.h>"); _source.println(); // Do user-specified forward declarations now. for (String declaration : fsm.getDeclarations()) { _source.print(declaration); _source.println(); } // Forward declare the application class. _source.println(); _source.print("struct "); _source.print(context); _source.println(";"); _source.print("struct "); _source.print(fsmClassName); _source.println(";"); // Declare user's base state class. _source.println(); _source.print("struct "); _source.print(context); _source.println("State {"); // Add the default Entry() and Exit() definitions. if (fsm.hasEntryActions() == true) { _source.print(" void(*Entry)(struct "); _source.print(fsmClassName); _source.println(" *const fsm);"); } if (fsm.hasExitActions() == true) { _source.print(" void(*Exit)(struct "); _source.print(fsmClassName); _source.println(" *const fsm);"); } // Print out the default definitions for all the // transitions. First, get the transitions list. transList = fsm.getTransitions(); // Output the global transition declarations. for (SmcTransition trans : transList) { // Don't output the default state here. if (trans.getName().equals("Default") == false) { _source.print(" void(*"); _source.print(trans.getName()); _source.print(")(struct "); _source.print(fsmClassName); _source.print(" *const fsm"); params = trans.getParameters(); for (SmcParameter param : params) { _source.print(", "); _source.print(param.getType()); _source.print(" "); _source.print(param.getName()); } _source.println(");"); } } _source.print(" void(*Default)(struct "); _source.print(fsmClassName); _source.println(" *const fsm);"); _source.println(" STATE_MEMBERS"); // The base class has been defined. _source.println("};"); _source.println(); // Generate the map classes. The maps will, in turn, // generate the state classes. for (SmcMap map : fsm.getMaps()) { map.accept(this); } // Generate the FSM context class. _source.println(); _source.print("struct "); _source.print(fsmClassName); _source.println(" {"); _source.print(" struct "); _source.print(context); _source.println(" *_owner;"); _source.print(" FSM_MEMBERS("); _source.print(context); _source.println(")"); // Put the closing brace on the context class. _source.println("};"); _source.println(); // The state name "map::state" must be changed to // "map_state". if ((index = startStateName.indexOf("::")) >= 0) { cState = startStateName.substring(0, index) + "_" + startStateName.substring(index + 2); } else { cState = startStateName; } _source.print("#ifdef NO_"); _source.print(targetfileCaps); _source.println("_MACRO"); // Constructor _source.print("extern void "); _source.print(fsmClassName); _source.print("_Init"); _source.print("(struct "); _source.print(fsmClassName); _source.print(" *const fsm, struct "); _source.print(context); _source.println(" *const owner);"); // EnterStartState method. if (fsm.hasEntryActions() == true) { _source.print("extern void "); _source.print(fsmClassName); _source.print("_EnterStartState(struct "); _source.print(fsmClassName); _source.println(" *const fsm);"); } // Generate a method for every transition in every map // *except* the default transition. for (SmcTransition trans : transList) { if (trans.getName().equals("Default") == false) { _source.print("extern void "); _source.print(fsmClassName); _source.print("_"); _source.print(trans.getName()); _source.print("(struct "); _source.print(fsmClassName); _source.print(" *const fsm"); params = trans.getParameters(); for (SmcParameter param : params) { _source.print(", "); _source.print(param.getType()); _source.print(" "); _source.print(param.getName()); } _source.println(");"); } } _source.println("#else"); // Constructor _source.print("#define "); _source.print(fsmClassName); _source.println("_Init(fsm, owner) \\"); _source.print(" FSM_INIT((fsm), &"); _source.print(cState); _source.println("); \\"); _source.println(" (fsm)->_owner = (owner)"); // EnterStartState method. if (fsm.hasEntryActions() == true) { _source.println(); _source.print("#define "); _source.print(fsmClassName); _source.println("_EnterStartState(fsm) \\"); _source.println(" ENTRY_STATE(getState(fsm))"); } // Generate a method for every transition in every map // *except* the default transition. for (SmcTransition trans : transList) { if (trans.getName().equals("Default") == false) { _source.println(); _source.print("#define "); _source.print(fsmClassName); _source.print("_"); _source.print(trans.getName()); _source.print("(fsm"); params = trans.getParameters(); for (SmcParameter param : params) { _source.print(", "); _source.print(param.getName()); } _source.println(") \\"); _source.println(" assert(getState(fsm) != NULL); \\"); _source.print(" setTransition((fsm), \""); _source.print(trans.getName()); _source.println("\"); \\"); _source.print(" getState(fsm)->"); _source.print(trans.getName()); _source.print("((fsm)"); for (SmcParameter param : params) { _source.print(", ("); _source.print(param.getName()); _source.print(")"); } _source.println("); \\"); _source.println(" setTransition((fsm), NULL)"); } } _source.println("#endif"); _source.println(); _source.println("#endif"); _source.println(); _source.println("/*"); _source.println(" * Local variables:"); _source.println(" * buffer-read-only: t"); _source.println(" * End:"); _source.println(" */"); return; } // end of visit(SmcFSM)