source: mainline/contrib/arch/hadlbppp.py@ 338d0935

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 338d0935 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100755
File size: 45.1 KB
Line 
1#!/usr/bin/env python
2#
3# Copyright (c) 2009 Martin Decky
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29"""
30HelenOS Architecture Description Language and Behavior Protocols preprocessor
31"""
32
33import sys
34import os
35
36INC, POST_INC, BLOCK_COMMENT, LINE_COMMENT, SYSTEM, ARCH, HEAD, BODY, NULL, \
37 INST, VAR, FIN, BIND, TO, SUBSUME, DELEGATE, IFACE, EXTENDS, PRE_BODY, \
38 PROTOTYPE, PAR_LEFT, PAR_RIGHT, SIGNATURE, PROTOCOL, INITIALIZATION, \
39 FINALIZATION, FRAME, PROVIDES, REQUIRES = range(29)
40
41def usage(prname):
42 "Print usage syntax"
43
44 print("%s <--bp|--ebp|--adl|--dot|--nop>+ <OUTPUT>" % prname)
45 print()
46 print("--bp Dump original Behavior Protocols (dChecker, BPSlicer)")
47 print("--ebp Dump Extended Behavior Protocols (bp2promela)")
48 print("--adl Dump Architecture Description Language (modified SOFA ADL/CDL)")
49 print("--dot Dump Dot architecture diagram (GraphViz)")
50 print("--nop Do not dump anything (just input files syntax check)")
51 print()
52
53def tabs(cnt):
54 "Return given number of tabs"
55
56 return ("\t" * cnt)
57
58def cond_append(tokens, token, trim):
59 "Conditionally append token to tokens with trim"
60
61 if (trim):
62 token = token.strip(" \t")
63
64 if (token != ""):
65 tokens.append(token)
66
67 return tokens
68
69def split_tokens(string, delimiters, trim = False, separate = False):
70 "Split string to tokens by delimiters, keep the delimiters"
71
72 tokens = []
73 last = 0
74 i = 0
75
76 while (i < len(string)):
77 for delim in delimiters:
78 if (len(delim) > 0):
79
80 if (string[i:(i + len(delim))] == delim):
81 if (separate):
82 tokens = cond_append(tokens, string[last:i], trim)
83 tokens = cond_append(tokens, delim, trim)
84 last = i + len(delim)
85 elif (i > 0):
86 tokens = cond_append(tokens, string[last:i], trim)
87 last = i
88
89 i += len(delim) - 1
90 break
91
92 i += 1
93
94 tokens = cond_append(tokens, string[last:len(string)], trim)
95
96 return tokens
97
98def identifier(token):
99 "Check whether the token is an identifier"
100
101 if (len(token) == 0):
102 return False
103
104 for i, char in enumerate(token):
105 if (i == 0):
106 if ((not char.isalpha()) and (char != "_")):
107 return False
108 else:
109 if ((not char.isalnum()) and (char != "_")):
110 return False
111
112 return True
113
114def descriptor(token):
115 "Check whether the token is an interface descriptor"
116
117 parts = token.split(":")
118 if (len(parts) != 2):
119 return False
120
121 return (identifier(parts[0]) and identifier(parts[1]))
122
123def word(token):
124 "Check whether the token is a word"
125
126 if (len(token) == 0):
127 return False
128
129 for i, char in enumerate(token):
130 if ((not char.isalnum()) and (char != "_") and (char != ".")):
131 return False
132
133 return True
134
135def tentative_bp(name, tokens):
136 "Preprocess tentative statements in Behavior Protocol"
137
138 result = []
139 i = 0
140
141 while (i < len(tokens)):
142 if (tokens[i] == "tentative"):
143 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
144 i += 2
145 start = i
146 level = 1
147
148 while ((i < len(tokens)) and (level > 0)):
149 if (tokens[i] == "{"):
150 level += 1
151 elif (tokens[i] == "}"):
152 level -= 1
153
154 i += 1
155
156 if (level == 0):
157 result.append("(")
158 result.extend(tentative_bp(name, tokens[start:(i - 1)]))
159 result.append(")")
160 result.append("+")
161 result.append("NULL")
162 if (i < len(tokens)):
163 result.append(tokens[i])
164 else:
165 print("%s: Syntax error in tentative statement" % name)
166 else:
167 print("%s: Expected '{' for tentative statement" % name)
168 else:
169 result.append(tokens[i])
170
171 i += 1
172
173 return result
174
175def alternative_bp(name, tokens):
176 "Preprocess alternative statements in Behavior Protocol"
177
178 result = []
179 i = 0
180
181 while (i < len(tokens)):
182 if (tokens[i] == "alternative"):
183 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "(")):
184 i += 2
185 reps = []
186
187 while ((i < len(tokens)) and (tokens[i] != ")")):
188 reps.append(tokens[i])
189 if ((i + 1 < len(tokens)) and (tokens[i + 1] == ";")):
190 i += 2
191 else:
192 i += 1
193
194 if (len(reps) >= 2):
195 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
196 i += 2
197
198 start = i
199 level = 1
200
201 while ((i < len(tokens)) and (level > 0)):
202 if (tokens[i] == "{"):
203 level += 1
204 elif (tokens[i] == "}"):
205 level -= 1
206
207 i += 1
208
209 if (level == 0):
210 first = True
211
212 for rep in reps[1:]:
213 retokens = []
214 for token in tokens[start:(i - 1)]:
215 parts = token.split(".")
216 if ((len(parts) == 2) and (parts[0] == reps[0])):
217 retokens.append("%s.%s" % (rep, parts[1]))
218 else:
219 retokens.append(token)
220
221 if (first):
222 first = False
223 else:
224 result.append("+")
225
226 result.append("(")
227 result.extend(alternative_bp(name, retokens))
228 result.append(")")
229
230 if (i < len(tokens)):
231 result.append(tokens[i])
232 else:
233 print("%s: Syntax error in alternative statement" % name)
234 else:
235 print("%s: Expected '{' for alternative statement body" % name)
236 else:
237 print("%s: At least one pattern and one replacement required for alternative statement" % name)
238 else:
239 print("%s: Expected '(' for alternative statement head" % name)
240 else:
241 result.append(tokens[i])
242
243 i += 1
244
245 return result
246
247def split_bp(protocol):
248 "Convert Behavior Protocol to tokens"
249
250 return split_tokens(protocol, ["\n", " ", "\t", "(", ")", "{", "}", "*", ";", "+", "||", "|", "!", "?"], True, True)
251
252def extend_bp(name, tokens, iface):
253 "Convert interface Behavior Protocol to generic protocol"
254
255 result = []
256 i = 0
257
258 while (i < len(tokens)):
259 result.append(tokens[i])
260
261 if (tokens[i] == "?"):
262 if (i + 1 < len(tokens)):
263 i += 1
264 parts = tokens[i].split(".")
265
266 if (len(parts) == 1):
267 result.append("%s.%s" % (iface, tokens[i]))
268 else:
269 result.append(tokens[i])
270 else:
271 print("%s: Unexpected end of protocol" % name)
272
273 i += 1
274
275 return result
276
277def merge_bp(initialization, finalization, protocols):
278 "Merge several Behavior Protocols"
279
280 indep = []
281
282 if (len(protocols) > 1):
283 first = True
284
285 for protocol in protocols:
286 if (first):
287 first = False
288 else:
289 indep.append("|")
290
291 indep.append("(")
292 indep.extend(protocol)
293 indep.append(")")
294 elif (len(protocols) == 1):
295 indep = protocols[0]
296
297 inited = []
298
299 if (initialization != None):
300 if (len(indep) > 0):
301 inited.append("(")
302 inited.extend(initialization)
303 inited.append(")")
304 inited.append(";")
305 inited.append("(")
306 inited.extend(indep)
307 inited.append(")")
308 else:
309 inited = initialization
310 else:
311 inited = indep
312
313 finited = []
314
315 if (finalization != None):
316 if (len(inited) > 0):
317 finited.append("(")
318 finited.extend(inited)
319 finited.append(")")
320 finited.append(";")
321 finited.append("(")
322 finited.extend(finalization)
323 finited.append(")")
324 else:
325 finited = finalization
326 else:
327 finited = inited
328
329 return finited
330
331def parse_bp(name, tokens, base_indent):
332 "Parse Behavior Protocol"
333
334 tokens = tentative_bp(name, tokens)
335 tokens = alternative_bp(name, tokens)
336
337 indent = base_indent
338 output = ""
339
340 for token in tokens:
341 if (token == "\n"):
342 continue
343
344 if ((token == ";") or (token == "+") or (token == "||") or (token == "|")):
345 output += " %s" % token
346 elif (token == "("):
347 output += "\n%s%s" % (tabs(indent), token)
348 indent += 1
349 elif (token == ")"):
350 if (indent < base_indent):
351 print("%s: Too many parentheses" % name)
352
353 indent -= 1
354 output += "\n%s%s" % (tabs(indent), token)
355 elif (token == "{"):
356 output += " %s" % token
357 indent += 1
358 elif (token == "}"):
359 if (indent < base_indent):
360 print("%s: Too many parentheses" % name)
361
362 indent -= 1
363 output += "\n%s%s" % (tabs(indent), token)
364 elif (token == "*"):
365 output += "%s" % token
366 elif ((token == "!") or (token == "?") or (token == "NULL")):
367 output += "\n%s%s" % (tabs(indent), token)
368 else:
369 output += "%s" % token
370
371 if (indent > base_indent):
372 print("%s: Missing parentheses" % name)
373
374 output = output.strip()
375 if (output == ""):
376 return "NULL"
377
378 return output
379
380def parse_ebp(component, name, tokens, base_indent):
381 "Parse Behavior Protocol and generate Extended Behavior Protocol output"
382
383 return "component %s {\n\tbehavior {\n\t\t%s\n\t}\n}" % (component, parse_bp(name, tokens, base_indent + 2))
384
385def get_iface(name):
386 "Get interface by name"
387
388 global iface_properties
389
390 if (name in iface_properties):
391 return iface_properties[name]
392
393 return None
394
395def inherited_protocols(iface):
396 "Get protocols inherited by an interface"
397
398 result = []
399
400 if ('extends' in iface):
401 supiface = get_iface(iface['extends'])
402 if (not supiface is None):
403 if ('protocol' in supiface):
404 result.append(supiface['protocol'])
405 result.extend(inherited_protocols(supiface))
406 else:
407 print("%s: Extends unknown interface '%s'" % (iface['name'], iface['extends']))
408
409 return result
410
411def dump_frame(directed_binds, frame, outdir, var, archf):
412 "Dump Behavior Protocol of a given frame"
413
414 global opt_bp
415 global opt_ebp
416
417 if (opt_ebp):
418 fname = "%s.ebp" % frame['name']
419 else:
420 fname = "%s.bp" % frame['name']
421
422 if (archf != None):
423 archf.write("instantiate %s from \"%s\"\n" % (var, fname))
424
425 outname = os.path.join(outdir, fname)
426
427 protocols = []
428 if ('protocol' in frame):
429 protocols.append(frame['protocol'])
430
431 if ('initialization' in frame):
432 initialization = frame['initialization']
433 else:
434 initialization = None
435
436 if ('finalization' in frame):
437 finalization = frame['finalization']
438 else:
439 finalization = None
440
441 if ('provides' in frame):
442 for provides in frame['provides']:
443 iface = get_iface(provides['iface'])
444 if (not iface is None):
445 binds = directed_binds['%s.%s' % (var, provides['iface'])]
446 if (not binds is None):
447 cnt = len(binds)
448 else:
449 cnt = 1
450
451 if ('protocol' in iface):
452 proto = extend_bp(outname, iface['protocol'], iface['name'])
453 for _ in range(0, cnt):
454 protocols.append(proto)
455
456 for protocol in inherited_protocols(iface):
457 proto = extend_bp(outname, protocol, iface['name'])
458 for _ in range(0, cnt):
459 protocols.append(proto)
460 else:
461 print("%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface']))
462
463 if (opt_bp):
464 outf = open(outname, "w")
465 outf.write(parse_bp(outname, merge_bp(initialization, finalization, protocols), 0))
466 outf.close()
467
468 if (opt_ebp):
469 outf = open(outname, "w")
470 outf.write(parse_ebp(frame['name'], outname, merge_bp(initialization, finalization, protocols), 0))
471 outf.close()
472
473def get_system_arch():
474 "Get system architecture"
475
476 global arch_properties
477
478 for arch, properties in arch_properties.items():
479 if ('system' in properties):
480 return properties
481
482 return None
483
484def get_arch(name):
485 "Get architecture by name"
486
487 global arch_properties
488
489 if (name in arch_properties):
490 return arch_properties[name]
491
492 return None
493
494def get_frame(name):
495 "Get frame by name"
496
497 global frame_properties
498
499 if (name in frame_properties):
500 return frame_properties[name]
501
502 return None
503
504def create_null_bp(fname, outdir, archf):
505 "Create null frame protocol"
506
507 global opt_bp
508 global opt_ebp
509
510 if (archf != None):
511 archf.write("frame \"%s\"\n" % fname)
512
513 outname = os.path.join(outdir, fname)
514
515 if (opt_bp):
516 outf = open(outname, "w")
517 outf.write("NULL")
518 outf.close()
519
520 if (opt_ebp):
521 outf = open(outname, "w")
522 outf.write("component null {\n\tbehavior {\n\t\tNULL\n\t}\n}")
523 outf.close()
524
525def flatten_binds(binds, delegates, subsumes):
526 "Remove bindings which are replaced by delegation or subsumption"
527
528 result = []
529 stable = True
530
531 for bind in binds:
532 keep = True
533
534 for delegate in delegates:
535 if (bind['to'] == delegate['to']):
536 keep = False
537 result.append({'from': bind['from'], 'to': delegate['rep']})
538
539 for subsume in subsumes:
540 if (bind['from'] == subsume['from']):
541 keep = False
542 result.append({'from': subsume['rep'], 'to': bind['to']})
543
544 if (keep):
545 result.append(bind)
546 else:
547 stable = False
548
549 if (stable):
550 return result
551 else:
552 return flatten_binds(result, delegates, subsumes)
553
554def direct_binds(binds):
555 "Convert bindings matrix to set of sources by destination"
556
557 result = {}
558
559 for bind in binds:
560 if (not bind['to'] in result):
561 result[bind['to']] = set()
562
563 result[bind['to']].add(bind['from'])
564
565 return result
566
567def merge_arch(prefix, arch, outdir):
568 "Merge subarchitecture into architecture"
569
570 insts = []
571 binds = []
572 delegates = []
573 subsumes = []
574
575 if ('inst' in arch):
576 for inst in arch['inst']:
577 subarch = get_arch(inst['type'])
578 if (not subarch is None):
579 (subinsts, subbinds, subdelegates, subsubsumes) = merge_arch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
580 insts.extend(subinsts)
581 binds.extend(subbinds)
582 delegates.extend(subdelegates)
583 subsumes.extend(subsubsumes)
584 else:
585 subframe = get_frame(inst['type'])
586 if (not subframe is None):
587 insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
588 else:
589 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
590
591 if ('bind' in arch):
592 for bind in arch['bind']:
593 binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
594
595 if ('delegate' in arch):
596 for delegate in arch['delegate']:
597 delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
598
599 if ('subsume' in arch):
600 for subsume in arch['subsume']:
601 subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
602
603 return (insts, binds, delegates, subsumes)
604
605def dump_archbp(outdir):
606 "Dump system architecture Behavior Protocol"
607
608 global opt_bp
609 global opt_ebp
610
611 arch = get_system_arch()
612
613 if (arch is None):
614 print("Unable to find system architecture")
615 return
616
617 insts = []
618 binds = []
619 delegates = []
620 subsumes = []
621
622 if ('inst' in arch):
623 for inst in arch['inst']:
624 subarch = get_arch(inst['type'])
625 if (not subarch is None):
626 (subinsts, subbinds, subdelegates, subsubsumes) = merge_arch(subarch['name'], subarch, outdir)
627 insts.extend(subinsts)
628 binds.extend(subbinds)
629 delegates.extend(subdelegates)
630 subsumes.extend(subsubsumes)
631 else:
632 subframe = get_frame(inst['type'])
633 if (not subframe is None):
634 insts.append({'var': inst['var'], 'frame': subframe})
635 else:
636 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
637
638 if ('bind' in arch):
639 for bind in arch['bind']:
640 binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
641
642 if ('delegate' in arch):
643 for delegate in arch['delegate']:
644 print("Unable to delegate interface in system architecture")
645 break
646
647 if ('subsume' in arch):
648 for subsume in arch['subsume']:
649 print("Unable to subsume interface in system architecture")
650 break
651
652 directed_binds = direct_binds(flatten_binds(binds, delegates, subsumes))
653
654 outname = os.path.join(outdir, "%s.archbp" % arch['name'])
655 if ((opt_bp) or (opt_ebp)):
656 outf = open(outname, "w")
657 else:
658 outf = None
659
660 create_null_bp("null.bp", outdir, outf)
661
662 for inst in insts:
663 dump_frame(directed_binds, inst['frame'], outdir, inst['var'], outf)
664
665 for dst, src in directed_binds.items():
666 if (outf != None):
667 outf.write("bind %s to %s\n" % (", ".join(src), dst))
668
669 if (outf != None):
670 outf.close()
671
672def preproc_adl(raw, inarg):
673 "Preprocess %% statements in ADL"
674
675 return raw.replace("%%", inarg)
676
677def parse_adl(base, root, inname, nested, indent):
678 "Parse Architecture Description Language"
679
680 global output
681 global context
682 global architecture
683 global interface
684 global frame
685 global protocol
686 global initialization
687 global finalization
688
689 global iface_properties
690 global frame_properties
691 global arch_properties
692
693 global arg0
694
695 if (nested):
696 parts = inname.split("%")
697
698 if (len(parts) > 1):
699 inarg = parts[1]
700 else:
701 inarg = "%%"
702
703 if (parts[0][0:1] == "/"):
704 path = os.path.join(base, ".%s" % parts[0])
705 nested_root = os.path.dirname(path)
706 else:
707 path = os.path.join(root, parts[0])
708 nested_root = root
709
710 if (not os.path.isfile(path)):
711 print("%s: Unable to include file %s" % (inname, path))
712 return ""
713 else:
714 inarg = "%%"
715 path = inname
716 nested_root = root
717
718 inf = open(path, "r")
719
720 raw = preproc_adl(inf.read(), inarg)
721 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
722
723 for token in tokens:
724
725 # Includes
726
727 if (INC in context):
728 context.remove(INC)
729 parse_adl(base, nested_root, token, True, indent)
730 context.add(POST_INC)
731 continue
732
733 if (POST_INC in context):
734 if (token != "]"):
735 print("%s: Expected ]" % inname)
736
737 context.remove(POST_INC)
738 continue
739
740 # Comments and newlines
741
742 if (BLOCK_COMMENT in context):
743 if (token == "*/"):
744 context.remove(BLOCK_COMMENT)
745
746 continue
747
748 if (LINE_COMMENT in context):
749 if (token == "\n"):
750 context.remove(LINE_COMMENT)
751
752 continue
753
754 # Any context
755
756 if (token == "/*"):
757 context.add(BLOCK_COMMENT)
758 continue
759
760 if (token == "#"):
761 context.add(LINE_COMMENT)
762 continue
763
764 if (token == "["):
765 context.add(INC)
766 continue
767
768 if (token == "\n"):
769 continue
770
771 # "frame"
772
773 if (FRAME in context):
774 if (NULL in context):
775 if (token != ";"):
776 print("%s: Expected ';' in frame '%s'" % (inname, frame))
777 else:
778 output += "%s\n" % token
779
780 context.remove(NULL)
781 context.remove(FRAME)
782 frame = None
783 continue
784
785 if (BODY in context):
786 if (FINALIZATION in context):
787 if (token == "{"):
788 indent += 1
789 elif (token == "}"):
790 indent -= 1
791
792 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
793 bp = split_bp(finalization)
794 finalization = None
795
796 if (not frame in frame_properties):
797 frame_properties[frame] = {}
798
799 if ('finalization' in frame_properties[frame]):
800 print("%s: Finalization protocol for frame '%s' already defined" % (inname, frame))
801 else:
802 frame_properties[frame]['finalization'] = bp
803
804 output += "\n%s" % tabs(2)
805 output += parse_bp(inname, bp, 2)
806
807 context.remove(FINALIZATION)
808 if (indent == -1):
809 output += "\n%s" % token
810 context.remove(BODY)
811 context.add(NULL)
812 indent = 0
813 continue
814 else:
815 indent = 2
816 else:
817 finalization += token
818 continue
819
820 if (INITIALIZATION in context):
821 if (token == "{"):
822 indent += 1
823 elif (token == "}"):
824 indent -= 1
825
826 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
827 bp = split_bp(initialization)
828 initialization = None
829
830 if (not frame in frame_properties):
831 frame_properties[frame] = {}
832
833 if ('initialization' in frame_properties[frame]):
834 print("%s: Initialization protocol for frame '%s' already defined" % (inname, frame))
835 else:
836 frame_properties[frame]['initialization'] = bp
837
838 output += "\n%s" % tabs(2)
839 output += parse_bp(inname, bp, 2)
840
841 context.remove(INITIALIZATION)
842 if (indent == -1):
843 output += "\n%s" % token
844 context.remove(BODY)
845 context.add(NULL)
846 indent = 0
847 continue
848 else:
849 indent = 2
850 else:
851 initialization += token
852 continue
853
854 if (PROTOCOL in context):
855 if (token == "{"):
856 indent += 1
857 elif (token == "}"):
858 indent -= 1
859
860 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
861 bp = split_bp(protocol)
862 protocol = None
863
864 if (not frame in frame_properties):
865 frame_properties[frame] = {}
866
867 if ('protocol' in frame_properties[frame]):
868 print("%s: Protocol for frame '%s' already defined" % (inname, frame))
869 else:
870 frame_properties[frame]['protocol'] = bp
871
872 output += "\n%s" % tabs(2)
873 output += parse_bp(inname, bp, 2)
874
875 context.remove(PROTOCOL)
876 if (indent == -1):
877 output += "\n%s" % token
878 context.remove(BODY)
879 context.add(NULL)
880 indent = 0
881 continue
882 else:
883 indent = 2
884 else:
885 protocol += token
886 continue
887
888 if (REQUIRES in context):
889 if (FIN in context):
890 if (token != ";"):
891 print("%s: Expected ';' in frame '%s'" % (inname, frame))
892 else:
893 output += "%s" % token
894
895 context.remove(FIN)
896 continue
897
898 if (VAR in context):
899 if (not identifier(token)):
900 print("%s: Variable name expected in frame '%s'" % (inname, frame))
901 else:
902 if (not frame in frame_properties):
903 frame_properties[frame] = {}
904
905 if (not 'requires' in frame_properties[frame]):
906 frame_properties[frame]['requires'] = []
907
908 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
909 arg0 = None
910
911 output += "%s" % token
912
913 context.remove(VAR)
914 context.add(FIN)
915 continue
916
917 if ((token == "}") or (token[-1] == ":")):
918 context.remove(REQUIRES)
919 else:
920 if (not identifier(token)):
921 print("%s: Interface name expected in frame '%s'" % (inname, frame))
922 else:
923 arg0 = token
924 output += "\n%s%s " % (tabs(indent), token)
925
926 context.add(VAR)
927 continue
928
929 if (PROVIDES in context):
930 if (FIN in context):
931 if (token != ";"):
932 print("%s: Expected ';' in frame '%s'" % (inname, frame))
933 else:
934 output += "%s" % token
935
936 context.remove(FIN)
937 continue
938
939 if (VAR in context):
940 if (not identifier(token)):
941 print("%s: Variable name expected in frame '%s'" % (inname, frame))
942 else:
943 if (not frame in frame_properties):
944 frame_properties[frame] = {}
945
946 if (not 'provides' in frame_properties[frame]):
947 frame_properties[frame]['provides'] = []
948
949 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
950 arg0 = None
951
952 output += "%s" % token
953
954 context.remove(VAR)
955 context.add(FIN)
956 continue
957
958 if ((token == "}") or (token[-1] == ":")):
959 context.remove(PROVIDES)
960 else:
961 if (not identifier(token)):
962 print("%s: Interface name expected in frame '%s'" % (inname, frame))
963 else:
964 arg0 = token
965 output += "\n%s%s " % (tabs(indent), token)
966
967 context.add(VAR)
968 continue
969
970 if (token == "}"):
971 if (indent != 2):
972 print("%s: Wrong number of parentheses in frame '%s'" % (inname, frame))
973 else:
974 indent = 0
975 output += "\n%s" % token
976
977 context.remove(BODY)
978 context.add(NULL)
979 continue
980
981 if (token == "provides:"):
982 output += "\n%s%s" % (tabs(indent - 1), token)
983 context.add(PROVIDES)
984 continue
985
986 if (token == "requires:"):
987 output += "\n%s%s" % (tabs(indent - 1), token)
988 context.add(REQUIRES)
989 continue
990
991 if (token == "initialization:"):
992 output += "\n%s%s" % (tabs(indent - 1), token)
993 indent = 0
994 context.add(INITIALIZATION)
995 initialization = ""
996 continue
997
998 if (token == "finalization:"):
999 output += "\n%s%s" % (tabs(indent - 1), token)
1000 indent = 0
1001 context.add(FINALIZATION)
1002 finalization = ""
1003 continue
1004
1005 if (token == "protocol:"):
1006 output += "\n%s%s" % (tabs(indent - 1), token)
1007 indent = 0
1008 context.add(PROTOCOL)
1009 protocol = ""
1010 continue
1011
1012 print("%s: Unknown token '%s' in frame '%s'" % (inname, token, frame))
1013 continue
1014
1015 if (HEAD in context):
1016 if (token == "{"):
1017 output += "%s" % token
1018 indent += 2
1019 context.remove(HEAD)
1020 context.add(BODY)
1021 continue
1022
1023 if (token == ";"):
1024 output += "%s\n" % token
1025 context.remove(HEAD)
1026 context.remove(FRAME)
1027 continue
1028
1029 print("%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame))
1030
1031 continue
1032
1033 if (not identifier(token)):
1034 print("%s: Expected frame name" % inname)
1035 else:
1036 frame = token
1037 output += "%s " % token
1038
1039 if (not frame in frame_properties):
1040 frame_properties[frame] = {}
1041
1042 frame_properties[frame]['name'] = frame
1043
1044 context.add(HEAD)
1045 continue
1046
1047 # "interface"
1048
1049 if (IFACE in context):
1050 if (NULL in context):
1051 if (token != ";"):
1052 print("%s: Expected ';' in interface '%s'" % (inname, interface))
1053 else:
1054 output += "%s\n" % token
1055
1056 context.remove(NULL)
1057 context.remove(IFACE)
1058 interface = None
1059 continue
1060
1061 if (BODY in context):
1062 if (PROTOCOL in context):
1063 if (token == "{"):
1064 indent += 1
1065 elif (token == "}"):
1066 indent -= 1
1067
1068 if (indent == -1):
1069 bp = split_bp(protocol)
1070 protocol = None
1071
1072 if (not interface in iface_properties):
1073 iface_properties[interface] = {}
1074
1075 if ('protocol' in iface_properties[interface]):
1076 print("%s: Protocol for interface '%s' already defined" % (inname, interface))
1077 else:
1078 iface_properties[interface]['protocol'] = bp
1079
1080 output += "\n%s" % tabs(2)
1081 output += parse_bp(inname, bp, 2)
1082 output += "\n%s" % token
1083 indent = 0
1084
1085 context.remove(PROTOCOL)
1086 context.remove(BODY)
1087 context.add(NULL)
1088 else:
1089 protocol += token
1090
1091 continue
1092
1093 if (PROTOTYPE in context):
1094 if (FIN in context):
1095 if (token != ";"):
1096 print("%s: Expected ';' in interface '%s'" % (inname, interface))
1097 else:
1098 output += "%s" % token
1099
1100 context.remove(FIN)
1101 context.remove(PROTOTYPE)
1102 continue
1103
1104 if (PAR_RIGHT in context):
1105 if (token == ")"):
1106 output += "%s" % token
1107 context.remove(PAR_RIGHT)
1108 context.add(FIN)
1109 else:
1110 output += " %s" % token
1111
1112 continue
1113
1114 if (SIGNATURE in context):
1115 output += "%s" % token
1116 if (token == ")"):
1117 context.remove(SIGNATURE)
1118 context.add(FIN)
1119
1120 context.remove(SIGNATURE)
1121 context.add(PAR_RIGHT)
1122 continue
1123
1124 if (PAR_LEFT in context):
1125 if (token != "("):
1126 print("%s: Expected '(' in interface '%s'" % (inname, interface))
1127 else:
1128 output += "%s" % token
1129
1130 context.remove(PAR_LEFT)
1131 context.add(SIGNATURE)
1132 continue
1133
1134 if (not identifier(token)):
1135 print("%s: Method identifier expected in interface '%s'" % (inname, interface))
1136 else:
1137 output += "%s" % token
1138
1139 context.add(PAR_LEFT)
1140 continue
1141
1142 if (token == "}"):
1143 if (indent != 2):
1144 print("%s: Wrong number of parentheses in interface '%s'" % (inname, interface))
1145 else:
1146 indent = 0
1147 output += "\n%s" % token
1148
1149 context.remove(BODY)
1150 context.add(NULL)
1151 continue
1152
1153 if (token == "sysarg_t"):
1154 output += "\n%s%s " % (tabs(indent), token)
1155 context.add(PROTOTYPE)
1156 continue
1157
1158 if (token == "protocol:"):
1159 output += "\n%s%s" % (tabs(indent - 1), token)
1160 indent = 0
1161 context.add(PROTOCOL)
1162 protocol = ""
1163 continue
1164
1165 print("%s: Unknown token '%s' in interface '%s'" % (inname, token, interface))
1166 continue
1167
1168 if (HEAD in context):
1169 if (PRE_BODY in context):
1170 if (token == "{"):
1171 output += "%s" % token
1172 indent += 2
1173 context.remove(PRE_BODY)
1174 context.remove(HEAD)
1175 context.add(BODY)
1176 continue
1177
1178 if (token == ";"):
1179 output += "%s\n" % token
1180 context.remove(PRE_BODY)
1181 context.remove(HEAD)
1182 context.remove(IFACE)
1183 continue
1184
1185 print("%s: Expected '{' or ';' in interface head '%s'" % (inname, interface))
1186 continue
1187
1188 if (EXTENDS in context):
1189 if (not identifier(token)):
1190 print("%s: Expected inherited interface name in interface head '%s'" % (inname, interface))
1191 else:
1192 output += "%s " % token
1193 if (not interface in iface_properties):
1194 iface_properties[interface] = {}
1195
1196 iface_properties[interface]['extends'] = token
1197
1198 context.remove(EXTENDS)
1199 context.add(PRE_BODY)
1200 continue
1201
1202 if (token == "extends"):
1203 output += "%s " % token
1204 context.add(EXTENDS)
1205 continue
1206
1207 if (token == "{"):
1208 output += "%s" % token
1209 indent += 2
1210 context.remove(HEAD)
1211 context.add(BODY)
1212 continue
1213
1214 if (token == ";"):
1215 output += "%s\n" % token
1216 context.remove(HEAD)
1217 context.remove(IFACE)
1218 continue
1219
1220 print("%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface))
1221 continue
1222
1223 if (not identifier(token)):
1224 print("%s: Expected interface name" % inname)
1225 else:
1226 interface = token
1227 output += "%s " % token
1228
1229 if (not interface in iface_properties):
1230 iface_properties[interface] = {}
1231
1232 iface_properties[interface]['name'] = interface
1233
1234 context.add(HEAD)
1235 continue
1236
1237 # "architecture"
1238
1239 if (ARCH in context):
1240 if (NULL in context):
1241 if (token != ";"):
1242 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
1243 else:
1244 output += "%s\n" % token
1245
1246 context.remove(NULL)
1247 context.remove(ARCH)
1248 context.discard(SYSTEM)
1249 architecture = None
1250 continue
1251
1252 if (BODY in context):
1253 if (DELEGATE in context):
1254 if (FIN in context):
1255 if (token != ";"):
1256 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
1257 else:
1258 output += "%s" % token
1259
1260 context.remove(FIN)
1261 context.remove(DELEGATE)
1262 continue
1263
1264 if (VAR in context):
1265 if (not descriptor(token)):
1266 print("%s: Expected interface descriptor in architecture '%s'" % (inname, architecture))
1267 else:
1268 if (not architecture in arch_properties):
1269 arch_properties[architecture] = {}
1270
1271 if (not 'delegate' in arch_properties[architecture]):
1272 arch_properties[architecture]['delegate'] = []
1273
1274 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1275 arg0 = None
1276
1277 output += "%s" % token
1278
1279 context.add(FIN)
1280 context.remove(VAR)
1281 continue
1282
1283 if (TO in context):
1284 if (token != "to"):
1285 print("%s: Expected 'to' in architecture '%s'" % (inname, architecture))
1286 else:
1287 output += "%s " % token
1288
1289 context.add(VAR)
1290 context.remove(TO)
1291 continue
1292
1293 if (not identifier(token)):
1294 print("%s: Expected interface name in architecture '%s'" % (inname, architecture))
1295 else:
1296 output += "%s " % token
1297 arg0 = token
1298
1299 context.add(TO)
1300 continue
1301
1302 if (SUBSUME in context):
1303 if (FIN in context):
1304 if (token != ";"):
1305 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
1306 else:
1307 output += "%s" % token
1308
1309 context.remove(FIN)
1310 context.remove(SUBSUME)
1311 continue
1312
1313 if (VAR in context):
1314 if (not identifier(token)):
1315 print("%s: Expected interface name in architecture '%s'" % (inname, architecture))
1316 else:
1317 if (not architecture in arch_properties):
1318 arch_properties[architecture] = {}
1319
1320 if (not 'subsume' in arch_properties[architecture]):
1321 arch_properties[architecture]['subsume'] = []
1322
1323 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1324 arg0 = None
1325
1326 output += "%s" % token
1327
1328 context.add(FIN)
1329 context.remove(VAR)
1330 continue
1331
1332 if (TO in context):
1333 if (token != "to"):
1334 print("%s: Expected 'to' in architecture '%s'" % (inname, architecture))
1335 else:
1336 output += "%s " % token
1337
1338 context.add(VAR)
1339 context.remove(TO)
1340 continue
1341
1342 if (not descriptor(token)):
1343 print("%s: Expected interface descriptor in architecture '%s'" % (inname, architecture))
1344 else:
1345 output += "%s " % token
1346 arg0 = token
1347
1348 context.add(TO)
1349 continue
1350
1351 if (BIND in context):
1352 if (FIN in context):
1353 if (token != ";"):
1354 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
1355 else:
1356 output += "%s" % token
1357
1358 context.remove(FIN)
1359 context.remove(BIND)
1360 continue
1361
1362 if (VAR in context):
1363 if (not descriptor(token)):
1364 print("%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture))
1365 else:
1366 if (not architecture in arch_properties):
1367 arch_properties[architecture] = {}
1368
1369 if (not 'bind' in arch_properties[architecture]):
1370 arch_properties[architecture]['bind'] = []
1371
1372 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1373 arg0 = None
1374
1375 output += "%s" % token
1376
1377 context.add(FIN)
1378 context.remove(VAR)
1379 continue
1380
1381 if (TO in context):
1382 if (token != "to"):
1383 print("%s: Expected 'to' in architecture '%s'" % (inname, architecture))
1384 else:
1385 output += "%s " % token
1386
1387 context.add(VAR)
1388 context.remove(TO)
1389 continue
1390
1391 if (not descriptor(token)):
1392 print("%s: Expected interface descriptor in architecture '%s'" % (inname, architecture))
1393 else:
1394 output += "%s " % token
1395 arg0 = token
1396
1397 context.add(TO)
1398 continue
1399
1400 if (INST in context):
1401 if (FIN in context):
1402 if (token != ";"):
1403 print("%s: Expected ';' in architecture '%s'" % (inname, architecture))
1404 else:
1405 output += "%s" % token
1406
1407 context.remove(FIN)
1408 context.remove(INST)
1409 continue
1410
1411 if (VAR in context):
1412 if (not identifier(token)):
1413 print("%s: Expected instance name in architecture '%s'" % (inname, architecture))
1414 else:
1415 if (not architecture in arch_properties):
1416 arch_properties[architecture] = {}
1417
1418 if (not 'inst' in arch_properties[architecture]):
1419 arch_properties[architecture]['inst'] = []
1420
1421 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1422 arg0 = None
1423
1424 output += "%s" % token
1425
1426 context.add(FIN)
1427 context.remove(VAR)
1428 continue
1429
1430 if (not identifier(token)):
1431 print("%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture))
1432 else:
1433 output += "%s " % token
1434 arg0 = token
1435
1436 context.add(VAR)
1437 continue
1438
1439 if (token == "}"):
1440 if (indent != 1):
1441 print("%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture))
1442 else:
1443 indent -= 1
1444 output += "\n%s" % token
1445
1446 context.remove(BODY)
1447 context.add(NULL)
1448 continue
1449
1450 if (token == "inst"):
1451 output += "\n%s%s " % (tabs(indent), token)
1452 context.add(INST)
1453 continue
1454
1455 if (token == "bind"):
1456 output += "\n%s%s " % (tabs(indent), token)
1457 context.add(BIND)
1458 continue
1459
1460 if (token == "subsume"):
1461 output += "\n%s%s " % (tabs(indent), token)
1462 context.add(SUBSUME)
1463 continue
1464
1465 if (token == "delegate"):
1466 output += "\n%s%s " % (tabs(indent), token)
1467 context.add(DELEGATE)
1468 continue
1469
1470 print("%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture))
1471 continue
1472
1473 if (HEAD in context):
1474 if (token == "{"):
1475 output += "%s" % token
1476 indent += 1
1477 context.remove(HEAD)
1478 context.add(BODY)
1479 continue
1480
1481 if (token == ";"):
1482 output += "%s\n" % token
1483 context.remove(HEAD)
1484 context.remove(ARCH)
1485 context.discard(SYSTEM)
1486 continue
1487
1488 if (not word(token)):
1489 print("%s: Expected word in architecture head '%s'" % (inname, architecture))
1490 else:
1491 output += "%s " % token
1492
1493 continue
1494
1495 if (not identifier(token)):
1496 print("%s: Expected architecture name" % inname)
1497 else:
1498 architecture = token
1499 output += "%s " % token
1500
1501 if (not architecture in arch_properties):
1502 arch_properties[architecture] = {}
1503
1504 arch_properties[architecture]['name'] = architecture
1505
1506 if (SYSTEM in context):
1507 arch_properties[architecture]['system'] = True
1508
1509 context.add(HEAD)
1510 continue
1511
1512 # "system architecture"
1513
1514 if (SYSTEM in context):
1515 if (token != "architecture"):
1516 print("%s: Expected 'architecture'" % inname)
1517 else:
1518 output += "%s " % token
1519
1520 context.add(ARCH)
1521 continue
1522
1523 if (token == "frame"):
1524 output += "\n%s " % token
1525 context.add(FRAME)
1526 continue
1527
1528 if (token == "interface"):
1529 output += "\n%s " % token
1530 context.add(IFACE)
1531 continue
1532
1533 if (token == "system"):
1534 output += "\n%s " % token
1535 context.add(SYSTEM)
1536 continue
1537
1538 if (token == "architecture"):
1539 output += "\n%s " % token
1540 context.add(ARCH)
1541 continue
1542
1543 print("%s: Unknown token '%s'" % (inname, token))
1544
1545 inf.close()
1546
1547def open_adl(base, root, inname, outdir, outname):
1548 "Open Architecture Description file"
1549
1550 global output
1551 global context
1552 global architecture
1553 global interface
1554 global frame
1555 global protocol
1556 global initialization
1557 global finalization
1558
1559 global arg0
1560
1561 global opt_adl
1562
1563 output = ""
1564 context = set()
1565 architecture = None
1566 interface = None
1567 frame = None
1568 protocol = None
1569 initialization = None
1570 finalization = None
1571 arg0 = None
1572
1573 parse_adl(base, root, inname, False, 0)
1574 output = output.strip()
1575
1576 if ((output != "") and (opt_adl)):
1577 outf = open(outname, "w")
1578 outf.write(output)
1579 outf.close()
1580
1581def recursion(base, root, output, level):
1582 "Recursive directory walk"
1583
1584 for name in os.listdir(root):
1585 canon = os.path.join(root, name)
1586
1587 if (os.path.isfile(canon)):
1588 fcomp = split_tokens(canon, ["."])
1589 cname = canon.split("/")
1590
1591 if (fcomp[-1] == ".adl"):
1592 output_path = os.path.join(output, cname[-1])
1593 open_adl(base, root, canon, output, output_path)
1594
1595 if (os.path.isdir(canon)):
1596 recursion(base, canon, output, level + 1)
1597
1598def merge_dot_frame(prefix, name, frame, outf, indent):
1599 "Dump Dot frame"
1600
1601 outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
1602 outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
1603 outf.write("%s\tstyle=filled;\n" % tabs(indent))
1604 outf.write("%s\tcolor=red;\n" % tabs(indent))
1605 outf.write("%s\tfillcolor=yellow;\n" % tabs(indent))
1606 outf.write("%s\t\n" % tabs(indent))
1607
1608 if ('provides' in frame):
1609 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, style=filled, color=green, fillcolor=yellow];\n" % (tabs(indent), prefix))
1610
1611 if ('requires' in frame):
1612 outf.write("%s\t%s__requires [label=\"\", shape=circle, style=filled, color=red, fillcolor=yellow];\n" % (tabs(indent), prefix))
1613
1614 outf.write("%s}\n" % tabs(indent))
1615 outf.write("%s\n" % tabs(indent))
1616
1617def merge_dot_arch(prefix, name, arch, outf, indent):
1618 "Dump Dot subarchitecture"
1619
1620 outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
1621 outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
1622 outf.write("%s\tcolor=red;\n" % tabs(indent))
1623 outf.write("%s\t\n" % tabs(indent))
1624
1625 if ('inst' in arch):
1626 for inst in arch['inst']:
1627 subarch = get_arch(inst['type'])
1628 if (not subarch is None):
1629 merge_dot_arch("%s_%s" % (prefix, inst['var']), inst['var'], subarch, outf, indent + 1)
1630 else:
1631 subframe = get_frame(inst['type'])
1632 if (not subframe is None):
1633 merge_dot_frame("%s_%s" % (prefix, inst['var']), inst['var'], subframe, outf, indent + 1)
1634 else:
1635 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
1636
1637 if ('bind' in arch):
1638 labels = {}
1639 for bind in arch['bind']:
1640 if (bind['from'][1] != bind['to'][1]):
1641 label = "%s:%s" % (bind['from'][1], bind['to'][1])
1642 else:
1643 label = bind['from'][1]
1644
1645 if (not (bind['from'][0], bind['to'][0]) in labels):
1646 labels[(bind['from'][0], bind['to'][0])] = []
1647
1648 labels[(bind['from'][0], bind['to'][0])].append(label)
1649
1650 for bind in arch['bind']:
1651 if (not (bind['from'][0], bind['to'][0]) in labels):
1652 continue
1653
1654 attrs = []
1655
1656 if (bind['from'][0] != bind['to'][0]):
1657 attrs.append("ltail=cluster_%s_%s" % (prefix, bind['from'][0]))
1658 attrs.append("lhead=cluster_%s_%s" % (prefix, bind['to'][0]))
1659
1660 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1661 del labels[(bind['from'][0], bind['to'][0])]
1662
1663 outf.write("%s\t%s_%s__requires -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, bind['from'][0], prefix, bind['to'][0], ", ".join(attrs)))
1664
1665 if ('delegate' in arch):
1666 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, color=green];\n" % (tabs(indent), prefix))
1667
1668 labels = {}
1669 for delegate in arch['delegate']:
1670 if (delegate['from'] != delegate['to'][1]):
1671 label = "%s:%s" % (delegate['from'], delegate['to'][1])
1672 else:
1673 label = delegate['from']
1674
1675 if (not delegate['to'][0] in labels):
1676 labels[delegate['to'][0]] = []
1677
1678 labels[delegate['to'][0]].append(label)
1679
1680 for delegate in arch['delegate']:
1681 if (not delegate['to'][0] in labels):
1682 continue
1683
1684 attrs = []
1685 attrs.append("color=gray")
1686 attrs.append("lhead=cluster_%s_%s" % (prefix, delegate['to'][0]))
1687 attrs.append("label=\"%s\"" % "\\n".join(labels[delegate['to'][0]]))
1688 del labels[delegate['to'][0]]
1689
1690 outf.write("%s\t%s__provides -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, prefix, delegate['to'][0], ", ".join(attrs)))
1691
1692 if ('subsume' in arch):
1693 outf.write("%s\t%s__requires [label=\"\", shape=circle, color=red];\n" % (tabs(indent), prefix))
1694
1695 labels = {}
1696 for subsume in arch['subsume']:
1697 if (subsume['from'][1] != subsume['to']):
1698 label = "%s:%s" % (subsume['from'][1], subsume['to'])
1699 else:
1700 label = subsume['to']
1701
1702 if (not subsume['from'][0] in labels):
1703 labels[subsume['from'][0]] = []
1704
1705 labels[subsume['from'][0]].append(label)
1706
1707 for subsume in arch['subsume']:
1708 if (not subsume['from'][0] in labels):
1709 continue
1710
1711 attrs = []
1712 attrs.append("color=gray")
1713 attrs.append("ltail=cluster_%s_%s" % (prefix, subsume['from'][0]))
1714 attrs.append("label=\"%s\"" % "\\n".join(labels[subsume['from'][0]]))
1715 del labels[subsume['from'][0]]
1716
1717 outf.write("%s\t%s_%s__requires -> %s__requires [%s];\n" % (tabs(indent), prefix, subsume['from'][0], prefix, ", ".join(attrs)))
1718
1719 outf.write("%s}\n" % tabs(indent))
1720 outf.write("%s\n" % tabs(indent))
1721
1722def dump_dot(outdir):
1723 "Dump Dot architecture"
1724
1725 global opt_dot
1726
1727 arch = get_system_arch()
1728
1729 if (arch is None):
1730 print("Unable to find system architecture")
1731 return
1732
1733 if (opt_dot):
1734 outname = os.path.join(outdir, "%s.dot" % arch['name'])
1735 outf = open(outname, "w")
1736
1737 outf.write("digraph {\n")
1738 outf.write("\tlabel=\"%s\";\n" % arch['name'])
1739 outf.write("\tcompound=true;\n")
1740 outf.write("\tsplines=\"polyline\";\n")
1741 outf.write("\tedge [fontsize=8];\n")
1742 outf.write("\t\n")
1743
1744 if ('inst' in arch):
1745 for inst in arch['inst']:
1746 subarch = get_arch(inst['type'])
1747 if (not subarch is None):
1748 merge_dot_arch(inst['var'], inst['var'], subarch, outf, 1)
1749 else:
1750 subframe = get_frame(inst['type'])
1751 if (not subframe is None):
1752 merge_dot_frame("%s" % inst['var'], inst['var'], subframe, outf, 1)
1753 else:
1754 print("%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type']))
1755
1756 if ('bind' in arch):
1757 labels = {}
1758 for bind in arch['bind']:
1759 if (bind['from'][1] != bind['to'][1]):
1760 label = "%s:%s" % (bind['from'][1], bind['to'][1])
1761 else:
1762 label = bind['from'][1]
1763
1764 if (not (bind['from'][0], bind['to'][0]) in labels):
1765 labels[(bind['from'][0], bind['to'][0])] = []
1766
1767 labels[(bind['from'][0], bind['to'][0])].append(label)
1768
1769 for bind in arch['bind']:
1770 if (not (bind['from'][0], bind['to'][0]) in labels):
1771 continue
1772
1773 attrs = []
1774
1775 if (bind['from'][0] != bind['to'][0]):
1776 attrs.append("ltail=cluster_%s" % bind['from'][0])
1777 attrs.append("lhead=cluster_%s" % bind['to'][0])
1778
1779 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1780 del labels[(bind['from'][0], bind['to'][0])]
1781
1782 outf.write("\t%s__requires -> %s__provides [%s];\n" % (bind['from'][0], bind['to'][0], ", ".join(attrs)))
1783
1784 if ('delegate' in arch):
1785 for delegate in arch['delegate']:
1786 print("Unable to delegate interface in system architecture")
1787 break
1788
1789 if ('subsume' in arch):
1790 for subsume in arch['subsume']:
1791 print("Unable to subsume interface in system architecture")
1792 break
1793
1794 outf.write("}\n")
1795
1796 outf.close()
1797
1798def main():
1799 global iface_properties
1800 global frame_properties
1801 global arch_properties
1802 global opt_bp
1803 global opt_ebp
1804 global opt_adl
1805 global opt_dot
1806
1807 if (len(sys.argv) < 3):
1808 usage(sys.argv[0])
1809 return
1810
1811 opt_bp = False
1812 opt_ebp = False
1813 opt_adl = False
1814 opt_dot = False
1815
1816 for arg in sys.argv[1:(len(sys.argv) - 1)]:
1817 if (arg == "--bp"):
1818 opt_bp = True
1819 elif (arg == "--ebp"):
1820 opt_ebp = True
1821 elif (arg == "--adl"):
1822 opt_adl = True
1823 elif (arg == "--dot"):
1824 opt_dot = True
1825 elif (arg == "--nop"):
1826 pass
1827 else:
1828 print("Error: Unknown command line option '%s'" % arg)
1829 return
1830
1831 if ((opt_bp) and (opt_ebp)):
1832 print("Error: Cannot dump both original Behavior Protocols and Extended Behavior Protocols")
1833 return
1834
1835 path = os.path.abspath(sys.argv[-1])
1836 if (not os.path.isdir(path)):
1837 print("Error: <OUTPUT> is not a directory")
1838 return
1839
1840 iface_properties = {}
1841 frame_properties = {}
1842 arch_properties = {}
1843
1844 recursion(".", ".", path, 0)
1845 dump_archbp(path)
1846 dump_dot(path)
1847
1848if __name__ == '__main__':
1849 main()
Note: See TracBrowser for help on using the repository browser.