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