GithubHelp home page GithubHelp logo

jp-embedded / scxmlcc Goto Github PK

View Code? Open in Web Editor NEW
131.0 131.0 33.0 24.93 MB

The SCXML state machine to C++ compiler

License: GNU General Public License v3.0

C 0.52% C++ 87.51% Makefile 4.67% XSLT 1.79% Shell 0.41% Batchfile 0.62% CMake 4.49%

scxmlcc's People

Contributors

aboseley avatar jp-embedded avatar marcel-behlau-elfin avatar ringlej avatar sstiller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scxmlcc's Issues

LCA?

In the README.md, you mention LCA:

LCA calculation is done (mostly) compile time.

I've been trying to figure out what is meant by LCA... Do you mean LCCA (Least Common Compound Ancestor) that is mentioned in https://www.w3.org/TR/scxml/#LCCA ?

Undeclared event on <raise>

If a signal is triggered with <raise>, but it has no matching transition in the SM, it leads to a compile error.

The solution should be similar to the fix for #69

Example:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="raise" datamodel="cplusplus">
    <state id="State_1">
        <onentry>
            <raise event="ev1"/>
        </onentry>
    </state>
</scxml>

Result:

raise.h: In member function ‘void sc_raise::state_actions<C>::enter(sc_raise::data_model&) [with C = sc_raise::state_State_1]::with::operator()()’:
raise.h:163:46: error: ‘event_ev1’ is not a member of ‘sc_raise::state’
   event_queue.emplace_back(&sc_raise::state::event_ev1);
                                              ^~~~~~~~~

sc.get_state

Could you give me a example about get_state,this function has a "public" in class sc, how can i use it to get the current state,thanks

Licensing issue

The README mentions that "However, the generated state machine code is not covered by license." What does that mean. Does this mean that the generated code's license is up to the user? He can license the way he wants.
or the user needs to obtain some special license if his code is not going to be open source.

Adding event payloads

This is a suggestion for improvement:

It would be nice if it was possible to pass additional data when dispatching an event. I currently get around this by placing data in the user_model area, but it complicates control of the access in a multi-threaded environment. It would be much simpler if one could pass payload data alongside the event instance when firing events.

fix version

scxmlcc version should be generated equally on windows/linux with make and cmake

note from pull request 55:
Well the version is/should be the same on windows and unix. The thing is, the autorevision tool is currently not used on windows and therefore the postfix part of the version is currently left out on windows (in version.cpp) - I am mainly using linux. If it is possible to use the autorevision tool on windows I think that would be the best solution since autorevision is a more generic way of doing it. Anyway, the goal must be to use the same method on windows/unix/make/cmake. Note that the current method will work also when build from a zip file or even if the source is checked out using subversion.

if condition of all transitions evaluates to false, search parent

if condition of all transitions evaluates to false, search parent

For each atomic state , find a transition whose 'event' attribute matches event 
and whose condition evaluates to true. If multiple matching transitions are 
present, take the first in document order. If none are present, search in the 
state's ancestors in ancestry order until one is found. 

Original issue reported on code.google.com by [email protected] on 9 Jan 2015 at 3:54

datamodel does not support custom structures "natively" (but some workaround is available)

