sbdl 1.18.19__tar.gz → 1.18.21__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sbdl
3
- Version: 1.18.19
3
+ Version: 1.18.21
4
4
  Summary: System Behaviour Description Language (Compiler)
5
5
  Home-page: https://sbdl.dev
6
6
  Author: Michael A. Hicks
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sbdl
3
- Version: 1.18.19
3
+ Version: 1.18.21
4
4
  Summary: System Behaviour Description Language (Compiler)
5
5
  Home-page: https://sbdl.dev
6
6
  Author: Michael A. Hicks
@@ -1,84 +1,85 @@
1
1
  #!/usr/bin/python3
2
- _Ce='SteeringFirmware::correctCourse'
3
- _Cd='rocket_in_motion'
4
- _Cc='rocket_ready'
5
- _Cb='correct_course'
6
- _Ca='fire_booster'
7
- _CZ='steering_requirement_1'
8
- _CY='booster_requirement_1'
9
- _CX='steering_firmware'
10
- _CW='test/macro.py'
11
- _CV='--custom-mode'
12
- _CU='--custom-directive'
13
- _CT='template-fill'
14
- _CS='openfmea-csv'
15
- _CR='skinparam linetype ortho\n'
16
- _CQ='{} .{}.{} {}{}\n'
17
- _CP='\n{}{} "{}" as {} {}{}'
18
- _CO='Not a file: {}'
19
- _CN='Reading: {}'
20
- _CM='class_type_name'
21
- _CL='unicode_escape'
22
- _CK='identifier'
23
- _CJ='reference'
24
- _CI='^\\s*{}\\s*{}.*?{}\\s*$'
25
- _CH='customtype'
26
- _CG='arguments'
27
- _CF='skinparam NoteBackgroundColor LightSteelBlue\nskinparam ParticipantBackgroundColor LightGrey\nskinparam backgroundColor transparent'
28
- _CE='multipartite'
29
- _CD='sbdl_unique_identifier_gen_alphabet'
30
- _CC='sbdl_unique_identifier_gen_length'
31
- _CB='profile_output'
32
- _CA='fmea_cause_extension'
33
- _C9='openfmea_complex_aspect'
34
- _C8='openfmea_bidirectional_import_relations'
35
- _C7='openfmea_include_in_template'
36
- _C6='openfmea_fmeadev_url'
37
- _C5='openfmea_content_based_keys'
38
- _C4='openfmea_include_cme_unlinked'
39
- _C3='openfmea_include_cme_orphans'
40
- _C2='openfmea_expand_compoundfields'
41
- _C1='remote_procedure_call_api_endpoint'
42
- _C0='remote_procedure_call_api_key'
43
- _B_='remote_procedure_call_enable'
44
- _Bz='remote_resouce_fetch_enable'
45
- _By='sbdl_disable_pretty_print'
46
- _Bx='sbdl_disable_pretty_print_environ'
47
- _Bw='manual_command'
48
- _Bv='add_description_bsci_property'
49
- _Bu='elision_placeholder'
50
- _Bt='reference_maximum_length'
51
- _Bs='usecase_diagram_style'
52
- _Br='state_diagram_descriptions'
53
- _Bq='state_diagram_style'
54
- _Bp='uml_text_block_wrap_element'
55
- _Bo='process_diagram_descriptions'
56
- _Bn='function_diagram_aspect'
57
- _Bm='function_diagram_descriptions'
58
- _Bl='aspect_diagram_descriptions'
59
- _Bk='aspect_diagram_element'
60
- _Bj='aspect_diagram_aspect'
61
- _Bi='requirement_diagram_legend'
62
- _Bh='requirement_diagram_style'
63
- _Bg='requirement_diagram_title_node_always'
64
- _Bf='requirement_diagram_toplevel_depth'
65
- _Be='requirement_diagram_aspect_groups'
66
- _Bd='network_diagram_hide_types'
67
- _Bc='network_diagram_dpi'
68
- _Bb='network_diagram_layout'
69
- _Ba='network_diagram_labels'
70
- _BZ='network_diagram_descriptions'
71
- _BY='network_diagram_height'
72
- _BX='network_diagram_width'
73
- _BW='parser_allow_load_config'
74
- _BV='parser_allow_custom_directive_import'
75
- _BU='parser_custom_attributes'
76
- _BT='parser_allow_preparse_directives'
77
- _BS='plantuml_generate_footer'
78
- _BR='plantuml_output_type'
79
- _BQ='plantuml_limit_size'
80
- _BP='plantuml_command'
81
- _BO='wsl_auto_correct_paths'
2
+ _Cf='SteeringFirmware::correctCourse'
3
+ _Ce='rocket_in_motion'
4
+ _Cd='rocket_ready'
5
+ _Cc='correct_course'
6
+ _Cb='fire_booster'
7
+ _Ca='steering_requirement_1'
8
+ _CZ='booster_requirement_1'
9
+ _CY='steering_firmware'
10
+ _CX='test/macro.py'
11
+ _CW='--custom-mode'
12
+ _CV='--custom-directive'
13
+ _CU='template-fill'
14
+ _CT='openfmea-csv'
15
+ _CS='skinparam linetype ortho\n'
16
+ _CR='{} .{}.{} {}{}\n'
17
+ _CQ='\n{}{} "{}" as {} {}{}'
18
+ _CP='Not a file: {}'
19
+ _CO='Reading: {}'
20
+ _CN='class_type_name'
21
+ _CM='unicode_escape'
22
+ _CL='identifier'
23
+ _CK='reference'
24
+ _CJ='^\\s*{}\\s*{}.*?{}\\s*$'
25
+ _CI='customtype'
26
+ _CH='arguments'
27
+ _CG='skinparam NoteBackgroundColor LightSteelBlue\nskinparam ParticipantBackgroundColor LightGrey\nskinparam backgroundColor transparent'
28
+ _CF='multipartite'
29
+ _CE='sbdl_unique_identifier_gen_alphabet'
30
+ _CD='sbdl_unique_identifier_gen_length'
31
+ _CC='profile_output'
32
+ _CB='fmea_cause_extension'
33
+ _CA='openfmea_complex_aspect'
34
+ _C9='openfmea_bidirectional_import_relations'
35
+ _C8='openfmea_include_in_template'
36
+ _C7='openfmea_fmeadev_url'
37
+ _C6='openfmea_content_based_keys'
38
+ _C5='openfmea_include_cme_unlinked'
39
+ _C4='openfmea_include_cme_orphans'
40
+ _C3='openfmea_expand_compoundfields'
41
+ _C2='remote_procedure_call_api_endpoint'
42
+ _C1='remote_procedure_call_api_key'
43
+ _C0='remote_procedure_call_enable'
44
+ _B_='remote_resouce_fetch_enable'
45
+ _Bz='sbdl_disable_pretty_print'
46
+ _By='sbdl_disable_pretty_print_environ'
47
+ _Bx='manual_command'
48
+ _Bw='add_description_bsci_property'
49
+ _Bv='elision_placeholder'
50
+ _Bu='reference_maximum_length'
51
+ _Bt='usecase_diagram_style'
52
+ _Bs='state_diagram_descriptions'
53
+ _Br='state_diagram_style'
54
+ _Bq='uml_text_block_wrap_element'
55
+ _Bp='process_diagram_descriptions'
56
+ _Bo='function_diagram_aspect'
57
+ _Bn='function_diagram_descriptions'
58
+ _Bm='aspect_diagram_descriptions'
59
+ _Bl='aspect_diagram_element'
60
+ _Bk='aspect_diagram_aspect'
61
+ _Bj='requirement_diagram_legend'
62
+ _Bi='requirement_diagram_style'
63
+ _Bh='requirement_diagram_title_node_always'
64
+ _Bg='requirement_diagram_toplevel_depth'
65
+ _Bf='requirement_diagram_aspect_groups'
66
+ _Be='network_diagram_hide_types'
67
+ _Bd='network_diagram_dpi'
68
+ _Bc='network_diagram_layout'
69
+ _Bb='network_diagram_labels'
70
+ _Ba='network_diagram_descriptions'
71
+ _BZ='network_diagram_height'
72
+ _BY='network_diagram_width'
73
+ _BX='parser_allow_load_config'
74
+ _BW='parser_allow_custom_directive_import'
75
+ _BV='parser_custom_attributes'
76
+ _BU='parser_allow_preparse_directives'
77
+ _BT='plantuml_generate_footer'
78
+ _BS='plantuml_output_type'
79
+ _BR='plantuml_limit_size'
80
+ _BQ='plantuml_command'
81
+ _BP='wsl_auto_correct_paths'
82
+ _BO='sbdl_reference_prefix_strip'
82
83
  _BN='sbdl_caching_suffix'
83
84
  _BM='sbdl_caching_enabled'
84
85
  _BL='sbdl_import_allows_recurse'
@@ -221,15 +222,15 @@ _A=True
221
222
  import argparse,base64,datetime,csv,functools,getpass,hashlib,importlib,io,json,os,pathlib,pickle,platform,re,shlex,string,subprocess,sys,tarfile,tempfile,textwrap,time,traceback,types,unittest,urllib.request,urllib.parse,warnings,zlib,zipfile
222
223
  warnings.filterwarnings(_A1,category=DeprecationWarning)
223
224
  __NAME=_j
224
- __VERSION='1.18.19'
225
- __VERSION_DEV='ab2813a'
225
+ __VERSION='1.18.21'
226
+ __VERSION_DEV='af05bbc'
226
227
  __VERSION_DSL='25.6'
227
228
  __VERSION_REST_API='1.1.0'
228
229
  __AUTHOR='contact@sbdl.dev'
229
230
  __URL='https://sbdl.dev'
230
231
  __LOGO=''
231
232
  __HELP_TEXT=''
232
- _CONFIG_DATA={_B4:'_sbdl\\s?\\(',_B5:'\\)$',_B6:'_sbdl_block_begin',_B7:'_sbdl_block_end',_B8:'^\\.\\.\\.$',_B9:_B,_BA:_A,_BB:_C,_p:_A,_BC:{},_V:_C,_BD:_A,_BE:'.sbdl',_BF:_O,_BG:[],_k:[],_BH:5,_BI:_A,_BJ:'sbdl-package.tar.gz',_AL:_C,_A2:_C,_A3:_C,_BK:_A,_BL:_A,_BM:_C,_BN:'.sbdlc',_AM:{},_BO:_A,_l:_A,_A4:_C,_AN:_B,_AO:_C,_BP:'plantuml',_BQ:65536,_BR:'png',_BS:_A,_AP:_C,_AQ:_C,_A5:_A,_BT:_A,_AR:_A,_AS:_A,_T:{},_BU:_A,_BV:_A,_BW:_A,_BX:38,_BY:22,_BZ:_C,_Ba:_A,_AT:20000,_Bb:_CE,_Bc:200,_Bd:'',_Be:_C,_Bf:2,_Bg:_C,_W:"!pragma layout newlayouter\nskinparam dpi 200\nskinparam backgroundColor transparent\n'skinparam monochrome reverse\n\n",_Bh:'\n<style>\n node {\n HorizontalAlignment center\n MaximumWidth 150\n }\n wbsDiagram {\n Linecolor black\n arrow {\n LineColor black\n }\n .toplevel {\n }\n .source {\n LineStyle 2\n RoundCorner 10\n }\n .aspect {\n LineStyle 8.0;3.0\n LineColor lightgray\n BackgroundColor lightgray\n LineThickness 1.0\n RoundCorner 0\n Shadowing 0.0\n }\n }\n</style>',_Bi:_B,_AU:'hide circle',_Bj:'frame',_Bk:'class',_Bl:_C,_AV:_CF,_Bm:_C,_Bn:'participant','process_diagram_style':_CF,_Bo:_C,_q:_C,_b:15,_Bp:40,_Bq:'',_Br:_C,_Bs:'',_AW:_C,_Bt:0,_Bu:'[...]',_Bv:_C,_Bw:'less -R'if os.name=='posix'else'',_Bx:'SBDL_NO_PRETTY',_By:_C,_Bz:_A,_B_:_C,_C0:'1879da28-0fc2-4f1d-8ff1-407f4c070c44',_C1:'{base}/{endp}'.format(base=__URL,endp='rest.api'),_AX:'; ',_C2:'',_C3:_A,_C4:_A,_C5:_C,_C6:'https://fmea.dev',_C7:_A,_C8:_C,_C9:_C,_CA:_U,_CB:_B,_CC:8,_CD:'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'}
233
+ _CONFIG_DATA={_B4:'_sbdl\\s?\\(',_B5:'\\)$',_B6:'_sbdl_block_begin',_B7:'_sbdl_block_end',_B8:'^\\.\\.\\.$',_B9:_B,_BA:_A,_BB:_C,_p:_A,_BC:{},_V:_C,_BD:_A,_BE:'.sbdl',_BF:_O,_BG:[],_k:[],_BH:5,_BI:_A,_BJ:'sbdl-package.tar.gz',_AL:_C,_A2:_C,_A3:_C,_BK:_A,_BL:_A,_BM:_C,_BN:'.sbdlc',_AM:{},_BO:'',_BP:_A,_l:_A,_A4:_C,_AN:_B,_AO:_C,_BQ:'plantuml',_BR:65536,_BS:'png',_BT:_A,_AP:_C,_AQ:_C,_A5:_A,_BU:_A,_AR:_A,_AS:_A,_T:{},_BV:_A,_BW:_A,_BX:_A,_BY:38,_BZ:22,_Ba:_C,_Bb:_A,_AT:20000,_Bc:_CF,_Bd:200,_Be:'',_Bf:_C,_Bg:2,_Bh:_C,_W:"!pragma layout newlayouter\nskinparam dpi 200\nskinparam backgroundColor transparent\n'skinparam monochrome reverse\n\n",_Bi:'\n<style>\n node {\n HorizontalAlignment center\n MaximumWidth 150\n }\n wbsDiagram {\n Linecolor black\n arrow {\n LineColor black\n }\n .toplevel {\n }\n .source {\n LineStyle 2\n RoundCorner 10\n }\n .aspect {\n LineStyle 8.0;3.0\n LineColor lightgray\n BackgroundColor lightgray\n LineThickness 1.0\n RoundCorner 0\n Shadowing 0.0\n }\n }\n</style>',_Bj:_B,_AU:'hide circle',_Bk:'frame',_Bl:'class',_Bm:_C,_AV:_CG,_Bn:_C,_Bo:'participant','process_diagram_style':_CG,_Bp:_C,_q:_C,_b:15,_Bq:40,_Br:'',_Bs:_C,_Bt:'',_AW:_C,_Bu:0,_Bv:'[...]',_Bw:_C,_Bx:'less -R'if os.name=='posix'else'',_By:'SBDL_NO_PRETTY',_Bz:_C,_B_:_A,_C0:_C,_C1:'1879da28-0fc2-4f1d-8ff1-407f4c070c44',_C2:'{base}/{endp}'.format(base=__URL,endp='rest.api'),_AX:'; ',_C3:'',_C4:_A,_C5:_A,_C6:_C,_C7:'https://fmea.dev',_C8:_A,_C9:_C,_CA:_C,_CB:_U,_CC:_B,_CD:8,_CE:'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'}
233
234
  def name():return __NAME
