1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021-2023 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import sys 17import os 18import stat 19import json 20import argparse 21from collections import Counter 22 23sys.path.append( 24 os.path.dirname( 25 os.path.dirname( 26 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) 27 28from third_party.PyYAML.lib import yaml # noqa: E402 29 30_DUPLICATE_KEY_DEF = "duplicate key definition" 31_EMPTY_YAML = "empty yaml file input" 32_INVALID_YAML = "invalid yaml format" 33_DUPLICATE_DOMAIN = "duplicate domain" 34_INVALID_DOMAIN_NUMBER = "invalid domain number" 35_INVALID_DOMAIN_LENGTH = "invalid domain length" 36_INVALID_DOMAIN_CHAR = "invalid domain character" 37_INVALID_DOMAIN_CHAR_HEAD = "invalid domain character head" 38_INVALID_EVENT_NUMBER = "invalid event number" 39_INVALID_EVENT_LENGTH = "invalid event length" 40_INVALID_EVENT_CHAR = "invalid event character" 41_INVALID_EVENT_CHAR_HEAD = "invalid event character head" 42_MISSING_EVENT_BASE = "missing event base" 43_MISSING_EVENT_TYPE = "missing event type" 44_INVALID_EVENT_TYPE = "invalid event type" 45_MISSING_EVENT_LEVEL = "missing event level" 46_INVALID_EVENT_LEVEL = "invalid event level" 47_MISSING_EVENT_DESC = "missing event desc" 48_INVALID_EVENT_DESC_LENGTH = "invalid event desc length" 49_INVALID_EVENT_TAG_NUM = "invalid event tag number" 50_INVALID_EVENT_TAG_LEN = "invalid event tag length" 51_INVALID_EVENT_TAG_CHAR = "invalid event tag character" 52_DUPLICATE_EVENT_TAG = "duplicate event tag" 53_INVALID_EVENT_BASE_KEY = "invalid event base key" 54_INVALID_EVENT_PARAM_NUM = "invalid event param number" 55_INVALID_EVENT_PARAM_LEN = "invalid event param length" 56_INVALID_EVENT_PARAM_CHAR = "invalid event param character" 57_INVALID_EVENT_PARAM_CHAR_HEAD = "invalid event param character head" 58_MISSING_EVENT_PARAM_TYPE = "missing event param type" 59_INVALID_EVENT_PARAM_TYPE = "invalid event param type" 60_INVALID_EVENT_PARAM_ARRSIZE = "invalid event param arrsize" 61_MISSING_EVENT_PARAM_DESC = "missing event param desc" 62_INVALID_EVENT_PARAM_DESC_LEN = "invalid event param desc length" 63_INVALID_EVENT_PARAM_KEY = "invalid event param key" 64_DEPRECATED_EVENT_NAME_PREFIX = "deprecated event name prefix" 65_DEPRECATED_PARAM_NAME_PREFIX = "deprecated param name prefix" 66_DEPRECATED_TAG_NAME = "deprecated tag name" 67_DEPRECATED_EVENT_DESC_NAME = "deprecated event desc name" 68_DEPRECATED_PARAM_DESC_NAME = "deprecated param desc name" 69_INVALID_DOMAIN_DEF = "invalid definition type for domain" 70_INVALID_EVENT_DEF = "invalid definition type for event" 71_INVALID_EVENT_BASE_DEF = "invalid definition type for event base" 72_INVALID_EVENT_TYPE_DEF = "invalid definition type for event type" 73_INVALID_EVENT_LEVEL_DEF = "invalid definition type for event level" 74_INVALID_EVENT_DESC_DEF = "invalid definition type for event desc" 75_INVALID_EVENT_TAG_DEF = "invalid definition type for event tag" 76_INVALID_EVENT_PRESERVE_DEF = "invalid definition type for event preserve" 77_INVALID_EVENT_PARAM_DEF = "invalid definition type for event param" 78_INVALID_PARAM_TYPE_DEF = "invalid definition type for param type" 79_INVALID_PARAM_ARRSIZE_DEF = "invalid definition type for param arrsize" 80_INVALID_PARAM_DESC_DEF = "invalid definition type for param desc" 81_WARNING_MAP = { 82 _EMPTY_YAML : 83 "The yaml file list is empty.", 84 _INVALID_YAML : 85 "Invalid yaml file, error message: <<%s>>.", 86 _DUPLICATE_DOMAIN : 87 "Domain <<%s>> is already defined in <<%s>>.", 88 _INVALID_DOMAIN_NUMBER : 89 "The domain definition is missing in the yaml file.", 90 _INVALID_DOMAIN_LENGTH : 91 "The length of the domain must be between [1, 16], "\ 92 "but the actual length of the domain <<%s>> is <<%d>>.", 93 _INVALID_DOMAIN_CHAR : 94 "The character of the domain must be in [A-Z0-9_], "\ 95 "but the domain <<%s>> actually has <<%c>>.", 96 _INVALID_DOMAIN_CHAR_HEAD : 97 "The header of the domain must be in [A-Z], "\ 98 "but the actual header of the domain <<%s>> is <<%c>>.", 99 _INVALID_EVENT_NUMBER : 100 "The number of the events must be between [1, 4096], ."\ 101 "but there are actually <<%d>> events.", 102 _INVALID_EVENT_LENGTH : 103 "The length of the event must be between [1, 32], "\ 104 "but the actual length of the event <<%s>> is <<%d>>.", 105 _INVALID_EVENT_CHAR : 106 "The character of the event must be in [A-Z0-9_], "\ 107 "but the event <<%s>> actually has <<%c>>.", 108 _INVALID_EVENT_CHAR_HEAD : 109 "The header of the event must be in [A-Z], "\ 110 "but the actual header of the event <<%s>> is <<%c>>.", 111 _MISSING_EVENT_BASE : 112 "Event <<%s>> is missing __BASE definition.", 113 _MISSING_EVENT_TYPE : 114 "__BASE for event <<%s>> is missing type definition.", 115 _INVALID_EVENT_TYPE : 116 "The type of the event <<%s>> must be in "\ 117 "[FAULT, STATISTIC, SECURITY, BEHAVIOR], "\ 118 "but the actual event type is <<%s>>.", 119 _MISSING_EVENT_LEVEL : 120 "__BASE for event <<%s>> is missing level definition.", 121 _INVALID_EVENT_LEVEL : 122 "The level of the event <<%s>> must be in [CRITICAL, MINOR], "\ 123 "but the actual event level is <<%s>>.", 124 _MISSING_EVENT_DESC : 125 "__BASE for event <<%s>> is missing desc definition.", 126 _INVALID_EVENT_DESC_LENGTH : 127 "The length of the event desc must be between [3, 128], "\ 128 "but the actual length of the event <<%s>> desc <<%s>> is <<%d>>.", 129 _INVALID_EVENT_TAG_NUM : 130 "The number of the event tags must be between [0, 5], "\ 131 "but actually the event <<%s>> tag <<%s>> has <<%d>> tags.", 132 _INVALID_EVENT_TAG_LEN : 133 "The length of the event tag must be between [1, 16], "\ 134 "but the actual length of the event <<%s>> tag <<%s>> is <<%d>>.", 135 _INVALID_EVENT_TAG_CHAR : 136 "The character of the event tag must be in [A-Za-z0-9], "\ 137 "but the event <<%s>> tag <<%s>> actually has <<%c>>.", 138 _DUPLICATE_EVENT_TAG : 139 "Event tag should not be duplicated, "\ 140 "but tag <<%s>> for event <<%s>> has multiple identical.", 141 _INVALID_EVENT_BASE_KEY : 142 "Event <<%s>> __BASE key should be [type, level, tag, desc], "\ 143 "but actually has an invalid key <<%s>>.", 144 _INVALID_EVENT_PARAM_NUM : 145 "The number of the event param must be between [0, 128], "\ 146 "but actually the event <<%s>> has <<%d>> params.", 147 _INVALID_EVENT_PARAM_LEN : 148 "The length of the event param must be between [1, 32], "\ 149 "but the actual length of the event <<%s>> param <<%s>> is <<%d>>.", 150 _INVALID_EVENT_PARAM_CHAR : 151 "The character of the event param must be in [A-Z0-9_], "\ 152 "but the event <<%s>> param <<%s>> actually has <<%c>>.", 153 _INVALID_EVENT_PARAM_CHAR_HEAD: 154 "The header of the event param must be in [A-Z], "\ 155 "but the actual header of the event <<%s>> param <<%s>> is <<%c>>.", 156 _MISSING_EVENT_PARAM_TYPE : 157 "Event <<%s>> param <<%s>> is missing type definition.", 158 _INVALID_EVENT_PARAM_TYPE : 159 "The type of the event <<%s>> param <<%s>> must be in "\ 160 "[BOOL, INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, "\ 161 "FLOAT, DOUBLE, STRING], but the actual type is <<%s>>.", 162 _INVALID_EVENT_PARAM_ARRSIZE : 163 "The arrsize of the event param must be between [1, 100], "\ 164 "but the actual arrsize of the event <<%s>> param <<%s>> is <<%d>>.", 165 _MISSING_EVENT_PARAM_DESC : 166 "Event <<%s>> param <<%s>> is missing desc definition.", 167 _INVALID_EVENT_PARAM_DESC_LEN : 168 "The length of the event param desc must be between [3, 128], "\ 169 "but the actual length of the event <<%s>> param <<%s>> "\ 170 "desc <<%s>> is <<%d>>.", 171 _INVALID_EVENT_PARAM_KEY : 172 "Event <<%s>> param <<%s>> key should be [type, arrsize, desc], "\ 173 "but actually has an invalid key <<%s>>.", 174 _DEPRECATED_EVENT_NAME_PREFIX : 175 "Event <<%s>> should not start with domain <<%s>>.", 176 _DEPRECATED_PARAM_NAME_PREFIX : 177 "Event param <<%s>> should not start with event <<%s>>.", 178 _DEPRECATED_TAG_NAME : 179 "Event tag <<%s>> should not be same as %s <<%s>>.", 180 _DEPRECATED_EVENT_DESC_NAME : 181 "Event desc <<%s>> should not be same as event <<%s>> and "\ 182 "should be more detailed.", 183 _DEPRECATED_PARAM_DESC_NAME : 184 "Event param desc <<%s>> should not be same as event <<%s>> "\ 185 "param <<%s>> and should be more detailed.", 186 _INVALID_DOMAIN_DEF : 187 "The definition type of the domain must be string.", 188 _INVALID_EVENT_DEF : 189 "The definition type of the event <<%s>> must be dictionary.", 190 _INVALID_EVENT_BASE_DEF : 191 "The definition type of the event <<%s>> __BASE must be dictionary.", 192 _INVALID_EVENT_TYPE_DEF : 193 "The definition type of the event <<%s>> type must be string.", 194 _INVALID_EVENT_LEVEL_DEF : 195 "The definition type of the event <<%s>> level must be string.", 196 _INVALID_EVENT_DESC_DEF : 197 "The definition type of the event <<%s>> desc must be string.", 198 _INVALID_EVENT_TAG_DEF : 199 "The definition type of the event <<%s>> tag must be string.", 200 _INVALID_EVENT_PRESERVE_DEF : 201 "The definition type of the event <<%s>> preserve must be bool.", 202 _INVALID_EVENT_PARAM_DEF : 203 "The definition type of the event <<%s>> param <<%s>> "\ 204 "must be dictionary.", 205 _INVALID_PARAM_TYPE_DEF : 206 "The definition type of the event <<%s>> param <<%s>> "\ 207 "type must be string.", 208 _INVALID_PARAM_ARRSIZE_DEF : 209 "The definition type of the event <<%s>> param <<%s>> "\ 210 "arrsize must be integer.", 211 _INVALID_PARAM_DESC_DEF : 212 "The definition type of the event <<%s>> param <<%s>> "\ 213 "desc must be string.", 214 _DUPLICATE_KEY_DEF : 215 "Duplicate key <<%s>> exists%s.", 216} 217 218 219_domain_dict = {} 220_warning_dict = {} 221_warning_file_path = "" 222_yaml_file_path = "" 223_warning_file = None 224_hisysevent_parse_res = True 225_deprecated_dict = {} 226 227 228class _UniqueKeySafeLoader(yaml.SafeLoader): 229 def construct_mapping(self, node, deep=False): 230 mapping = [] 231 for key_node, value_node in node.value: 232 key = self.construct_object(key_node, deep=deep) 233 if (key in mapping): 234 _build_warning_info(_DUPLICATE_KEY_DEF, 235 (key, key_node.start_mark)) 236 global _hisysevent_parse_res 237 _hisysevent_parse_res = False 238 continue 239 mapping.append(key) 240 return super().construct_mapping(node, deep) 241 242 243def _build_header(info_dict: dict): 244 table_header = "HiSysEvent yaml file: <<%s>>" % _yaml_file_path 245 info_dict[_yaml_file_path] = [table_header] 246 table_boundary = "-".rjust(100, '-') 247 info_dict[_yaml_file_path].append(table_boundary) 248 table_title = "Failed Item".ljust(50) + "| " + "Failed Reason" 249 info_dict[_yaml_file_path].append(table_title) 250 info_dict[_yaml_file_path].append(table_boundary) 251 252 253def _build_warning_header(): 254 global _warning_dict 255 _build_header(_warning_dict) 256 257 258def _build_deprecated_header(): 259 global _deprecated_dict 260 _build_header(_deprecated_dict) 261 262 263def _build_warning_info(item, values): 264 detail = _WARNING_MAP[item] % values 265 content = item.ljust(50) + "| " + detail 266 global _warning_dict 267 _warning_dict[_yaml_file_path].append(content) 268 269 270# Current set to warning, subsequent set to error. 271def _build_deprecated_info(item, values): 272 _build_deprecated_header() 273 detail = _WARNING_MAP[item] % values 274 content = item.ljust(50) + "| " + detail 275 global _deprecated_dict 276 _deprecated_dict[_yaml_file_path].append(content) 277 278 279def _open_warning_file(output_path: str): 280 global _warning_file_path 281 _warning_file_path = os.path.join(output_path, 'hisysevent_warning.txt') 282 global _warning_file 283 _warning_file = open(_warning_file_path, 'w+') 284 285 286def _close_warning_file(): 287 if not _warning_file: 288 _warning_file.close() 289 290 291def _output_warning(): 292 for warning_list in _warning_dict.values(): 293 if len(warning_list) > 4 or len(warning_list) == 1: 294 warning_list.append("") 295 for content in warning_list: 296 print(content) 297 print(content, file=_warning_file) 298 299 300def _output_deprecated(output_path: str): 301 deprecated_file = open(os.path.join(output_path, 'hisysevent_deprecated.txt'), 'w+') 302 for deprecated_list in _deprecated_dict.values(): 303 deprecated_list.append("") 304 for content in deprecated_list: 305 print(content, file=deprecated_file) 306 if not deprecated_file: 307 deprecated_file.close() 308 309 310def _exit_sys(): 311 print("Failed to parse the yaml file. For details about the error "\ 312 "information, see file %s." % (_warning_file_path)) 313 _output_warning() 314 _close_warning_file() 315 sys.exit(1) 316 317 318def _is_valid_length(content: str, len_min: int, len_max: int) -> bool: 319 return len(content) >= len_min and len(content) <= len_max 320 321 322def _is_valid_header(content: str) -> bool: 323 return len(content) == 0 or (content[0] >= 'A' and content[0] <= 'Z') 324 325 326def _is_invalid_char(ch) -> bool: 327 return (ch >= 'A' and ch <= 'Z') or (ch >= '0' and ch <= '9') or ch == '_' 328 329 330def _check_invalid_char(content: str): 331 for ch in iter(content): 332 if not _is_invalid_char(ch): 333 return ch 334 return None 335 336 337def _check_domain_duplicate(domain: str) -> bool: 338 if domain in _domain_dict: 339 _build_warning_info(_DUPLICATE_DOMAIN, (domain, _domain_dict[domain])) 340 return False 341 else: 342 _domain_dict[domain] = _yaml_file_path 343 return True 344 345 346def _check_event_domain(yaml_info: dict) -> bool: 347 if not "domain" in yaml_info: 348 _build_warning_info(_INVALID_DOMAIN_NUMBER, ()) 349 return False 350 if not isinstance(yaml_info["domain"], str): 351 _build_warning_info(_INVALID_DOMAIN_DEF, ()) 352 return False 353 domain = yaml_info["domain"] 354 check_res = True 355 if not _is_valid_length(domain, 1, 16): 356 _build_warning_info(_INVALID_DOMAIN_LENGTH, (domain, len(domain))) 357 check_res = False 358 if not _is_valid_header(domain): 359 _build_warning_info(_INVALID_DOMAIN_CHAR_HEAD, (domain, domain[0])) 360 check_res = False 361 invalid_ch = _check_invalid_char(domain) 362 if invalid_ch: 363 _build_warning_info(_INVALID_DOMAIN_CHAR, (domain, invalid_ch)) 364 check_res = False 365 if not _check_domain_duplicate(domain): 366 check_res = False 367 return check_res 368 369 370def _check_yaml_format(yaml_info) -> bool: 371 if not yaml_info: 372 _build_warning_info(_INVALID_YAML, ("The yaml file is empty")) 373 return False 374 if not isinstance(yaml_info, dict): 375 _build_warning_info(_INVALID_YAML, 376 ("The content of yaml file is invalid")) 377 return False 378 return True 379 380 381def _check_event_name(domain: str, event_name: str) -> bool: 382 check_res = True 383 if not _is_valid_length(event_name, 1, 32): 384 _build_warning_info(_INVALID_EVENT_LENGTH, 385 (event_name, len(event_name))) 386 check_res = False 387 if len(domain) > 0 and event_name.startswith(domain): 388 _build_deprecated_info(_DEPRECATED_EVENT_NAME_PREFIX, 389 (event_name, domain)) 390 if not _is_valid_header(event_name): 391 _build_warning_info(_INVALID_EVENT_CHAR_HEAD, 392 (event_name, event_name[0])) 393 check_res = False 394 invalid_ch = _check_invalid_char(event_name) 395 if invalid_ch: 396 _build_warning_info(_INVALID_DOMAIN_CHAR, (event_name, invalid_ch)) 397 check_res = False 398 return check_res 399 400 401def _check_event_type(event_name: str, event_base: dict) -> bool: 402 if not "type" in event_base: 403 _build_warning_info(_MISSING_EVENT_TYPE, (event_name)) 404 return False 405 else: 406 if not isinstance(event_base["type"], str): 407 _build_warning_info(_INVALID_EVENT_TYPE_DEF, event_name) 408 return False 409 type_list = ["FAULT", "STATISTIC", "SECURITY", "BEHAVIOR"] 410 if not event_base["type"] in type_list: 411 _build_warning_info(_INVALID_EVENT_TYPE, 412 (event_name, event_base["type"])) 413 return False 414 return True 415 416 417def _check_event_level(event_name: str, event_base: dict) -> bool: 418 if not "level" in event_base: 419 _build_warning_info(_MISSING_EVENT_LEVEL, (event_name)) 420 return False 421 else: 422 if not isinstance(event_base["level"], str): 423 _build_warning_info(_INVALID_EVENT_LEVEL_DEF, event_name) 424 return False 425 level_list = ["CRITICAL", "MINOR"] 426 if not event_base["level"] in level_list: 427 _build_warning_info(_INVALID_EVENT_LEVEL, 428 (event_name, event_base["level"])) 429 return False 430 return True 431 432 433def _check_event_desc(event_name: str, event_base: dict) -> bool: 434 if not "desc" in event_base: 435 _build_warning_info(_MISSING_EVENT_DESC, (event_name)) 436 return False 437 else: 438 event_desc = event_base["desc"] 439 if not isinstance(event_desc, str): 440 _build_warning_info(_INVALID_EVENT_DESC_DEF, event_name) 441 return False 442 check_res = True 443 if event_desc.lower() == event_name.lower(): 444 _build_deprecated_info(_DEPRECATED_EVENT_DESC_NAME, 445 (event_desc, event_name)) 446 if not _is_valid_length(event_desc, 3, 128): 447 _build_warning_info(_INVALID_EVENT_DESC_LENGTH, 448 (event_name, event_desc, len(event_desc))) 449 check_res = False 450 return check_res 451 452 453def _check_tag_char(event_tag: list): 454 for ch in iter(event_tag): 455 if not ch.isalnum(): 456 return ch 457 return None 458 459 460def _check_tag_name(event_name: str, event_base: dict, tag_name: str) -> bool: 461 check_res = True 462 if tag_name.lower() == event_name.lower(): 463 _build_deprecated_info(_DEPRECATED_TAG_NAME, 464 (tag_name, "event", event_name)) 465 if "type" in event_base and tag_name.lower() == event_base["type"].lower(): 466 _build_deprecated_info(_DEPRECATED_TAG_NAME, 467 (tag_name, "event type", event_base["type"])) 468 if not _is_valid_length(tag_name, 1, 16): 469 _build_warning_info(_INVALID_EVENT_TAG_LEN, 470 (event_name, tag_name, len(tag_name))) 471 check_res = False 472 invalid_ch = _check_tag_char(tag_name) 473 if invalid_ch: 474 _build_warning_info(_INVALID_EVENT_TAG_CHAR, 475 (event_name, tag_name, invalid_ch)) 476 check_res = False 477 return check_res 478 479 480def _get_duplicate_tag(tag_list: list): 481 tag_dict = dict(Counter(tag_list)) 482 for key, value in tag_dict.items(): 483 if value > 1: 484 return key 485 return None 486 487 488def _check_event_tag(event_name: str, event_base: dict) -> bool: 489 if not "tag" in event_base: 490 return True 491 event_tag = event_base["tag"] 492 if not isinstance(event_tag, str): 493 _build_warning_info(_INVALID_EVENT_TAG_DEF, event_name) 494 return False 495 tag_list = event_tag.split() 496 if not _is_valid_length(tag_list, 1, 5): 497 _build_warning_info(_INVALID_EVENT_TAG_NUM, 498 (event_name, event_tag, len(tag_list))) 499 return False 500 check_res = True 501 for each_tag in tag_list: 502 if not _check_tag_name(event_name, event_base, each_tag): 503 check_res = False 504 dup_tag = _get_duplicate_tag(tag_list) 505 if dup_tag: 506 _build_warning_info(_DUPLICATE_EVENT_TAG, (dup_tag, event_name)) 507 check_res = False 508 return check_res 509 510 511def _check_event_preserve(event_name: str, event_base: dict) -> bool: 512 if not "preserve" in event_base: 513 return True 514 event_preserve = event_base["preserve"] 515 if not isinstance(event_preserve, bool): 516 _build_warning_info(_INVALID_EVENT_PRESERVE_DEF, event_name) 517 return False 518 return True 519 520 521def _check_base_key(event_name: str, event_base: dict) -> bool: 522 key_list = ["type", "level", "tag", "desc", "preserve"] 523 for base_key in event_base.keys(): 524 if not base_key in key_list: 525 _build_warning_info(_INVALID_EVENT_BASE_KEY, 526 (event_name, base_key)) 527 return False 528 return True 529 530 531def _check_event_base(event_name: str, event_def: str) -> bool: 532 if not "__BASE" in event_def: 533 _build_warning_info(_MISSING_EVENT_BASE, (event_name)) 534 return False 535 event_base = event_def["__BASE"] 536 if not isinstance(event_base, dict): 537 _build_warning_info(_INVALID_EVENT_BASE_DEF, (event_name)) 538 return False 539 check_res = True 540 if not _check_event_type(event_name, event_base): 541 check_res = False 542 if not _check_event_level(event_name, event_base): 543 check_res = False 544 if not _check_event_desc(event_name, event_base): 545 check_res = False 546 if not _check_event_tag(event_name, event_base): 547 check_res = False 548 if not _check_event_preserve(event_name, event_base): 549 check_res = False 550 if not _check_base_key(event_name, event_base): 551 check_res = False 552 return check_res 553 554 555def _check_param_name(event_name: str, name: str) -> bool: 556 check_res = True 557 if not _is_valid_length(name, 1, 32): 558 _build_warning_info(_INVALID_EVENT_PARAM_LEN, 559 (event_name, name, len(name))) 560 check_res = False 561 if len(event_name) > 0 and name.startswith(event_name): 562 _build_deprecated_info(_DEPRECATED_PARAM_NAME_PREFIX, (name, event_name)) 563 if not _is_valid_header(name): 564 _build_warning_info(_INVALID_EVENT_PARAM_CHAR_HEAD, 565 (event_name, name, name[0])) 566 check_res = False 567 invalid_ch = _check_invalid_char(name) 568 if invalid_ch: 569 _build_warning_info(_INVALID_EVENT_PARAM_CHAR, 570 (event_name, name, invalid_ch)) 571 check_res = False 572 return check_res 573 574 575def _check_param_type(event_name: str, param_name: str, param_info: dict) -> bool: 576 if not "type" in param_info: 577 _build_warning_info(_MISSING_EVENT_PARAM_TYPE, 578 (event_name, param_name)) 579 return False 580 else: 581 if not isinstance(param_info["type"], str): 582 _build_warning_info(_INVALID_PARAM_TYPE_DEF, 583 (event_name, param_name)) 584 return False 585 type_list = ["BOOL", "INT8", "UINT8", "INT16", "UINT16", "INT32", 586 "UINT32", "INT64", "UINT64", "FLOAT", "DOUBLE", "STRING"] 587 if not param_info["type"] in type_list: 588 _build_warning_info(_INVALID_EVENT_PARAM_TYPE, 589 (event_name, param_name, param_info["type"])) 590 return False 591 return True 592 593 594def _check_param_arrsize(event_name: str, param_name: str, param_info: dict) -> bool: 595 if not "arrsize" in param_info: 596 return True 597 arrsize = param_info["arrsize"] 598 if not isinstance(arrsize, int): 599 _build_warning_info(_INVALID_PARAM_ARRSIZE_DEF, 600 (event_name, param_name)) 601 return False 602 if not (arrsize >= 1 and arrsize <= 100): 603 _build_warning_info(_INVALID_EVENT_PARAM_ARRSIZE, 604 (event_name, param_name, arrsize)) 605 return False 606 return True 607 608 609def _check_param_desc(event_name: str, param_name: str, param_info: dict) -> bool: 610 if not "desc" in param_info: 611 _build_warning_info(_MISSING_EVENT_PARAM_DESC, 612 (event_name, param_name)) 613 return False 614 else: 615 param_desc = param_info["desc"] 616 if not isinstance(param_desc, str): 617 _build_warning_info(_INVALID_PARAM_DESC_DEF, 618 (event_name, param_name)) 619 return False 620 check_res = True 621 if param_desc.lower() == param_name.lower(): 622 _build_deprecated_info(_DEPRECATED_PARAM_DESC_NAME, 623 (param_desc, event_name, param_name)) 624 if not _is_valid_length(param_desc, 3, 128): 625 _build_warning_info(_INVALID_EVENT_PARAM_DESC_LEN, 626 (event_name, param_name, param_desc, len(param_desc))) 627 check_res = False 628 return check_res 629 630 631def _check_param_key(event_name: str, param_name: str, param_info: dict) -> bool: 632 key_list = ["type", "arrsize", "desc"] 633 for key in param_info.keys(): 634 if not key in key_list: 635 _build_warning_info(_INVALID_EVENT_PARAM_KEY, 636 (event_name, param_name, key)) 637 return False 638 return True 639 640 641def _check_param_info(event_name: str, param_name: str, param_info: dict) -> bool: 642 check_res = True 643 if not _check_param_type(event_name, param_name, param_info): 644 check_res = False 645 if not _check_param_arrsize(event_name, param_name, param_info): 646 check_res = False 647 if not _check_param_desc(event_name, param_name, param_info): 648 check_res = False 649 if not _check_param_key(event_name, param_name, param_info): 650 check_res = False 651 return check_res 652 653 654def _check_event_param(event_name: str, event_def: str) -> bool: 655 sub_num = (0, 1)["__BASE" in event_def] 656 check_res = True 657 if not _is_valid_length(event_def, 0 + sub_num, 128 + sub_num): 658 _build_warning_info(_INVALID_EVENT_PARAM_NUM, 659 (event_name, (len(event_def) - sub_num))) 660 check_res = False 661 for param_name in event_def.keys(): 662 if param_name == "__BASE": 663 continue 664 if not _check_param_name(event_name, param_name): 665 check_res = False 666 param_info = event_def[param_name] 667 if not isinstance(param_info, dict): 668 _build_warning_info(_INVALID_EVENT_PARAM_DEF, 669 (event_name, param_name)) 670 check_res = False 671 continue 672 if not _check_param_info(event_name, param_name, param_info): 673 check_res = False 674 return check_res 675 676 677def _check_event_def(event_name: str, event_def: str) -> bool: 678 check_res = True 679 if not _check_event_base(event_name, event_def): 680 check_res = False 681 if not _check_event_param(event_name, event_def): 682 check_res = False 683 return check_res 684 685 686def _check_event_info(domain: str, event_info: list) -> bool: 687 event_name = event_info[0] 688 event_def = event_info[1] 689 check_res = True 690 if not isinstance(event_def, dict): 691 _build_warning_info(_INVALID_EVENT_DEF, (event_name)) 692 return False 693 if not _check_event_name(domain, event_name): 694 check_res = False 695 if not _check_event_def(event_name, event_def): 696 check_res = False 697 return check_res 698 699 700def _check_events_info(domain: str, yaml_info: str) -> bool: 701 event_num = len(yaml_info) 702 if not (event_num >= 1 and event_num <= 4096): 703 _build_warning_info(_INVALID_EVENT_NUMBER, (event_num)) 704 return False 705 check_res = True 706 for event_info in yaml_info.items(): 707 if not _check_event_info(domain, event_info): 708 check_res = False 709 return check_res 710 711 712def merge_hisysevent_config(yaml_list: str, output_path: str) -> str: 713 if (len(output_path) == 0): 714 present_path = os.path.dirname(os.path.abspath(__file__)) 715 output_path = present_path 716 if (len(yaml_list) == 0): 717 _build_warning_info(_EMPTY_YAML, ()) 718 _exit_sys() 719 if not os.path.exists(output_path): 720 os.makedirs(output_path, exist_ok=True) 721 _open_warning_file(output_path) 722 723 yaml_info_dict = {} 724 global _hisysevent_parse_res 725 for yaml_path in yaml_list: 726 global _yaml_file_path 727 _yaml_file_path = yaml_path.replace("../", "") 728 _build_warning_header() 729 with os.fdopen(os.open(yaml_path, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 730 'r', encoding='utf-8') as yaml_file: 731 yaml_info = yaml.load(yaml_file, Loader=_UniqueKeySafeLoader) 732 if not _check_yaml_format(yaml_info): 733 _hisysevent_parse_res = False 734 continue 735 if not _check_event_domain(yaml_info): 736 _hisysevent_parse_res = False 737 continue 738 domain = yaml_info["domain"] 739 del yaml_info["domain"] 740 if not _check_events_info(domain, yaml_info): 741 _hisysevent_parse_res = False 742 continue 743 yaml_info_dict[domain] = yaml_info 744 _output_deprecated(output_path) 745 if not _hisysevent_parse_res: 746 _exit_sys() 747 748 hisysevent_def_file = os.path.join(output_path, 'hisysevent.def') 749 with open(hisysevent_def_file, 'w') as j: 750 json.dump(yaml_info_dict, j, indent=4) 751 print("The hisysevent.def {} is generated successfully." 752 .format(hisysevent_def_file)) 753 _close_warning_file() 754 return hisysevent_def_file 755 756 757def main(argv) -> int: 758 parser = argparse.ArgumentParser(description='yaml list') 759 parser.add_argument("--yaml-list", nargs='+', required=True) 760 parser.add_argument("--def-path", required=True) 761 args = parser.parse_args(argv) 762 hisysevent_def_file = merge_hisysevent_config(args.yaml_list, 763 args.def_path) 764 print(hisysevent_def_file) 765 return 0 766 767 768if __name__ == '__main__': 769 sys.exit(main(sys.argv[1:])) 770