It seems impossible to put your own type for the entries - float, std::vector, some custom structure (#include "custom_struct.h" prior to), etc.
Data in SCXML like that:

  <!--  trivial 5 second microwave oven example -->
  <datamodel>
    <data id="cook_time" expr="5"/>
    <data id="door_closed" expr="true"/>
    <data id="timer" expr="0"/>
  </datamodel>

produce the following snippet:

//...
  int cook_time;
  int door_closed;
  int timer;
  data_model() : cook_time(5), door_closed(true), timer(0) {}
//...

Is it known to fixing it or how to workaround it in a different way?

For example if have something like that:

  <!--  trivial 5 second microwave oven example -->
  <datamodel>
    <data id="CustomStruct1 cust" expr=""/>
    <data id="float flt" expr="0.5"/>
  </datamodel>

how the output will become (or anything compilable close to):

//...
  #include "<path_to_my_custom_header.h>"
  CustomStruct1 cust;
  float flt;
  data_model() : cust(), flt(0.5) {}
//...

New feature: setting the initial state when instantiating the state machine

I'm trying to implement a persistent state machine. One of the requirements is on powerup the state machine goes straight into the last saved state, without any on-entry actions being invoked. Looking into the implementation, I can't see how this can be done with scxmlcc generated state machine directly.

I can think of work-arounds, but it would greatly simplify things if the state machine constructor could accept the initial state as a parameter.

Forward declaration of `sc_XXX::user_model `

I have a problem with the type of data_model::user:

  • There is (only) a forward declaration for the type user_model - and it can not be fully declared by a user
  • To use it, an ugly reinterpret_cast must be used in the constructor of the state machine

Wouldn't it be better to use void* user, as done in other libraries?

validate <inital> child transition

Note that the child transition must not contain cond or event attributes, and must specify a target whose value is state(s) consisting solely of descendants of the containing state

Prevent use of RTTI

At least for non-parallel machines.

To avoid the RTTI overhead on eg embedded systems

Feature: user-defined log function

What do you think about a logging function, defined by the user?
In my case the logs of the state machine do not fit into the logging concept. The logs shall be sent to stderr or to a logging server depending on the current log level.
Before I add something, I'd like to know what other people think about it.

  • How can a user implement it
  • Should a fallback be added if the user doesn't implement it
  • Other ideas?

contact

The readme.md you write:

For a chat, you can also write to me on messenger here

Just wondering if this is still valid?

Incorrect processing of <script> content

The text inside <script> ... </script> is modified resulting in uncompilable code.
Example:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="script">
    <state id="State_1">
        <onentry>
            <script>auto str = new std::string(&quot;Hello&quot;);
str-&gt;append(&quot; world&quot;);
std::cout &lt;&lt; *str &lt;&lt; '\n';
delete str;</script>
        </onentry>
    </state>
    <script>#include &lt;iostream&gt;</script>
</scxml>

In the generated code, the text str-&gt;append is replaced by str_>append instead of str->append

Parallel: Undeclared event used if child of <parallel> contains a final state

Compiler error:

parallel.h: In member function ‘void sc_parallel::state_P1::parallel_enter_final(sc_parallel::data_model&)’:
parallel.h:268:98: error: ‘event_done_state_P1’ is not a member of ‘sc_parallel::state’
   void parallel_enter_final(data_model &m) { if (++m.finals.P1 == 2) m.event_queue.emplace_back(&sc_parallel::state::event_done_state_P1), parent_t::parallel_enter_final(m); }

Example scxml:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="parallel" initial="P1">
    <parallel id="P1">
        <state id="P1S1">
            <onentry/>
            <onexit/>
            <state id="P1S11">
                <onentry/>
                <transition type="external" event="ev" target="P1S11"/>
            </state>
        </state>
        <state id="P1S2">
            <onentry/>
            <state id="P1S21">
                <onentry/>
                <onexit/>
                <transition type="external" event="ev" target="Final"/>
            </state>
            <onexit/>
            <final id="Final">
            </final>
        </state>
        <onentry/>
        <transition type="external" event="ev2" target="S1">
        </transition>
        <onexit/>
    </parallel>
    <state id="S1">
        <onentry/>
    </state>
</scxml>

SCXML supported elements

Hi,

First, thank you for sxcmlcc, it is a great tool!

I was wondering if you could document what scxml tags are currently implemented. In particular I am interested in the following

  • defining actions in the SCXML document
  • defining the user data model in SCXML
  • actions during transitions

Thanks

Christophe

bad naming for eventless transitions

'sc::state::unconditional' is bad naming. The transition is not unconditional, but eventless. Consider to change this to for example 'sc::state::eventless' or 'sc::state::none'

"example/hello_world.cpp" error pops up

when compiling the project "example/hello_world.cpp" error pops up:

Error[Pe1449]: explicit specialization of function "sc_hello_world::state_actions::enter [with C=sc_hello_world::state_hello]" must precede its first use

cmake compilation error

Using the latest release, 0.8.7 the cmake compilation fails with:

CMake Error at src/test/CMakeLists.txt:6 (add_subdirectory):
The source directory

/home/marius/kit/scxmlcc-0.8.7/src/test/gtest

does not contain a CMakeLists.txt file.

Support for invoke attribute

Hello, hope that the invoker attribute of external interaction can be added later.
It is decided that this is also one of the basic functions
Thanks

Build breaks if gtest is found

I get the following error when building

 cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
ma-- Detecting CXX compile features - done
k-- Boost version: 1.58.0
-- Found the following Boost libraries:
--   filesystem
--   system
--   program_options
eCMake Error at src/test/CMakeLists.txt:6 (add_subdirectory):
  The source directory

    /home/jdamon/Downloads/scxmlcc/src/test/gtest

  does not contain a CMakeLists.txt file.


-- Configuring incomplete, errors occurred!

If I run

touch  ../src/test/gtest/CMakeLists.txt
nice build (master)% cmake ..
-- Boost version: 1.58.0
-- Found the following Boost libraries:
--   filesystem
--   system
--   program_options
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jdamon/Downloads/scxmlcc/build
nice build (master)% make
[  1%] Generating ../version_auto.h
...

Then it works

Building the project

Hello,

I've downloaded the project and all of the required libraries, but when I tried to build it I got the following errors:

autorevision -tsh > autorevision.mk && sh makerevision.sh || truncate -s0 autorevision_postfix.h
warning: Counting the number of revisions may be slower due to an outdated git version less than 1.7.2.3. If something breaks, please update it.
g++ -Wall -O2 -MD -MP -c -o main.o main.cpp
main.cpp: In function ‘void scxmlcc(const options&)’:
main.cpp:41: error: ‘struct std::basic_string<char, std::char_traits, std::allocator >’ has no member named ‘string’
main.cpp:44: error: ‘const struct boost::filesystem::path’ has no member named ‘c_str’
main.cpp: In function ‘int main(int, char*)’:
main.cpp:69: error: ‘cerr’ was not declared in this scope
main.cpp:86: error: ‘cout’ was not declared in this scope
main.cpp:108: error: ‘cout’ was not declared in this scope
main.cpp:117: error: ‘cerr’ was not declared in this scope
make: *
* [main.o] Error 1

Parallel: Wrong transition executed

If a parallel state and one of its descendants have a transition with the same event, the wrong transition is executed.

At least I understand the algorithm in this way:

  • selectTransitions(event) selects both transitions and calls removeConflictingTransitions
  • removeConflictingTransitions removes the transition with the source P1 because P1S1S1 is a descendant of P1
  • The left transition (source P1S1S1) is executed.

Behavior of the state machine generated by scxmlcc:

  • The transition (source P1) is executed.

The SCXML code:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="parallelevent">
    <parallel id="P1">
        <state id="P1S1">
            <state id="P1S1S1">
                <transition type="external" event="ev1" target="P1S1S2"/>
            </state>
            <state id="P1S1S2">
            </state>
        </state>
        <state id="P1S2">
            <state id="P1S2S1">
            </state>
        </state>
        <transition type="external" event="ev1" target="Final_1"/>
    </parallel>
    <final id="Final_1">
    </final>
</scxml>

Test program:

#include <iostream>
#include "parallelevent.h"

using namespace std;
typedef sc_parallelevent sc;

int main(int argc, char *argv[])
{
  sc sc;
  sc.init();
  std::clog << "event here\n";
  sc.dispatch("ev1");
  return 0;
}

scxmlcc command line:
scxmlcc -d clog --cpp14 --stringevents -o parallelevent.h parallelevent.scxml

log:

$ ./parallelevent 
sc_parallelevent: transition [initial] sc_parallelevent::scxml -> sc_parallelevent::state_P1
sc_parallelevent: enter sc_parallelevent::state_P1
sc_parallelevent: transition [initial] sc_parallelevent::state_P1 -> sc_parallelevent::state_P1S1
sc_parallelevent: enter sc_parallelevent::state_P1S1
sc_parallelevent: enter sc_parallelevent::state_P1S2
sc_parallelevent: transition [initial] sc_parallelevent::state_P1S2 -> sc_parallelevent::state_P1S2S1
sc_parallelevent: enter sc_parallelevent::state_P1S2S1
sc_parallelevent: transition [initial] sc_parallelevent::state_P1S1 -> sc_parallelevent::state_P1S1S1
sc_parallelevent: enter sc_parallelevent::state_P1S1S1
event here
sc_parallelevent: transition [event_ev1] sc_parallelevent::state_P1 -> sc_parallelevent::state_Final_1
sc_parallelevent: exit sc_parallelevent::state_P1S1S1
sc_parallelevent: exit sc_parallelevent::state_P1S1
sc_parallelevent: exit sc_parallelevent::state_P1S2S1
sc_parallelevent: exit sc_parallelevent::state_P1S2
sc_parallelevent: exit sc_parallelevent::state_P1
sc_parallelevent: enter sc_parallelevent::state_Final_1

GCC warns about extra ;

Hello,

In cpp_output.cpp, there is the following code (line 887):

// new_state
out << tab << "template<class T> T* new_state()" << endl;
out << tab << '{' << endl;
out << tab << tab << "static T t;" << endl;
out << tab << tab << "return &t;" << endl;
out << tab << "};" << endl;

out << "};" << endl;
out << endl;

The last ; is not necessary. GCC warns about this extra ; if the -Wpedantic option is used.
Is there any good reason not to remove it?

Best regards,
Bktero

Not building from tar (version issue)

Probably related to #56

I can't build scxmlcc using tar package. It is failing on Generating ../version_auto.h.

Steps to reproduce:

wget https://github.com/jp-embedded/scxmlcc/archive/0.9.tar.gz
tar axf 0.9.tar.gz
mkdir build && cd build
cmake ../scxmlcc-0.9
make

Output:

$ make
[ 16%] Generating ../version_auto.h
error: No repo or cache detected.
src/CMakeFiles/scxmlcc.dir/build.make:61: recipe for target 'version_auto.h' failed
make[2]: *** [version_auto.h] Error 1
CMakeFiles/Makefile2:85: recipe for target 'src/CMakeFiles/scxmlcc.dir/all' failed
make[1]: *** [src/CMakeFiles/scxmlcc.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

Tested on ubutnu 16.04 and 18.04.

support for multiple transitions for same event

support for multiple transitions for same event:

For each atomic state , find a transition whose 'event' attribute matches event 
and whose condition evaluates to true. If multiple matching transitions are 
present, take the first in document order. If none are present, search in the 
state's ancestors in ancestry order until one is found. 

Original issue reported on code.google.com by [email protected] on 9 Jan 2015 at 3:45

Wrong behaviour with multiple parallel states

Some states (children of parallel) are left if another parallel state is entered.

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="multiparallel" initial="P1">
    <parallel id="P1">
        <state id="P1S1">
        </state>
        <parallel id="P1P1">
            <state id="P1P1S1">
            </state>
            <state id="P1P1S2">
            </state>
        </parallel>
    </parallel>
</scxml>

C++ code:

#include "multi-parallel.h"

int main(int argc, char *argv[])
{
	sc_multiparallel sc;
	sc.init();

	return 0;
}

On start, all the states should be active, but as you can see, when entering P1P1S1, the state P1S1 is left:

sc_multiparallel: transition [initial] sc_multiparallel::scxml -> sc_multiparallel::state_P1
sc_multiparallel: enter sc_multiparallel::state_P1
sc_multiparallel: transition [initial] sc_multiparallel::state_P1 -> sc_multiparallel::state_P1S1
sc_multiparallel: enter sc_multiparallel::state_P1S1
sc_multiparallel: enter sc_multiparallel::state_P1P1
sc_multiparallel: transition [initial] sc_multiparallel::state_P1P1 -> sc_multiparallel::state_P1P1S1
sc_multiparallel: exit sc_multiparallel::state_P1S1
sc_multiparallel: enter sc_multiparallel::state_P1P1S1
sc_multiparallel: enter sc_multiparallel::state_P1P1S2

Version is bad

Hello,

version.h contains 0.8.3 in both master/head and tag for version 0.8.5. I guess this is obviously wrong ;)

Best regards,
Bktero

Error on empty <raise>

If empty <raise/> actions exist in the document, scxmlcc gives up:
error: parse_raise: No such node (<xmlattr>)
The same problem seems to exist for other elements, too.
See also #62

Example:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="raise_err" initial="State_1">
    <state id="State_1">
        <onentry>
            <raise/>
        </onentry>
    </state>
</scxml>

cmake build fails in gtest

@aboseley I'm trying to use the cmake build procedure you added. I'm getting the following error:

$ cmake ..
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.66.0
-- Found the following Boost libraries:
--   filesystem
--   system
--   program_options
CMake Error at src/test/CMakeLists.txt:6 (add_subdirectory):
  The source directory

    /home/jringle-admin/git/scxmlcc/src/test/gtest

  does not contain a CMakeLists.txt file.


-- Configuring incomplete, errors occurred!
See also "/home/jringle-admin/git/scxmlcc/build/CMakeFiles/CMakeOutput.log".

Are there instructions that can be added to the getting-started.md to properly populate src/test/gtest/?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.