234
235
  def version():return __VERSION
235
236
  def version_dev():return __VERSION_DEV
@@ -237,7 +238,7 @@ def version_dsl():return __VERSION_DSL
237
238
  def version_rest_api():return __VERSION_REST_API
238
239
  def author():return __AUTHOR
239
240
  def url():return __URL
240
- def allow_pretty_print():return not get_config_value(_Bx)in os.environ and not get_config_value(_By,number=_A)
241
+ def allow_pretty_print():return not get_config_value(_By)in os.environ and not get_config_value(_Bz,number=_A)
241
242
  def logo():return __LOGO if allow_pretty_print()else''
242
243
  def help_text():return __HELP_TEXT
243
244
  def current_os():
@@ -310,16 +311,16 @@ def lazy_import(package_name,custom_message=_B):
310
311
  return imported_package
311
312
  def fix_wsl_path(path):
312
313
  result=path
313
- if get_config_value(_BO,number=_A):
314
+ if get_config_value(_BP,number=_A):
314
315
  if result.startswith(_X)and not result.startswith('\\\\'):result='\\\\wsl$'+result;result=str(pathlib.Path(result))
315
316
  return result
316
317
  def rest_api_call(function_name,arguments_dict,print_l=print_null):
317
- D='result';C='api_version';B='errors';A='api_name';API_END_POINT=get_config_value(_C1);result_data={}
318
- def create_rest_object(command,arguments_dict):return{A:name(),C:version_rest_api(),'api_key':get_config_value(_C0),_Aa:command,_CG:{**arguments_dict}}
318
+ D='result';C='api_version';B='errors';A='api_name';API_END_POINT=get_config_value(_C2);result_data={}
319
+ def create_rest_object(command,arguments_dict):return{A:name(),C:version_rest_api(),'api_key':get_config_value(_C1),_Aa:command,_CH:{**arguments_dict}}
319
320
  def report_errors(response_struct):
320
321
  print_l('REST_API_CALL:: {} <-- {}'.format(API_END_POINT,response_struct),debug=_A)
321
322
  if B in response_struct and isinstance(response_struct[B],list)and len(response_struct[B])>0:print_l('REST_API_CALL:: Response errors: \n {}'.format(_G.join(response_struct[B])),error=_A)
322
- if get_config_value(_B_,number=_A):
323
+ if get_config_value(_C0,number=_A):
323
324
  rest_object=create_rest_object(function_name,arguments_dict);print_l('REST_API_CALL:: {} --> {}'.format(API_END_POINT,rest_object),debug=_A);request_point=urllib.request.Request(API_END_POINT);request_point.add_header('Content-Type','application/json; charset=utf-8');request_data=json.dumps(rest_object).encode(_r);request_point.add_header('Content-Length',len(request_data))
324
325
  try:rest_response=urllib.request.urlopen(request_point,request_data)
325
326
  except(urllib.error.HTTPError,urllib.error.URLError)as e:print_l('REST_API_CALL:: Error: {}'.format(e),error=_A);rest_response=e
@@ -341,10 +342,10 @@ def rest_api_call(function_name,arguments_dict,print_l=print_null):
341
342
  return result_data
342
343
  def rest_api_call_ping(print_l):print_l(rest_api_call('ping',{'date':get_date_string()},print_l=print_l));return 0
343
344
  class SBDL_Parser:
344
- class Statements:declaration='declaration';using='using';scope='scope';operator='operator';customtype=_CH
345
+ class Statements:declaration='declaration';using='using';scope='scope';operator='operator';customtype=_CI
345
346
  class Types:aspect=_c;requirement=_Y;mode='fmea:mode';effect='fmea:effect';cause='fmea:cause';current_control='fmea:control';current_detection='fmea:detection';action_control='fmea:action-control';action_detection='fmea:action-detection';test='test';definition='definition';realisation='realisation';function=_Aa;event='event';state='state';transition='transition';usecase='usecase';interface=_A6;trace='trace';group='group'
346
- class Tokens:declaration='is';declaration_group_delimeters=['{','}'];declaration_attribute_assign=' {} '.format(declaration);declaration_attribute_delimeter='"';general_separator=';';raw_content_delimiters=['[[[',']]]'];declaration_attribute_separator=general_separator;statement_separator=general_separator;hashbang='#!sbdl';prefix='@sbdl\\s';prefix_block_start='@sbdl\\-begin';prefix_block_end='@sbdl\\-end';comment='#';using='using';scope='scope';customtype=_CH;line_continuation=_X;replacement_string_default='';replacement_map={_S:',',';':';'};declaration_token_rule='\\s+{}\\s+'.format(declaration);declaration_rule='^.+?{}\\S+\\s*{}.*?{}\\s*$'.format(declaration_token_rule,declaration_group_delimeters[0],declaration_group_delimeters[1]);using_rule=_CI.format(using,declaration_group_delimeters[0],declaration_group_delimeters[1]);scope_rule=_CI.format(scope,declaration_group_delimeters[0],declaration_group_delimeters[1]);customtype_rule='^\\s*{}\\s+{}'.format(customtype,declaration_rule.replace('^',''));macro_delimeters=[_d,']'];macro_variable='@';macro_defer='%';macro_rule='\\{}{}(?:[^\\]\\\\]|\\\\.)*\\{}'.format(macro_delimeters[0],macro_variable,macro_delimeters[1]);macro_index_separator=':';whitespace_list=list(string.whitespace);escape=_X;stereotype_separator='^';link_operator='||';source_link_operator='~|';operator_rule='\\s*({}|{})\\s*'.format(_X+_X.join(link_operator),_X+_X.join(source_link_operator));inherit='inherit';compose='compose';hash_separator='~';scope_prefix=_m;stdio_name='-'
347
- class Attributes:description=_P;detectability=_s;detectability_post=_A7;severity=_t;occurrence=_u;occurrence_post=_A8;separator=_S;parent='parent';child='child';related='related';pragma='pragma';remark='remark';reference=_CJ;identifier=_CK;type=_K;types=_Z;stereotype='stereotype';actor=_Ab;tag='tag';description_bsci='description_bsci';precondition='precondition';postcondition='postcondition';invariant='invariant';output='output';input='input';custom_prefix='custom:';condition='condition';condition_alternative='alternative';custom_required_attr='required_property';custom_optional_attr='optional_property';custom_link_types='relation_type';color='color';control_only='control_only';return_control='return_control';raw_content='raw_content';loop_name='loop';parallel_name='parallel';port_name='port'
347
+ class Tokens:declaration='is';declaration_group_delimeters=['{','}'];declaration_attribute_assign=' {} '.format(declaration);declaration_attribute_delimeter='"';general_separator=';';raw_content_delimiters=['[[[',']]]'];declaration_attribute_separator=general_separator;statement_separator=general_separator;hashbang='#!sbdl';prefix='@sbdl\\s';prefix_block_start='@sbdl\\-begin';prefix_block_end='@sbdl\\-end';comment='#';using='using';scope='scope';customtype=_CI;line_continuation=_X;replacement_string_default='';replacement_map={_S:',',';':';'};declaration_token_rule='\\s+{}\\s+'.format(declaration);declaration_rule='^.+?{}\\S+\\s*{}.*?{}\\s*$'.format(declaration_token_rule,declaration_group_delimeters[0],declaration_group_delimeters[1]);using_rule=_CJ.format(using,declaration_group_delimeters[0],declaration_group_delimeters[1]);scope_rule=_CJ.format(scope,declaration_group_delimeters[0],declaration_group_delimeters[1]);customtype_rule='^\\s*{}\\s+{}'.format(customtype,declaration_rule.replace('^',''));macro_delimeters=[_d,']'];macro_variable='@';macro_defer='%';macro_rule='\\{}{}(?:[^\\]\\\\]|\\\\.)*\\{}'.format(macro_delimeters[0],macro_variable,macro_delimeters[1]);macro_index_separator=':';whitespace_list=list(string.whitespace);escape=_X;stereotype_separator='^';link_operator='||';source_link_operator='~|';operator_rule='\\s*({}|{})\\s*'.format(_X+_X.join(link_operator),_X+_X.join(source_link_operator));inherit='inherit';compose='compose';hash_separator='~';scope_prefix=_m;stdio_name='-'
348
+ class Attributes:description=_P;detectability=_s;detectability_post=_A7;severity=_t;occurrence=_u;occurrence_post=_A8;separator=_S;parent='parent';child='child';related='related';pragma='pragma';remark='remark';reference=_CK;identifier=_CL;type=_K;types=_Z;stereotype='stereotype';actor=_Ab;tag='tag';description_bsci='description_bsci';precondition='precondition';postcondition='postcondition';invariant='invariant';output='output';input='input';custom_prefix='custom:';condition='condition';condition_alternative='alternative';custom_required_attr='required_property';custom_optional_attr='optional_property';custom_link_types='relation_type';color='color';control_only='control_only';return_control='return_control';raw_content='raw_content';loop_name='loop';parallel_name='parallel';port_name='port'
348
349
  class Macros:self_element='SELF';self_reference='SELF_ID';self_reference_attr='SELF_PROP';abort='ABORT';message='MESSAGE';msg='MSG';date='DATE';user='USER';add='ADD';sub='SUB';equal='EQUAL';concat='CONCAT';instli='INSTLI';showall='SHOW_ALL';rmcom='RMCOM';mkid='MKID';dfp='DFP';requiredsl='REQUIRE_DSL_VERSION';requirecompiler='REQUIRE_COMPILER_VERSION';requiredsl_exact='REQUIRE_DSL_VERSION_EXACT';path='PATH';file_name='FILE';directory='DIR';context='CONTEXT';curline='=LINE';preline='-LINE';sucline='+LINE';line='LINE';import_sbdl='IMPORT';import_directive='IMPORT_DIRECTIVE';load_config='LOAD_CONFIG';git_commit_hash='GIT_COMMIT_HASH';define='DEFINE';define_append='DEFINE_APPEND';define_from_func='DEFUNC';define_from_index='DEFIND';define_from_file='DEFINEF';define_from_file_hash='DEFINEFH';expand_define='EXPAND';parsed_elements='PARSED_ELEMENTS';generated_elements='GENERATED_ELEMENTS';synthetic_element='SYNTHETIC_ELEMENT';cross_reference_available='CROSS_REFS_AVAILABLE';extend_cause='EXTEND_CAUSE';cpp_class='CPPCLASS';py_class='PYCLASS';c_func='CFUNC';py_func='PYFUNC';prolog_startup='PL_START';prolog_assert='PL_ASSERT';prolog_assert_n='PL_ASSERT!';prolog_cmd='PL_COMMAND';prolog_trace_file='PL_TRACE_FILE';prolog_result_output='PL_RESULT_OUTPUT';id_from_prop='ID_FROM_PROP'
349
350
  class Parser_Element:
350
351
  def __init__(self,content,source,indexes,context=''):self.__content=content;self.__source=source;self.__index=indexes;self.__context=context
@@ -381,8 +382,8 @@ class SBDL_Parser:
381
382
  def copy(self):return SBDL_Parser.Parser_Element(self.content(),self.source(),self.indexes(),self.context())
382
383
  @classmethod
383
384
  def shorten_reference(self,reference):
384
- reference_result=reference;max_length=get_config_value(_Bt,number=_A)
385
- if max_length!=_B and max_length>0:reference_result=(reference_result[::-1][:max_length]+(reference_result[::-1][max_length:]and get_config_value(_Bu)[::-1]))[::-1]
385
+ reference_result=reference.removeprefix(get_config_value(_BO));max_length=get_config_value(_Bu,number=_A)
386
+ if max_length!=_B and max_length>0:reference_result=(reference_result[::-1][:max_length]+(reference_result[::-1][max_length:]and get_config_value(_Bv)[::-1]))[::-1]
386
387
  return reference_result
387
388
  @classmethod
388
389
  def line_layout_content_indexes(self,content,indexes):
@@ -455,7 +456,7 @@ class SBDL_Parser:
455
456
  else:highest_severity=worst_severity
456
457
  return highest_severity if highest_severity>0 else worst_severity
457
458
  if SBDL_Parser.Macros.cross_reference_available in macros:
458
- extend_symbol=get_config_value(_CA)
459
+ extend_symbol=get_config_value(_CB)
459
460
  if len(inp)<1:raise Exception('No element identifier provided')
460
461
  this_elem=macros[macros[SBDL_Parser.Macros.self_reference]];this_aspect_links=[]
461
462
  if SBDL_Parser.Types.aspect in this_elem:
@@ -570,14 +571,14 @@ class SBDL_Parser:
570
571
  set_config_value(_AN,inp[0]);return''
571
572
  def import_directive(macros,*inp):
572
573
  param_path=''.join(inp);import_path=os.path.join(macros[SBDL_Parser.Macros.path].replace(macros[SBDL_Parser.Macros.file_name],''),param_path)
