summaryrefslogtreecommitdiff
path: root/tools/dfagen/dfagen/output/c.py
blob: 12379ae3b16483deed86148240e391b820f5bc57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import os.path

class WriterData:

    def __init__ (self, prefix, automaton, user):
	self.prefix = prefix
	self.automaton = automaton
	self.user = user
	self.states = self.automaton.states.values ()
	self.events = self.automaton.events.values ()
	self.dict = dict (
		prefix = prefix,
		PREFIX = prefix.upper (),
		name = automaton.name,
		comments = automaton.comments,
		initial = automaton.initial.name,
		states = self.list_states,
		events = self.list_events,
		branches = self.list_branches,
		transition_table = self.transition_table,
		states_template = self.states_template,
		)

    def list_states (self):
	return ''.join (['    ' + self.prefix.upper () + '_STATE_' + s.name
	    + ',\n' for s in self.states])

    def list_events (self):
	return ''.join (['    ' + self.prefix.upper () + '_EVENT_'
	    + e.name.replace (' ', '_') + ',\n' for e in self.events])

    def list_branches (self):
	l = ''
	for s in self.states:
	    for tr in s.transitions.values ():
		for br in tr.branches.values ():
		    n = dict (
			    PREFIX = self.prefix.upper (),
			    state = s.name,
			    event = tr.event.name.replace (' ', '_'),
			    branch = (br.name and br.name.replace (' ', '_')
				or ''),
			    to = (br.to and br.to.name or s.name),
			    )
		    l += ('    %(PREFIX)s_BRANCH__%(state)s__%(event)s__%(branch)s = '
			    + '_BRANCH (%(state)s, %(event)s, %(to)s),\n') % n
	return l

    def transition_table (self):
	r = ''
	for s in self.states:
	    r += '    { '
	    es = [ ]
	    for e in self.events:
		if e in s.transitions:
		    es.append (self.prefix + '__' + s.name + '__'
			    + e.name.replace (' ', '_'))
		else:
		    es.append ('NULL')
	    r += ',\n      '.join (es)
	    r += ' },\n'
	return r

    def states_template (self, template):
	t = open (os.path.join (self.templatedir, template), 'r')
	tt = t.read ()
	t.close ()
	exp = ''
	for s in self.states:
	    for tr in s.transitions.values ():
		d = WriterData (self.prefix, self.automaton, self.user)
		branches_to = '\n'.join (
			[(br.name and br.name or '')
			    + ' => '
			    + (br.to and br.to.name or s.name)
			    + (br.comments and ('\n  '
				+ br.comments.replace ('\n', '\n  ')) or '')
			    for br in tr.branches.values ()])
		returns = '\n'.join (
			['    return ' + self.prefix + '_next'
			    + (br.name and '_branch' or '')
			    + ' (' + s.name + ', '
			    + tr.event.name.replace (' ', '_')
			    + (br.name and ', ' + br.name.replace (' ', '_')
				or '')
			    + ');'
			    for br in tr.branches.values ()])
		d.dict = dict (
			prefix = self.prefix,
			user = self.user,
			state = s.name,
			event = tr.event.name.replace (' ', '_'),
			branches_to = branches_to,
			returns = returns,
			)
		exp += tt % d
	return exp

    def __getitem__ (self, key):
	preproc = lambda v: v
	args = []
	key = key.split (',')
	key, args = key[0], key[1:]
	if key.startswith ('*'):
	    key = key[1:]
	    preproc = lambda v: ' * ' + v.replace ('\n', '\n * ') + '\n'
	if key.startswith ('_'):
	    key = key[1:]
	    preproc = lambda v: v and v + '\n' or ''
	val = None
	if key in self.dict:
	    try:
		val = self.dict[key] (*args)
	    except TypeError:
		val = self.dict[key]
	elif key.startswith ('user.'):
	    val = self.user[key[5:]]
	val = preproc (val)
	if val is None:
	    raise KeyError, key
	return val

class Writer:

    def __init__ (self, data, templatedir):
	data.templatedir = templatedir
	self.data = data
	self.templatedir = templatedir

    def write_template (self, template, output):
	t = open (os.path.join (self.templatedir, template), 'r')
	tt = t.read ()
	t.close ()
	exp = tt % self.data
	o = open (output, 'w')
	o.write (exp)
	o.close ()

    def write (self):
	templates = self.data.user.templates
	if not templates:
	    templates = {
		    'template.h': '%.h',
		    'template.c': '%.c',
		    'template_cb.h': '%_cb.h',
		    'template_cb_skel.c': '%_cb_skel.c',
		    }
	for (t, f) in templates.iteritems ():
	    self.write_template (t, f.replace ('%', self.data.prefix))

def write (prefix, automaton, user):
    w = Writer (WriterData (prefix, automaton, user), 'template-dir' in user
	    and user['template-dir'] or os.path.splitext (__file__)[0])
    w.write ()