source: mainline/contrib/arch/hadlbppp.py@ d7365604

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d7365604 was c088fd4, checked in by Martin Decky <martin@…>, 16 years ago

draw bindings as line segments, not splines

  • Property mode set to 100755
File size: 45.9 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(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 if ('protocol' in iface):
446 protocols.append(extend_bp(outname, iface['protocol'], iface['name']))
447 for protocol in inherited_protocols(iface):
448 protocols.append(extend_bp(outname, protocol, iface['name']))
449 else:
450 print "%s: Provided interface '%s' is undefined" % (frame['name'], provides['iface'])
451
452 if (opt_bp):
453 outf = file(outname, "w")
454 outf.write(parse_bp(outname, merge_bp(initialization, finalization, protocols), 0))
455 outf.close()
456
457 if (opt_ebp):
458 outf = file(outname, "w")
459 outf.write(parse_ebp(frame['name'], outname, merge_bp(initialization, finalization, protocols), 0))
460 outf.close()
461
462def get_system_arch():
463 "Get system architecture"
464
465 global arch_properties
466
467 for arch, properties in arch_properties.items():
468 if ('system' in properties):
469 return properties
470
471 return None
472
473def get_arch(name):
474 "Get architecture by name"
475
476 global arch_properties
477
478 if (name in arch_properties):
479 return arch_properties[name]
480
481 return None
482
483def get_frame(name):
484 "Get frame by name"
485
486 global frame_properties
487
488 if (name in frame_properties):
489 return frame_properties[name]
490
491 return None
492
493def create_null_bp(fname, outdir, archf):
494 "Create null frame protocol"
495
496 global opt_bp
497 global opt_ebp
498
499 if (archf != None):
500 archf.write("frame \"%s\"\n" % fname)
501
502 outname = os.path.join(outdir, fname)
503
504 if (opt_bp):
505 outf = file(outname, "w")
506 outf.write("NULL")
507 outf.close()
508
509 if (opt_ebp):
510 outf = file(outname, "w")
511 outf.write("component null {\n\tbehavior {\n\t\tNULL\n\t}\n}")
512 outf.close()
513
514def flatten_binds(binds, delegates, subsumes):
515 "Remove bindings which are replaced by delegation or subsumption"
516
517 result = []
518 stable = True
519
520 for bind in binds:
521 keep = True
522
523 for delegate in delegates:
524 if (bind['to'] == delegate['to']):
525 keep = False
526 result.append({'from': bind['from'], 'to': delegate['rep']})
527
528 for subsume in subsumes:
529 if (bind['from'] == subsume['from']):
530 keep = False
531 result.append({'from': subsume['rep'], 'to': bind['to']})
532
533 if (keep):
534 result.append(bind)
535 else:
536 stable = False
537
538 if (stable):
539 return result
540 else:
541 return flatten_binds(result, delegates, subsumes)
542
543def direct_binds(binds):
544 "Convert bindings matrix to set of sources by destination"
545
546 result = {}
547
548 for bind in binds:
549 if (not bind['to'] in result):
550 result[bind['to']] = set()
551
552 result[bind['to']].add(bind['from'])
553
554 return result
555
556def merge_arch(prefix, arch, outdir):
557 "Merge subarchitecture into architecture"
558
559 insts = []
560 binds = []
561 delegates = []
562 subsumes = []
563
564 if ('inst' in arch):
565 for inst in arch['inst']:
566 subarch = get_arch(inst['type'])
567 if (not subarch is None):
568 (subinsts, subbinds, subdelegates, subsubsumes) = merge_arch("%s_%s" % (prefix, subarch['name']), subarch, outdir)
569 insts.extend(subinsts)
570 binds.extend(subbinds)
571 delegates.extend(subdelegates)
572 subsumes.extend(subsubsumes)
573 else:
574 subframe = get_frame(inst['type'])
575 if (not subframe is None):
576 insts.append({'var': "%s_%s" % (prefix, inst['var']), 'frame': subframe})
577 else:
578 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
579
580 if ('bind' in arch):
581 for bind in arch['bind']:
582 binds.append({'from': "%s_%s.%s" % (prefix, bind['from'][0], bind['from'][1]), 'to': "%s_%s.%s" % (prefix, bind['to'][0], bind['to'][1])})
583
584 if ('delegate' in arch):
585 for delegate in arch['delegate']:
586 delegates.append({'to': "%s.%s" % (prefix, delegate['from']), 'rep': "%s_%s.%s" % (prefix, delegate['to'][0], delegate['to'][1])})
587
588 if ('subsume' in arch):
589 for subsume in arch['subsume']:
590 subsumes.append({'from': "%s.%s" % (prefix, subsume['to']), 'rep': "%s_%s.%s" % (prefix, subsume['from'][0], subsume['from'][1])})
591
592 return (insts, binds, delegates, subsumes)
593
594def dump_archbp(outdir):
595 "Dump system architecture Behavior Protocol"
596
597 global opt_bp
598 global opt_ebp
599
600 arch = get_system_arch()
601
602 if (arch is None):
603 print "Unable to find system architecture"
604 return
605
606 insts = []
607 binds = []
608 delegates = []
609 subsumes = []
610
611 if ('inst' in arch):
612 for inst in arch['inst']:
613 subarch = get_arch(inst['type'])
614 if (not subarch is None):
615 (subinsts, subbinds, subdelegates, subsubsumes) = merge_arch(subarch['name'], subarch, outdir)
616 insts.extend(subinsts)
617 binds.extend(subbinds)
618 delegates.extend(subdelegates)
619 subsumes.extend(subsubsumes)
620 else:
621 subframe = get_frame(inst['type'])
622 if (not subframe is None):
623 insts.append({'var': inst['var'], 'frame': subframe})
624 else:
625 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
626
627 if ('bind' in arch):
628 for bind in arch['bind']:
629 binds.append({'from': "%s.%s" % (bind['from'][0], bind['from'][1]), 'to': "%s.%s" % (bind['to'][0], bind['to'][1])})
630
631 if ('delegate' in arch):
632 for delegate in arch['delegate']:
633 print "Unable to delegate interface in system architecture"
634 break
635
636 if ('subsume' in arch):
637 for subsume in arch['subsume']:
638 print "Unable to subsume interface in system architecture"
639 break
640
641 outname = os.path.join(outdir, "%s.archbp" % arch['name'])
642 if ((opt_bp) or (opt_ebp)):
643 outf = file(outname, "w")
644 else:
645 outf = None
646
647 create_null_bp("null.bp", outdir, outf)
648
649 for inst in insts:
650 dump_frame(inst['frame'], outdir, inst['var'], outf)
651
652 directed_binds = direct_binds(flatten_binds(binds, delegates, subsumes))
653
654 for dst, src in directed_binds.items():
655 if (outf != None):
656 outf.write("bind %s to %s\n" % (", ".join(src), dst))
657
658 if (outf != None):
659 outf.close()
660
661def preproc_adl(raw, inarg):
662 "Preprocess %% statements in ADL"
663
664 return raw.replace("%%", inarg)
665
666def parse_adl(base, root, inname, nested, indent):
667 "Parse Architecture Description Language"
668
669 global output
670 global context
671 global architecture
672 global interface
673 global frame
674 global protocol
675 global initialization
676 global finalization
677
678 global iface_properties
679 global frame_properties
680 global arch_properties
681
682 global arg0
683
684 if (nested):
685 parts = inname.split("%")
686
687 if (len(parts) > 1):
688 inarg = parts[1]
689 else:
690 inarg = "%%"
691
692 if (parts[0][0:1] == "/"):
693 path = os.path.join(base, ".%s" % parts[0])
694 nested_root = os.path.dirname(path)
695 else:
696 path = os.path.join(root, parts[0])
697 nested_root = root
698
699 if (not os.path.isfile(path)):
700 print "%s: Unable to include file %s" % (inname, path)
701 return ""
702 else:
703 inarg = "%%"
704 path = inname
705 nested_root = root
706
707 inf = file(path, "r")
708
709 raw = preproc_adl(inf.read(), inarg)
710 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
711
712 for token in tokens:
713
714 # Includes
715
716 if (INC in context):
717 context.remove(INC)
718 parse_adl(base, nested_root, token, True, indent)
719 context.add(POST_INC)
720 continue
721
722 if (POST_INC in context):
723 if (token != "]"):
724 print "%s: Expected ]" % inname
725
726 context.remove(POST_INC)
727 continue
728
729 # Comments and newlines
730
731 if (BLOCK_COMMENT in context):
732 if (token == "*/"):
733 context.remove(BLOCK_COMMENT)
734
735 continue
736
737 if (LINE_COMMENT in context):
738 if (token == "\n"):
739 context.remove(LINE_COMMENT)
740
741 continue
742
743 # Any context
744
745 if (token == "/*"):
746 context.add(BLOCK_COMMENT)
747 continue
748
749 if (token == "#"):
750 context.add(LINE_COMMENT)
751 continue
752
753 if (token == "["):
754 context.add(INC)
755 continue
756
757 if (token == "\n"):
758 continue
759
760 # "frame"
761
762 if (FRAME in context):
763 if (NULL in context):
764 if (token != ";"):
765 print "%s: Expected ';' in frame '%s'" % (inname, frame)
766 else:
767 output += "%s\n" % token
768
769 context.remove(NULL)
770 context.remove(FRAME)
771 frame = None
772 continue
773
774 if (BODY in context):
775 if (FINALIZATION in context):
776 if (token == "{"):
777 indent += 1
778 elif (token == "}"):
779 indent -= 1
780
781 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
782 bp = split_bp(finalization)
783 finalization = None
784
785 if (not frame in frame_properties):
786 frame_properties[frame] = {}
787
788 if ('finalization' in frame_properties[frame]):
789 print "%s: Finalization protocol for frame '%s' already defined" % (inname, frame)
790 else:
791 frame_properties[frame]['finalization'] = bp
792
793 output += "\n%s" % tabs(2)
794 output += parse_bp(inname, bp, 2)
795
796 context.remove(FINALIZATION)
797 if (indent == -1):
798 output += "\n%s" % token
799 context.remove(BODY)
800 context.add(NULL)
801 indent = 0
802 continue
803 else:
804 indent = 2
805 else:
806 finalization += token
807 continue
808
809 if (INITIALIZATION in context):
810 if (token == "{"):
811 indent += 1
812 elif (token == "}"):
813 indent -= 1
814
815 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
816 bp = split_bp(initialization)
817 initialization = None
818
819 if (not frame in frame_properties):
820 frame_properties[frame] = {}
821
822 if ('initialization' in frame_properties[frame]):
823 print "%s: Initialization protocol for frame '%s' already defined" % (inname, frame)
824 else:
825 frame_properties[frame]['initialization'] = bp
826
827 output += "\n%s" % tabs(2)
828 output += parse_bp(inname, bp, 2)
829
830 context.remove(INITIALIZATION)
831 if (indent == -1):
832 output += "\n%s" % token
833 context.remove(BODY)
834 context.add(NULL)
835 indent = 0
836 continue
837 else:
838 indent = 2
839 else:
840 initialization += token
841 continue
842
843 if (PROTOCOL in context):
844 if (token == "{"):
845 indent += 1
846 elif (token == "}"):
847 indent -= 1
848
849 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
850 bp = split_bp(protocol)
851 protocol = None
852
853 if (not frame in frame_properties):
854 frame_properties[frame] = {}
855
856 if ('protocol' in frame_properties[frame]):
857 print "%s: Protocol for frame '%s' already defined" % (inname, frame)
858 else:
859 frame_properties[frame]['protocol'] = bp
860
861 output += "\n%s" % tabs(2)
862 output += parse_bp(inname, bp, 2)
863
864 context.remove(PROTOCOL)
865 if (indent == -1):
866 output += "\n%s" % token
867 context.remove(BODY)
868 context.add(NULL)
869 indent = 0
870 continue
871 else:
872 indent = 2
873 else:
874 protocol += token
875 continue
876
877 if (REQUIRES in context):
878 if (FIN in context):
879 if (token != ";"):
880 print "%s: Expected ';' in frame '%s'" % (inname, frame)
881 else:
882 output += "%s" % token
883
884 context.remove(FIN)
885 continue
886
887 if (VAR in context):
888 if (not identifier(token)):
889 print "%s: Variable name expected in frame '%s'" % (inname, frame)
890 else:
891 if (not frame in frame_properties):
892 frame_properties[frame] = {}
893
894 if (not 'requires' in frame_properties[frame]):
895 frame_properties[frame]['requires'] = []
896
897 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
898 arg0 = None
899
900 output += "%s" % token
901
902 context.remove(VAR)
903 context.add(FIN)
904 continue
905
906 if ((token == "}") or (token[-1] == ":")):
907 context.remove(REQUIRES)
908 else:
909 if (not identifier(token)):
910 print "%s: Interface name expected in frame '%s'" % (inname, frame)
911 else:
912 arg0 = token
913 output += "\n%s%s " % (tabs(indent), token)
914
915 context.add(VAR)
916 continue
917
918 if (PROVIDES in context):
919 if (FIN in context):
920 if (token != ";"):
921 print "%s: Expected ';' in frame '%s'" % (inname, frame)
922 else:
923 output += "%s" % token
924
925 context.remove(FIN)
926 continue
927
928 if (VAR in context):
929 if (not identifier(token)):
930 print "%s: Variable name expected in frame '%s'" % (inname, frame)
931 else:
932 if (not frame in frame_properties):
933 frame_properties[frame] = {}
934
935 if (not 'provides' in frame_properties[frame]):
936 frame_properties[frame]['provides'] = []
937
938 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
939 arg0 = None
940
941 output += "%s" % token
942
943 context.remove(VAR)
944 context.add(FIN)
945 continue
946
947 if ((token == "}") or (token[-1] == ":")):
948 context.remove(PROVIDES)
949 else:
950 if (not identifier(token)):
951 print "%s: Interface name expected in frame '%s'" % (inname, frame)
952 else:
953 arg0 = token
954 output += "\n%s%s " % (tabs(indent), token)
955
956 context.add(VAR)
957 continue
958
959 if (token == "}"):
960 if (indent != 2):
961 print "%s: Wrong number of parentheses in frame '%s'" % (inname, frame)
962 else:
963 indent = 0
964 output += "\n%s" % token
965
966 context.remove(BODY)
967 context.add(NULL)
968 continue
969
970 if (token == "provides:"):
971 output += "\n%s%s" % (tabs(indent - 1), token)
972 context.add(PROVIDES)
973 continue
974
975 if (token == "requires:"):
976 output += "\n%s%s" % (tabs(indent - 1), token)
977 context.add(REQUIRES)
978 continue
979
980 if (token == "initialization:"):
981 output += "\n%s%s" % (tabs(indent - 1), token)
982 indent = 0
983 context.add(INITIALIZATION)
984 initialization = ""
985 continue
986
987 if (token == "finalization:"):
988 output += "\n%s%s" % (tabs(indent - 1), token)
989 indent = 0
990 context.add(FINALIZATION)
991 finalization = ""
992 continue
993
994 if (token == "protocol:"):
995 output += "\n%s%s" % (tabs(indent - 1), token)
996 indent = 0
997 context.add(PROTOCOL)
998 protocol = ""
999 continue
1000
1001 print "%s: Unknown token '%s' in frame '%s'" % (inname, token, frame)
1002 continue
1003
1004 if (HEAD in context):
1005 if (token == "{"):
1006 output += "%s" % token
1007 indent += 2
1008 context.remove(HEAD)
1009 context.add(BODY)
1010 continue
1011
1012 if (token == ";"):
1013 output += "%s\n" % token
1014 context.remove(HEAD)
1015 context.remove(FRAME)
1016 continue
1017
1018 print "%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame)
1019
1020 continue
1021
1022 if (not identifier(token)):
1023 print "%s: Expected frame name" % inname
1024 else:
1025 frame = token
1026 output += "%s " % token
1027
1028 if (not frame in frame_properties):
1029 frame_properties[frame] = {}
1030
1031 frame_properties[frame]['name'] = frame
1032
1033 context.add(HEAD)
1034 continue
1035
1036 # "interface"
1037
1038 if (IFACE in context):
1039 if (NULL in context):
1040 if (token != ";"):
1041 print "%s: Expected ';' in interface '%s'" % (inname, interface)
1042 else:
1043 output += "%s\n" % token
1044
1045 context.remove(NULL)
1046 context.remove(IFACE)
1047 interface = None
1048 continue
1049
1050 if (BODY in context):
1051 if (PROTOCOL in context):
1052 if (token == "{"):
1053 indent += 1
1054 elif (token == "}"):
1055 indent -= 1
1056
1057 if (indent == -1):
1058 bp = split_bp(protocol)
1059 protocol = None
1060
1061 if (not interface in iface_properties):
1062 iface_properties[interface] = {}
1063
1064 if ('protocol' in iface_properties[interface]):
1065 print "%s: Protocol for interface '%s' already defined" % (inname, interface)
1066 else:
1067 iface_properties[interface]['protocol'] = bp
1068
1069 output += "\n%s" % tabs(2)
1070 output += parse_bp(inname, bp, 2)
1071 output += "\n%s" % token
1072 indent = 0
1073
1074 context.remove(PROTOCOL)
1075 context.remove(BODY)
1076 context.add(NULL)
1077 else:
1078 protocol += token
1079
1080 continue
1081
1082 if (PROTOTYPE in context):
1083 if (FIN in context):
1084 if (token != ";"):
1085 print "%s: Expected ';' in interface '%s'" % (inname, interface)
1086 else:
1087 output += "%s" % token
1088
1089 context.remove(FIN)
1090 context.remove(PROTOTYPE)
1091 continue
1092
1093 if (PAR_RIGHT in context):
1094 if (token == ")"):
1095 output += "%s" % token
1096 context.remove(PAR_RIGHT)
1097 context.add(FIN)
1098 else:
1099 output += " %s" % token
1100
1101 continue
1102
1103 if (SIGNATURE in context):
1104 output += "%s" % token
1105 if (token == ")"):
1106 context.remove(SIGNATURE)
1107 context.add(FIN)
1108
1109 context.remove(SIGNATURE)
1110 context.add(PAR_RIGHT)
1111 continue
1112
1113 if (PAR_LEFT in context):
1114 if (token != "("):
1115 print "%s: Expected '(' in interface '%s'" % (inname, interface)
1116 else:
1117 output += "%s" % token
1118
1119 context.remove(PAR_LEFT)
1120 context.add(SIGNATURE)
1121 continue
1122
1123 if (not identifier(token)):
1124 print "%s: Method identifier expected in interface '%s'" % (inname, interface)
1125 else:
1126 output += "%s" % token
1127
1128 context.add(PAR_LEFT)
1129 continue
1130
1131 if (token == "}"):
1132 if (indent != 2):
1133 print "%s: Wrong number of parentheses in interface '%s'" % (inname, interface)
1134 else:
1135 indent = 0
1136 output += "\n%s" % token
1137
1138 context.remove(BODY)
1139 context.add(NULL)
1140 continue
1141
1142 if ((token == "ipcarg_t") or (token == "unative_t")):
1143 output += "\n%s%s " % (tabs(indent), token)
1144 context.add(PROTOTYPE)
1145 continue
1146
1147 if (token == "protocol:"):
1148 output += "\n%s%s" % (tabs(indent - 1), token)
1149 indent = 0
1150 context.add(PROTOCOL)
1151 protocol = ""
1152 continue
1153
1154 print "%s: Unknown token '%s' in interface '%s'" % (inname, token, interface)
1155 continue
1156
1157 if (HEAD in context):
1158 if (PRE_BODY in context):
1159 if (token == "{"):
1160 output += "%s" % token
1161 indent += 2
1162 context.remove(PRE_BODY)
1163 context.remove(HEAD)
1164 context.add(BODY)
1165 continue
1166
1167 if (token == ";"):
1168 output += "%s\n" % token
1169 context.remove(PRE_BODY)
1170 context.remove(HEAD)
1171 context.remove(IFACE)
1172 continue
1173
1174 print "%s: Expected '{' or ';' in interface head '%s'" % (inname, interface)
1175 continue
1176
1177 if (EXTENDS in context):
1178 if (not identifier(token)):
1179 print "%s: Expected inherited interface name in interface head '%s'" % (inname, interface)
1180 else:
1181 output += "%s " % token
1182 if (not interface in iface_properties):
1183 iface_properties[interface] = {}
1184
1185 iface_properties[interface]['extends'] = token
1186
1187 context.remove(EXTENDS)
1188 context.add(PRE_BODY)
1189 continue
1190
1191 if (token == "extends"):
1192 output += "%s " % token
1193 context.add(EXTENDS)
1194 continue
1195
1196 if (token == "{"):
1197 output += "%s" % token
1198 indent += 2
1199 context.remove(HEAD)
1200 context.add(BODY)
1201 continue
1202
1203 if (token == ";"):
1204 output += "%s\n" % token
1205 context.remove(HEAD)
1206 context.remove(IFACE)
1207 continue
1208
1209 print "%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface)
1210 continue
1211
1212 if (not identifier(token)):
1213 print "%s: Expected interface name" % inname
1214 else:
1215 interface = token
1216 output += "%s " % token
1217
1218 if (not interface in iface_properties):
1219 iface_properties[interface] = {}
1220
1221 iface_properties[interface]['name'] = interface
1222
1223 context.add(HEAD)
1224 continue
1225
1226 # "architecture"
1227
1228 if (ARCH in context):
1229 if (NULL in context):
1230 if (token != ";"):
1231 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1232 else:
1233 output += "%s\n" % token
1234
1235 context.remove(NULL)
1236 context.remove(ARCH)
1237 context.discard(SYSTEM)
1238 architecture = None
1239 continue
1240
1241 if (BODY in context):
1242 if (DELEGATE in context):
1243 if (FIN in context):
1244 if (token != ";"):
1245 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1246 else:
1247 output += "%s" % token
1248
1249 context.remove(FIN)
1250 context.remove(DELEGATE)
1251 continue
1252
1253 if (VAR in context):
1254 if (not descriptor(token)):
1255 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1256 else:
1257 if (not architecture in arch_properties):
1258 arch_properties[architecture] = {}
1259
1260 if (not 'delegate' in arch_properties[architecture]):
1261 arch_properties[architecture]['delegate'] = []
1262
1263 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1264 arg0 = None
1265
1266 output += "%s" % token
1267
1268 context.add(FIN)
1269 context.remove(VAR)
1270 continue
1271
1272 if (TO in context):
1273 if (token != "to"):
1274 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1275 else:
1276 output += "%s " % token
1277
1278 context.add(VAR)
1279 context.remove(TO)
1280 continue
1281
1282 if (not identifier(token)):
1283 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1284 else:
1285 output += "%s " % token
1286 arg0 = token
1287
1288 context.add(TO)
1289 continue
1290
1291 if (SUBSUME in context):
1292 if (FIN in context):
1293 if (token != ";"):
1294 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1295 else:
1296 output += "%s" % token
1297
1298 context.remove(FIN)
1299 context.remove(SUBSUME)
1300 continue
1301
1302 if (VAR in context):
1303 if (not identifier(token)):
1304 print "%s: Expected interface name in architecture '%s'" % (inname, architecture)
1305 else:
1306 if (not architecture in arch_properties):
1307 arch_properties[architecture] = {}
1308
1309 if (not 'subsume' in arch_properties[architecture]):
1310 arch_properties[architecture]['subsume'] = []
1311
1312 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1313 arg0 = None
1314
1315 output += "%s" % token
1316
1317 context.add(FIN)
1318 context.remove(VAR)
1319 continue
1320
1321 if (TO in context):
1322 if (token != "to"):
1323 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1324 else:
1325 output += "%s " % token
1326
1327 context.add(VAR)
1328 context.remove(TO)
1329 continue
1330
1331 if (not descriptor(token)):
1332 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1333 else:
1334 output += "%s " % token
1335 arg0 = token
1336
1337 context.add(TO)
1338 continue
1339
1340 if (BIND in context):
1341 if (FIN in context):
1342 if (token != ";"):
1343 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1344 else:
1345 output += "%s" % token
1346
1347 context.remove(FIN)
1348 context.remove(BIND)
1349 continue
1350
1351 if (VAR in context):
1352 if (not descriptor(token)):
1353 print "%s: Expected second interface descriptor in architecture '%s'" % (inname, architecture)
1354 else:
1355 if (not architecture in arch_properties):
1356 arch_properties[architecture] = {}
1357
1358 if (not 'bind' in arch_properties[architecture]):
1359 arch_properties[architecture]['bind'] = []
1360
1361 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1362 arg0 = None
1363
1364 output += "%s" % token
1365
1366 context.add(FIN)
1367 context.remove(VAR)
1368 continue
1369
1370 if (TO in context):
1371 if (token != "to"):
1372 print "%s: Expected 'to' in architecture '%s'" % (inname, architecture)
1373 else:
1374 output += "%s " % token
1375
1376 context.add(VAR)
1377 context.remove(TO)
1378 continue
1379
1380 if (not descriptor(token)):
1381 print "%s: Expected interface descriptor in architecture '%s'" % (inname, architecture)
1382 else:
1383 output += "%s " % token
1384 arg0 = token
1385
1386 context.add(TO)
1387 continue
1388
1389 if (INST in context):
1390 if (FIN in context):
1391 if (token != ";"):
1392 print "%s: Expected ';' in architecture '%s'" % (inname, architecture)
1393 else:
1394 output += "%s" % token
1395
1396 context.remove(FIN)
1397 context.remove(INST)
1398 continue
1399
1400 if (VAR in context):
1401 if (not identifier(token)):
1402 print "%s: Expected instance name in architecture '%s'" % (inname, architecture)
1403 else:
1404 if (not architecture in arch_properties):
1405 arch_properties[architecture] = {}
1406
1407 if (not 'inst' in arch_properties[architecture]):
1408 arch_properties[architecture]['inst'] = []
1409
1410 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1411 arg0 = None
1412
1413 output += "%s" % token
1414
1415 context.add(FIN)
1416 context.remove(VAR)
1417 continue
1418
1419 if (not identifier(token)):
1420 print "%s: Expected frame/architecture type in architecture '%s'" % (inname, architecture)
1421 else:
1422 output += "%s " % token
1423 arg0 = token
1424
1425 context.add(VAR)
1426 continue
1427
1428 if (token == "}"):
1429 if (indent != 1):
1430 print "%s: Wrong number of parentheses in architecture '%s'" % (inname, architecture)
1431 else:
1432 indent -= 1
1433 output += "\n%s" % token
1434
1435 context.remove(BODY)
1436 context.add(NULL)
1437 continue
1438
1439 if (token == "inst"):
1440 output += "\n%s%s " % (tabs(indent), token)
1441 context.add(INST)
1442 continue
1443
1444 if (token == "bind"):
1445 output += "\n%s%s " % (tabs(indent), token)
1446 context.add(BIND)
1447 continue
1448
1449 if (token == "subsume"):
1450 output += "\n%s%s " % (tabs(indent), token)
1451 context.add(SUBSUME)
1452 continue
1453
1454 if (token == "delegate"):
1455 output += "\n%s%s " % (tabs(indent), token)
1456 context.add(DELEGATE)
1457 continue
1458
1459 print "%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture)
1460 continue
1461
1462 if (HEAD in context):
1463 if (token == "{"):
1464 output += "%s" % token
1465 indent += 1
1466 context.remove(HEAD)
1467 context.add(BODY)
1468 continue
1469
1470 if (token == ";"):
1471 output += "%s\n" % token
1472 context.remove(HEAD)
1473 context.remove(ARCH)
1474 context.discard(SYSTEM)
1475 continue
1476
1477 if (not word(token)):
1478 print "%s: Expected word in architecture head '%s'" % (inname, architecture)
1479 else:
1480 output += "%s " % token
1481
1482 continue
1483
1484 if (not identifier(token)):
1485 print "%s: Expected architecture name" % inname
1486 else:
1487 architecture = token
1488 output += "%s " % token
1489
1490 if (not architecture in arch_properties):
1491 arch_properties[architecture] = {}
1492
1493 arch_properties[architecture]['name'] = architecture
1494
1495 if (SYSTEM in context):
1496 arch_properties[architecture]['system'] = True
1497
1498 context.add(HEAD)
1499 continue
1500
1501 # "system architecture"
1502
1503 if (SYSTEM in context):
1504 if (token != "architecture"):
1505 print "%s: Expected 'architecture'" % inname
1506 else:
1507 output += "%s " % token
1508
1509 context.add(ARCH)
1510 continue
1511
1512 if (token == "frame"):
1513 output += "\n%s " % token
1514 context.add(FRAME)
1515 continue
1516
1517 if (token == "interface"):
1518 output += "\n%s " % token
1519 context.add(IFACE)
1520 continue
1521
1522 if (token == "system"):
1523 output += "\n%s " % token
1524 context.add(SYSTEM)
1525 continue
1526
1527 if (token == "architecture"):
1528 output += "\n%s " % token
1529 context.add(ARCH)
1530 continue
1531
1532 print "%s: Unknown token '%s'" % (inname, token)
1533
1534 inf.close()
1535
1536def open_adl(base, root, inname, outdir, outname):
1537 "Open Architecture Description file"
1538
1539 global output
1540 global context
1541 global architecture
1542 global interface
1543 global frame
1544 global protocol
1545 global initialization
1546 global finalization
1547
1548 global arg0
1549
1550 global opt_adl
1551
1552 output = ""
1553 context = set()
1554 architecture = None
1555 interface = None
1556 frame = None
1557 protocol = None
1558 initialization = None
1559 finalization = None
1560 arg0 = None
1561
1562 parse_adl(base, root, inname, False, 0)
1563 output = output.strip()
1564
1565 if ((output != "") and (opt_adl)):
1566 outf = file(outname, "w")
1567 outf.write(output)
1568 outf.close()
1569
1570def recursion(base, root, output, level):
1571 "Recursive directory walk"
1572
1573 for name in os.listdir(root):
1574 canon = os.path.join(root, name)
1575
1576 if (os.path.isfile(canon)):
1577 fcomp = split_tokens(canon, ["."])
1578 cname = canon.split("/")
1579
1580 if (fcomp[-1] == ".adl"):
1581 output_path = os.path.join(output, cname[-1])
1582 open_adl(base, root, canon, output, output_path)
1583
1584 if (os.path.isdir(canon)):
1585 recursion(base, canon, output, level + 1)
1586
1587def merge_dot_frame(prefix, name, frame, outf, indent):
1588 "Dump Dot frame"
1589
1590 outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
1591 outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
1592 outf.write("%s\tstyle=filled;\n" % tabs(indent))
1593 outf.write("%s\tcolor=red;\n" % tabs(indent))
1594 outf.write("%s\tfillcolor=yellow;\n" % tabs(indent))
1595 outf.write("%s\t\n" % tabs(indent))
1596
1597 if ('provides' in frame):
1598 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, style=filled, color=green, fillcolor=yellow];\n" % (tabs(indent), prefix))
1599
1600 if ('requires' in frame):
1601 outf.write("%s\t%s__requires [label=\"\", shape=circle, style=filled, color=red, fillcolor=yellow];\n" % (tabs(indent), prefix))
1602
1603 outf.write("%s}\n" % tabs(indent))
1604 outf.write("%s\n" % tabs(indent))
1605
1606def merge_dot_arch(prefix, name, arch, outf, indent):
1607 "Dump Dot subarchitecture"
1608
1609 outf.write("%ssubgraph cluster_%s {\n" % (tabs(indent), prefix))
1610 outf.write("%s\tlabel=\"%s\";\n" % (tabs(indent), name))
1611 outf.write("%s\tcolor=red;\n" % tabs(indent))
1612 outf.write("%s\t\n" % tabs(indent))
1613
1614 if ('inst' in arch):
1615 for inst in arch['inst']:
1616 subarch = get_arch(inst['type'])
1617 if (not subarch is None):
1618 merge_dot_arch("%s_%s" % (prefix, inst['var']), inst['var'], subarch, outf, indent + 1)
1619 else:
1620 subframe = get_frame(inst['type'])
1621 if (not subframe is None):
1622 merge_dot_frame("%s_%s" % (prefix, inst['var']), inst['var'], subframe, outf, indent + 1)
1623 else:
1624 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
1625
1626 if ('bind' in arch):
1627 labels = {}
1628 for bind in arch['bind']:
1629 if (bind['from'][1] != bind['to'][1]):
1630 label = "%s:%s" % (bind['from'][1], bind['to'][1])
1631 else:
1632 label = bind['from'][1]
1633
1634 if (not (bind['from'][0], bind['to'][0]) in labels):
1635 labels[(bind['from'][0], bind['to'][0])] = []
1636
1637 labels[(bind['from'][0], bind['to'][0])].append(label)
1638
1639 for bind in arch['bind']:
1640 if (not (bind['from'][0], bind['to'][0]) in labels):
1641 continue
1642
1643 attrs = []
1644
1645 if (bind['from'][0] != bind['to'][0]):
1646 attrs.append("ltail=cluster_%s_%s" % (prefix, bind['from'][0]))
1647 attrs.append("lhead=cluster_%s_%s" % (prefix, bind['to'][0]))
1648
1649 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1650 del labels[(bind['from'][0], bind['to'][0])]
1651
1652 outf.write("%s\t%s_%s__requires -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, bind['from'][0], prefix, bind['to'][0], ", ".join(attrs)))
1653
1654 if ('delegate' in arch):
1655 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, color=green];\n" % (tabs(indent), prefix))
1656
1657 labels = {}
1658 for delegate in arch['delegate']:
1659 if (delegate['from'] != delegate['to'][1]):
1660 label = "%s:%s" % (delegate['from'], delegate['to'][1])
1661 else:
1662 label = delegate['from']
1663
1664 if (not delegate['to'][0] in labels):
1665 labels[delegate['to'][0]] = []
1666
1667 labels[delegate['to'][0]].append(label)
1668
1669 for delegate in arch['delegate']:
1670 if (not delegate['to'][0] in labels):
1671 continue
1672
1673 attrs = []
1674 attrs.append("color=gray")
1675 attrs.append("lhead=cluster_%s_%s" % (prefix, delegate['to'][0]))
1676 attrs.append("label=\"%s\"" % "\\n".join(labels[delegate['to'][0]]))
1677 del labels[delegate['to'][0]]
1678
1679 outf.write("%s\t%s__provides -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, prefix, delegate['to'][0], ", ".join(attrs)))
1680
1681 if ('subsume' in arch):
1682 outf.write("%s\t%s__requires [label=\"\", shape=circle, color=red];\n" % (tabs(indent), prefix))
1683
1684 labels = {}
1685 for subsume in arch['subsume']:
1686 if (subsume['from'][1] != subsume['to']):
1687 label = "%s:%s" % (subsume['from'][1], subsume['to'])
1688 else:
1689 label = subsume['to']
1690
1691 if (not subsume['from'][0] in labels):
1692 labels[subsume['from'][0]] = []
1693
1694 labels[subsume['from'][0]].append(label)
1695
1696 for subsume in arch['subsume']:
1697 if (not subsume['from'][0] in labels):
1698 continue
1699
1700 attrs = []
1701 attrs.append("color=gray")
1702 attrs.append("ltail=cluster_%s_%s" % (prefix, subsume['from'][0]))
1703 attrs.append("label=\"%s\"" % "\\n".join(labels[subsume['from'][0]]))
1704 del labels[subsume['from'][0]]
1705
1706 outf.write("%s\t%s_%s__requires -> %s__requires [%s];\n" % (tabs(indent), prefix, subsume['from'][0], prefix, ", ".join(attrs)))
1707
1708 outf.write("%s}\n" % tabs(indent))
1709 outf.write("%s\n" % tabs(indent))
1710
1711def dump_dot(outdir):
1712 "Dump Dot architecture"
1713
1714 global opt_dot
1715
1716 arch = get_system_arch()
1717
1718 if (arch is None):
1719 print "Unable to find system architecture"
1720 return
1721
1722 if (opt_dot):
1723 outname = os.path.join(outdir, "%s.dot" % arch['name'])
1724 outf = file(outname, "w")
1725
1726 outf.write("digraph {\n")
1727 outf.write("\tlabel=\"%s\";\n" % arch['name'])
1728 outf.write("\tcompound=true;\n")
1729 outf.write("\tsplines=\"polyline\";\n")
1730 outf.write("\tedge [fontsize=8];\n")
1731 outf.write("\t\n")
1732
1733 if ('inst' in arch):
1734 for inst in arch['inst']:
1735 subarch = get_arch(inst['type'])
1736 if (not subarch is None):
1737 merge_dot_arch(inst['var'], inst['var'], subarch, outf, 1)
1738 else:
1739 subframe = get_frame(inst['type'])
1740 if (not subframe is None):
1741 merge_dot_frame("%s" % inst['var'], inst['var'], subframe, outf, 1)
1742 else:
1743 print "%s: '%s' is neither an architecture nor a frame" % (arch['name'], inst['type'])
1744
1745 if ('bind' in arch):
1746 labels = {}
1747 for bind in arch['bind']:
1748 if (bind['from'][1] != bind['to'][1]):
1749 label = "%s:%s" % (bind['from'][1], bind['to'][1])
1750 else:
1751 label = bind['from'][1]
1752
1753 if (not (bind['from'][0], bind['to'][0]) in labels):
1754 labels[(bind['from'][0], bind['to'][0])] = []
1755
1756 labels[(bind['from'][0], bind['to'][0])].append(label)
1757
1758 for bind in arch['bind']:
1759 if (not (bind['from'][0], bind['to'][0]) in labels):
1760 continue
1761
1762 attrs = []
1763
1764 if (bind['from'][0] != bind['to'][0]):
1765 attrs.append("ltail=cluster_%s" % bind['from'][0])
1766 attrs.append("lhead=cluster_%s" % bind['to'][0])
1767
1768 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1769 del labels[(bind['from'][0], bind['to'][0])]
1770
1771 outf.write("\t%s__requires -> %s__provides [%s];\n" % (bind['from'][0], bind['to'][0], ", ".join(attrs)))
1772
1773 if ('delegate' in arch):
1774 for delegate in arch['delegate']:
1775 print "Unable to delegate interface in system architecture"
1776 break
1777
1778 if ('subsume' in arch):
1779 for subsume in arch['subsume']:
1780 print "Unable to subsume interface in system architecture"
1781 break
1782
1783 outf.write("}\n")
1784
1785 outf.close()
1786
1787def main():
1788 global iface_properties
1789 global frame_properties
1790 global arch_properties
1791 global opt_bp
1792 global opt_ebp
1793 global opt_adl
1794 global opt_dot
1795
1796 if (len(sys.argv) < 3):
1797 usage(sys.argv[0])
1798 return
1799
1800 opt_bp = False
1801 opt_ebp = False
1802 opt_adl = False
1803 opt_dot = False
1804
1805 for arg in sys.argv[1:(len(sys.argv) - 1)]:
1806 if (arg == "--bp"):
1807 opt_bp = True
1808 elif (arg == "--ebp"):
1809 opt_ebp = True
1810 elif (arg == "--adl"):
1811 opt_adl = True
1812 elif (arg == "--dot"):
1813 opt_dot = True
1814 elif (arg == "--nop"):
1815 pass
1816 else:
1817 print "Error: Unknown command line option '%s'" % arg
1818 return
1819
1820 if ((opt_bp) and (opt_ebp)):
1821 print "Error: Cannot dump both original Behavior Protocols and Extended Behavior Protocols"
1822 return
1823
1824 path = os.path.abspath(sys.argv[-1])
1825 if (not os.path.isdir(path)):
1826 print "Error: <OUTPUT> is not a directory"
1827 return
1828
1829 iface_properties = {}
1830 frame_properties = {}
1831 arch_properties = {}
1832
1833 recursion(".", ".", path, 0)
1834 dump_archbp(path)
1835 dump_dot(path)
1836
1837if __name__ == '__main__':
1838 main()
Note: See TracBrowser for help on using the repository browser.