573
- if get_config_value(_BV,number=_A):
574
+ if get_config_value(_BW,number=_A):
574
575
  import_errors=import_custom_directive_file(import_path,f_print)
575
576
  if import_errors:raise self.MacroReplaceException(f'ERROR importing custom directive file: "{import_path}"',first_pass_can_ignore=_C)
576
577
  else:raise self.MacroReplaceException('ERROR import of custom directives is disabled',first_pass_can_ignore=_C)
577
578
  return''
578
579
  def load_config_directive(macros,*inp):
579
580
  param_path=''.join(inp);config_path=os.path.join(macros[SBDL_Parser.Macros.path].replace(macros[SBDL_Parser.Macros.file_name],''),param_path)
580
- if get_config_value(_BW,number=_A):
581
+ if get_config_value(_BX,number=_A):
581
582
  try:load_config(config_path,skip_keys=[_T])
582
583
  except Exception as e:raise self.MacroReplaceException(f"ERROR loading config: {e}",first_pass_can_ignore=_C)
583
584
  else:raise self.MacroReplaceException('ERROR loading of config is disabled',first_pass_can_ignore=_C)
@@ -585,7 +586,7 @@ class SBDL_Parser:
585
586
  def git_commit_hash(macros,*inp):
586
587
  param_path=''.join(inp);config_path=os.path.join(macros[SBDL_Parser.Macros.path].replace(macros[SBDL_Parser.Macros.file_name],''),param_path)
587
588
  try:repo_root=pathlib.Path(config_path).resolve();hash_value=subprocess.check_output(['git','-C',str(repo_root),'rev-parse','--short','HEAD'],text=_A).strip()
588
- except Exception as e:raise self.MacroReplaceException(f"ERROR retrieving Git commit hash: {e}",first_pass_can_ignore=_C)
589
+ except Exception as e:hash_value='GIT_HASH_UNAVAILABLE';f_print(f"{macros[SBDL_Parser.Macros.file_name]}:{macros[SBDL_Parser.Macros.line]}:: WARNING cannot retrieve Git commit hash: {e}",warning=_A)
589
590
  return hash_value
590
591
  def identifier_from_property(macros,*inp):
591
592
  A='SBDL_PROPERTY_VALUE_CACHE_MEMO'
@@ -866,14 +867,14 @@ class SBDL_Parser:
866
867
  return represult
867
868
  replace_list=[SBDL_Parser.Tokens.comment,SBDL_Parser.Tokens.declaration_attribute_delimeter,*SBDL_Parser.Tokens.declaration_group_delimeters];result=unclean_string
868
869
  for char_to_rep in replace_list:result=replace_unescapechar(result,char_to_rep)
869
- return result.encode(_CL).decode(_Ad).replace('\\\\',_X)
870
+ return result.encode(_CM).decode(_Ad).replace('\\\\',_X)
870
871
  @classmethod
871
872
  def sanitize_escaped(self,unclean_string,reverse=_C):
872
873
  escape_list=[[SBDL_Parser.Tokens.escape+SBDL_Parser.Tokens.declaration_group_delimeters[0],'##1'],[SBDL_Parser.Tokens.escape+SBDL_Parser.Tokens.declaration_group_delimeters[1],'##2']];result=unclean_string;incr=-1 if reverse else 1
873
874
  for escape_pair in escape_list:result=result.replace(*escape_pair[::incr])
874
875
  return result
875
876
  @classmethod
876
- def remove_escape_chars(self,escaped_string):return escaped_string.encode(_r).decode(_CL)
877
+ def remove_escape_chars(self,escaped_string):return escaped_string.encode(_r).decode(_CM)
877
878
  @classmethod
878
879
  def attribute_string(self,statement_object):
879
880
  indent_str='';newline_str='';spacing_str=_I
@@ -1019,12 +1020,12 @@ class SBDL_Semantics:
1019
1020
  if right_to_left:text_words.reverse()
1020
1021
  text_words=[x.capitalize()if not x.isupper()else x for x in text_words];return SBDL_Parser.sanitize_identifier(separator.join(text_words))
1021
1022
  @classmethod
1022
- def get_identifier_from_string_eng_standard(self,input_string,aggressive_length=20,min_word_len=3,separator='',right_to_left=_A):stop_words={'the','and','of','to','in','a','on','for','with','at','by','an',_A9,'shall','should','must','will','can','may','might','could','be','have','use','perform','execute','define','configure','manage','then'};stop_chars={'a','e','i','o','u'};abbreviations={'acceleration':'accel','actuator':'act','aerodynamics':'aero','analysis':'anal','approximate':'approx','architecture':'arch','assembly':'assy','auxiliary':'aux','battery':'batt','calculation':'calc','center of gravity':'cg','center of mass':'cm','coefficient':'coeff','configuration':'config',_o:'ctrl','controller':'cntrlr','coordinate':'coord','correction':'corr','current':'curr','data acquisition':'daq','decibel':'db','degrees of freedom':'dof','design':'des','development':'dev','diameter':'dia','dimension':'dim','dynamic':'dyn','efficiency':'eff','electrical':'elec','electromagnetic':'em','error':'err','estimate':'est','evaluation':'eval','failure mode and effects analysis':_x,'fatigue':'fat','feature':'feat','feedback':'fb','frequency':'freq',_Aa:'func','gradient':'grad','hardware':'hw','heat transfer':'ht','high voltage':'hv',_CK:'id','identification':'id','implementation':'impl','input':'in','inspection':'insp','instrumentation':'instr','integration':'intg',_A6:'intf','iteration':'iter','load':'ld','logic':'log','maintenance':'maint','management':'mgmt','manufacturing':'mfg','material':'matl','maximum':'max','measurement':'meas','mechanism':'mech','minimum':'min','model':'mdl','momentum':'mom','nominal':'nom','operating system':'os','optimization':'opt','output':'out','parameter':'param','performance':'perf','physics':'phys','position':'pos','power':'pwr','pressure':'pres','process':'proc','proportional-integral-derivative':'pid','quality assurance':'qa','radiation':'rad','redundancy':'redund',_CJ:'ref','reliability':'rel',_Y:'req','resolution':'res','resistance':'resist','safety':'sfty','sensor':'sens','simulation':'sim','software':'sw','specification':'spec','stability':'stab','static':'stat','structure':'struc','subsystem':'subsys',_A9:'sys','temperature':'temp','tension':'tens','testing':'test','thermal':'therm','torque':'torq','transient':'trans','uncertainty':'uncert','validation':'val','verification':'verif','voltage':'volt','weight':'wt','target':'targ'};return self.get_identifier_from_string(re.sub('[^a-zA-Z0-9.:_ ]+|(?<=.)\\.$','',input_string),aggressive_length,min_word_len,separator,stop_words=stop_words,stop_chars=stop_chars,abbreviations=abbreviations,right_to_left=right_to_left)
1023
+ def get_identifier_from_string_eng_standard(self,input_string,aggressive_length=20,min_word_len=3,separator='',right_to_left=_A):stop_words={'the','and','of','to','in','a','on','for','with','at','by','an',_A9,'shall','should','must','will','can','may','might','could','be','have','use','perform','execute','define','configure','manage','then'};stop_chars={'a','e','i','o','u'};abbreviations={'acceleration':'accel','actuator':'act','aerodynamics':'aero','analysis':'anal','approximate':'approx','architecture':'arch','assembly':'assy','auxiliary':'aux','battery':'batt','calculation':'calc','center of gravity':'cg','center of mass':'cm','coefficient':'coeff','configuration':'config',_o:'ctrl','controller':'cntrlr','coordinate':'coord','correction':'corr','current':'curr','data acquisition':'daq','decibel':'db','degrees of freedom':'dof','design':'des','development':'dev','diameter':'dia','dimension':'dim','dynamic':'dyn','efficiency':'eff','electrical':'elec','electromagnetic':'em','error':'err','estimate':'est','evaluation':'eval','failure mode and effects analysis':_x,'fatigue':'fat','feature':'feat','feedback':'fb','frequency':'freq',_Aa:'func','gradient':'grad','hardware':'hw','heat transfer':'ht','high voltage':'hv',_CL:'id','identification':'id','implementation':'impl','input':'in','inspection':'insp','instrumentation':'instr','integration':'intg',_A6:'intf','iteration':'iter','load':'ld','logic':'log','maintenance':'maint','management':'mgmt','manufacturing':'mfg','material':'matl','maximum':'max','measurement':'meas','mechanism':'mech','minimum':'min','model':'mdl','momentum':'mom','nominal':'nom','operating system':'os','optimization':'opt','output':'out','parameter':'param','performance':'perf','physics':'phys','position':'pos','power':'pwr','pressure':'pres','process':'proc','proportional-integral-derivative':'pid','quality assurance':'qa','radiation':'rad','redundancy':'redund',_CK:'ref','reliability':'rel',_Y:'req','resolution':'res','resistance':'resist','safety':'sfty','sensor':'sens','simulation':'sim','software':'sw','specification':'spec','stability':'stab','static':'stat','structure':'struc','subsystem':'subsys',_A9:'sys','temperature':'temp','tension':'tens','testing':'test','thermal':'therm','torque':'torq','transient':'trans','uncertainty':'uncert','validation':'val','verification':'verif','voltage':'volt','weight':'wt','target':'targ'};return self.get_identifier_from_string(re.sub('[^a-zA-Z0-9.:_ ]+|(?<=.)\\.$','',input_string),aggressive_length,min_word_len,separator,stop_words=stop_words,stop_chars=stop_chars,abbreviations=abbreviations,right_to_left=right_to_left)
1023
1024
  @classmethod
1024
1025
  def shorten_string_on_word_boundary(self,input_string,shorten_length):return _I.join(input_string.split()[-len(input_string[-shorten_length:].split()):])
1025
1026
  @classmethod
1026
1027
  def get_unique_id_from_string(self,input_string):
1027
- digest=hashlib.sha256(input_string.encode('utf‑8')).digest();alphabet=get_config_value(_CD);length=get_config_value(_CC,number=_A);num=int.from_bytes(digest,'big');base=len(alphabet);smart_key=[]
1028
+ digest=hashlib.sha256(input_string.encode('utf‑8')).digest();alphabet=get_config_value(_CE);length=get_config_value(_CD,number=_A);num=int.from_bytes(digest,'big');base=len(alphabet);smart_key=[]
1028
1029
  while len(smart_key)<length:num,idx=divmod(num,base);smart_key.append(alphabet[idx])
1029
1030
  return''.join(smart_key)
1030
1031
  @classmethod
@@ -1171,7 +1172,7 @@ class SBDL_Element:
1171
1172
  if self.type()==target:result=_A
1172
1173
  except Exception as _:pass
1173
1174
  if not result:
1174
- if isinstance(target,type)and hasattr(target,_CM):
1175
+ if isinstance(target,type)and hasattr(target,_CN):
1175
1176
  if target.class_type_name()==self.type()or target.class_type_name()in self.types():result=_A
1176
1177
  return result
1177
1178
  Element_Relation=Element_Link
@@ -1189,7 +1190,7 @@ class SBDL_Element:
1189
1190
  if self.type()==target:result=_A
1190
1191
  except Exception as _:pass
1191
1192
  if not result:
1192
- if isinstance(target,type)and hasattr(target,_CM):
1193
+ if isinstance(target,type)and hasattr(target,_CN):
1193
1194
  if target.class_type_name()in self.types():result=_A
1194
1195
  return result
1195
1196
  def __init__(self,declaration_statement):
@@ -1201,10 +1202,11 @@ class SBDL_Element:
1201
1202
  if self.type()in SBDL_Semantics.type_properties:
1202
1203
  for aprop in SBDL_Semantics.type_properties[self.type()]:self._gather_properties_from_attr_type(aprop)
1203
1204
  for aprop in SBDL_Semantics.global_properties:self._gather_properties_from_attr_type(aprop)
1204
- if get_config_value(_BU,number=_A):
1205
+ if get_config_value(_BV,number=_A):
1205
1206
  for aprop in[x for x in declaration_statement.data().keys()if x.startswith(SBDL_Parser.Attributes.custom_prefix)]:self._gather_properties_from_attr_type(aprop)
1206
1207
  self.__check_raise_attrs()
1207
1208
  if not SBDL_Parser.Attributes.reference in self.properties():self.set_property(SBDL_Parser.Attributes.reference,self._definition.parser_element().reference())
1209
+ else:self.set_property(SBDL_Parser.Attributes.reference,self.reference())
1208
1210
  def _gather_links_from_attr_type(self,attr_type,target_list):self._gather_links_from_attr_type_source(attr_type,self._definition.data(),target_list)
1209
1211
  def _gather_links_from_attr_type_source(self,attr_type,source_list,target_list):
1210
1212
  if attr_type in source_list:
@@ -1629,7 +1631,7 @@ class SBDL_AST:
1629
1631
  try:
1630
1632
  statement_element=SBDL_Element.statement_to_element(parsed_object)
1631
1633
  if not statement_element.identifier()in sbdl_elements:
1632
- if get_config_value(_Bv,number=_A)and statement_element.description():statement_element.set_property(SBDL_Parser.Attributes.description_bsci,SBDL_Semantics.calc_bsci(statement_element.description(),'english'))
1634
+ if get_config_value(_Bw,number=_A)and statement_element.description():statement_element.set_property(SBDL_Parser.Attributes.description_bsci,SBDL_Semantics.calc_bsci(statement_element.description(),'english'))
1633
1635
  sbdl_elements[statement_element.identifier()]=statement_element;sbdl_e_stack.append((statement_element,{}))
1634
1636
  else:error_count+=1;self.__parser_error(print_l,parsed_object.parser_element().reference(),'Element redefinition ({})'.format(statement_element.identifier()),parsed_object.parser_element().content())
1635
1637
  except Exception as e:error_count+=1;self.__parser_error(print_l,parsed_object.parser_element().reference(),str(e),parsed_object.parser_element().content())
@@ -1890,7 +1892,7 @@ def msexcel_input_handler(file_reference):
1890
1892
  return result,handler
1891
1893
  def make_remote_file_local(file_reference):
1892
1894
  local_file_reference=file_reference;parsed_file_reference=urllib.parse.urlparse(local_file_reference);error_string=_B
