source: mainline/contrib/arch/hadlbppp.py@ 77578e8

Last change on this file since 77578e8 was 4dd3912, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update python scripts

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