gv_fsm 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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