1893
- if parsed_file_reference.scheme in['http','https','ftp','file://']and get_config_value(_Bz,number=_A):
1895
+ if parsed_file_reference.scheme in['http','https','ftp','file://']and get_config_value(_B_,number=_A):
1894
1896
  try:local_file_reference,_=urllib.request.urlretrieve(local_file_reference)
1895
1897
  except Exception as e:error_string=str(e)+_d+file_reference+']'
1896
1898
  if error_string:raise Exception(error_string)
@@ -1988,7 +1990,7 @@ def get_parser_elements_from_filepath(filepath,elements_list,print_l=print_null,
1988
1990
  if pre_line==non_sbdl_line_prefix.strip():pre_line=prev_non_sbdl_non_empty_lines[-2].strip()
1989
1991
  return pre_line
1990
1992
  local_directives.update({SBDL_Parser.Macros.context:prev_non_sbdl_non_empty_lines[-1],SBDL_Parser.Macros.curline:non_sbdl_line_prefix,SBDL_Parser.Macros.preline:previous_line(),SBDL_Parser.Macros.sucline:next_non_sbdl_non_empty_lines[0],SBDL_Parser.Macros.line:str(line_count)})
1991
- if get_config_value(_BT,number=_A):
1993
+ if get_config_value(_BU,number=_A):
1992
1994
  try:result_line=SBDL_Parser.replace_directives(result_line,local_directives,throw_error=_A,print_l=print_l)[0].strip()
1993
1995
  except SBDL_Parser.MacroReplaceException as macro_excep:
1994
1996
  if not macro_excep.first_pass_can_ignore():raise macro_excep
@@ -2055,11 +2057,11 @@ def aggregate_all_parser_elements_from_files(input_list,do_recurse,do_hidden,pri
2055
2057
  else:print_l('Skipping directory: {}'.format(afile))
2056
2058
  elif is_input_file(afile):
2057
2059
  if not is_hidden(afile)or do_hidden:
2058
- print_l(_CN.format(afile))
2060
+ print_l(_CO.format(afile))
2059
2061
  try:parser_elements=[];errors_l=get_parser_elements_from_filepath(afile,parser_elements,print_l,file_opener,read_input_set);errors+=errors_l;aggregated_elements.extend(parser_elements)
2060
2062
  except Exception as e:errors+=1;print_l('Error reading: {}\n {}'.format(afile,str(e)),error=_A)
2061
2063
  else:print_l('Skipping hidden file: {}'.format(afile))
2062
- else:errors+=1;print_l(_CO.format(afile),error=_A)
2064
+ else:errors+=1;print_l(_CP.format(afile),error=_A)
2063
2065
  return aggregated_elements,errors
2064
2066
  def data_tree_node_to_element(identifier,data_node):
2065
2067
  if not isinstance(data_node,dict):raise Exception('Trying to extract tree information from not dict object')
@@ -2112,14 +2114,14 @@ def plantuml_writer(file_opener,output_file,content,_):
2112
2114
  content_to_output=content
2113
2115
  if not get_config_value(_AO,number=_A):
2114
2116
  try:
2115
- plantuml_env=os.environ.copy();plantuml_env.pop('LD_LIBRARY_PATH',_B);plantuml_env['PLANTUML_LIMIT_SIZE']=str(get_config_value(_BQ));plantuml_command=get_config_value(_BP)
2117
+ plantuml_env=os.environ.copy();plantuml_env.pop('LD_LIBRARY_PATH',_B);plantuml_env['PLANTUML_LIMIT_SIZE']=str(get_config_value(_BR));plantuml_command=get_config_value(_BQ)
2116
2118
  if isinstance(plantuml_command,str):plantuml_command=shlex.split(plantuml_command)
2117
- plantuml_command_full=plantuml_command+['-t',get_config_value(_BR),'-p'];debug_out('EXECUTE_PLANTUML: '+str(plantuml_command_full));exec_result=subprocess.run(plantuml_command_full,input=content.encode(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,env=plantuml_env,check=_C);content_to_output=exec_result.stdout
2119
+ plantuml_command_full=plantuml_command+['-t',get_config_value(_BS),'-p'];debug_out('EXECUTE_PLANTUML: '+str(plantuml_command_full));exec_result=subprocess.run(plantuml_command_full,input=content.encode(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,env=plantuml_env,check=_C);content_to_output=exec_result.stdout
2118
2120
  except:raise Exception('Error while executing PlantUML')
2119
2121
  with file_opener(output_file,is_text=get_config_value(_AO,number=_A))as plantuml_file:plantuml_file.write(content_to_output)
2120
2122
  def plantuml_footer_generator():
2121
2123
  footer_content=''
2122
- if get_config_value(_BS,number=_A):footer_content+='footer \\nGenerated by {generator} on {date}\\n\\n\n'.format(generator='{} version {}'.format(__NAME,__VERSION),date=get_date_string())
2124
+ if get_config_value(_BT,number=_A):footer_content+='footer \\nGenerated by {generator} on {date}\\n\\n\n'.format(generator='{} version {}'.format(__NAME,__VERSION),date=get_date_string())
2123
2125
  return footer_content
2124
2126
  def plantuml_identifier(in_string):
2125
2127
  result=in_string.strip(_I).replace('/',_U).replace(_N,_U).replace('-',_U).replace(_m,_U)
@@ -2129,7 +2131,7 @@ def write_requirement_graph_output(sbdl_ast,output_file,file_opener,arguments,pr
2129
2131
  B='rtype';A='rid';elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);requirements={k:v for(k,v)in elements.items()if v.is_a(SBDL_Requirement)};title_sanitized=SBDL_Parser.sanitize_identifier(arguments.title);root_requirement=SBDL_Element_Synthetic(title_sanitized,'',SBDL_Parser.Types.requirement,_B);root_requirement.add_link(SBDL_Element.Element_Link(title_sanitized,SBDL_Parser.Types.aspect));top_level_requirements=[]
2130
2132
  for(rid,rev)in requirements.items():
2131
2133
  if len(SBDL_AST.get_all_parents_for_element(rev,requirements))==0:top_level_requirements.append({A:rid,B:rev.type()})
2132
- if len(top_level_requirements)==1 and not get_config_value(_Bg):root_requirement=requirements[top_level_requirements[0][A]]
2134
+ if len(top_level_requirements)==1 and not get_config_value(_Bh):root_requirement=requirements[top_level_requirements[0][A]]
2133
2135
  else:
2134
2136
  for top_level_requirement in top_level_requirements:root_requirement.add_child(SBDL_Element.Element_Link(top_level_requirement[A],top_level_requirement[B]))
2135
2137
  def line_wrap(content,columns=1000):return _H.join(textwrap.wrap(content,columns))
@@ -2146,23 +2148,23 @@ def write_requirement_graph_output(sbdl_ast,output_file,file_opener,arguments,pr
2146
2148
  else:prefix+='<'
2147
2149
  rtype=''
2148
2150
  if depth==1:rtype='<<source>>'
2149
- elif depth<=get_config_value(_Bf):rtype='<<toplevel>>'
2151
+ elif depth<=get_config_value(_Bg):rtype='<<toplevel>>'
2150
2152
  else:rtype='<<regular>>'
2151
- occurrences=len(SBDL_AST.get_all_parents_for_element(r_element,requirements));output='{prefix} <i>{aspect} </i>\\n<b>{rid} </b>\\n{rdesc}{occ} {rtype}\n'.format(prefix=prefix,aspect=line_wrap(r_element.get_ids_string(sbdl_ast.get_all_links_for_element(r_element,elements),SBDL_Aspect)),rid=r_element.identifier(),rdesc=sanitize_desc(r_element.description()),occ='\\n<i>[{} occurrences]</i>'.format(occurrences)if occurrences>1 else'',rtype=rtype);children=SBDL_AST.get_all_children_for_element(r_element,requirements);children.sort(key=lambda x:requirements[x.identifier()].get_ids_string(sbdl_ast.get_all_links_for_element(requirements[x.identifier()],elements),SBDL_Aspect));last_child_aspect=_B;prefix=_O*(depth+1);aspect_groups=get_config_value(_Be)
2153
+ occurrences=len(SBDL_AST.get_all_parents_for_element(r_element,requirements));output='{prefix} <i>{aspect} </i>\\n<b>{rid} </b>\\n{rdesc}{occ} {rtype}\n'.format(prefix=prefix,aspect=line_wrap(r_element.get_ids_string(sbdl_ast.get_all_links_for_element(r_element,elements),SBDL_Aspect)),rid=r_element.identifier(),rdesc=sanitize_desc(r_element.description()),occ='\\n<i>[{} occurrences]</i>'.format(occurrences)if occurrences>1 else'',rtype=rtype);children=SBDL_AST.get_all_children_for_element(r_element,requirements);children.sort(key=lambda x:requirements[x.identifier()].get_ids_string(sbdl_ast.get_all_links_for_element(requirements[x.identifier()],elements),SBDL_Aspect));last_child_aspect=_B;prefix=_O*(depth+1);aspect_groups=get_config_value(_Bf)
2152
2154
  for child in children:
2153
2155
  child_aspect=requirements[child.identifier()].get_ids_string(sbdl_ast.get_all_links_for_element(requirements[child.identifier()],elements),SBDL_Aspect)
2154
2156
  if aspect_groups and child_aspect!=last_child_aspect:last_child_aspect=child_aspect;output+='{prefix} <i>{aspect} </i> <<aspect>>\n'.format(prefix=prefix,aspect=child_aspect)
2155
2157
  lr=not lr;output+=output_requirement_tree(requirements[child.identifier()],depth+2 if aspect_groups else depth+1,path+[r_element.identifier()],lr)
2156
2158
  return output
2157
2159
  def plantuml_requirement_diagram_wrap(content):
2158
- header=plantuml_footer_generator();legend_text='';legend=get_config_value(_Bi)
2160
+ header=plantuml_footer_generator();legend_text='';legend=get_config_value(_Bj)
2159
2161
  if legend!=_B:legend_text='legend\n{legend_content}\nendlegend\n'.format(legend_content=legend)
2160
- plant_uml_prepost='@startwbs\n{style}\n\n{header}\n{content}\n{legend}@endwbs\n';return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_Bh),header=header,content=content,legend=legend_text)
2162
+ plant_uml_prepost='@startwbs\n{style}\n\n{header}\n{content}\n{legend}@endwbs\n';return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_Bi),header=header,content=content,legend=legend_text)
2161
2163
  plantuml_writer(file_opener,output_file,plantuml_requirement_diagram_wrap(output_requirement_tree(root_requirement)),print_l);return errors
2162
2164
  def write_decomposition_graph_output(sbdl_ast,output_file,file_opener,arguments,print_l):
2163
2165
  elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A)
2164
2166
  def plantuml_decomposition_diagram():
2165
- header=plantuml_footer_generator();title=_y.format(arguments.title)if arguments.title!=''else'';plant_uml_prepost=_z;content='';notes='';note_count=0;interface_count=0;relations='';descriptions=get_config_value(_Bl,number=_A);interface_mem={};handled_elems=[];indentation_prefix=_M
2167
+ header=plantuml_footer_generator();title=_y.format(arguments.title)if arguments.title!=''else'';plant_uml_prepost=_z;content='';notes='';note_count=0;interface_count=0;relations='';descriptions=get_config_value(_Bm,number=_A);interface_mem={};handled_elems=[];indentation_prefix=_M
2166
2168
  def puml_id(elem_id):return plantuml_identifier(elem_id)
2167
2169
  def note_rel_pos(posindex):positions={0:'top',1:'bottom',2:_AA,3:_AB};return positions[posindex%4]
2168
2170
  def interface_rel_pos(posindex):positions={0:'up',1:'down',2:_AA,3:_AB};return positions[posindex%4]if get_config_value(_AP,number=_A)else''
