gv_fsm 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cdb522af0bd9bac3a853e75ad379b063657a6bd21ceb2fcad80c427ca6c00ed
4
- data.tar.gz: 350cd6c0dbdbe1e3ff03f8e26eda97b16be7764dc7f5c244a98b3e0997d50b3a
3
+ metadata.gz: 450afef3dccacff09f92f297a5b5bcbdfb9d1c960bea0d546bcafe7123f5cebd
4
+ data.tar.gz: 1fa684d748abecd8c8f17ac2a2b7ca17c83506003eb2cc143596668a32d0a1ea
5
5
  SHA512:
6
- metadata.gz: 2b623ee5a2d45345ff3ab13db5605ffa978b30add3b0ca912588d531fbf81f13b3f5a3210b02bbcee29e736115a10b936201e57828635d81c9c2c82eec869e74
7
- data.tar.gz: bc2584dfcc1025b41499bc66ff85113eb2b440031467e1ac74a44450717cc48850cc4c35cfe8594262b59ac6d3e0164c766f439aa9f8eaf6e36e6cdc790262d9
6
+ metadata.gz: 98d883a1bff3afaae6fe1531a8f702b6600c97bd37fa4260b3eef02ecccfaf978ab3a9acc096a0c62d9d95c2b4450df105a5cc38f1a03f624984813c9ac5bcb9
7
+ data.tar.gz: 20af124b281a5aeba975d5124c4a552480d03ea9d4cb13903f4c60f3408c28876adf12a040455dd48afb98ebed8dedb0ee65121e6e93e0d3c9d854a43e4fea57
data/bin/gv_fsm CHANGED
@@ -36,12 +36,17 @@ OptionParser.new do |parser|
36
36
  options[:header] = false
37
37
  end
38
38
 
39
+ parser.on("-x", "--prefix PREFIX", "Prepend PREFIX to names of generated functions and objects") do |p|
40
+ sm.prefix = p
41
+ end
42
+
39
43
  end.parse!
40
44
 
41
45
  raise ArgumentError, "I need the path to a Graphviz file!" unless ARGV[0]
42
46
  raise ArgumentError, "#{ARGV[0]} does not look like a Graphviz file!" unless File.extname(ARGV[0]) == ".dot"
43
47
 
44
48
  sm.parse(ARGV[0])
49
+
45
50
  puts "Parsed #{sm.dotfile}.\nGenerating C stub for states: #{sm.states_list.join(", ")}."
46
51
  if options[:header] then
47
52
  sm.generate_h
@@ -8,14 +8,19 @@ require File.expand_path("../version.rb", __FILE__)
8
8
 
9
9
  module GV_FSM
10
10
  class FSM
11
- attr_reader :states, :transitions, :dotfile
11
+ attr_reader :states, :transitions, :dotfile, :prefix
12
12
  attr_accessor :project_name, :description, :cname
13
13
  include GV_FSM::Templates
14
14
 
15
15
  def initialize(filename = nil)
16
+ @prefix = ""
16
17
  parse(filename) if filename
17
18
  end
18
19
 
20
+ def prefix=(v)
21
+ @prefix = v + '_'
22
+ end
23
+
19
24
  def parse(filename)
20
25
  raise ArgumentError, "File must be in .dot format" unless File.extname(filename) == ".dot"
21
26
  @cname = File.basename(filename, ".dot") unless (@cname and ! @cname.empty?)
@@ -26,7 +31,7 @@ module GV_FSM
26
31
  g.each_node do |id|
27
32
  n = g.get_node(id)
28
33
  label = n[:label].source.empty? ? "do_#{id}" : n[:label].source
29
- @states << {id: id, function: label}
34
+ @states << {id: id, function: @prefix+label}
30
35
  end
31
36
  g.each_edge do |e|
32
37
  from = e.node_one
@@ -40,7 +45,7 @@ module GV_FSM
40
45
  else
41
46
  label = e[:label].source
42
47
  end
43
- @transitions << {from: from, to: to, function: label}
48
+ @transitions << {from: from, to: to, function: label ? @prefix+label : nil}
44
49
  end
45
50
  end
46
51
  end
@@ -3,63 +3,64 @@ module GV_FSM
3
3
  module Templates
4
4
  HEADER =<<~EOHEADER
5
5
  // Finite State Machine
6
- // Project: <%= self.project_name or self.dotfile %>
7
- // Description: <%= self.description or "<none given>" %>
6
+ // Project: <%= @project_name or @dotfile %>
7
+ // Description: <%= @description or "<none given>" %>
8
8
  //
9
9
  // Generated by gv_fsm ruby gem, see https://rubygems.org/gems/gv_fsm
10
10
  // gv_fsm version <%= GV_FSM::VERSION %>
11
11
  // Generation date: <%= Time.now %>
12
- // Generated from: <%= self.dotfile %>
12
+ // Generated from: <%= @dotfile %>
13
13
  // The finite state machine has:
