(configfile)
| 75 | return have_error |
| 76 | |
| 77 | def loadConfig(configfile): |
| 78 | if not os.path.exists(configfile): |
| 79 | configError("cannot find config file '%s'"%configfile) |
| 80 | |
| 81 | try: |
| 82 | with open(configfile) as fh: |
| 83 | data = json.load(fh) |
| 84 | except json.JSONDecodeError as e: |
| 85 | configError("error parsing config file as JSON at line %d: %s"%(e.lineno,e.msg)) |
| 86 | except Exception as e: |
| 87 | configError("error opening config file '%s': %s"%(configfile,e)) |
| 88 | |
| 89 | if not isinstance(data, dict): |
| 90 | configError('config file must contain a JSON object at the top level') |
| 91 | |
| 92 | # All errors are emitted before bailing out, to make the unit test more |
| 93 | # effective. |
| 94 | have_error = False |
| 95 | |
| 96 | # Put config items in a class, so that settings can be accessed using |
| 97 | # config.feature |
| 98 | class Config: |
| 99 | pass |
| 100 | config = Config() |
| 101 | |
| 102 | mapping = { |
| 103 | 'file': ('RE_FILE', (list,)), |
| 104 | 'namespace': ('RE_NAMESPACE', (list,dict)), |
| 105 | 'include_guard': ('include_guard', (dict,)), |
| 106 | 'variable': ('RE_VARNAME', (list,dict)), |
| 107 | 'variable_prefixes': ('var_prefixes', (dict,), {}), |
| 108 | 'private_member': ('RE_PRIVATE_MEMBER_VARIABLE', (list,dict)), |
| 109 | 'public_member': ('RE_PUBLIC_MEMBER_VARIABLE', (list,dict)), |
| 110 | 'global_variable': ('RE_GLOBAL_VARNAME', (list,dict)), |
| 111 | 'function_name': ('RE_FUNCTIONNAME', (list,dict)), |
| 112 | 'function_prefixes': ('function_prefixes', (dict,), {}), |
| 113 | 'class_name': ('RE_CLASS_NAME', (list,dict)), |
| 114 | 'skip_one_char_variables': ('skip_one_char_variables', (bool,)), |
| 115 | } |
| 116 | |
| 117 | # parse defined keys and store as members of config object |
| 118 | for key,opts in mapping.items(): |
| 119 | json_key = opts[0] |
| 120 | req_type = opts[1] |
| 121 | default = None if len(opts)<3 else opts[2] |
| 122 | |
| 123 | value = data.pop(json_key,default) |
| 124 | if value is not None and type(value) not in req_type: |
| 125 | req_typename = ' or '.join([tp.__name__ for tp in req_type]) |
| 126 | got_typename = type(value).__name__ |
| 127 | configError('%s must be %s (not %s), or not set'%(json_key,req_typename,got_typename),fatal=False) |
| 128 | have_error = True |
| 129 | continue |
| 130 | |
| 131 | # type list implies that this is either a list of REs or a dict with RE keys |
| 132 | if list in req_type and value is not None: |
| 133 | re_error = validateConfigREs(value,json_key) |
| 134 | if re_error: |
no test coverage detected