@@ -2180,7 +2182,7 @@ def write_decomposition_graph_output(sbdl_ast,output_file,file_opener,arguments,
2180
2182
  aspect_stereotype=elements[elem_id].stereotype()
2181
2183
  if not aspect_stereotype:aspect_stereotype=elements[elem_id].type()
2182
2184
  else:aspect_stereotype=elements[elem_id].type()+_m+aspect_stereotype
2183
- aspect_stereotype=_Ak.format(aspect_stereotype);content+=_CP.format(pref,get_config_value(_Bj),elem_id,puml_id(elem_id),aspect_stereotype,''if not SBDL_Parser.Attributes.color in elements[elem_id].properties()else' #'+elements[elem_id].get_property(SBDL_Parser.Attributes.color));children=SBDL_AST.get_all_children_for_element(elements[elem_id],elements)
2185
+ aspect_stereotype=_Ak.format(aspect_stereotype);content+=_CQ.format(pref,get_config_value(_Bk),elem_id,puml_id(elem_id),aspect_stereotype,''if not SBDL_Parser.Attributes.color in elements[elem_id].properties()else' #'+elements[elem_id].get_property(SBDL_Parser.Attributes.color));children=SBDL_AST.get_all_children_for_element(elements[elem_id],elements)
2184
2186
  if len(children)>0 or len(interfaces):
2185
2187
  content+=' { '
2186
2188
  for port in ports:port_type='port'if len(interface_mem)%2==0 else'portout';add_interface_line(port,port_type,indentation_prefix)
@@ -2193,13 +2195,13 @@ def write_decomposition_graph_output(sbdl_ast,output_file,file_opener,arguments,
2193
2195
  if relation_type.startswith(SBDL_Parser.Tokens.inherit):relation_end='|>'
2194
2196
  elif elements[relation.identifier()].is_a(SBDL_Interface):relation_end='('
2195
2197
  elif relation_type.startswith(SBDL_Parser.Tokens.compose):relation_end=_O
2196
- relations+=_CQ.format(puml_id(elem_id),interface_rel_pos(interface_count),relation_end,puml_id(relation.identifier()),link_text);interface_count+=1
2198
+ relations+=_CR.format(puml_id(elem_id),interface_rel_pos(interface_count),relation_end,puml_id(relation.identifier()),link_text);interface_count+=1
2197
2199
  else:0
2198
2200
  elements_ordered=list(elements.keys());elements_ordered.sort(key=lambda key:len(SBDL_AST.get_all_parents_for_element(elements[key],elements)))
2199
2201
  for elem in elements_ordered:handle_elem(elem)
2200
2202
  for interface_id in interface_mem:
2201
2203
  for int_link in interface_mem[interface_id]:relations+='{} .{}. {}\n'.format(puml_id(interface_id),interface_rel_pos(interface_count),puml_id(int_link.identifier()));interface_count+=1
2202
- return plant_uml_prepost.format(style=(_CR if get_config_value(_AQ,number=_A)else'')+get_config_value(_W)+get_config_value(_AU),header=header+title,content=content+_D+relations+_D+(_D+notes if descriptions or arguments.source else''))
2204
+ return plant_uml_prepost.format(style=(_CS if get_config_value(_AQ,number=_A)else'')+get_config_value(_W)+get_config_value(_AU),header=header+title,content=content+_D+relations+_D+(_D+notes if descriptions or arguments.source else''))
2203
2205
  plantuml_writer(file_opener,output_file,plantuml_decomposition_diagram(),print_l);return errors
2204
2206
  def write_element_graph_output(sbdl_ast,output_file,file_opener,arguments,print_l):
2205
2207
  elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A)
@@ -2209,7 +2211,7 @@ def write_element_graph_output(sbdl_ast,output_file,file_opener,arguments,print_
2209
2211
  def interface_rel_pos(posindex):positions={0:'up',1:'down',2:_AA,3:_AB};return positions[posindex%4]if get_config_value(_AP,number=_A)else''
2210
2212
  def detailed_content(elem_id):
2211
2213
  props=[];links={};result='\t{}: **{}**\n'.format(SBDL_Parser.Attributes.type,elements[elem_id].type());elem=elements[elem_id]
2212
- for prop in elem.properties():props.append('\t{}:\n\t {}'.format(prop,textwrap.shorten(elem.get_property(prop),width=get_config_value(_Bp,number=_A),placeholder='...')))
2214
+ for prop in elem.properties():props.append('\t{}:\n\t {}'.format(prop,textwrap.shorten(elem.get_property(prop),width=get_config_value(_Bq,number=_A),placeholder='...')))
2213
2215
  for link in elem.links():
2214
2216
  if not link.type()in links:links[link.type()]=[]
2215
2217
  links[link.type()].append(link.identifier())
@@ -2230,20 +2232,20 @@ def write_element_graph_output(sbdl_ast,output_file,file_opener,arguments,print_
2230
2232
  aspect_stereotype=elements[elem_id].stereotype()
2231
2233
  if not aspect_stereotype:aspect_stereotype=elements[elem_id].type()
2232
2234
  else:aspect_stereotype=elements[elem_id].type()+_m+aspect_stereotype
2233
- aspect_stereotype=_Ak.format(aspect_stereotype);content+=_CP.format(pref,get_config_value(_Bk),elem_id,puml_id(elem_id),aspect_stereotype,''if not SBDL_Parser.Attributes.color in elements[elem_id].properties()else' #'+elements[elem_id].get_property(SBDL_Parser.Attributes.color));content+='{{\n{}\n}}\n'.format(detailed_content(elem_id));related=elements[elem_id].related();related.extend([link for link in elements[elem_id].links()])
2235
+ aspect_stereotype=_Ak.format(aspect_stereotype);content+=_CQ.format(pref,get_config_value(_Bl),elem_id,puml_id(elem_id),aspect_stereotype,''if not SBDL_Parser.Attributes.color in elements[elem_id].properties()else' #'+elements[elem_id].get_property(SBDL_Parser.Attributes.color));content+='{{\n{}\n}}\n'.format(detailed_content(elem_id));related=elements[elem_id].related();related.extend([link for link in elements[elem_id].links()])
2234
2236
  for relation in related:
2235
2237
  relation_type=relation.stereotype();relation_type=relation_type if relation_type else'';link_text=': '+relation_type if relation_type else'';relation_end='>'
2236
2238
  if relation_type.startswith(SBDL_Parser.Tokens.inherit):relation_end='|>'
2237
2239
  elif elements[relation.identifier()].is_a(SBDL_Parser.Types.interface):relation_end='('
2238
2240
  elif relation_type.startswith(SBDL_Parser.Tokens.compose):relation_end=_O
2239
- relations+=_CQ.format(puml_id(elem_id),interface_rel_pos(interface_count),relation_end,puml_id(relation.identifier()),link_text)
2241
+ relations+=_CR.format(puml_id(elem_id),interface_rel_pos(interface_count),relation_end,puml_id(relation.identifier()),link_text)
2240
2242
  else:0
2241
2243
  elements_ordered=list(elements.keys())
2242
2244
  for elem in elements_ordered:handle_elem(elem)
2243
- return plant_uml_prepost.format(style=(_CR if get_config_value(_AQ,number=_A)else'')+get_config_value(_W)+get_config_value(_AU),header=header+title,content=content+_D+relations+_D+(_D+''))
2245
+ return plant_uml_prepost.format(style=(_CS if get_config_value(_AQ,number=_A)else'')+get_config_value(_W)+get_config_value(_AU),header=header+title,content=content+_D+relations+_D+(_D+''))
2244
2246
  plantuml_writer(file_opener,output_file,plantuml_decomposition_diagram(),print_l);return errors
2245
2247
  def write_function_graph_output(sbdl_ast,output_file,file_opener,arguments,print_l):
2246
- elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);show_descriptions=get_config_value(_Bm,number=_A);event_count=0;entities={}
2248
+ elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);show_descriptions=get_config_value(_Bn,number=_A);event_count=0;entities={}
2247
2249
  def puml_id(elem_id):return plantuml_identifier(elem_id)
2248
2250
  def plantuml_function_diagram():
2249
2251
  header=plantuml_footer_generator();title=_y.format(arguments.title)if arguments.title!=''else'';plant_uml_prepost=_z;content='';empty_aspect_replace=_w
@@ -2263,7 +2265,7 @@ def write_function_graph_output(sbdl_ast,output_file,file_opener,arguments,print
2263
2265
  else:aspect_stereotype=elements[aspect_name].type()+_m+aspect_stereotype
2264
2266
  aspect_stereotype=_Ak.format(aspect_stereotype);aspect_color=''
2265
2267
  if aspect_name in elements and SBDL_Parser.Attributes.color in elements[aspect_name].properties():aspect_color=f" #{elements[aspect_name].get_property(SBDL_Parser.Attributes.color)}"
2266
- content+='{}{} "{}{}" as {} {}{}\n'.format(_M*depth,get_config_value(_Bn),aspect_name,_H+elements[aspect_name].reference()if arguments.source else'',puml_id(aspect_name),aspect_stereotype,aspect_color)
2268
+ content+='{}{} "{}{}" as {} {}{}\n'.format(_M*depth,get_config_value(_Bo),aspect_name,_H+elements[aspect_name].reference()if arguments.source else'',puml_id(aspect_name),aspect_stereotype,aspect_color)
2267
2269
  content+='group {}<<{}>> {}{} #red\n'.format(elem_colour_prefix(func_element),f"{func_element.type()}::{func_element.stereotype()}"if func_element.stereotype()else func_element.type(),puml_id(func_element.identifier()),_H+func_element.reference()if arguments.source else'')
2268
2270
  if show_descriptions:content+='{}note across: {}\n'.format(_M*depth,func_element.description())
2269
2271
  for child in children:
@@ -2301,7 +2303,7 @@ def write_function_graph_output(sbdl_ast,output_file,file_opener,arguments,print
2301
2303
  return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_AV),header=header+title,content=content)
2302
2304
  plantuml_writer(file_opener,output_file,plantuml_function_diagram(),print_l);return errors
2303
2305
  def write_process_graph_output(sbdl_ast,output_file,file_opener,_,print_l):
2304
- errors=0;elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);show_descriptions=get_config_value(_Bo,number=_A);first_event=_A;g_process_elem=_B;note_stagger=_C
2306
+ errors=0;elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);show_descriptions=get_config_value(_Bp,number=_A);first_event=_A;g_process_elem=_B;note_stagger=_C
2305
2307
  def elem_colour_prefix(elem):
2306
2308
  colour=''
2307
2309
  if SBDL_Parser.Attributes.color in elem.properties():colour=f"#{elem.get_property(SBDL_Parser.Attributes.color)} "
@@ -2351,7 +2353,7 @@ def write_process_graph_output(sbdl_ast,output_file,file_opener,_,print_l):
2351
2353
  process_dia_cont+='\n@enduml\n';return process_dia_cont
2352
2354
  plantuml_writer(file_opener,output_file,plantuml_process_diagram(),print_l);return errors
2353
2355
  def write_state_graph_output(sbdl_ast,output_file,file_opener,arguments,print_l):
2354
- elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);show_descriptions=get_config_value(_Br,number=_A)
2356
+ elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);show_descriptions=get_config_value(_Bs,number=_A)
2355
2357
  def plantuml_state_diagram():
2356
2358
  header=plantuml_footer_generator();title=_y.format(arguments.title)if arguments.title!=''else'';plant_uml_prepost=_z;statedefs='';statedefs_dict={};transitions_visited={};content='';relations=''
2357
2359
  def handle_elem(elem_id,depth=0):
@@ -2367,7 +2369,7 @@ def write_state_graph_output(sbdl_ast,output_file,file_opener,arguments,print_l)
2367
2369
  for elem_id in top_level_elems:
2368
2370
  if elements[elem_id].is_a(SBDL_State):handle_elem(elem_id)
2369
2371
  for statedef in statedefs_dict:statedefs+=statedefs_dict[statedef]+_D
2370
- return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_Bq),header=header+title,content=statedefs+content+_D+relations)
2372
+ return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_Br),header=header+title,content=statedefs+content+_D+relations)
2371
2373
  plantuml_writer(file_opener,output_file,plantuml_state_diagram(),print_l);return errors
2372
2374
  def write_usecase_graph_output(sbdl_ast,output_file,file_opener,arguments,print_l):
2373
2375
  elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A)
@@ -2385,18 +2387,18 @@ def write_usecase_graph_output(sbdl_ast,output_file,file_opener,arguments,print_
2385
2387
  content+='\nframe "{}" {{\n'.format(puml_id(aspect))
2386
2388
  for usecase_tuple in aspects[aspect]:content+=' usecase "{}" as {}\n'.format('**{}**\\n{}{}'.format(usecase_tuple[3],_H.join(textwrap.wrap(usecase_tuple[4],get_config_value(_b,number=_A))),_H+usecase_tuple[6]if arguments.source else'')if get_config_value(_AW,number=_A)else usecase_tuple[3],puml_id(usecase_tuple[3]));relations+='\n{} --> {}: {}{}\n'.format(puml_id(usecase_tuple[0]),puml_id(usecase_tuple[3]),'**{}**\\n{}'.format(usecase_tuple[1],_H.join(textwrap.wrap(usecase_tuple[2],get_config_value(_b,number=_A))))if get_config_value(_AW,number=_A)else usecase_tuple[1],_H+usecase_tuple[5]if arguments.source else'')
2387
2389
  content+='}\n'
2388
- content+=relations;return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_Bs),header=header+title,content=content)
2390
+ content+=relations;return plant_uml_prepost.format(style=get_config_value(_W)+get_config_value(_Bt),header=header+title,content=content)
2389
2391
  plantuml_writer(file_opener,output_file,plantuml_usecase_diagram(),print_l);return errors
2390
2392
  def write_network_graph_output(sbdl_ast,output_file,_,arguments,print_l):
2391
2393
  try:import networkx as nx,matplotlib.pyplot as plt
2392
2394
  except Exception as _:print_l('Could not import Python packages necessary for network graph rendering: networkx, matplotlib',error=_A);return 1
2393
- elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);sbdl_graph=nx.MultiDiGraph();skip_types={x for x in get_config_value(_Bd,number=_C).split(_S)};node_name_sep=_m;node_text_wrap_width=25
2395
+ elements,errors=sbdl_ast.elements(print_l,prune_missing_references=_A);sbdl_graph=nx.MultiDiGraph();skip_types={x for x in get_config_value(_Be,number=_C).split(_S)};node_name_sep=_m;node_text_wrap_width=25
2394
2396
  def node_name(elem_id):
2395
2397
  etype=elements[elem_id].type();stereotype=elements[elem_id].stereotype()
2396
2398
  if stereotype:stereotype=f"\n<<{etype}∷{stereotype}>>"
2397
2399
  else:stereotype=f"\n<<{etype}>>"
2398
2400
  node_text=_D.join(textwrap.wrap('{}{}{}'.format(elem_id,node_name_sep,elements[elem_id].type()),width=node_text_wrap_width));node_text+=stereotype
2399
- if get_config_value(_BZ,number=_A):node_text+=_f+_D.join(textwrap.wrap(elements[elem_id].description(),width=node_text_wrap_width))
2401
+ if get_config_value(_Ba,number=_A):node_text+=_f+_D.join(textwrap.wrap(elements[elem_id].description(),width=node_text_wrap_width))
2400
2402
  if arguments.source:node_text+=_f+_D.join(textwrap.wrap(elements[elem_id].reference(),width=node_text_wrap_width))
2401
2403
  return node_text
2402
2404
  def elem_id_f(node_name):return node_name_sep.join(node_name.replace(_D,'').split(node_name_sep)[:-1])
@@ -2412,11 +2414,11 @@ def write_network_graph_output(sbdl_ast,output_file,_,arguments,print_l):
2412
2414
  def mpl(graphin):return nx.multipartite_layout(graphin,subset_key='elem_type')
2413
2415
  def dot(graphin):return nx.nx_agraph.graphviz_layout(graphin,prog='dot',args='-Goverlap=false -Goverlap_scaling=1000000 -Gscale={} -Gsep=20 -Gdefaultdist=100000'.format(get_config_value(_AT,number=_A)))
2414
2416
  def spring(graphin):return nx.spring_layout(graphin,k=1)