14
- // <%= self.states.count %> states
15
- // <%= self.transitions.count %> transitions
14
+ // <%= @states.count %> states
15
+ // <%= @transitions.count %> transitions
16
+ // <%= transition_functions_list.select {|e| e != 'NULL'}.count %> transition functions
16
17
 
17
18
  EOHEADER
18
19
 
19
20
  HH =<<~EOH
20
- #ifndef <%= self.cname.upcase %>_H
21
- #define <%= self.cname.upcase %>_H
21
+ #ifndef <%= @cname.upcase %>_H
22
+ #define <%= @cname.upcase %>_H
22
23
  #include <stdlib.h>
23
24
 
24
25
  // List of states
25
26
  typedef enum {
26
- <% self.states.each_with_index do |s, i| %>
27
- STATE_<%= s[:id].upcase %><%= i == 0 ? " = 0" : "" %>,
27
+ <% @states.each_with_index do |s, i| %>
28
+ <%= @prefix.upcase %>STATE_<%= s[:id].upcase %><%= i == 0 ? " = 0" : "" %>,
28
29
  <% end %>
29
- NUM_STATES,
30
- NO_CHANGE
30
+ <%= @prefix.upcase %>NUM_STATES,
31
+ <%= @prefix.upcase %>NO_CHANGE
31
32
  } state_t;
32
33
 
33
- const char *state_names[] = {<%= self.states_list.map {|sn| '"'+sn+'"'}.join(", ") %>};
34
+ const char *state_names[] = {<%= states_list.map {|sn| '"'+sn+'"'}.join(", ") %>};
34
35
 
35
36
  // State function and state transition prototypes
36
37
  typedef state_t state_func_t(void *data);
37
38
  typedef void transition_func_t(void *data);
38
39
 
39
40
  // state functions
40
- <% self.states.each do |s| %>
41
+ <% @states.each do |s| %>
41
42
  state_t <%= s[:function] %>(void *data);
42
43
  <% end %>
43
44
 
44
45
  // List of state functions
