Create a slab cache for allocating phone_t structures
[helenos.git] / contrib / arch / hadlbppp.py
blob9415037449999498cc56ad5f23411224c1123538
1 #!/usr/bin/env python
3 # Copyright (c) 2009 Martin Decky
4 # All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
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.
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.
29 """
30 HelenOS Architecture Description Language and Behavior Protocols preprocessor
31 """
33 import sys
34 import os
36 INC, 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)
41 def usage(prname):
42 "Print usage syntax"
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()
53 def tabs(cnt):
54 "Return given number of tabs"
56 return ("\t" * cnt)
58 def cond_append(tokens, token, trim):
59 "Conditionally append token to tokens with trim"
61 if (trim):
62 token = token.strip(" \t")
64 if (token != ""):
65 tokens.append(token)
67 return tokens
69 def split_tokens(string, delimiters, trim = False, separate = False):
70 "Split string to tokens by delimiters, keep the delimiters"
72 tokens = []
73 last = 0
74 i = 0
76 while (i < len(string)):
77 for delim in delimiters:
78 if (len(delim) > 0):
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
89 i += len(delim) - 1
90 break
92 i += 1
94 tokens = cond_append(tokens, string[last:len(string)], trim)
96 return tokens
98 def identifier(token):
99 "Check whether the token is an identifier"
101 if (len(token) == 0):
102 return False
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
112 return True
114 def descriptor(token):
115 "Check whether the token is an interface descriptor"
117 parts = token.split(":")
118 if (len(parts) != 2):
119 return False
121 return (identifier(parts[0]) and identifier(parts[1]))
123 def word(token):
124 "Check whether the token is a word"
126 if (len(token) == 0):
127 return False
129 for i, char in enumerate(token):
130 if ((not char.isalnum()) and (char != "_") and (char != ".")):
131 return False
133 return True
135 def tentative_bp(name, tokens):
136 "Preprocess tentative statements in Behavior Protocol"
138 result = []
139 i = 0
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
148 while ((i < len(tokens)) and (level > 0)):
149 if (tokens[i] == "{"):
150 level += 1
151 elif (tokens[i] == "}"):
152 level -= 1
154 i += 1
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])
171 i += 1
173 return result
175 def alternative_bp(name, tokens):
176 "Preprocess alternative statements in Behavior Protocol"
178 result = []
179 i = 0
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 = []
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
194 if (len(reps) >= 2):
195 if ((i + 1 < len(tokens)) and (tokens[i + 1] == "{")):
196 i += 2
198 start = i
199 level = 1
201 while ((i < len(tokens)) and (level > 0)):
202 if (tokens[i] == "{"):
203 level += 1
204 elif (tokens[i] == "}"):
205 level -= 1
207 i += 1
209 if (level == 0):
210 first = True
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)
221 if (first):
222 first = False
223 else:
224 result.append("+")
226 result.append("(")
227 result.extend(alternative_bp(name, retokens))
228 result.append(")")
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])
243 i += 1
245 return result
247 def split_bp(protocol):
248 "Convert Behavior Protocol to tokens"
250 return split_tokens(protocol, ["\n", " ", "\t", "(", ")", "{", "}", "*", ";", "+", "||", "|", "!", "?"], True, True)
252 def extend_bp(name, tokens, iface):
253 "Convert interface Behavior Protocol to generic protocol"
255 result = []
256 i = 0
258 while (i < len(tokens)):
259 result.append(tokens[i])
261 if (tokens[i] == "?"):
262 if (i + 1 < len(tokens)):
263 i += 1
264 parts = tokens[i].split(".")
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)
273 i += 1
275 return result
277 def merge_bp(initialization, finalization, protocols):
278 "Merge several Behavior Protocols"
280 indep = []
282 if (len(protocols) > 1):
283 first = True
285 for protocol in protocols:
286 if (first):
287 first = False
288 else:
289 indep.append("|")
291 indep.append("(")
292 indep.extend(protocol)
293 indep.append(")")
294 elif (len(protocols) == 1):
295 indep = protocols[0]
297 inited = []
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
313 finited = []
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
329 return finited
331 def parse_bp(name, tokens, base_indent):
332 "Parse Behavior Protocol"
334 tokens = tentative_bp(name, tokens)
335 tokens = alternative_bp(name, tokens)
337 indent = base_indent
338 output = ""
340 for token in tokens:
341 if (token == "\n"):
342 continue
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)
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)
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
371 if (indent > base_indent):
372 print("%s: Missing parentheses" % name)
374 output = output.strip()
375 if (output == ""):
376 return "NULL"
378 return output
380 def parse_ebp(component, name, tokens, base_indent):
381 "Parse Behavior Protocol and generate Extended Behavior Protocol output"
383 return "component %s {\n\tbehavior {\n\t\t%s\n\t}\n}" % (component, parse_bp(name, tokens, base_indent + 2))
385 def get_iface(name):
386 "Get interface by name"
388 global iface_properties
390 if (name in iface_properties):
391 return iface_properties[name]
393 return None
395 def inherited_protocols(iface):
396 "Get protocols inherited by an interface"
398 result = []
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']))
409 return result
411 def dump_frame(directed_binds, frame, outdir, var, archf):
412 "Dump Behavior Protocol of a given frame"
414 global opt_bp
415 global opt_ebp
417 if (opt_ebp):
418 fname = "%s.ebp" % frame['name']
419 else:
420 fname = "%s.bp" % frame['name']
422 if (archf != None):
423 archf.write("instantiate %s from \"%s\"\n" % (var, fname))
425 outname = os.path.join(outdir, fname)
427 protocols = []
428 if ('protocol' in frame):
429 protocols.append(frame['protocol'])
431 if ('initialization' in frame):
432 initialization = frame['initialization']
433 else:
434 initialization = None
436 if ('finalization' in frame):
437 finalization = frame['finalization']
438 else:
439 finalization = None
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
451 if ('protocol' in iface):
452 proto = extend_bp(outname, iface['protocol'], iface['name'])
453 for _ in range(0, cnt):
454 protocols.append(proto)
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']))
463 if (opt_bp):
464 outf = open(outname, "w")
465 outf.write(parse_bp(outname, merge_bp(initialization, finalization, protocols), 0))
466 outf.close()
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()
473 def get_system_arch():
474 "Get system architecture"
476 global arch_properties
478 for arch, properties in arch_properties.items():
479 if ('system' in properties):
480 return properties
482 return None
484 def get_arch(name):
485 "Get architecture by name"
487 global arch_properties
489 if (name in arch_properties):
490 return arch_properties[name]
492 return None
494 def get_frame(name):
495 "Get frame by name"
497 global frame_properties
499 if (name in frame_properties):
500 return frame_properties[name]
502 return None
504 def create_null_bp(fname, outdir, archf):
505 "Create null frame protocol"
507 global opt_bp
508 global opt_ebp
510 if (archf != None):
511 archf.write("frame \"%s\"\n" % fname)
513 outname = os.path.join(outdir, fname)
515 if (opt_bp):
516 outf = open(outname, "w")
517 outf.write("NULL")
518 outf.close()
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()
525 def flatten_binds(binds, delegates, subsumes):
526 "Remove bindings which are replaced by delegation or subsumption"
528 result = []
529 stable = True
531 for bind in binds:
532 keep = True
534 for delegate in delegates:
535 if (bind['to'] == delegate['to']):
536 keep = False
537 result.append({'from': bind['from'], 'to': delegate['rep']})
539 for subsume in subsumes:
540 if (bind['from'] == subsume['from']):
541 keep = False
542 result.append({'from': subsume['rep'], 'to': bind['to']})
544 if (keep):
545 result.append(bind)
546 else:
547 stable = False
549 if (stable):
550 return result
551 else:
552 return flatten_binds(result, delegates, subsumes)
554 def direct_binds(binds):
555 "Convert bindings matrix to set of sources by destination"
557 result = {}
559 for bind in binds:
560 if (not bind['to'] in result):
561 result[bind['to']] = set()
563 result[bind['to']].add(bind['from'])
565 return result
567 def merge_arch(prefix, arch, outdir):
568 "Merge subarchitecture into architecture"
570 insts = []
571 binds = []
572 delegates = []
573 subsumes = []
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']))
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])})
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])})
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])})
603 return (insts, binds, delegates, subsumes)
605 def dump_archbp(outdir):
606 "Dump system architecture Behavior Protocol"
608 global opt_bp
609 global opt_ebp
611 arch = get_system_arch()
613 if (arch is None):
614 print("Unable to find system architecture")
615 return
617 insts = []
618 binds = []
619 delegates = []
620 subsumes = []
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']))
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])})
642 if ('delegate' in arch):
643 for delegate in arch['delegate']:
644 print("Unable to delegate interface in system architecture")
645 break
647 if ('subsume' in arch):
648 for subsume in arch['subsume']:
649 print("Unable to subsume interface in system architecture")
650 break
652 directed_binds = direct_binds(flatten_binds(binds, delegates, subsumes))
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
660 create_null_bp("null.bp", outdir, outf)
662 for inst in insts:
663 dump_frame(directed_binds, inst['frame'], outdir, inst['var'], outf)
665 for dst, src in directed_binds.items():
666 if (outf != None):
667 outf.write("bind %s to %s\n" % (", ".join(src), dst))
669 if (outf != None):
670 outf.close()
672 def preproc_adl(raw, inarg):
673 "Preprocess %% statements in ADL"
675 return raw.replace("%%", inarg)
677 def parse_adl(base, root, inname, nested, indent):
678 "Parse Architecture Description Language"
680 global output
681 global context
682 global architecture
683 global interface
684 global frame
685 global protocol
686 global initialization
687 global finalization
689 global iface_properties
690 global frame_properties
691 global arch_properties
693 global arg0
695 if (nested):
696 parts = inname.split("%")
698 if (len(parts) > 1):
699 inarg = parts[1]
700 else:
701 inarg = "%%"
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
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
718 inf = open(path, "r")
720 raw = preproc_adl(inf.read(), inarg)
721 tokens = split_tokens(raw, ["\n", " ", "\t", "(", ")", "{", "}", "[", "]", "/*", "*/", "#", ";"], True, True)
723 for token in tokens:
725 # Includes
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
733 if (POST_INC in context):
734 if (token != "]"):
735 print("%s: Expected ]" % inname)
737 context.remove(POST_INC)
738 continue
740 # Comments and newlines
742 if (BLOCK_COMMENT in context):
743 if (token == "*/"):
744 context.remove(BLOCK_COMMENT)
746 continue
748 if (LINE_COMMENT in context):
749 if (token == "\n"):
750 context.remove(LINE_COMMENT)
752 continue
754 # Any context
756 if (token == "/*"):
757 context.add(BLOCK_COMMENT)
758 continue
760 if (token == "#"):
761 context.add(LINE_COMMENT)
762 continue
764 if (token == "["):
765 context.add(INC)
766 continue
768 if (token == "\n"):
769 continue
771 # "frame"
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
780 context.remove(NULL)
781 context.remove(FRAME)
782 frame = None
783 continue
785 if (BODY in context):
786 if (FINALIZATION in context):
787 if (token == "{"):
788 indent += 1
789 elif (token == "}"):
790 indent -= 1
792 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
793 bp = split_bp(finalization)
794 finalization = None
796 if (not frame in frame_properties):
797 frame_properties[frame] = {}
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
804 output += "\n%s" % tabs(2)
805 output += parse_bp(inname, bp, 2)
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
820 if (INITIALIZATION in context):
821 if (token == "{"):
822 indent += 1
823 elif (token == "}"):
824 indent -= 1
826 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
827 bp = split_bp(initialization)
828 initialization = None
830 if (not frame in frame_properties):
831 frame_properties[frame] = {}
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
838 output += "\n%s" % tabs(2)
839 output += parse_bp(inname, bp, 2)
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
854 if (PROTOCOL in context):
855 if (token == "{"):
856 indent += 1
857 elif (token == "}"):
858 indent -= 1
860 if (((token[-1] == ":") and (indent == 0)) or (indent == -1)):
861 bp = split_bp(protocol)
862 protocol = None
864 if (not frame in frame_properties):
865 frame_properties[frame] = {}
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
872 output += "\n%s" % tabs(2)
873 output += parse_bp(inname, bp, 2)
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
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
895 context.remove(FIN)
896 continue
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] = {}
905 if (not 'requires' in frame_properties[frame]):
906 frame_properties[frame]['requires'] = []
908 frame_properties[frame]['requires'].append({'iface': arg0, 'var': token})
909 arg0 = None
911 output += "%s" % token
913 context.remove(VAR)
914 context.add(FIN)
915 continue
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)
926 context.add(VAR)
927 continue
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
936 context.remove(FIN)
937 continue
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] = {}
946 if (not 'provides' in frame_properties[frame]):
947 frame_properties[frame]['provides'] = []
949 frame_properties[frame]['provides'].append({'iface': arg0, 'var': token})
950 arg0 = None
952 output += "%s" % token
954 context.remove(VAR)
955 context.add(FIN)
956 continue
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)
967 context.add(VAR)
968 continue
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
977 context.remove(BODY)
978 context.add(NULL)
979 continue
981 if (token == "provides:"):
982 output += "\n%s%s" % (tabs(indent - 1), token)
983 context.add(PROVIDES)
984 continue
986 if (token == "requires:"):
987 output += "\n%s%s" % (tabs(indent - 1), token)
988 context.add(REQUIRES)
989 continue
991 if (token == "initialization:"):
992 output += "\n%s%s" % (tabs(indent - 1), token)
993 indent = 0
994 context.add(INITIALIZATION)
995 initialization = ""
996 continue
998 if (token == "finalization:"):
999 output += "\n%s%s" % (tabs(indent - 1), token)
1000 indent = 0
1001 context.add(FINALIZATION)
1002 finalization = ""
1003 continue
1005 if (token == "protocol:"):
1006 output += "\n%s%s" % (tabs(indent - 1), token)
1007 indent = 0
1008 context.add(PROTOCOL)
1009 protocol = ""
1010 continue
1012 print("%s: Unknown token '%s' in frame '%s'" % (inname, token, frame))
1013 continue
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
1023 if (token == ";"):
1024 output += "%s\n" % token
1025 context.remove(HEAD)
1026 context.remove(FRAME)
1027 continue
1029 print("%s: Unknown token '%s' in frame head '%s'" % (inname, token, frame))
1031 continue
1033 if (not identifier(token)):
1034 print("%s: Expected frame name" % inname)
1035 else:
1036 frame = token
1037 output += "%s " % token
1039 if (not frame in frame_properties):
1040 frame_properties[frame] = {}
1042 frame_properties[frame]['name'] = frame
1044 context.add(HEAD)
1045 continue
1047 # "interface"
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
1056 context.remove(NULL)
1057 context.remove(IFACE)
1058 interface = None
1059 continue
1061 if (BODY in context):
1062 if (PROTOCOL in context):
1063 if (token == "{"):
1064 indent += 1
1065 elif (token == "}"):
1066 indent -= 1
1068 if (indent == -1):
1069 bp = split_bp(protocol)
1070 protocol = None
1072 if (not interface in iface_properties):
1073 iface_properties[interface] = {}
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
1080 output += "\n%s" % tabs(2)
1081 output += parse_bp(inname, bp, 2)
1082 output += "\n%s" % token
1083 indent = 0
1085 context.remove(PROTOCOL)
1086 context.remove(BODY)
1087 context.add(NULL)
1088 else:
1089 protocol += token
1091 continue
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
1100 context.remove(FIN)
1101 context.remove(PROTOTYPE)
1102 continue
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
1112 continue
1114 if (SIGNATURE in context):
1115 output += "%s" % token
1116 if (token == ")"):
1117 context.remove(SIGNATURE)
1118 context.add(FIN)
1120 context.remove(SIGNATURE)
1121 context.add(PAR_RIGHT)
1122 continue
1124 if (PAR_LEFT in context):
1125 if (token != "("):
1126 print("%s: Expected '(' in interface '%s'" % (inname, interface))
1127 else:
1128 output += "%s" % token
1130 context.remove(PAR_LEFT)
1131 context.add(SIGNATURE)
1132 continue
1134 if (not identifier(token)):
1135 print("%s: Method identifier expected in interface '%s'" % (inname, interface))
1136 else:
1137 output += "%s" % token
1139 context.add(PAR_LEFT)
1140 continue
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
1149 context.remove(BODY)
1150 context.add(NULL)
1151 continue
1153 if (token == "sysarg_t"):
1154 output += "\n%s%s " % (tabs(indent), token)
1155 context.add(PROTOTYPE)
1156 continue
1158 if (token == "protocol:"):
1159 output += "\n%s%s" % (tabs(indent - 1), token)
1160 indent = 0
1161 context.add(PROTOCOL)
1162 protocol = ""
1163 continue
1165 print("%s: Unknown token '%s' in interface '%s'" % (inname, token, interface))
1166 continue
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
1178 if (token == ";"):
1179 output += "%s\n" % token
1180 context.remove(PRE_BODY)
1181 context.remove(HEAD)
1182 context.remove(IFACE)
1183 continue
1185 print("%s: Expected '{' or ';' in interface head '%s'" % (inname, interface))
1186 continue
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] = {}
1196 iface_properties[interface]['extends'] = token
1198 context.remove(EXTENDS)
1199 context.add(PRE_BODY)
1200 continue
1202 if (token == "extends"):
1203 output += "%s " % token
1204 context.add(EXTENDS)
1205 continue
1207 if (token == "{"):
1208 output += "%s" % token
1209 indent += 2
1210 context.remove(HEAD)
1211 context.add(BODY)
1212 continue
1214 if (token == ";"):
1215 output += "%s\n" % token
1216 context.remove(HEAD)
1217 context.remove(IFACE)
1218 continue
1220 print("%s: Expected 'extends', '{' or ';' in interface head '%s'" % (inname, interface))
1221 continue
1223 if (not identifier(token)):
1224 print("%s: Expected interface name" % inname)
1225 else:
1226 interface = token
1227 output += "%s " % token
1229 if (not interface in iface_properties):
1230 iface_properties[interface] = {}
1232 iface_properties[interface]['name'] = interface
1234 context.add(HEAD)
1235 continue
1237 # "architecture"
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
1246 context.remove(NULL)
1247 context.remove(ARCH)
1248 context.discard(SYSTEM)
1249 architecture = None
1250 continue
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
1260 context.remove(FIN)
1261 context.remove(DELEGATE)
1262 continue
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] = {}
1271 if (not 'delegate' in arch_properties[architecture]):
1272 arch_properties[architecture]['delegate'] = []
1274 arch_properties[architecture]['delegate'].append({'from': arg0, 'to': token.split(":")})
1275 arg0 = None
1277 output += "%s" % token
1279 context.add(FIN)
1280 context.remove(VAR)
1281 continue
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
1289 context.add(VAR)
1290 context.remove(TO)
1291 continue
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
1299 context.add(TO)
1300 continue
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
1309 context.remove(FIN)
1310 context.remove(SUBSUME)
1311 continue
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] = {}
1320 if (not 'subsume' in arch_properties[architecture]):
1321 arch_properties[architecture]['subsume'] = []
1323 arch_properties[architecture]['subsume'].append({'from': arg0.split(":"), 'to': token})
1324 arg0 = None
1326 output += "%s" % token
1328 context.add(FIN)
1329 context.remove(VAR)
1330 continue
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
1338 context.add(VAR)
1339 context.remove(TO)
1340 continue
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
1348 context.add(TO)
1349 continue
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
1358 context.remove(FIN)
1359 context.remove(BIND)
1360 continue
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] = {}
1369 if (not 'bind' in arch_properties[architecture]):
1370 arch_properties[architecture]['bind'] = []
1372 arch_properties[architecture]['bind'].append({'from': arg0.split(":"), 'to': token.split(":")})
1373 arg0 = None
1375 output += "%s" % token
1377 context.add(FIN)
1378 context.remove(VAR)
1379 continue
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
1387 context.add(VAR)
1388 context.remove(TO)
1389 continue
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
1397 context.add(TO)
1398 continue
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
1407 context.remove(FIN)
1408 context.remove(INST)
1409 continue
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] = {}
1418 if (not 'inst' in arch_properties[architecture]):
1419 arch_properties[architecture]['inst'] = []
1421 arch_properties[architecture]['inst'].append({'type': arg0, 'var': token})
1422 arg0 = None
1424 output += "%s" % token
1426 context.add(FIN)
1427 context.remove(VAR)
1428 continue
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
1436 context.add(VAR)
1437 continue
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
1446 context.remove(BODY)
1447 context.add(NULL)
1448 continue
1450 if (token == "inst"):
1451 output += "\n%s%s " % (tabs(indent), token)
1452 context.add(INST)
1453 continue
1455 if (token == "bind"):
1456 output += "\n%s%s " % (tabs(indent), token)
1457 context.add(BIND)
1458 continue
1460 if (token == "subsume"):
1461 output += "\n%s%s " % (tabs(indent), token)
1462 context.add(SUBSUME)
1463 continue
1465 if (token == "delegate"):
1466 output += "\n%s%s " % (tabs(indent), token)
1467 context.add(DELEGATE)
1468 continue
1470 print("%s: Unknown token '%s' in architecture '%s'" % (inname, token, architecture))
1471 continue
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
1481 if (token == ";"):
1482 output += "%s\n" % token
1483 context.remove(HEAD)
1484 context.remove(ARCH)
1485 context.discard(SYSTEM)
1486 continue
1488 if (not word(token)):
1489 print("%s: Expected word in architecture head '%s'" % (inname, architecture))
1490 else:
1491 output += "%s " % token
1493 continue
1495 if (not identifier(token)):
1496 print("%s: Expected architecture name" % inname)
1497 else:
1498 architecture = token
1499 output += "%s " % token
1501 if (not architecture in arch_properties):
1502 arch_properties[architecture] = {}
1504 arch_properties[architecture]['name'] = architecture
1506 if (SYSTEM in context):
1507 arch_properties[architecture]['system'] = True
1509 context.add(HEAD)
1510 continue
1512 # "system architecture"
1514 if (SYSTEM in context):
1515 if (token != "architecture"):
1516 print("%s: Expected 'architecture'" % inname)
1517 else:
1518 output += "%s " % token
1520 context.add(ARCH)
1521 continue
1523 if (token == "frame"):
1524 output += "\n%s " % token
1525 context.add(FRAME)
1526 continue
1528 if (token == "interface"):
1529 output += "\n%s " % token
1530 context.add(IFACE)
1531 continue
1533 if (token == "system"):
1534 output += "\n%s " % token
1535 context.add(SYSTEM)
1536 continue
1538 if (token == "architecture"):
1539 output += "\n%s " % token
1540 context.add(ARCH)
1541 continue
1543 print("%s: Unknown token '%s'" % (inname, token))
1545 inf.close()
1547 def open_adl(base, root, inname, outdir, outname):
1548 "Open Architecture Description file"
1550 global output
1551 global context
1552 global architecture
1553 global interface
1554 global frame
1555 global protocol
1556 global initialization
1557 global finalization
1559 global arg0
1561 global opt_adl
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
1573 parse_adl(base, root, inname, False, 0)
1574 output = output.strip()
1576 if ((output != "") and (opt_adl)):
1577 outf = open(outname, "w")
1578 outf.write(output)
1579 outf.close()
1581 def recursion(base, root, output, level):
1582 "Recursive directory walk"
1584 for name in os.listdir(root):
1585 canon = os.path.join(root, name)
1587 if (os.path.isfile(canon)):
1588 fcomp = split_tokens(canon, ["."])
1589 cname = canon.split("/")
1591 if (fcomp[-1] == ".adl"):
1592 output_path = os.path.join(output, cname[-1])
1593 open_adl(base, root, canon, output, output_path)
1595 if (os.path.isdir(canon)):
1596 recursion(base, canon, output, level + 1)
1598 def merge_dot_frame(prefix, name, frame, outf, indent):
1599 "Dump Dot frame"
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))
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))
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))
1614 outf.write("%s}\n" % tabs(indent))
1615 outf.write("%s\n" % tabs(indent))
1617 def merge_dot_arch(prefix, name, arch, outf, indent):
1618 "Dump Dot subarchitecture"
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))
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']))
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]
1645 if (not (bind['from'][0], bind['to'][0]) in labels):
1646 labels[(bind['from'][0], bind['to'][0])] = []
1648 labels[(bind['from'][0], bind['to'][0])].append(label)
1650 for bind in arch['bind']:
1651 if (not (bind['from'][0], bind['to'][0]) in labels):
1652 continue
1654 attrs = []
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]))
1660 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1661 del labels[(bind['from'][0], bind['to'][0])]
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)))
1665 if ('delegate' in arch):
1666 outf.write("%s\t%s__provides [label=\"\", shape=doublecircle, color=green];\n" % (tabs(indent), prefix))
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']
1675 if (not delegate['to'][0] in labels):
1676 labels[delegate['to'][0]] = []
1678 labels[delegate['to'][0]].append(label)
1680 for delegate in arch['delegate']:
1681 if (not delegate['to'][0] in labels):
1682 continue
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]]
1690 outf.write("%s\t%s__provides -> %s_%s__provides [%s];\n" % (tabs(indent), prefix, prefix, delegate['to'][0], ", ".join(attrs)))
1692 if ('subsume' in arch):
1693 outf.write("%s\t%s__requires [label=\"\", shape=circle, color=red];\n" % (tabs(indent), prefix))
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']
1702 if (not subsume['from'][0] in labels):
1703 labels[subsume['from'][0]] = []
1705 labels[subsume['from'][0]].append(label)
1707 for subsume in arch['subsume']:
1708 if (not subsume['from'][0] in labels):
1709 continue
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]]
1717 outf.write("%s\t%s_%s__requires -> %s__requires [%s];\n" % (tabs(indent), prefix, subsume['from'][0], prefix, ", ".join(attrs)))
1719 outf.write("%s}\n" % tabs(indent))
1720 outf.write("%s\n" % tabs(indent))
1722 def dump_dot(outdir):
1723 "Dump Dot architecture"
1725 global opt_dot
1727 arch = get_system_arch()
1729 if (arch is None):
1730 print("Unable to find system architecture")
1731 return
1733 if (opt_dot):
1734 outname = os.path.join(outdir, "%s.dot" % arch['name'])
1735 outf = open(outname, "w")
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")
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']))
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]
1764 if (not (bind['from'][0], bind['to'][0]) in labels):
1765 labels[(bind['from'][0], bind['to'][0])] = []
1767 labels[(bind['from'][0], bind['to'][0])].append(label)
1769 for bind in arch['bind']:
1770 if (not (bind['from'][0], bind['to'][0]) in labels):
1771 continue
1773 attrs = []
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])
1779 attrs.append("label=\"%s\"" % "\\n".join(labels[(bind['from'][0], bind['to'][0])]))
1780 del labels[(bind['from'][0], bind['to'][0])]
1782 outf.write("\t%s__requires -> %s__provides [%s];\n" % (bind['from'][0], bind['to'][0], ", ".join(attrs)))
1784 if ('delegate' in arch):
1785 for delegate in arch['delegate']:
1786 print("Unable to delegate interface in system architecture")
1787 break
1789 if ('subsume' in arch):
1790 for subsume in arch['subsume']:
1791 print("Unable to subsume interface in system architecture")
1792 break
1794 outf.write("}\n")
1796 outf.close()
1798 def 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
1807 if (len(sys.argv) < 3):
1808 usage(sys.argv[0])
1809 return
1811 opt_bp = False
1812 opt_ebp = False
1813 opt_adl = False
1814 opt_dot = False
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
1831 if ((opt_bp) and (opt_ebp)):
1832 print("Error: Cannot dump both original Behavior Protocols and Extended Behavior Protocols")
1833 return
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
1840 iface_properties = {}
1841 frame_properties = {}
1842 arch_properties = {}
1844 recursion(".", ".", path, 0)
1845 dump_archbp(path)
1846 dump_dot(path)
1848 if __name__ == '__main__':
1849 main()