2415
- layouts={_CE:mpl,'graphviz':dot,'spring':spring,'spiral':nx.spiral_layout,'random':nx.random_layout,'planar':nx.planar_layout};options={'font_size':10,'node_size':get_config_value(_AT,number=_A),'edgecolors':'gray','edge_color':'darkgray','linewidths':1,'with_labels':get_config_value(_Ba,number=_A),'width':2,'node_color':colour_list,'node_shape':'s','pos':layouts[get_config_value(_Bb,number=_C)](sbdl_graph)};plt.figure(figsize=(get_config_value(_BX,number=_A),get_config_value(_BY,number=_A)));nx.draw_networkx(sbdl_graph,**options,alpha=1.);ax=plt.gca();ax.margins(.0);plt.axis('off');plt.tight_layout();plt.plot();plt.savefig(output_file,dpi=get_config_value(_Bc,number=_A));return errors
2417
+ layouts={_CF:mpl,'graphviz':dot,'spring':spring,'spiral':nx.spiral_layout,'random':nx.random_layout,'planar':nx.planar_layout};options={'font_size':10,'node_size':get_config_value(_AT,number=_A),'edgecolors':'gray','edge_color':'darkgray','linewidths':1,'with_labels':get_config_value(_Bb,number=_A),'width':2,'node_color':colour_list,'node_shape':'s','pos':layouts[get_config_value(_Bc,number=_C)](sbdl_graph)};plt.figure(figsize=(get_config_value(_BY,number=_A),get_config_value(_BZ,number=_A)));nx.draw_networkx(sbdl_graph,**options,alpha=1.);ax=plt.gca();ax.margins(.0);plt.axis('off');plt.tight_layout();plt.plot();plt.savefig(output_file,dpi=get_config_value(_Bd,number=_A));return errors
2416
2418
  class OpenFMEA:
2417
2419
  @classmethod
2418
2420
  def generate_sbdl_table_from_ast(self,sbdl_ast,id_in_body=_C,source_in_body=_C,print_l=print_null,multi_field_separator=_B):
2419
- A='key';complex_aspect=get_config_value(_C9,number=_A)
2421
+ A='key';complex_aspect=get_config_value(_CA,number=_A)
2420
2422
  if multi_field_separator is _B:multi_field_separator=get_config_value(_AX)
2421
2423
  id_counter=0;sbdl_row={A:_B,_c:_B,_Y:_B,_L:_B,_a:_B,_R:_B,_o:_B,_g:_B,_t:_B,_u:_B,_A8:_B,_s:_B,_A7:_B,_A0:_B,_h:_B}
2422
2424
  def is_row_empty(row):
@@ -2464,7 +2466,7 @@ class OpenFMEA:
2464
2466
  else:result_rows=[in_row]
2465
2467
  return result_rows
2466
2468
  for elem_id in path:elements[elem_id].visited=_A
2467
- rows_to_add=[row];expand_attrs=get_config_value(_C2)
2469
+ rows_to_add=[row];expand_attrs=get_config_value(_C3)
2468
2470
  if len(expand_attrs)>0:
2469
2471
  for exp_attr in expand_attrs.split(_S):rows_to_add=expand_rows_by_compound_attribute(rows_to_add,exp_attr)
2470
2472
  for add_row in rows_to_add:add_row_local(flatten_row(add_row))
@@ -2486,7 +2488,7 @@ class OpenFMEA:
2486
2488
  if element.identifier()==start_node.identifier():recurse_links(SBDL_Failure_Cause)
2487
2489
  elif element.identifier()==end_node.identifier():
2488
2490
  print_l('ADD',element.identifier(),debug=_A)
2489
- if not is_fully_meta()and(get_config_value(_C4,number=_A)or not is_partly_meta()):add_row()
2491
+ if not is_fully_meta()and(get_config_value(_C5,number=_A)or not is_partly_meta()):add_row()
2490
2492
  elif element.is_a(SBDL_Failure_Cause):
2491
2493
  events=get_compounded_linked_events();assign_column(_R,_I+events if len(events)>0 else'');assign_column_value(_u,element.rating());assign_column_value(_A8,element.rating(post=_A))
2492
2494
  if not element.is_meta():
@@ -2515,12 +2517,12 @@ class OpenFMEA:
2515
2517
  return rows
2516
2518
  def get_orphans(elements_l):
2517
2519
  rows=[]
2518
- if get_config_value(_C3,number=_A):
2520
+ if get_config_value(_C4,number=_A):
2519
2521
  for el in elements_l:
2520
2522
  if not'visited'in vars(elements[el])and not elements[el].is_a(SBDL_Event)and not elements[el].is_meta():print_l('ORPHAN',elements[el].identifier(),debug=_A);rows.extend(generate_table(elements[el],row=sbdl_row.copy(),add_single=_A))
2521
2523
  return rows
2522
2524
  def apply_smart_keys(input_rows):
2523
- if get_config_value(_C5,number=_A):
2525
+ if get_config_value(_C6,number=_A):
2524
2526
  for row in input_rows:
2525
2527
  join_props=[_Y,_R,_L,_a];join_string=''
2526
2528
  for join_prop in join_props:
@@ -2569,7 +2571,7 @@ class OpenFMEA:
2569
2571
  with file_opener(output_file)as open_sbdl_file:OpenFMEA.write_struct_to_file(OpenFMEA.struct_from_table(arguments.title,self.replace_table_entries_in_place(sbdl_table,_B,'')),open_sbdl_file)
2570
2572
  return errors
2571
2573
  @classmethod
2572
- def get_quickshare_output(self,sbdl_ast,arguments,print_l):mem_file=io.StringIO();sbdl_table,errors=OpenFMEA.generate_sbdl_table_from_ast(sbdl_ast,id_in_body=arguments.identifier,source_in_body=arguments.source,print_l=print_l);OpenFMEA.write_struct_to_file(OpenFMEA.struct_from_table(arguments.title,self.replace_table_entries_in_place(sbdl_table,_B,'')),mem_file,pretty=_C);mem_file.seek(0);compressed_openfmea=base64.b64encode(zlib.compress(mem_file.read().encode(_r))).decode(_r);mem_file.close();output_uri='{baseurl}/analyzer/?QUICK_SHARE#>>{content}<<'.format(baseurl=get_config_value(_C6),content=compressed_openfmea);return errors,output_uri
2574
+ def get_quickshare_output(self,sbdl_ast,arguments,print_l):mem_file=io.StringIO();sbdl_table,errors=OpenFMEA.generate_sbdl_table_from_ast(sbdl_ast,id_in_body=arguments.identifier,source_in_body=arguments.source,print_l=print_l);OpenFMEA.write_struct_to_file(OpenFMEA.struct_from_table(arguments.title,self.replace_table_entries_in_place(sbdl_table,_B,'')),mem_file,pretty=_C);mem_file.seek(0);compressed_openfmea=base64.b64encode(zlib.compress(mem_file.read().encode(_r))).decode(_r);mem_file.close();output_uri='{baseurl}/analyzer/?QUICK_SHARE#>>{content}<<'.format(baseurl=get_config_value(_C7),content=compressed_openfmea);return errors,output_uri
2573
2575
  @classmethod
2574
2576
  def write_quickshare_output(self,sbdl_ast,output_file,file_opener,arguments,print_l):
2575
2577
  errors,output_uri=self.get_quickshare_output(sbdl_ast,arguments,print_l)
@@ -2611,13 +2613,18 @@ class OpenFMEA:
2611
2613
  if not raw:content=result[1:-1];result=SBDL_Parser.Tokens.replacement_string_default.join(content.split());result=SBDL_Parser.sanitize_identifier(result)
2612
2614
  return result
2613
2615
  @classmethod
2616
+ def remove_id_from_description(self,description):
2617
+ result=description;id_string=self.get_id_from_string(description,_A)
2618
+ if id_string!=_B:result=result.replace(id_string,'')
2619
+ return result
2620
+ @classmethod
2614
2621
  def add_id_to_string(self,identifier,string_content):return'[{}] {}'.format(identifier,string_content)
2615
2622
  @classmethod
2616
2623
  def sbdl_elements_from_table(self,sbdl_table,_):return self.elements_from_table(sbdl_table,_)
2617
2624
  @classmethod
2618
2625
  def elements_from_table(self,sbdl_table,_):
2619
2626
  multi_field_separator=get_config_value(_AX);elems_to_consider={_c:SBDL_Parser.Types.aspect,_Y:SBDL_Parser.Types.requirement,_L:SBDL_Parser.Types.mode,_a:SBDL_Parser.Types.effect,_R:SBDL_Parser.Types.cause,_o:SBDL_Parser.Types.current_control,_g:SBDL_Parser.Types.current_detection,_A0:SBDL_Parser.Types.action_control,_h:SBDL_Parser.Types.action_detection};elem_rating={_a:_t,_R:_u,_L:_s};elem_rating_post={_R:_A8,_L:_A7};elem_link={_R:[_L,_o,_A0,_g,_h],_L:[_c,_a,_g,_Y,_h,_R],_Y:[_c,_L],_a:[_L],_o:[_R],_g:[_L],_A0:[_R],_h:[_L]};elem_present_every_row={_g,_h};replace_str=SBDL_Parser.Tokens.replacement_string_default;elements={};id_lookup={}
2620
- if not get_config_value(_C8,number=_A):elem_link[_L].remove(_R);elem_link[_a].remove(_L)
2627
+ if not get_config_value(_C9,number=_A):elem_link[_L].remove(_R);elem_link[_a].remove(_L)
2621
2628
  def get_id_from_attr(attr_type,attr):
2622
2629
  A='$COUNTER$';result=self.get_id_from_string(attr)
2623
2630
  if result!=_B:0
@@ -2626,10 +2633,6 @@ class OpenFMEA:
2626
2633
  if not attr_type in id_lookup:id_lookup[attr_type]={};id_lookup[attr_type][A]=1
2627
2634
  result=id_lookup[attr_type][attr]=replace_str.join((elems_to_consider[attr_type]+replace_str+str(id_lookup[attr_type][A]).zfill(3)).split());id_lookup[attr_type][A]+=1
2628
2635
  return result
2629
- def remove_id_from_description(description):
2630
- result=description;id_string=self.get_id_from_string(description,_A)
2631
- if id_string!=_B:result=result.replace(id_string,'')
2632
- return result
2633
2636
  def split_multi_field(multi_data):return[x.strip()for x in str(multi_data).split(multi_field_separator)]
2634
2637
  def present_on_relevant_rows(source_content,source_column,target_content,target_column):
2635
2638
  result=_A
@@ -2656,7 +2659,7 @@ class OpenFMEA:
2656
2659
  def handle_elem(row_data,attr):
2657
2660
  attr_data_full=split_multi_field(row_data[attr])
2658
2661
  for attr_data in attr_data_full:
2659
- attr_data_no_id=remove_id_from_description(attr_data).strip()
2662
+ attr_data_no_id=self.remove_id_from_description(attr_data).strip()
2660
2663
  if len(attr_data)>0:
2661
2664
  if attr in elems_to_consider:
2662
2665
  id_ref=get_id_from_attr(attr,attr_data);elem=_B
@@ -2685,7 +2688,7 @@ class OpenFMEA:
2685
2688
  if'id'in gen_elem_obj and _P in gen_elem_obj and _K in gen_elem_obj:
2686
2689
  if gen_elem_obj[_K]in supported_general_types:
2687
2690
  if supported_general_types[gen_elem_obj[_K]][B]==0:supported_general_types[gen_elem_obj[_K]][B]+=1;new_customtype_statement=SBDL_Parser.parse_customtype(SBDL_Parser.Parser_Element(supported_general_types[gen_elem_obj[_K]][C],_AC,0));new_customtype_def=SBDL_CustomType(new_customtype_statement);general_elements.append(new_customtype_def)
2688
- new_gen_elem=SBDL_Element_Synthetic(entry_identifier(gen_elem_obj),gen_elem_obj[_P],supported_general_types[gen_elem_obj[_K]][A],_B)
2691
+ new_gen_elem=SBDL_Element_Synthetic(entry_identifier(gen_elem_obj),self.remove_id_from_description(gen_elem_obj[_P]),supported_general_types[gen_elem_obj[_K]][A],_B)
2689
2692
  if D in gen_elem_obj:
2690
2693
  for edge in gen_elem_obj[D]:
2691
2694
  explicit_identifier=self.get_id_from_string(edge);matching_identifier=_B;matching_type=_B
@@ -2717,9 +2720,9 @@ class OpenFMEA:
2717
2720
  if hidden or recurse:raise Exception('Cannot recurse for OpenFMEA input files')
2718
2721
  aggregated_elements=[];errors=0
2719
2722
  for input_file in source_files:
2720
- print_l(_CN.format(input_file))
2723
+ print_l(_CO.format(input_file))
2721
2724
  if is_input_file(input_file):open_sbdl_data=self.read_file(input_file);aggregated_elements.extend(self.statements_from_openfmea(open_sbdl_data,input_file))
2722
- else:errors+=1;print_l(_CO.format(input_file),error=_A)
2725
+ else:errors+=1;print_l(_CP.format(input_file),error=_A)
2723
2726
  set_config_value(_A2,_A);set_config_value(_A3,_A);return aggregated_elements,errors
2724
2727
  @classmethod
2725
2728
  def aggregate_all_parser_elements_from_quickshare(self,source_files,recurse,hidden,_):
@@ -2764,7 +2767,7 @@ def write_rpc_output(sbdl_ast,output_file,file_opener,arguments,print_l):
2764
2767
  A='sbdl_statements';print_l('Remote processing to output [{}]: {}'.format(arguments.rpc,output_file),debug=_A);sbdl_elements,errors=sbdl_ast.elements();sbdl_statement_strings=[sbdl_elements[e].definition().string()for e in sbdl_elements]
2765
2768
  if arguments.rpc==_B:errors+=1;print_l('RPC parameter required',error=_A)
2766
2769
  else:
2767
- rpc_result=rest_api_call(arguments.rpc,{_CG:str(sys.argv),A:sbdl_statement_strings},print_l)
2770
+ rpc_result=rest_api_call(arguments.rpc,{_CH:str(sys.argv),A:sbdl_statement_strings},print_l)
2768
2771
  with file_opener(output_file)as outfile:
2769
2772
  if isinstance(rpc_result,dict):
2770
2773
  if A in rpc_result and isinstance(rpc_result[A],list):outfile.write(_D.join(rpc_result[A]))
@@ -2814,7 +2817,7 @@ def apply_template_to_officex_files(officex_dir,sbdl_ast,print_l):
2814
2817
  def template_docx_file(template_dict,infile,outfile):warnings.filterwarnings(_A1,category=UserWarning,module='docxcompose');docxtpl=lazy_import('docxtpl');word_template=docxtpl.DocxTemplate(infile);word_template.render(template_dict);word_template.save(outfile)
2815
2818
  def write_template_fill(sbdl_ast,output_file,file_opener,arguments,print_l):
2816
2819
  elements,errors=sbdl_ast.elements();full_dict,errors_dict=sbdl_ast.get_full_ast_as_dict(elements);errors+=errors_dict;template_context={_j:full_dict}
2817
- if get_config_value(_C7,number=_A):openfmea,errors_fmea=OpenFMEA.generate_sbdl_table_from_ast(sbdl_ast,id_in_body=arguments.identifier,source_in_body=arguments.source,print_l=print_l);errors+=errors_fmea;template_context[_AE]=openfmea
2820
+ if get_config_value(_C8,number=_A):openfmea,errors_fmea=OpenFMEA.generate_sbdl_table_from_ast(sbdl_ast,id_in_body=arguments.identifier,source_in_body=arguments.source,print_l=print_l);errors+=errors_fmea;template_context[_AE]=openfmea
2818
2821
  file_ext=os.path.splitext(arguments.template)[1]
2819
2822
  if arguments.template==_B:print_l('Template file not specified',error=_A);errors+=1
2820
2823
  elif file_ext in['.docx']:debug_out('Word Docx template detected');template_docx_file(template_context,arguments.template,output_file)
@@ -2949,7 +2952,7 @@ def main(arguments):
2949
2952
  else:print_l('Encountered {} errors during: {} {}'.format(error_count,step,content),error=_A)
2950
2953
  else:print_l(f"{step} done [{time.time()-step_time_point:.3f}s]")
2951
2954
  step_time_point=time.time()
2952
- operations={_Am:write_aggregated_output,'aggregate':write_aggregated_output,'query':query_output,_AF:write_matrixcsv_output,'matrixcsv':write_matrixcsv_output,_AG:write_matrixjson_output,'matrixjson':write_matrixjson_output,_An:write_yaml_tree_output,_CS:write_csv_output,'fmeacsv':write_csv_output,_AE:OpenFMEA.write_opensbdl_output,'openfmea-quickshare':OpenFMEA.write_quickshare_output,_Ao:OpenFMEA.write_opensbdl_portfolio_output,A:write_aggregated_output,_Ap:write_aggregated_output,B:write_aggregated_output,C:write_aggregated_output,_Aq:write_decomposition_graph_output,_Ar:write_element_graph_output,_As:write_requirement_graph_output,_At:write_network_graph_output,_Au:write_function_graph_output,_Av:write_process_graph_output,_Aw:write_state_graph_output,_Ax:write_usecase_graph_output,_CT:write_template_fill,'rpc':write_rpc_output,_AH:write_aggregated_output,_Ay:write_aggregated_output,_AI:write_aggregated_output,'type-info':write_type_information};macro_errors=0
2955
+ operations={_Am:write_aggregated_output,'aggregate':write_aggregated_output,'query':query_output,_AF:write_matrixcsv_output,'matrixcsv':write_matrixcsv_output,_AG:write_matrixjson_output,'matrixjson':write_matrixjson_output,_An:write_yaml_tree_output,_CT:write_csv_output,'fmeacsv':write_csv_output,_AE:OpenFMEA.write_opensbdl_output,'openfmea-quickshare':OpenFMEA.write_quickshare_output,_Ao:OpenFMEA.write_opensbdl_portfolio_output,A:write_aggregated_output,_Ap:write_aggregated_output,B:write_aggregated_output,C:write_aggregated_output,_Aq:write_decomposition_graph_output,_Ar:write_element_graph_output,_As:write_requirement_graph_output,_At:write_network_graph_output,_Au:write_function_graph_output,_Av:write_process_graph_output,_Aw:write_state_graph_output,_Ax:write_usecase_graph_output,_CU:write_template_fill,'rpc':write_rpc_output,_AH:write_aggregated_output,_Ay:write_aggregated_output,_AI:write_aggregated_output,'type-info':write_type_information};macro_errors=0
2953
2956
  for amacropath in arguments.custom_directive:macro_errors+=import_custom_directive_file(amacropath,print_l)
2954
2957
  check_step('Custom directive import',macro_errors);mode_errors=0
2955
2958
  for amodepath in arguments.custom_mode:
@@ -2978,7 +2981,7 @@ def main(arguments):
2978
2981
  if arguments.trace:trace_elements,trace_errors=aggregate_all_parser_elements_from_files(arguments.trace,arguments.recurse,arguments.hidden,print_l);_,trace_process_errors=sbdl_ast.process_trace_elements(trace_elements,print_l);trace_errors+=trace_process_errors;check_step('Tracing',trace_errors)
2979
2982
  for post_hook in get_config_value(_k):check_step('Post Hook: {}'.format(post_hook.__name__),post_hook(sbdl_ast,print_l))
2980
2983
  print_l('Mode: {}'.format(arguments.mode));print_l('Writing: {}'.format(arguments.output));check_step('Output writing',operations[arguments.mode](sbdl_ast,arguments.output,open_output_file,arguments,print_l));print_l('C_DEF GLOBALS: {}'.format(get_config_value(_T)),debug=_A);print_l(f"All operations complete [{time.time()-start_time_point:.3f}s]");return total_errors if not arguments.skip_errors else 0
2981
- def handle_arguments(args_l):F='append';E='config_file';D='normal';C='output_file';B='element_identifier';A='store_true';operating_modes={_Am:'Parse all specified input files, gather SBDL elements, validate model, apply filters, write SBDL-formatted output','query':'Compile inputs, then pretty print the results (after filtering)',_AF:'Compile inputs, then write a CSV-formatted representation of the SBDL elements to the output',_AG:'Compile inputs, then write a JSON-formatted representation of the SBDL elements to the output',_An:'Compile inputs, then write a YAML-formatted representation of the SBDL elements to the output',_AI:'Read SBDL-schema CSV-matrix inputs and write SBDL-formatted output',_AH:'Read SBDL-schema JSON-tree inputs and write SBDL-formatted output',_Ay:'Read SBDL-schema YAML-tree inputs and write SBDL-formatted output',_AE:'Compile inputs, then write the FMEA-related content to an OpenFMEA-formatted ouput',_Ao:'Compile inputs, then write the FMEA-related content to an OpenFMEA Portfolio-formatted ouput, organised by aspect hierarchy',_Ap:'Read OpenFMEA-formatted input and write SBDL-formatted output',_CS:'Compile inputs, then write the FMEA-related content to a CSV-formatted ouput',_At:'Compile inputs, then write a PNG-formatted output, visually representing the network of SBDL elements',_As:'Compile inputs, then write a SysML-style requirements diagram to rendering-backend-formatted output',_Aq:'Compile inputs, then write a SysML-style block diagram to rendering-backend-formatted output (simplified, aspects only)',_Ar:'Compile inputs, then write a SysML-style block diagram to rendering-backend-formatted output (detailed, with properties and relations)',_Au:'Compile inputs, then write a SysML-style sequence diagram to rendering-backend-formatted output',_Av:'Compile inputs, then write a SysML-style activity diagram to rendering-backend-formatted output',_Aw:'Compile inputs, then write a SysML-style state diagram to rendering-backend-formatted output',_Ax:'Compile inputs, then write a SysML-style use-case diagram to rendering-backend-formatted output',_CT:"Compile inputs, then provide an object, 'sbdl', in a Jinja parsing environment and apply it to the specified template file",'rpc':'Compile inputs, then transmit to the RPC server for processing by the specified RPC (see --rpc)'};parser=argparse.ArgumentParser(description='{}\n\n{} Version {} (DSL Version {}). System Behaviour Description Language (SBDL) compiler.\nWWW: {}. Author: {}.'.format(logo(),name().upper(),version(),version_dsl(),url(),author()),epilog='e.g. "'+os.path.basename(sys.argv[0])+' <file 1> <file 2> <file n>"\n\n---------------\nOperating Modes\n---------------\n{}'.format(_D.join(['{}: {}'.format(x.rjust(25),operating_modes[x])for x in operating_modes])),formatter_class=argparse.RawDescriptionHelpFormatter);parser._positionals.title='Base Arguments';parser._optionals.title='Optional Arguments';parser.add_argument('source_files',help='List of files to compile ["-" implies stdin]',nargs=_O);parser.add_argument(_F,'--mode',metavar='operating_mode',help='Specify the mode of operation',default=_Am);parser.add_argument(_E,'--output',metavar=C,help='Specify the name of the output file',default=SBDL_Parser.Tokens.stdio_name);parser.add_argument('--version',help='Print the current version',action=A,default=_C);parser.add_argument('--debug',help=argparse.SUPPRESS,action=A,default=_C);parser.add_argument('-W','-w','--warning',help='Set warning level',choices=[D,'all'],default=D);parser.add_argument('--hidden',help='Include hidden files when recursing',action=A,default=_C);parser.add_argument('-i','--identifier',help='Include element identifiers in applicable output formats',action=A,default=_C);parser.add_argument('-s','--source',help='Include source reference in applicable output formats',action=A,default=_C);parser.add_argument('-r','--recurse',help='Recurse on directories specified in the input list',action=A,default=_C);parser.add_argument('--skip-errors',help='Do not stop for errors (emit warning instead)',action=A,default=_C);parser.add_argument('--skip-validation',help='Do not validate model elements and relations',action=A,default=_C);parser.add_argument('--already-processed',help='Disables certain processing actions (implies --skip-validation). Useful when input has already been processed',action=A,default=_C);parser.add_argument('--title',help='Provide a default title for certain output formats',default='');parser.add_argument('-v','--verbose',help='Enable verbose output during execution',action=A,default=_C);parser.add_argument('--dumpaffinitygraph',metavar=C,help=argparse.SUPPRESS,action=_B);parser.add_argument('--dumplanginfo',metavar=C,help=argparse.SUPPRESS,action=_B);parser.add_argument('--run_tests','--run-tests',action=A,help=argparse.SUPPRESS);parser.add_argument('--rest-api-ping',action=A,help=argparse.SUPPRESS);parser.add_argument('--manual',help='Show extensive {} manual page'.format(name().upper()),action=A);parser.add_argument('--dump-config','--dumpconfig',metavar=E,help='Dump the internal configuration to a named JSON file',action=_B);parser.add_argument('--load-config','--loadconfig',metavar=E,help='Load the internal configuration from a named JSON file',default=_B);parser.add_argument('--list-config','--listconfig',help='List internal configuration options',action=A,default=_C);parser.add_argument('--set-config','--setconfig',metavar=('config_option','config_value'),help='Set a named configuration option',action=F,nargs=2);parser.add_argument('-D','--define',metavar=('name','value'),help='Specify a named global definition',action=F,nargs=2);parser.add_argument('--trace',metavar='trace_files',help='Provide a trace file to be processed',default=_B,nargs=_O);parser.add_argument('--template',metavar='template_file',help="Specify a template file for the 'template-fill' mode",default=_B);parser.add_argument('-fr','--filter-related',metavar=B,help='Filter everything but those elements with a direct or indirect relation to the specified element identifier (regex) [INCLUDES: parents/children]',default=_B);parser.add_argument('-frx','--filter-related-x',metavar=B,help='Filter everything but those elements with a direct or indirect connection to the specified element identifier (regex) [EXCLUDES: parents/children]',default=_B);parser.add_argument('-fch','--filter-children',metavar=B,help='Filter everything but those elements which are children of the specified element identifier (regex)',default=_B);parser.add_argument('-fpa','--filter-parents',metavar=B,help='Filter everything but those elements which are parental ancestors of the specified element identifier (regex)',default=_B);parser.add_argument('-fd','--filter-depth',metavar='filter_depth',help='Maximum depth for filters which pursue links (natural number)',type=int,default=_B);parser.add_argument('-ft','--filter-type',metavar='element_type',help='Filter everything but those elements which are of the specified element type (regex)',default=_B);parser.add_argument('-fi','--filter-identifier',metavar=B,help='Filter everything but those elements whose identifiers match the specified string (regex)',default=_B);parser.add_argument('-fpr','--filter-property',metavar=('property_name','property_value'),help='Filter everything but those elements possessing a named property matching the specified string (regex)',default=_B,nargs=2);parser.add_argument('-fg','--filter-group',metavar='group_identifier',help='Shortcut filter for everything but those elements which are children of the specified group identifier (regex) -- excludes the group element itself',default=_B);parser.add_argument(_CU,metavar='compiler_definitions',help='Specify a file path defining custom compiler directives',default=[],nargs=_O);parser.add_argument(_CV,'--custom_mode',metavar='mode_definitions',help='Specify a file path containing custom compiler modes',default=[],nargs=_O);parser.add_argument('--rpc',help='Remote Procedure Call to be used by RPC-based modes',default=_B);parser.add_argument('--update',help=argparse.SUPPRESS,action=A,default=_C);parser.add_argument('--update-force',help=argparse.SUPPRESS,action=A,default=_C);parser.add_argument('--install-deps',help=argparse.SUPPRESS,action=A,default=_C);help_tmp=io.StringIO();parser.print_help(file=help_tmp);help_tmp.seek(0);global __HELP_TEXT;__HELP_TEXT=help_tmp.read();return parser.parse_args(args_l)
2984
+ def handle_arguments(args_l):F='append';E='config_file';D='normal';C='output_file';B='element_identifier';A='store_true';operating_modes={_Am:'Parse all specified input files, gather SBDL elements, validate model, apply filters, write SBDL-formatted output','query':'Compile inputs, then pretty print the results (after filtering)',_AF:'Compile inputs, then write a CSV-formatted representation of the SBDL elements to the output',_AG:'Compile inputs, then write a JSON-formatted representation of the SBDL elements to the output',_An:'Compile inputs, then write a YAML-formatted representation of the SBDL elements to the output',_AI:'Read SBDL-schema CSV-matrix inputs and write SBDL-formatted output',_AH:'Read SBDL-schema JSON-tree inputs and write SBDL-formatted output',_Ay:'Read SBDL-schema YAML-tree inputs and write SBDL-formatted output',_AE:'Compile inputs, then write the FMEA-related content to an OpenFMEA-formatted ouput',_Ao:'Compile inputs, then write the FMEA-related content to an OpenFMEA Portfolio-formatted ouput, organised by aspect hierarchy',_Ap:'Read OpenFMEA-formatted input and write SBDL-formatted output',_CT:'Compile inputs, then write the FMEA-related content to a CSV-formatted ouput',_At:'Compile inputs, then write a PNG-formatted output, visually representing the network of SBDL elements',_As:'Compile inputs, then write a SysML-style requirements diagram to rendering-backend-formatted output',_Aq:'Compile inputs, then write a SysML-style block diagram to rendering-backend-formatted output (simplified, aspects only)',_Ar:'Compile inputs, then write a SysML-style block diagram to rendering-backend-formatted output (detailed, with properties and relations)',_Au:'Compile inputs, then write a SysML-style sequence diagram to rendering-backend-formatted output',_Av:'Compile inputs, then write a SysML-style activity diagram to rendering-backend-formatted output',_Aw:'Compile inputs, then write a SysML-style state diagram to rendering-backend-formatted output',_Ax:'Compile inputs, then write a SysML-style use-case diagram to rendering-backend-formatted output',_CU:"Compile inputs, then provide an object, 'sbdl', in a Jinja parsing environment and apply it to the specified template file",'rpc':'Compile inputs, then transmit to the RPC server for processing by the specified RPC (see --rpc)'};parser=argparse.ArgumentParser(description='{}\n\n{} Version {} (DSL Version {}). System Behaviour Description Language (SBDL) compiler.\nWWW: {}. Author: {}.'.format(logo(),name().upper(),version(),version_dsl(),url(),author()),epilog='e.g. "'+os.path.basename(sys.argv[0])+' <file 1> <file 2> <file n>"\n\n---------------\nOperating Modes\n---------------\n{}'.format(_D.join(['{}: {}'.format(x.rjust(25),operating_modes[x])for x in operating_modes])),formatter_class=argparse.RawDescriptionHelpFormatter);parser._positionals.title='Base Arguments';parser._optionals.title='Optional Arguments';parser.add_argument('source_files',help='List of files to compile ["-" implies stdin]',nargs=_O);parser.add_argument(_F,'--mode',metavar='operating_mode',help='Specify the mode of operation',default=_Am);parser.add_argument(_E,'--output',metavar=C,help='Specify the name of the output file',default=SBDL_Parser.Tokens.stdio_name);parser.add_argument('--version',help='Print the current version',action=A,default=_C);parser.add_argument('--debug',help=argparse.SUPPRESS,action=A,default=_C);parser.add_argument('-W','-w','--warning',help='Set warning level',choices=[D,'all'],default=D);parser.add_argument('--hidden',help='Include hidden files when recursing',action=A,default=_C);parser.add_argument('-i','--identifier',help='Include element identifiers in applicable output formats',action=A,default=_C);parser.add_argument('-s','--source',help='Include source reference in applicable output formats',action=A,default=_C);parser.add_argument('-r','--recurse',help='Recurse on directories specified in the input list',action=A,default=_C);parser.add_argument('--skip-errors',help='Do not stop for errors (emit warning instead)',action=A,default=_C);parser.add_argument('--skip-validation',help='Do not validate model elements and relations',action=A,default=_C);parser.add_argument('--already-processed',help='Disables certain processing actions (implies --skip-validation). Useful when input has already been processed',action=A,default=_C);parser.add_argument('--title',help='Provide a default title for certain output formats',default='');parser.add_argument('-v','--verbose',help='Enable verbose output during execution',action=A,default=_C);parser.add_argument('--dumpaffinitygraph',metavar=C,help=argparse.SUPPRESS,action=_B);parser.add_argument('--dumplanginfo',metavar=C,help=argparse.SUPPRESS,action=_B);parser.add_argument('--run_tests','--run-tests',action=A,help=argparse.SUPPRESS);parser.add_argument('--rest-api-ping',action=A,help=argparse.SUPPRESS);parser.add_argument('--manual',help='Show extensive {} manual page'.format(name().upper()),action=A);parser.add_argument('--dump-config','--dumpconfig',metavar=E,help='Dump the internal configuration to a named JSON file',action=_B);parser.add_argument('--load-config','--loadconfig',metavar=E,help='Load the internal configuration from a named JSON file',default=_B);parser.add_argument('--list-config','--listconfig',help='List internal configuration options',action=A,default=_C);parser.add_argument('--set-config','--setconfig',metavar=('config_option','config_value'),help='Set a named configuration option',action=F,nargs=2);parser.add_argument('-D','--define',metavar=('name','value'),help='Specify a named global definition',action=F,nargs=2);parser.add_argument('--trace',metavar='trace_files',help='Provide a trace file to be processed',default=_B,nargs=_O);parser.add_argument('--template',metavar='template_file',help="Specify a template file for the 'template-fill' mode",default=_B);parser.add_argument('-fr','--filter-related',metavar=B,help='Filter everything but those elements with a direct or indirect relation to the specified element identifier (regex) [INCLUDES: parents/children]',default=_B);parser.add_argument('-frx','--filter-related-x',metavar=B,help='Filter everything but those elements with a direct or indirect connection to the specified element identifier (regex) [EXCLUDES: parents/children]',default=_B);parser.add_argument('-fch','--filter-children',metavar=B,help='Filter everything but those elements which are children of the specified element identifier (regex)',default=_B);parser.add_argument('-fpa','--filter-parents',metavar=B,help='Filter everything but those elements which are parental ancestors of the specified element identifier (regex)',default=_B);parser.add_argument('-fd','--filter-depth',metavar='filter_depth',help='Maximum depth for filters which pursue links (natural number)',type=int,default=_B);parser.add_argument('-ft','--filter-type',metavar='element_type',help='Filter everything but those elements which are of the specified element type (regex)',default=_B);parser.add_argument('-fi','--filter-identifier',metavar=B,help='Filter everything but those elements whose identifiers match the specified string (regex)',default=_B);parser.add_argument('-fpr','--filter-property',metavar=('property_name','property_value'),help='Filter everything but those elements possessing a named property matching the specified string (regex)',default=_B,nargs=2);parser.add_argument('-fg','--filter-group',metavar='group_identifier',help='Shortcut filter for everything but those elements which are children of the specified group identifier (regex) -- excludes the group element itself',default=_B);parser.add_argument(_CV,metavar='compiler_definitions',help='Specify a file path defining custom compiler directives',default=[],nargs=_O);parser.add_argument(_CW,'--custom_mode',metavar='mode_definitions',help='Specify a file path containing custom compiler modes',default=[],nargs=_O);parser.add_argument('--rpc',help='Remote Procedure Call to be used by RPC-based modes',default=_B);parser.add_argument('--update',help=argparse.SUPPRESS,action=A,default=_C);parser.add_argument('--update-force',help=argparse.SUPPRESS,action=A,default=_C);parser.add_argument('--install-deps',help=argparse.SUPPRESS,action=A,default=_C);help_tmp=io.StringIO();parser.print_help(file=help_tmp);help_tmp.seek(0);global __HELP_TEXT;__HELP_TEXT=help_tmp.read();return parser.parse_args(args_l)
2982
2985
  def show_manual(_):