45
- state_func_t *const state_table[NUM_STATES] = {
46
- <%= self.state_functions_list.join(",\n ")%>
46
+ state_func_t *const <%= @prefix %>state_table[<%= @prefix.upcase %>NUM_STATES] = {
47
+ <%= state_functions_list.join(",\n ")%>
47
48
  };
48
49
 
49
- <% if self.transition_functions_list.count > 0 then %>
50
+ <% if transition_functions_list.count > 0 then %>
50
51
  // transition functions
51
- <% self.transition_functions_list.each do |t| %>
52
+ <% transition_functions_list.each do |t| %>
52
53
  <% next if t == "NULL" %>
53
54
  void <%= t %>(void *data);
54
55
  <% end %>
55
56
 
56
57
  // Table of transition functions
57
- transition_func_t *const transition_table[NUM_STATES][NUM_STATES] = {
58
- <% sl = self.states_list %>
59
- <% fw = self.transition_functions_list.max {|a, b| a.length <=> b.length}.length %>
60
- <% sw = self.states_list.max {|a, b| a.length <=> b.length}.length %>
58
+ transition_func_t *const <%= @prefix %>transition_table[<%= @prefix.upcase %>NUM_STATES][<%= @prefix.upcase %>NUM_STATES] = {
59
+ <% sl = states_list %>
60
+ <% fw = transition_functions_list.max {|a, b| a.length <=> b.length}.length %>
61
+ <% sw = states_list.max {|a, b| a.length <=> b.length}.length %>
61
62
  /* <%= "states:".ljust(sw) %> <%= sl.map {|e| e.ljust(fw) }.join(", ") %> */
62
- <% self.transitions_map.each_with_index do |l, i| %>
63
+ <% transitions_map.each_with_index do |l, i| %>
63
64
  /* <%= sl[i].ljust(sw) %> */ {<%= l.map {|e| e.ljust(fw)}.join(", ") %>},
64
65
  <% end %>
65
66
  };
@@ -68,14 +69,14 @@ module GV_FSM
68
69
  <% end %>
69
70
 
70
71
  // state manager
71
- state_t run_state(state_t cur_state, void *data);
72
+ state_t <%= @prefix %>run_state(state_t cur_state, void *data);
72
73
 
73
74
  #endif
74
75
  EOH
75
76
 
76
77
  CC =<<~EOC
77
78
  #include <syslog.h>
78
- #include "<%= self.cname %>.h"
79
+ #include "<%= @cname %>.h"
79
80
 
80
81
  // ____ _ _
81
82
  // / ___|| |_ __ _| |_ ___
@@ -89,12 +90,12 @@ module GV_FSM
89
90
  // | _| |_| | | | | (__| |_| | (_) | | | \\__ \\
90
91
  // |_| \\__,_|_| |_|\\___|\\__|_|\\___/|_| |_|___/
91
92
  //
92
- <% dest = self.destinations.dup %>
93
- <% self.states.each do |s| %>
93
+ <% dest = destinations.dup %>
94
+ <% @states.each do |s| %>
94
95
  <% stable = true if dest[s[:id]].include? s[:id] %>
95
- <% dest[s[:id]].map! {|n| "STATE_"+n.upcase} %>
96
+ <% dest[s[:id]].map! {|n| (@prefix+"STATE_"+n).upcase} %>
96
97
  <% if dest[s[:id]].empty? or stable then
97
- dest[s[:id]].unshift "NO_CHANGE"
98
+ dest[s[:id]].unshift @prefix.upcase+"NO_CHANGE"
98
99
  end %>
99
100
  // To be executed in state <%= s[:id] %>
100
101
  state_t <%= s[:function] %>(void *data) {
@@ -111,17 +112,17 @@ module GV_FSM
111
112
  break;
112
113
  default:
113
114
  syslog(LOG_WARNING, "[FSM] Cannot pass from <%= s[:id] %> to %s, remaining in this state", state_names[next_state]);
114
- next_state = NO_CHANGE;
115
+ next_state = <%= @prefix.upcase %>NO_CHANGE;
115
116
  }
116
117
  return next_state;
117
118
  }
118
119
 
119
120
  <% end %>
120
121
 
121
- <% if self.transition_functions_list.count > 0 then %>
122
+ <% if transition_functions_list.count > 0 then %>
122
123
  // _____ _ _ _
123
124
  // |_ _| __ __ _ _ __ ___(_) |_(_) ___ _ __
124
- // | || '__/ _` | '_ \\/ __| | __| |/ _ \\| '_ \\
125
+ // | || '__/ _` | '_ \\/ __| | __| |/ _ \\| '_ \\
125
126
  // | || | | (_| | | | \\__ \\ | |_| | (_) | | | |
126
127
  // |_||_| \\__,_|_| |_|___/_|\\__|_|\\___/|_| |_|
127
128
  //
@@ -132,10 +133,10 @@ module GV_FSM
132
133
  // |_| \\__,_|_| |_|\\___|\\__|_|\\___/|_| |_|___/
133
134
  //
134
135
 
135
- <% self.transition_functions_list.each do |t| %>
136
+ <% transition_functions_list.each do |t| %>
136
137
  <% next if t == "NULL" %>
137
138
  // This function is called in transitions:
138
- <% self.transitions_paths[t].each do |e| %>
139
+ <% transitions_paths[t].each do |e| %>
139
140
  // from <%= e[:from] %> to <%= e[:to] %>
140
141
  <% end %>
141
142
  void <%= t %>(void *data) {
@@ -148,7 +149,7 @@ module GV_FSM
148
149
 
149
150
  // ____ _ _
150
151
  // / ___|| |_ __ _| |_ ___
151
- // \\___ \\| __/ _` | __/ _ \\
152
+ // \\___ \\| __/ _` | __/ _ \\
152
153
  // ___) | || (_| | || __/
153
154
  // |____/ \\__\\__,_|\\__\\___|
154
155
  //
@@ -159,27 +160,27 @@ module GV_FSM
159
160
  // |_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_|
160
161
  // |___/
161
162
 
162
- state_t run_state(state_t cur_state, void *data) {
163
- state_t new_state = state_table[cur_state](data);
164
- <% if self.transition_functions_list.count > 0 then %>
165
- transition_func_t *transition = transition_table[cur_state][new_state];
163
+ state_t <%= @prefix %>run_state(state_t cur_state, void *data) {
164
+ state_t new_state = <%= @prefix %>state_table[cur_state](data);
165
+ <% if transition_functions_list.count > 0 then %>
166
+ transition_func_t *transition = <%= @prefix %>transition_table[cur_state][new_state];
166
167
  if (transition)
167
168
  transition(data);
168
169
  <% end %>
169
- return new_state == NO_CHANGE ? cur_state : new_state;
170
+ return new_state == <%= @prefix.upcase %>NO_CHANGE ? cur_state : new_state;
170
171
  };
171
172
 
172
173
 
173
174
  #ifdef TEST_MAIN
174
175
  #include <unistd.h>
175
176
  int main() {
176
- state_t cur_state = STATE_INIT;
177
+ state_t cur_state = <%= @prefix.upcase %>STATE_INIT;
177
178
  openlog("SM", LOG_PID | LOG_PERROR, LOG_USER);
178
179
  syslog(LOG_INFO, "Starting SM");
179
180
  do {
180
181
  cur_state = run_state(cur_state, NULL);
181
182
  sleep(1);
182
- } while (cur_state != STATE_STOP);
183
+ } while (cur_state != <%= @prefix.upcase %>STATE_STOP);
183
184
  return 0;
184
185
  }
185
186
  #endif
@@ -1,3 +1,3 @@
1
1
  module GV_FSM
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gv_fsm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paolo Bosetti