2983
2986
  B='----------------------\n';A='===========================================================\n';manual_text=A;manual_text+=' {} Manual\n'.format(name().upper());manual_text+=A;manual_text+=help_text()+_D;manual_text+=B;manual_text+='Model Type Information\n';manual_text+=B
2984
2987
  def add_manual(strcon=''):nonlocal manual_text;manual_text+=strcon+_D
@@ -2996,7 +2999,7 @@ def show_manual(_):
2996
2999
  add_manual('\n-------------------');add_manual('Compiler Directives');add_manual('-------------------\n')
2997
3000
  for directive in sbdl_directives:add_manual(' {}: {}'.format(directive,sbdl_directives[directive]))
2998
3001
  try:
2999
- manual_command=get_config_value(_Bw)
3002
+ manual_command=get_config_value(_Bx)
3000
3003
  if isinstance(manual_command,str)and len(manual_command)==0:f_print(_D+manual_text,prefix=_B)
3001
3004
  else:
3002
3005
  if not isinstance(manual_command,list):manual_command=shlex.split(manual_command)
@@ -3023,8 +3026,8 @@ class LanguageLevelTests(unittest.TestCase):
3023
3026
  def testEscaping(self):main(handle_arguments(['test/escaped_directive_test.sbdl',_E,self.TEST_OUTPUT_FILE]))
3024
3027
  def testCustomDirectiveImport(self):main(handle_arguments(['test/directive_imp_test.sbdl',_E,self.TEST_OUTPUT_FILE]))
3025
3028
  def testProlog(self):main(handle_arguments(['test/test_prolog.sbdl',_E,self.TEST_OUTPUT_FILE]))
3026
- def testCustomDirective(self):main(handle_arguments([_J,_CU,_CW,_E,self.TEST_OUTPUT_FILE]))
3027
- def testCustomModes(self):main(handle_arguments([_J,'--mode','test_mode',_CV,_CW,_E,self.TEST_OUTPUT_FILE]))
3029
+ def testCustomDirective(self):main(handle_arguments([_J,_CV,_CX,_E,self.TEST_OUTPUT_FILE]))
3030
+ def testCustomModes(self):main(handle_arguments([_J,'--mode','test_mode',_CW,_CX,_E,self.TEST_OUTPUT_FILE]))
3028
3031
  def testIdFromProp(self):main(handle_arguments(['test/id_from_prop.sbdl',_E,self.TEST_OUTPUT_FILE]))
3029
3032
  def testDirectiveChain(self):main(handle_arguments(['test/macro_chain.sbdl',_E,self.TEST_OUTPUT_FILE]))
3030
3033
  def testGeneralAspectDiagram(self):main(handle_arguments([_J,_E,self.TEST_DIAGRAM_OUTPUT_FILE,_F,_Aq]))
@@ -3054,10 +3057,10 @@ class LanguageSemanticTests(unittest.TestCase):
3054
3057
  def test_geneal_relations_check(self):
3055
3058
  for elem in self.sbdl_elements:0
3056
3059
  def test_existence_type_semantic_check(self):
3057
- expected_elem_type={_A_:SBDL_Aspect,'rocket_booster':SBDL_Aspect,_B0:SBDL_Aspect,_CX:SBDL_Aspect,_B1:SBDL_Requirement,_CY:SBDL_Requirement,_CZ:SBDL_Requirement,_B2:SBDL_Function,_Ca:SBDL_Event,_Cb:SBDL_Event,_Cc:SBDL_State,_Cd:SBDL_State,_B3:SBDL_Transition,_Ce:SBDL_Event}
3060
+ expected_elem_type={_A_:SBDL_Aspect,'rocket_booster':SBDL_Aspect,_B0:SBDL_Aspect,_CY:SBDL_Aspect,_B1:SBDL_Requirement,_CZ:SBDL_Requirement,_Ca:SBDL_Requirement,_B2:SBDL_Function,_Cb:SBDL_Event,_Cc:SBDL_Event,_Cd:SBDL_State,_Ce:SBDL_State,_B3:SBDL_Transition,_Cf:SBDL_Event}
3058
3061
  for elem in expected_elem_type:0
3059
3062
  def test_existence_semantic_relation(self):
3060
- relations_between={_CX:_B0,_B1:_A_,_CY:_B1,_CZ:_B0,_B2:_A_,_Ca:_B2,_Cb:_Ce,_Cc:_B3,_Cd:_B3}
3063
+ relations_between={_CY:_B0,_B1:_A_,_CZ:_B1,_Ca:_B0,_B2:_A_,_Cb:_B2,_Cc:_Cf,_Cd:_B3,_Ce:_B3}
3061
3064
  def relation_exists(elemidA,elemidB):return elemidB in[*[x.identifier()for x in SBDL_AST.get_all_children_for_element(self.sbdl_elements[elemidA],self.sbdl_elements)],*[x.identifier()for x in SBDL_AST.get_all_parents_for_element(self.sbdl_elements[elemidA],self.sbdl_elements)],*[x.identifier()for x in SBDL_AST.get_all_links_for_element(self.sbdl_elements[elemidA],self.sbdl_elements)]]
3062
3065
  for elem in relations_between:0
3063
3066
  def run_tests(_):errors=0;test_results=unittest.main(argv=[name()],exit=_C,verbosity=2).result;errors=errors+len(test_results.failures)+len(test_results.errors);return errors
@@ -3108,7 +3111,7 @@ def whoopsie_handler(whoopsie):
3108
3111
  except Exception as _:w_print('Could not print stack trace')
3109
3112
  w_print(A);sys.exit(99)
3110
3113
  def init_profiling():
3111
- global main,main_original;profile_output=get_config_value(_CB)
3114
+ global main,main_original;profile_output=get_config_value(_CC)
3112
3115
  def wrap_main(ARGS):
3113
3116
  f_print(f"Profiling to: {profile_output}",warning=_A,do_warning=_A);cProfile=lazy_import('cProfile')
3114
3117
  def profile_main():main_original(ARGS)
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='sbdl',
5
- version='1.18.19',
5
+ version='1.18.21',
6
6
  description = "System Behaviour Description Language (Compiler)",
7
7
  author = "Michael A. Hicks",
8
8
  author_email = "michael@mahicks.org",
File without changes
File without changes
File without changes
File without changes
File without changes